我在Linux系统上的C程序运行时生成x86-64代码(确切地说是centos 5.4)。
我生成我的字节码到全局数组中,如下所示
char program[1024 * 1024] __attribute__((aligned (16)));
然后通过函数指针调用它。
我的问题是,当我编译这样的程序
gcc -std=gnu99 parse.c -o parse -lm
我得到一个SIGSEGV,我猜测是由于bss部分没有被设置为可执行的,如pmap所示
0000000000601000 4K rw--- /data/work/tmp/parse 0000000000602000 1024K rw--- [ anon ]
当我这样编译时,(empty.s是一个零长度的文件)
gcc -std=gnu99 parse.c empty.s -o parse -lm
在运行时,bss部分奇迹般地设置了执行位,并且一切正常。
0000000000601000 4K rwx-- /data/work/tmp/parse 0000000000602000 1024K rwx-- [ anon ]
那么,ELF如何设置这些标志呢? 是否有一个可靠的,正确的方式来获得一个权限的RBX部分?
更多细节 – 软件版本
gcc版本4.1.2 20080704(红帽4.1.2-48)
Linux 2.6.18-164.15.1.el5 x86_64 GNU / Linux
谢谢
更新 – 起初我以为我不能使用mmap来解决这个问题,因为咖啡馆build议,因为mmap给我回页面太遥远(我想跳转到附近的代码与相对地址)。 事实certificate,您可以要求mmap为您处理这个问题,像这样 – MAP_32BIT将在第一个2GB中返回一个页面。
char* program = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_32BIT | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
您应该直接请求一个可写,可执行的匿名映射与mmap()
来存储您生成的机器代码。