我正在尝试将我的C ++可执行文件链接到共享C库(也是由我/我的同事编写)。
C ++可执行文件只包含一个打印" Hello World"到stdout并返回0。
运行正常。但是一旦我动态链接到我的C库(我甚至没有调用这个lib),我的C ++可执行文件在启动时失败:
/opt/av-server # strace ./program
execve("./program", ["./program"], [/* 10 vars */]) = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
+++ killed by SIGSEGV +++
Segmentation fault
我做了一些研究,发现只要我链接到C库,我的ELF标题开始看起来很奇怪。入口点地址可疑地低,第一个LOAD的地址全为零:
Elf file type is DYN (Shared object file)
Entry point 0x6d8
There are 6 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
EXIDX 0x000960 0x00000960 0x00000960 0x00010 0x00010 R 0x4
LOAD 0x000000 0x00000000 0x00000000 0x00974 0x00974 R E 0x10000
LOAD 0x000ee0 0x00010ee0 0x00010ee0 0x0015c 0x00164 RW 0x10000
DYNAMIC 0x000ef0 0x00010ef0 0x00010ef0 0x00110 0x00110 RW 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
GNU_RELRO 0x000ee0 0x00010ee0 0x00010ee0 0x00120 0x00120 R 0x1
Section to Segment mapping:
Segment Sections...
00 .ARM.exidx
01 .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .ARM.extab .ARM.exidx .eh_frame
02 .init_array .fini_array .jcr .dynamic .got .data .bss
03 .dynamic
04
05 .init_array .fini_array .jcr .dynamic
我想这解释了为什么程序是segfaulting:它跳转到0:/作为比较,这是当我不与lib链接时生成的标题:
Elf file type is EXEC (Executable file)
Entry point 0x10588
There are 9 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
EXIDX 0x0007fc 0x000107fc 0x000107fc 0x00018 0x00018 R 0x4
PHDR 0x000034 0x00010034 0x00010034 0x00120 0x00120 R E 0x4
INTERP 0x000154 0x00010154 0x00010154 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.3]
LOAD 0x000000 0x00010000 0x00010000 0x00818 0x00818 R E 0x10000
LOAD 0x000ef0 0x00020ef0 0x00020ef0 0x00148 0x001dc RW 0x10000
DYNAMIC 0x000f00 0x00020f00 0x00020f00 0x00100 0x00100 RW 0x4
NOTE 0x000168 0x00010168 0x00010168 0x00020 0x00020 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
GNU_RELRO 0x000ef0 0x00020ef0 0x00020ef0 0x00110 0x00110 R 0x1
Section to Segment mapping:
Segment Sections...
00 .ARM.exidx
01
02 .interp
03 .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .ARM.extab .ARM.exidx .eh_frame
04 .init_array .fini_array .jcr .dynamic .got .data .bss
05 .dynamic
06 .note.ABI-tag
07
08 .init_array .fini_array .jcr .dynamic
我理解为什么它必须是段错误的。但真正的问题是: C库中的哪些内容可能会以这种方式破坏ELF标题?
我想知道要寻找。我怀疑是在lib的某个地方使用了一些编译器内在函数。只是一个疯狂的猜测。
我用GCC6.3交叉编译Linux bha-1CCAE370CE47 3.4.35 #1 Thu Mar 9 11:20:13 HKT 2017 armv5tejl GNU/Linux
。工具链是用crosstool-ng构建的。构建系统是macOS。