我有一个很大的二进制文件,其中包含一个符号。我可以在nm
或objdump
中看到该符号。
我知道使用了该符号,因为否则链接程序将不包括该符号(更确切地说,我知道在同一源文件中使用了某些符号)。
我正在尝试找到它的用法。
如果引用是通过函数(例如,函数调用函数,使用全局变量的函数),则可以使用objdump -rd
来反汇编文件并找到引用。
但是如果引用是通过变量进行的(例如,初始化为指向某个变量的全局指针),则反汇编不会显示它。
我找不到能做到的任何方法。
这是一个演示它的示例。在此示例中,很明显谁使用了x
,但我不知道如何检查生成的二进制文件并找到它。
// x.c
int x = 3;
// main.c
extern int x;
static int *y = &x;
int main() {
return *y;
}
// Build process
gcc -o x.o -c x.c
ar r libx.a x.o
gcc -o main.o -c main.c
gcc -o main main.o -L. -lx
答案 0 :(得分:2)
我编译了相同的代码(和相同的命令)并运行objdump -x main.o
。有一个部分
RELOCATION RECORDS FOR [.data]:
OFFSET TYPE VALUE
0000000000000000 R_X86_64_64 x
这意味着它是64位重定位记录(R_X86_64_64
)。它在数据部分的偏移量为0(这是数据部分的y的偏移量)。并且要重定位的值是x
(实际上是变量x
的地址,因为它是标签)。
为了更好地理解这一点,我添加了另一个变量-
extern int ** z = &y;
现在符号表看起来像-
0000000000000000 l O .data 0000000000000008 y
0000000000000008 l O .data 0000000000000008 z
第一个显示数据部分中两个变量的偏移量,第二个数字是它们的大小。
重定位表现在也看起来像-
0000000000000000 R_X86_64_64 x
0000000000000008 R_X86_64_64 .data
您可以看到现在有两个条目。一个用于x
的地址存储在y
中(偏移量0),另一个用于y
的地址存储在z
中(偏移量8)。您会看到y
而不是.data
,因为数据段的地址与y
的地址相同,因为y
的偏移量为0
。>
因此,通过查看重定位表,您可以找到所有变量(或函数)的绝对引用。
答案 1 :(得分:0)
这是我找到的方法。它适用于这个简单的示例,但不幸的是,不适用于我的真实案例。我不确定有什么区别。
我正在寻找二进制文件x
中符号为main
的用户:
$ objdump -t main | grep -w x
0000000000000000 l df *ABS* 0000000000000000 x.c
0000000000601040 g O .data 0000000000000004 x
因此x的偏移量为00601040
。我正在寻找这个地址,该地址是反向的(我想是因为字节顺序):
$ objdump -s main | egrep '^Contents of section|40106000'
... omitted irrelevant sections ...
Contents of section .data:
601028 00000000 00000000 40106000 00000000 ........@.`.....
因此601030
中偏移量.data
处的符号包含此地址。
$ objdump -t main | grep 601030
0000000000601030 g O .data 0000000000000008 y
所以引用来自y
在我的真实情况下,该地址位于.dynsym
部分,而objdump -t
在那里没有找到任何符号。