gcc - 在bss中编写和执行代码 - 设置权限标志

aus*_*der 9 c linux assembly gcc x86-64

我在运行时在Linux系统上的C程序中生成x86-64代码(准确地说是centos 5.4).

我将字节码生成为全局数组,如下所示

char program[1024 * 1024] __attribute__((aligned (16)));
Run Code Online (Sandbox Code Playgroud)

然后通过函数指针调用它.

我的问题是,当我编译这样的程序时

gcc -std=gnu99 parse.c -o parse -lm
Run Code Online (Sandbox Code Playgroud)

我得到一个SIGSEGV,我猜测是由于bss部分未被设置为可执行文件,如pmap所示

0000000000601000      4K rw---  /data/work/tmp/parse
0000000000602000   1024K rw---    [ anon ]
Run Code Online (Sandbox Code Playgroud)

当我像这样编译它时,(empty.s是一个零长度文件)

gcc -std=gnu99 parse.c empty.s -o parse -lm
Run Code Online (Sandbox Code Playgroud)

在运行时,bss部分神奇地设置了执行位,一切都很好.

0000000000601000      4K rwx--  /data/work/tmp/parse
0000000000602000   1024K rwx--    [ anon ]
Run Code Online (Sandbox Code Playgroud)

那么,这些标志如何在ELF中设置?是否有一种可靠,正确的方法来获得具有rwx权限的bss部分?

更多细节 - 软件版本

gcc版本4.1.2 20080704(Red Hat 4.1.2-48)
Linux 2.6.18-164.15.1.el5 x86_64 GNU/Linux

谢谢

更新 - 起初我以为我无法使用mmap来解决这个问题,因为我建议使用mmap,因为mmap给了我太远的页面(我想通过相对地址跳转到附近的代码).事实证明你可以让mmap为你处理这个问题,就像这样--MAP_32BIT会给你一个前2GB的页面.

char* program = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_32BIT | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
Run Code Online (Sandbox Code Playgroud)

caf*_*caf 1

您可能应该直接请求一个可写、可执行的匿名映射mmap()来存储生成的机器代码。