gcc - написание и выполнение кода в bss - установка флагов разрешений - PullRequest
9 голосов
/ 10 сентября 2010

Я генерирую код 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);

1 Ответ

1 голос
/ 10 сентября 2010

Возможно, вам просто нужно напрямую запросить записываемое, исполняемое анонимное отображение с помощью mmap() для хранения сгенерированного машинного кода.

...