c - 查找谁使用了 ELF 文件中的符号

标签 c linux elf linkage

我有一个很大的二进制文件,其中包含一个符号。我可以在 nmobjdump 中看到符号。
我知道使用了该符号,否则链接器不会包含它(更准确地说,我知道使用了同一源文件中的某些符号)。
我正在尝试找出它的具体使用方式。

如果引用是由一个函数(例如调用函数的函数、使用全局变量的函数),我可以使用 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

最佳答案

我编译了相同的代码(和相同的命令)并运行了 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

因此通过查看重定位表,您可以找到所有变量(或函数)的绝对引用。

关于c - 查找谁使用了 ELF 文件中的符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50944859/

相关文章:

c++ - 将 FILE * 或 HANDLE 转换(分配)到 Windows 中的 IStream

linux - 如何在 Linux 中使用 nslookup 命令检查电子邮件域

c++ - 从共享对象调用主可执行文件中的函数

assembly - 如何在 GNU 中指定 ELF 部分对齐方式?

c - 32位x86代码是否需要专门为共享库文件进行PIC编译?

c++ - 为什么声明为指向字符的指针并分配了 2 个字节大小的 String 的大小会被更改?

读取丑字后继续解析

linux - Bash awk 脚本 : document splitter issue

linux - 是否可以使用此系统检查登录失败,或者我需要使用expect?

c - C 中基本基数特里树的实现