【问题标题】:shared object on Cortex-M4 strange symbols in dynsym sectiondynsym 部分中 Cortex-M4 奇怪符号上的共享对象
【发布时间】:2016-11-15 09:40:33
【问题描述】:

我实际上编写了一个共享对象加载器,它在 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

为什么共享对象需要对主函数和__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 - 仅用于测试目的。

感谢您的帮助 :-)

【问题讨论】:

  • 如果您还为 foo.c 和 shared.ld 提供(修剪过的)代码会有所帮助。
  • “如果没有 -mlong-calls 选项,我的 gcc 在 .plt 部分会生成无效的操作码……我做错了什么?” - 如果这在最近的 binutils 上重现,你应该file a bug
  • 我想知道您的工具链是否能够构建共享库。您能查看stackoverflow.com/questions/18586291/… 中的建议吗?
  • 感谢您的链接。我的工具链是使用 --disable-shared 选项构建的,但目前我可以构建共享对象!?!?!???也许这可能是无效操作码的原因......

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


【解决方案1】:

我解决了第一个问题! -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,所以这个“错误”今天可能已修复。

【讨论】:

    猜你喜欢
    • 2023-04-07
    • 1970-01-01
    • 2013-03-10
    • 1970-01-01
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    相关资源
    最近更新 更多