![](/img/trans.png)
[英]undefined reference to `_GLOBAL_OFFSET_TABLE_' in gcc 32-bit code for a trivial function, freestanding OS
[英]How can I get the _GLOBAL_OFFSET_TABLE_ address in my program?
我想在我的程序中获取 _GLOBAL_OFFSET_TABLE_ 的地址。 一种方法是在 Linux 中使用nm命令,可能会将输出重定向到一个文件并解析该文件以获取 _GLOBAL_OFFSET_TABLE_ 的地址。 然而,这种方法似乎非常低效。 有哪些更有效的方法呢?
这似乎有效:
// test.c
#include <stdio.h>
extern void *_GLOBAL_OFFSET_TABLE_;
int main()
{
printf("_GLOBAL_OFFSET_TABLE = %p\n", &_GLOBAL_OFFSET_TABLE_);
return 0;
}
为了获得_GLOBAL_OFFSET_TABLE_
一致地址,匹配nm
的结果,您需要使用-fPIE
编译代码以执行代码生成,就像链接到与位置无关的可执行文件一样。 (否则你会得到一个像0x2ed6
这样的小整数和-fno-pie -no-pie
)。 大多数现代 Linux 发行版的 GCC 默认值是-fPIE -pie
,这将使 nm 地址只是相对于图像库的偏移量,并且运行时地址是 ASLRed。 (这通常有利于安全,但您可能不想要它。)
$: gcc -fPIE -no-pie test.c -o test
它给:
$ ./test
_GLOBAL_OFFSET_TABLE = 0x6006d0
然而, nm
想法不同:
$ nm test | fgrep GLOBAL
0000000000600868 d _GLOBAL_OFFSET_TABLE_
或者 GCC 太老以至于根本不知道 PIE,更不用说将-fPIE -pie
作为默认值, -fpic
可以工作。
如果使用汇编语言,则无需get_pc_thunk
即可获取_GLOBAL_OFFSET_TABLE_
地址。
这是棘手的方式。 :)
这是示例代码:
$ cat test.s
.global main
main:
lea HEREIS, %eax # Now %eax holds address of _GLOBAL_OFFSET_TABLE_
.section .got
HEREIS:
$ gcc -o test test.s
这是可用的,因为.got
部分与<.got.plt>
相邻
因此符号HEREIS
和_GLOBAL_OFFSET_TABLE_
位于相同的地址。
附注。 您可以检查它是否适用于 objdump。
Disassembly of section .got:
080495e8 <HEREIS-0x4>:
80495e8: 00 00 add %al,(%eax)
...
Disassembly of section .got.plt:
080495ec <_GLOBAL_OFFSET_TABLE_>:
80495ec: 00 95 04 08 00 00 add %dl,0x804(%ebp)
80495f2: 00 00 add %al,(%eax)
80495f4: 00 00 add %al,(%eax)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.