Я генерирую код 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
Спасибо
обновление - сначала я подумал, что не могу использовать mmap для решения этой проблемы, как предложено 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);