我想在我的arch(x86)上测试gcc的全局偏移表的限制大小。
在共享库(gcc -nostdlib -shared -o got.so ./got.c
)中使用多个未声明的函数
// got.c
extern int itestvariable1;
extern int testvariable2;
void test(void)
{
fun1();
...
fun8();
}
和readelf --relocs ./got.so
:
Relocation section '.rela.plt' at offset 0x3a8 contains 8 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000004018 000100000007 R_X86_64_JUMP_SLO 0000000000000000 fun7 + 0
000000004020 000200000007 R_X86_64_JUMP_SLO 0000000000000000 fun3 + 0
000000004028 000300000007 R_X86_64_JUMP_SLO 0000000000000000 fun4 + 0
000000004030 000400000007 R_X86_64_JUMP_SLO 0000000000000000 fun8 + 0
000000004038 000500000007 R_X86_64_JUMP_SLO 0000000000000000 fun2 + 0
000000004040 000600000007 R_X86_64_JUMP_SLO 0000000000000000 fun6 + 0
000000004048 000700000007 R_X86_64_JUMP_SLO 0000000000000000 fun1 + 0
000000004050 000800000007 R_X86_64_JUMP_SLO 0000000000000000 fun5 + 0
......
如上所示,全局偏移表由fun1-8
填充,但要填充以达到限制大小,还远远不够。我可以想到两种方式:
当然,可能有更多方法可以实现此目标。
如何达到全局偏移表的极限?
答案 0 :(得分:1)
在测试极限值之前,了解极限值通常会很有帮助。如果您只需要一打,那么声明数千个功能的技巧就太过分了。那么,GOT的尺寸限制是什么? According to Red Hat:“ SPARC的最大值为8k,m68k和RS / 6000的最大值为32k。386没有这样的限制。”
了解限制有两个要点。首先,试图使GOT过载确实需要一种可以合理地轻松生成数千个GOT条目的方法。其次,在您的体系结构(x86)上,这是没有希望的任务,因为它没有限制。
(对于那些对我如何找到该链接感兴趣的人:我只是在网上搜索“全局偏移表大小限制”。)
对于其他架构的人,我想扩展问题示例代码的一种简单方法是编写另一个程序来生成它。
#include <fstream>
constexpr unsigned NUM_FUN = 70000;
int main()
{
std::ofstream out("got.c");
out << "void test(void)\n{\n";
for ( unsigned i = 0; i < NUM_FUN; ++i )
out << "\tfun" << i << "();\n";
out << "}\n";
}
编译并运行该文件,以生成一个got.c
文件,该文件调用的功能比m68k的全局偏移表格式所能容纳的功能更多。