Estoy generando el código x86-64 en tiempo de ejecución en un programa C en un sistema Linux (centos 5.4 para ser exactos).gcc - escribiendo y ejecutando código en el bss - configurando los indicadores de permiso
genero mis códigos de bytes en una matriz global como se muestra a continuación
char program[1024 * 1024] __attribute__((aligned (16)));
y luego poner en ella a través de un puntero de función.
Mi problema es, cuando compilo el programa como este
gcc -std=gnu99 parse.c -o parse -lm
consigo un SIGSEGV, que estoy sospechas se debe a la sección BSS no está hecho ejecutable, como se muestra por pmap
0000000000601000 4K rw--- /data/work/tmp/parse
0000000000602000 1024K rw--- [ anon ]
cuando compilo como este, (empty.s es un archivo de longitud cero)
gcc -std=gnu99 parse.c empty.s -o parse -lm
durante el tiempo de ejecución , las secciones de bss mágicamente tienen el bit de ejecución establecido, y todo funciona muy bien.
0000000000601000 4K rwx-- /data/work/tmp/parse
0000000000602000 1024K rwx-- [ anon ]
Entonces, ¿cómo se configuran estos indicadores en el ELF? ¿Y existe una forma confiable y correcta de obtener una sección de bss con permisos rwx?
Más detalles - versiones de software
versión de gcc 4.1.2 20080704 (Red Hat 4.1.2-48)
Linux x86_64 2.6.18-164.15.1.el5 GNU/Linux
Thankyou
actualización - al principio pensé que no podía usar mmap para resolver este problema como sugirió caf, porque mmap me estaba devolviendo páginas que estaban demasiado lejos (quería saltar al código cercano con una dirección relativa). Resulta que puedes pedirle a mmap que se encargue de esto, como ese, el MAP_32BIT te devolverá una página en los primeros 2GB.
char* program = mmap(0, 1024 * 1024, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_32BIT | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
¿Has descubierto por qué el .bss tiene el bit de ejecución establecido? – cojocar