how to fill off global offset table?

∥☆過路亽.° 提交于 2019-12-25 17:44:42

问题


Motivation:

I want to test gcc's limition size of global offset table on my arch(x86).

What I have done:

use multiple undeclared functions in a shared library (gcc -nostdlib -shared -o got.so ./got.c)

// got.c
extern int itestvariable1;
extern int testvariable2;

 void test(void)
{
  fun1();
  ...
  fun8();
}

and 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
......

As above shows, the global offset table filled by fun1-8, but to fill reach the limition size, it is far from enough. I can think of two ways:

  • use a decent editor like emacs to generate more functions like these
  • use a decent codegen to generate such codes at preprocess time like macro (but I cannot find a solution with macro)

Of course, there may be more ways to achieve this goal.

Question:

How to reach the limit of the global offset table?


回答1:


Before testing a limit, it is often helpful to know what the limit is. The tricks for declaring thousands of functions would be overkill if all you need is a dozen. So what are the size limitations of a GOT? According to Red Hat: "These maximums are 8k on the SPARC and 32k on the m68k and RS/6000. The 386 has no such limit."

There are two takeaways from knowing the limits. First, trying to overload the GOT does require a method that can reasonably easily generate thousands of GOT entries. Second, on your architecture (x86), this is a hopeless task as there is no limit.

(For those interested in how I found that link: I just searched the web for "global offset table size restriction".)


For those on other architectures, I suppose an easy way to expand the question's example code is to write another program to generate it.

#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";
}

Compile and run this to generate a got.c file that calls more functions than will fit in a m68k's global offset table format.



来源:https://stackoverflow.com/questions/57032366/how-to-fill-off-global-offset-table

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!