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