我正在尝试阅读ELF符号表。
我在共享库中面临以下差异,无法理解其背后的原因。
对于libc,使用readelf
我得到了以下输出。
Num: Value Size Type Bind Vis Ndx Name
7: 00000033c32160b0 146 FUNC WEAK DEFAULT 11 realloc@@GLIBC_2.2.5
8: 00000033c3421000 4 OBJECT WEAK DEFAULT 21 _dl_starting_up@@GLIBC_PRIVATE
9: 00000033c32118f0 382 FUNC GLOBAL DEFAULT 11 _dl_allocate_tls@@GLIBC_PRIVATE
10: 00000033c3421280 40 OBJECT GLOBAL DEFAULT 21 _r_debug@@GLIBC_2.2.5
11: 00000033c341fdc8 8 OBJECT GLOBAL DEFAULT 17 __libc_stack_end@@GLIBC_2.2.5
12: 00000033c3215f30 252 FUNC WEAK DEFAULT 11 __libc_memalign@@GLIBC_2.2.5
13: 00000033c3211a70 140 FUNC GLOBAL DEFAULT 11 _dl_deallocate_tls@@GLIBC_PRIVATE
14: 00000033c3216040 52 FUNC WEAK DEFAULT 11 calloc@@GLIBC_2.2.5
15: 00000033c341fc88 8 OBJECT GLOBAL DEFAULT 17 _dl_argv@@GLIBC_PRIVATE
16: 00000033c3211000 599 FUNC GLOBAL DEFAULT 11 _dl_mcount@@GLIBC_2.2.5
使用以下命令构建我自己的共享库
gcc -rdynamic -Wint-to-pointer-cast -g -fPIC -lpthread -c probes.c -ldl -lelf
gcc -shared -lpthread -Wl,--no-as-needed,-soname,libprobes.so.1 -o libprobes.so.1 mutrace.o -ldl -lelf
输出
Num: Value Size Type Bind Vis Ndx Name
.
.
.
34: 00000000000040d0 66 FUNC GLOBAL DEFAULT 11 pthread_create
35: 0000000000001d72 109 FUNC GLOBAL DEFAULT 11 thread_local_init
36: 0000000000002b21 481 FUNC GLOBAL DEFAULT 11 trylock_ret_event
37: 00000000000030c4 652 FUNC GLOBAL DEFAULT 11 lock_init_event
38: 0000000000003e4d 130 FUNC GLOBAL DEFAULT 11 pthread_mutex_init
39: 0000000000004668 0 FUNC GLOBAL DEFAULT 12 _fini
40: 0000000000003dd0 125 FUNC GLOBAL DEFAULT 11 pthread_cond_timedwait
41: 0000000000001b03 92 FUNC GLOBAL DEFAULT 11 backtrace
42: 0000000000001b5f 94 FUNC GLOBAL DEFAULT 11 backtrace_symbols
43: 0000000000002ee3 481 FUNC GLOBAL DEFAULT 11 unlock_ret_event
44: 0000000000004026 95 FUNC GLOBAL DEFAULT 11 pthread_mutex_trylock
45: 0000000000003531 476 FUNC GLOBAL DEFAULT 11 lock_destroy_event
46: 0000000000004112 1012 FUNC GLOBAL DEFAULT 11 print_symtable
对于libc,符号值是绝对的(虚拟地址),但在我的库中,值是相对的。 是什么决定了这种行为?
我尝试过关注http://docs.oracle.com/cd/E19082-01/819-0690/chapter6-35166/index.html的信息,但后来当我检查ELF标题时,两个库都有相同的类型。
答案 0 :(得分:1)
使用以下命令构建我自己的共享库
gcc -rdynamic -Wint-to-pointer-cast -g -fPIC -lpthread -c probes.c -ldl -lelf
gcc -shared -lpthread -Wl, - no-as-needed,-soname,libprobes.so.1 -o libprobes.so.1
这些命令不正确。第一个是编译命令(因为-c
标志)。链接器选项(-rdynamic
,-lpthread
等)不属于它。
第二个命令是link命令,库顺序错误。此外,您忘记实际使用您编译的probes.o
。这会更好:
gcc -shared -o libprobes.so.1 -Wl,-soname=libprobes.so.1 probes.o -lpthread
对于libc,符号值是绝对的
不,他们不是。您的libc显然已预先链接到地址0x33c3210000
(或类似)。这不会使符号成为绝对符号。您可以撤消预链接(阅读man prelink
),您会在libc.so.6
中看到类似的“相对”地址。