2016-11-15 25 views
-1

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

为什么共享对象需要一个主功能和对__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通话选项,我的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至基准设置到linktime的主程序的printf - 仅用于测试目的。

感谢您的帮助:-)

+0

如果您还为foo.c和shared.ld提供了(修剪)代码,它会有所帮助。 – yugr

+0

“如果没有-mlong-calls选项,我的gcc会在.plt部分生成无效的操作码......我做错了什么?” - 如果在最近的binutils上复制,你应该[提交一个bug](https://sourceware.org/bugzilla/)。 – yugr

+0

我不知道你的工具链是否有能力建立共享库。你可以检查http://stackoverflow.com/questions/18586291/could-not-build-shared-library-using-toolchain-arm-uclinuxeabi中的建议吗? – yugr

回答

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,所以这个“bug”今天可能会修复。