gold linker support for shared libraries on powerpc
Hamish Macdonald
Hamish.Macdonald@alcatel-lucent.com
Wed Jan 11 23:17:00 GMT 2012
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.
More information about the Binutils
mailing list