-1

i actually write a shared object loader, which loads with the gcc created shared-objects (ELF) on a cortex-m4 controller. Loading, dependency resolving and relocating etc works fine. But the shared object has some strange symbols in the .dynsym section which i dont know how to handle.

readelf --dyn-sym libfoo.so

       Num:    Wert   Size Typ     Bind   Vis      Ndx Name                                                                                                                       
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND                                                                                                                            
     1: 000005c8     0 SECTION LOCAL  DEFAULT    8                                                                                                                            
     2: 00000874     0 SECTION LOCAL  DEFAULT   16                                                                                                                            
     3: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND printf                                                                                                                     
     4: 0000082d    32 FUNC    GLOBAL DEFAULT   12 foo3                                                                                                                       
     5: 0000087c     0 NOTYPE  GLOBAL DEFAULT   18 __bss_start__                                                                                                              
     6: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND __libc_init_array                                                                                                          
     7: 00000728     0 NOTYPE  GLOBAL DEFAULT   12 _mainCRTStartup                                                                                                            
     8: 000005c8     0 FUNC    GLOBAL DEFAULT    8 _init                                                                                                                      
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND __libc_fini_array                                                                                                          
    10: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __deregister_frame_info                                                                                                    
    11: 00000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable                                                                                                  
    12: 00000898     0 NOTYPE  GLOBAL DEFAULT   18 __bss_end__                                                                                                                
    13: 00000728     0 NOTYPE  GLOBAL DEFAULT   12 _start                                                                                                                     
    14: 00000000     0 NOTYPE  WEAK   DEFAULT  UND software_init_hook                                                                                                         
    15: 00000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab                                                                                                  
    16: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND memset                                                                                                                     
    17: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND main                                                                                                                       
    18: 00000000     0 NOTYPE  WEAK   DEFAULT  UND hardware_init_hook                                                                                                         
    19: 000005e0     0 FUNC    GLOBAL DEFAULT    9 _fini                                                                                                                      
    20: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND atexit                                                                                                                     
    21: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __stack                                                                                                                    
    22: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND exit                                                                                                                       
    23: 00000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses                                                                                                        
    24: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __register_frame_info

Why do the shared object need a reference to a main-function and to the __libc_init_array function? Especially the symbol to __libc_init_array makes no sense to me... This function normaly initializes the __preinit_array, _init and __init_array, but this job should be done by my loader not by the object itself, or i am wrong?

Is there anywhere a step-by-step documentation how to initialize a loaded shared-object with all its dependencies?

This is the way, how i build my shared-object:

gcc -std=gnu99 -W -Wall -Wstrict-prototypes -Wmissing-prototypes -ffunction-sections -fdata-sections -mfloat-abi=soft -mcpu=cortex-m4 -mthumb -mlong-calls -Os -g -c -fPIC -o foo.o foo.c

gcc -shared -fPIC -Wl,-soname,libfoo.so -T./shared.ld -o libfoo.so foo.o

There is just another question: Without the -mlong-calls option, my gcc generates invalid opcode in the .plt section... what i'm doing wrong?

EDIT: My foo.c is verry simple:

#include <stdio.h>
#include <string.h>

void foo3 (void)
{
    printf("Hello from shared-object");
}

This is my shared.ld:

OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")

OUTPUT_ARCH(arm)

SECTIONS
{
    .interp         : { *(.interp) } 
    .note.ABI-tag   : { *(.note.ABI-tag) }
    
    .gnu.version    : { *(.gnu.version) } 
    .gnu.version_d  : { *(.gnu.version_d) } 
    .gnu.version_r  : { *(.gnu.version_r) } 

    .dynamic        : { *(.dynamic) }

    .hash           : { *(.hash) } 
    .dynsym         : { *(.dynsym) } 
    .dynstr         : { *(.dynstr) } 
    
    .rel.dyn        : { *(.rel.dyn) }
    .rela.dyn       : { *(.rela.dyn) }
    .rel.plt        : { *(.rel.plt) }
    .rela.plt       : { *(.rela.plt) }

    .plt            : { *(.plt) }
    .got            : { *(.got.plt) *(.got) }

    .init ALIGN(32 / 8) :
    {
        KEEP (*(.init))
    } 

    .fini ALIGN(32 / 8) :
    {
        KEEP (*(.fini))
    } 

    .preinit_array ALIGN(32 / 8) :
    {
        PROVIDE(__preinit_array_start = .); 
        KEEP (*(.preinit_array))
        PROVIDE(__preinit_array_end = .); 
    }

    .init_array ALIGN(32 / 8) :
    {
        PROVIDE(__init_array_start = .); 
        KEEP (*(.init_array*))
        PROVIDE(__init_array_end = .); 
    }

    .fini_array ALIGN(32 / 8) :
    {
        PROVIDE(__fini_array_start = .); 
        KEEP (*(.fini_array*))
        PROVIDE(__fini_array_end = .); 
    }

    .text ALIGN(32 / 8) :
    {
        *(.text .text.*)
    } 

    .rodata ALIGN(32 / 8) : 
    { 
        *(.rodata .rodata.*) 
    } 

    .data ALIGN(32 / 8) :
    {
        *(.data .data.*)
    } 

    .bss ALIGN(32 / 8) :
    {
        PROVIDE(__bss_start__ = .);
    
        *(.bss .bss.*)
        *(COMMON)
    
        PROVIDE(__bss_end__ = .);
    } 
}

NOTICE: The reference to _printf_ is set to the the printf of my main program at linktime - just for testing purpose.

thanks for your help :-)

yugr
  • 19,769
  • 3
  • 51
  • 96
Andi
  • 21
  • 2
  • It'd help if you also provided (trimmed) code for foo.c and shared.ld. – yugr Nov 15 '16 at 10:21
  • "Without the -mlong-calls option, my gcc generates invalid opcode in the .plt section... what i'm doing wrong?" - if this reproduces on recent binutils, you should [file a bug](https://sourceware.org/bugzilla/). – yugr Nov 15 '16 at 10:22
  • I wonder if your toolchain is capable of building shared libraries. Could you check suggestions in http://stackoverflow.com/questions/18586291/could-not-build-shared-library-using-toolchain-arm-uclinuxeabi ? – yugr Nov 15 '16 at 12:40
  • Thanks for the link. My Toolchain is build with the --disable-shared option, but at the moment i can build shared-objects!?!?!??? Maybe this could be the reason for the invalid opcode... – Andi Nov 15 '16 at 14:09

1 Answers1

0

I solved the first problem! -nostartfiles was my friend :-)

gcc -std=gnu99 -W -Wall -Wstrict-prototypes -Wmissing-prototypes -ffunction-sections -fdata-sections -mfloat-abi=soft -mcpu=cortex-m4 -mthumb -mlong-calls -Os -g -c -fPIC -o foo.o foo.c

gcc -shared -fPIC -nostartfiles -mfloat-abi=soft -mcpu=cortex-m4 -mthumb -Wl,-soname,libfoo.so -T./shared.ld -o libfoo.so foo.o

without the whole crtxxx stuff the library is now clean!

the problem with the invalid opcode still exists, but i'm using gcc in version 4.7.4, so this "bug" maybe fixed today.

Andi
  • 21
  • 2