dynsym部分

时间:2016-11-15 09:40:34

标签: gcc elf shared-objects cortex-m dynamic-loading

我实际上编写了一个共享对象加载器,它在cortex-m4控制器上加载了gcc创建的共享对象(ELF)。加载,依赖解析和重定位等工作正常。但共享对象在.dynsym部分有一些奇怪的符号,我不知道如何处理。

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

为什么共享对象需要引用main-function和__libc_init_array函数?特别是__libc_init_array的符号对我没有意义......这个函数正常地初始化__preinit_array,_init和__init_array,但是这个工作应该由我的加载器完成,而不是由对象本身完成,或者我错了?

是否有任何地方的逐步文档如何初始化一个包含所有依赖项的已加载共享对象?

这就是我如何构建共享对象的方式:

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

还有另外一个问题:如果没有-mlong-calls选项,我的gcc会在.plt部分生成无效的操作码......我做错了什么?

修改 我的foo.c非常简单:

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

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

这是我的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__ = .);
    } 
}

注意: printf 的引用在链接时设置为主程序的printf - 仅用于测试目的。

感谢您的帮助: - )

1 个答案:

答案 0 :(得分:0)

我解决了第一个问题! -nostartfiles是我的朋友: - )

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

没有整个crtxxx的东西,库现在已经干净了!

无效操作码的问题仍然存在,但我在版本4.7.4中使用gcc,所以这个&#34; bug&#34;也许今天就修好了。