У меня есть следующая библиотека:
shared4.c
:
int get_another_int(void){
return 10;
}
И двоичный файл:
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
int get_another_int(void);
int main(void){
void *handle = dlopen("/home/me/c/build/libshar4.so", RTLD_GLOBAL | RTLD_NOW);
if(!handle){
exit(EXIT_FAILURE);
}
printf("handle = %p\n", handle);
printf("another_int = %d\n", get_another_int());
}
Я не связывал двоичный файл с библиотекойи добавлена опция ld
, чтобы игнорировать ошибку "символ не найден":
-Wl,-z,lazy -Wl,--unresolved-symbols=ignore-all
При таких параметрах двоичный файл скомпилирован и связан с "fine".
Раздел plt
выглядит следующим образом:
$ objdump -d -j .plt ./build/bin_shared
./build/bin_shared: file format elf64-x86-64
Disassembly of section .plt:
00000000000005e0 <.plt>:
5e0: ff 35 22 0a 20 00 pushq 0x200a22(%rip) # 201008 <_GLOBAL_OFFSET_TABLE_+0x8>
5e6: ff 25 24 0a 20 00 jmpq *0x200a24(%rip) # 201010 <_GLOBAL_OFFSET_TABLE_+0x10>
5ec: 0f 1f 40 00 nopl 0x0(%rax)
...
0000000000000600 <dlopen@plt>:
600: ff 25 1a 0a 20 00 jmpq *0x200a1a(%rip) # 201020 <dlopen@GLIBC_2.2.5>
606: 68 00 00 00 00 pushq $0x0
60b: e9 d0 ff ff ff jmpq 5e0 <.plt>
0000000000000610 <__printf_chk@plt>:
610: ff 25 12 0a 20 00 jmpq *0x200a12(%rip) # 201028 <__printf_chk@GLIBC_2.3.4>
616: 68 01 00 00 00 pushq $0x1
61b: e9 c0 ff ff ff jmpq 5e0 <.plt>
0000000000000620 <exit@plt>:
620: ff 25 0a 0a 20 00 jmpq *0x200a0a(%rip) # 201030 <exit@GLIBC_2.2.5>
626: 68 02 00 00 00 pushq $0x2
62b: e9 b0 ff ff ff jmpq 5e0 <.plt>
Я изучил objdump
и заметил следующий фрагмент main
:
66b: e8 a0 ff ff ff callq 610 <__printf_chk@plt>
670: e8 7b ff ff ff callq 5f0 <.plt+0x10>
Но приложение не запустилось со следующей ошибкой:
$ ./build/bin_shared
./build/bin_shared: error while loading shared libraries: unexpected PLT reloc type 0x00
Я посмотрел на все типы перемещения:
$ objdump -R ./build/bin_shared
./build/bin_shared: file format elf64-x86-64
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
0000000000200dd8 R_X86_64_RELATIVE *ABS*+0x00000000000007a0
0000000000200de0 R_X86_64_RELATIVE *ABS*+0x0000000000000760
0000000000201040 R_X86_64_RELATIVE *ABS*+0x0000000000201040
0000000000200fd8 R_X86_64_GLOB_DAT _ITM_deregisterTMCloneTable
0000000000200fe0 R_X86_64_GLOB_DAT __libc_start_main@GLIBC_2.2.5
0000000000200fe8 R_X86_64_GLOB_DAT __gmon_start__
0000000000200ff0 R_X86_64_GLOB_DAT _ITM_registerTMCloneTable
0000000000200ff8 R_X86_64_GLOB_DAT __cxa_finalize@GLIBC_2.2.5
0000000000201020 R_X86_64_JUMP_SLOT dlopen@GLIBC_2.2.5
0000000000201028 R_X86_64_JUMP_SLOT __printf_chk@GLIBC_2.3.4
0000000000201030 R_X86_64_JUMP_SLOT exit@GLIBC_2.2.5
0000000000000000 R_X86_64_NONE *ABS* //<---- This relocation
Есть ли способ обойти это и сделать символы из библиотеки, загруженной с dlopen
, но не связанной с ld
в течение времени ссылки, которое будет доступно для динамического компоновщика, поэтому приложение, которое я показал выше, будет работать как ожидалось?