如何让链接器优先选择动态库符号而非本地弱符号?
链接器优先选择本地弱符号而非动态库符号问题
我无法让链接器优先选用动态库中的puts符号,反而会使用目标文件a.o中的本地弱符号,无论是使用lld还是GNU ld均存在该问题。重定位被硬编码到本地puts而非通过PLT处理,我并未生成静态可执行文件。
代码与操作过程
# 查看代码内容 tail -n10 {a,main}.c ==> a.c <== #include <stdlib.h> __attribute__((weak)) int puts(const char *ignore) { abort(); } ==> main.c <== int puts(const char*); int main() { puts("Should work"); } # 编译生成目标文件 clang-16 -c {a,main}.c # 查看main.o的重定位表 readelf -r main.o Relocation section '.rela.text' at offset 0x180 contains 2 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000000007 000300000002 R_X86_64_PC32 0000000000000000 .L.str - 4 00000000000c 000500000004 R_X86_64_PLT32 0000000000000000 puts - 4 Relocation section '.rela.eh_frame' at offset 0x1b0 contains 1 entry: Offset Info Type Sym. Value Sym. Name + Addend 000000000020 000200000002 R_X86_64_PC32 0000000000000000 .text + 0 # 查看a.o的符号表 readelf --syms a.o Symbol table '.symtab' contains 5 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS a.c 2: 0000000000000000 0 SECTION LOCAL DEFAULT 2 .text 3: 0000000000000000 17 FUNC WEAK DEFAULT 2 puts 4: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND abort # 链接并追踪puts符号 clang-16 -fuse-ld=lld -v -Wl,--trace-symbol=puts /lib/x86_64-linux-gnu/libc.so.6 {a,main}.o Debian clang version 16.0.6 (++20230710041738+7cbf1a259152-1~exp1~20230710161755.7) Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/12 Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/12 Candidate multilib: .;@m64 Selected multilib: .;@m64 "/usr/lib/llvm-16/bin/ld.lld" -pie --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /lib/x86_64-linux-gnu/Scrt1.o /lib/x86_64-linux-gnu/crti.o /usr/bin/../lib/gcc/x86_64-linux-gnu/12/crtbeginS.o -L/usr/bin/../lib/gcc/x86_64-linux-gnu/12 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib64 -L/lib -L/usr/lib --trace-symbol=puts /lib/x86_64-linux-gnu/libc.so.6 a.o main.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/bin/../lib/gcc/x86_64-linux-gnu/12/crtendS.o /lib/x86_64-linux-gnu/crtn.o /lib/x86_64-linux-gnu/libc.so.6: shared definition of puts a.o: definition of puts main.o: reference to puts # 运行程序 ./a.out Aborted (core dumped) # 用gdb查看main函数汇编 gdb -quiet a.out Reading symbols from a.out... (No debugging symbols found in a.out) (gdb) disassemble main Dump of assembler code for function main: 0x0000000000001780 <+0>: push %rbp 0x0000000000001781 <+1>: mov %rsp,%rbp 0x0000000000001784 <+4>: lea -0x11df(%rip),%rdi # 0x5ac 0x000000000000178b <+11>: call 0x1760 <puts> 0x0000000000001790 <+16>: xor %eax,%eax 0x0000000000001792 <+18>: pop %rbp 0x0000000000001793 <+19>: ret End of assembler dump.
内容的提问来源于stack exchange,提问作者Artefacto
相关产品推荐
相关产品推荐

