This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: gold linker support for shared libraries on powerpc
On 11/01/2012 5:31 PM, Cary Coutant wrote:
My experiments seem to show that it cannot be done. The gold linker
complains about a relocation in my crti.o file (of type R_PPC_LOCAL24PC):
.../target/usr/lib/crti.o: requires unsupported dynamic reloc;
recompile with -fPIC
This relocation, as I understand it, is normally expected to be a
non-interposable reference to _GLOBAL_OFFSET_TABLE_. If the linker is
deciding that it needs a dynamic relocation here, it would be because
the symbol is undefined. I'm not sure why it would be undefined.
Hmm... Here is the relocation and symbol information from crti.o.
When I did a quick check with the debugger,
it appears to be the first relocation (the _GLOBAL_OFFSET_TABLE_
relative one) with which it is unhappy. The symbol is undefined
(presumably as expected) in the crti.o object file. Presumably the
linker should be providing a definition, however (although that
definition may not yet exist when gold is processing the relocations in
crti.o).
[hmacdona@linuxdev01 tmp]$ $objdump -r .../target/usr/lib/crti.o
.../target/usr/lib/crti.o: file format elf32-powerpc
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000010 R_PPC_LOCAL24PC _GLOBAL_OFFSET_TABLE_+0xfffffffc
0000001a R_PPC_GOT16 __gmon_start__
RELOCATION RECORDS FOR [.init]:
OFFSET TYPE VALUE
0000000c R_PPC_LOCAL24PC .text
RELOCATION RECORDS FOR [.debug_line]:
OFFSET TYPE VALUE
0000004d R_PPC_ADDR32 .fini
0000005e R_PPC_ADDR32 .init
00000070 R_PPC_ADDR32 .text
RELOCATION RECORDS FOR [.debug_info]:
OFFSET TYPE VALUE
00000006 R_PPC_ADDR32 .debug_abbrev
0000000c R_PPC_ADDR32 .debug_line
RELOCATION RECORDS FOR [.debug_aranges]:
OFFSET TYPE VALUE
00000006 R_PPC_ADDR32 .debug_info
00000010 R_PPC_ADDR32 .fini
00000018 R_PPC_ADDR32 .init
00000020 R_PPC_ADDR32 .text
[hmacdona@linuxdev01 tmp]$ $nm -a --format sysv
.../target/usr/lib/crti.o
Symbols from .../target/usr/lib/crti.o:
Name Value Class Type Size
Line Section
.bss |00000000| b | SECTION| |
|.bss
call_gmon_start |00000000| t | FUNC| |
|.text
.comment |00000000| n | SECTION| |
|.comment
.data |00000000| d | SECTION| |
|.data
.debug_abbrev |00000000| N | SECTION| |
|.debug_abbrev
.debug_aranges |00000000| N | SECTION| |
|.debug_aranges
.debug_info |00000000| N | SECTION| |
|.debug_info
.debug_line |00000000| N | SECTION| |
|.debug_line
_fini |00000000| T | FUNC| |
|.fini
.fini |00000000| t | SECTION| |
|.fini
_GLOBAL_OFFSET_TABLE_| | U | NOTYPE|
| |*UND*
__gmon_start__ | | w | NOTYPE| |
|*UND*
_init |00000000| T | FUNC| |
|.init
.init |00000000| t | SECTION| |
|.init
initfini.c |00000000| a | FILE| |
|*ABS*
.note.GNU-stack |00000000| n | SECTION| |
|.note.GNU-stack
.text |00000000| t | SECTION| |
|.text
/var/tmp/BUILD/glibc-2.3.3/objdir/csu/crti.S|00000000| a
| FILE| | |*ABS*
Here is the backtrace from when the error is generated:
(gdb) where
#0 check_non_pic (this=0xbfa525cf, object=0x8aff5c8, r_type=23)
at powerpc.cc:1278
#1 0x080a7a7d in global (this=0xbfa525cf, symtab=0xbfa558c4,
layout=0xbfa556a8, target=0x8aff580, object=0x8aff5c8, data_shndx=1,
output_section=0x8affe88, reloc=@0xbfa525c8, r_type=23,
gsym=0x8b01808)
at powerpc.cc:1536
#2 0x080a2d0e in scan_relocs<32, true, <unnamed>::Target_powerpc<32,
true>, 4, <unnamed>::Target_powerpc<32, true>::Scan> (symtab=0xbfa558c4,
layout=0xbfa556a8, target=0x8aff580, object=0x8aff5c8, data_shndx=1,
prelocs=0xb7f2977c "", reloc_count=2, output_section=0x8affe88,
needs_special_offset_handling=false, local_count=15,
plocal_syms=0xb7f295d0 "") at target-reloc.h:116
#3 0x0809cce0 in scan_relocs (this=0x8aff580, symtab=0xbfa558c4,
layout=0xbfa556a8, object=0x8aff5c8, data_shndx=1, sh_type=4,
prelocs=0xb7f2977c "", reloc_count=2, output_section=0x8affe88,
needs_special_offset_handling=false, local_symbol_count=15,
plocal_symbols=0xb7f295d0 "") at powerpc.cc:1695
#4 0x0822d82e in gold::Sized_relobj_file<32, true>::do_scan_relocs (
this=0x8aff5c8, symtab=0xbfa558c4, layout=0xbfa556a8, rd=0x8afca68)
at reloc.cc:462
#5 0x0822af8d in gold::Relobj::scan_relocs (this=0x8aff5c8,
symtab=0xbfa558c4, layout=0xbfa556a8, rd=0x8afca68) at object.h:1010
#6 0x0822ab69 in gold::Scan_relocs::run (this=0x8b60b50) at reloc.cc:188
#7 0x0829758b in gold::Workqueue::find_and_run_task (this=0xbfa55bd8,
thread_number=0) at workqueue.cc:319
#8 0x08297ace in gold::Workqueue::process (this=0xbfa55bd8,
thread_number=0)
at workqueue.cc:495
#9 0x0804b4ee in main (argc=32, argv=0xbfa55cf4) at main.cc:248
I see the following in the function ppc_elf_check_relocs in source file
elf32-ppc.c in the BFD sources. Perhaps something similar is needed in
gold.
/* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
This shows up in particular in an R_PPC_ADDR32 in the eabi
startup code. */
if (h != NULL
&& htab->got == NULL
&& strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
{
if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
if (!ppc_elf_create_got (htab->elf.dynobj, info))
return FALSE;
BFD_ASSERT (h == htab->elf.hgot);
}
/* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
This shows up in particular in an R_PPC_ADDR32 in the eabi
startup code. */
if (h != NULL
&& htab->got == NULL
&& strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
{
if (htab->elf.dynobj == NULL)
htab->elf.dynobj = abfd;
if (!ppc_elf_create_got (htab->elf.dynobj, info))
return FALSE;
BFD_ASSERT (h == htab->elf.hgot);
}
In addition, gold complains about about a R_POWERPC_REL32 relocation in my
single (test) object file (which was compiled with -fPIC):
error: shared.o: unsupported reloc 26 against global symbol
DW.ref.__gxx_personality_v0
This relocation is not expected to be used with a global symbol,
according to the powerpc target code in gold. If that's not accurate,
then gold will need to be fixed to handle it.
The relocation is in the ".eh_frame" section.
File was 'shared.cc', with contents:
----------------------------------------------------------
#include <stdio.h>
int foobar()
{
printf("Hello there\n");
return 0;
}
----------------------------------------------------------
Here are the relocation records for the object file:
[hmacdona@linuxdev01 tmp]$ $objdump -r shared.o
shared.o: file format elf32-powerpc
RELOCATION RECORDS FOR [.text]:
OFFSET TYPE VALUE
00000000 R_PPC_REL32 .got2+0x00007fe0
00000034 R_PPC_PLTREL24 printf
RELOCATION RECORDS FOR [.got2]:
OFFSET TYPE VALUE
00000000 R_PPC_ADDR32 .rodata
RELOCATION RECORDS FOR [.eh_frame]:
OFFSET TYPE VALUE
00000012 R_PPC_REL32 DW.ref.__gxx_personality_v0
00000024 R_PPC_REL32 .text+0x00000004
RELOCATION RECORDS FOR [.sdata.DW.ref.__gxx_personality_v0]:
OFFSET TYPE VALUE
00000000 R_PPC_ADDR32 __gxx_personality_v0
and the symbols.
[hmacdona@linuxdev01 tmp]$ $nm -a --format sysv shared.o
Symbols from shared.o:
Name Value Class Type Size
Line Section
.bss |00000000| b | SECTION| |
|.bss
.comment |00000000| n | SECTION| |
|.comment
.data |00000000| d | SECTION| |
|.data
DW.ref.__gxx_personality_v0|00000000| V |
OBJECT|00000004| |.sdata.DW.ref.__gxx_personality_v0
.eh_frame |00000000| r | SECTION| |
|.eh_frame
.got2 |00000000| d | SECTION| |
|.got2
.group |00000000| n | SECTION| |
|DW.ref.__gxx_personality_v0
__gxx_personality_v0| | U | NOTYPE| |
|*UND*
.note.GNU-stack |00000000| n | SECTION| |
|.note.GNU-stack
printf | | U | NOTYPE| |
|*UND*
.rodata |00000000| r | SECTION| |
|.rodata
.sdata.DW.ref.__gxx_personality_v0|00000000| g |
SECTION| | |.sdata.DW.ref.__gxx_personality_v0
shared.cc |00000000| a | FILE| |
|*ABS*
.text |00000000| t | SECTION| |
|.text
_Z6foobarv |00000004| T | FUNC|00000058|
|.text
If I compile with the C compiler (rather than the C++ compiler), it
doesn't generate the exception handling data, and gold doesn't complain
about the shared.o object file, but is still unhappy with crti.o, and
still refuses to generate the shared library.
Thanks,
Hamish.