Я генерирую код x86-64 во время выполнения в программе C в системе Linux (точнее, 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? И есть ли надежный, правильный способ получить секцию bss с разрешениями rwx?
Подробнее - версии программного обеспечения
gcc версия 4.1.2 20080704 (Red Hat 4.1.2-48)
Linux 2.6.18-164.15.1.el5 x86_64 GNU / Linux
Thankyou
update - сначала думал, что не могу использовать m map, чтобы решить эту проблему, как предложил caf, потому что mmap возвращал мне страницы, которые были слишком далеко (я хотел перейти в соседний код с относительной адресацией). Оказывается, вы можете попросить mmap позаботиться об этом за вас, например, MAP_32BIT вернет вам страницу в первых 2 ГБ.
char* program = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_32BIT | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);