2012-05-12 19 views
6

Encontré que cuando usamos nested functions, GCC requiere una pila ejecutable para trampoline code. Sin embargo, el código siguiente, cuando se compila con gcc, no muestra una pila ejecutable. (Utilicé execstack para verificar si la pila es ejecutable)Ejemplo de pila ejecutable en Linux (arquitectura i386)

#include <stdio.h> 
#include <unistd.h> 

int main() 
{ 
     int add(int a, int b) 
     { 
       return a + b; 
     } 
     return add(2, 3); 
} 

¿Por qué esto no resultará en una pila ejecutable? Y si no se supone que lo haga, ¿alguien puede dar un ejemplo de una construcción de código que hace dar una pila ejecutable?

+0

Creo funciones definidas a nivel local no necesitan pila ejecutable porque su código todavía se almacena en la misma sección de código como otras funciones, y no en el apilar. –

Respuesta

4

Si la función anidada no depende en su pila de "padre" 's en absoluto, entonces es sólo una función normal - la anidación es azúcar sintáctico (y de alcance).

Y si usted no toma la dirección de la función anidada, no hay código de trampolín es necesario tampoco. Entonces necesitarás algo un poco más involucrado para desencadenar todo eso.

Aquí está un ejemplo ficticio:

// file t.c 
int doit(int (*fun)(int), int x) 
{ 
    return fun(x); 
} 

int foo(int a) 
{ 
     int add(int b) 
     { 
       return a + b; 
     } 
     return doit(&add, 2); 
} 

int main(void) 
{ 
    return foo(1); 
} 
$ gcc t.c 
t.c: In function 'foo': 
t.c:8:13: warning: trampoline generated for nested function 'add' 
$ ./a.out 
$ echo $? 
3 
$ execstack a.out 
X a.out 
2

Como se ha dicho en su enlace http://gcc.gnu.org/onlinedocs/gccint/Trampolines.html

Una cama elástica es una pequeña pieza de código que se crea en tiempo de ejecución cuando la dirección de una función anidada se toma. Normalmente reside en la pila, en el marco de pila de la función que lo contiene.

En su dirección de ejemplo de anidado no se toma y gcc no necesita usar execstack.

Aquí es un ejemplo de código con cama elástica: http://www.win.tue.nl/~aeb/linux/hh/protection.html

% cat trampoline.c 
#include <stdio.h> 
int main(int ac, char **av) { 
     int localfn(int a) { 
       return a+ac; 
     } 
     int (*fptr)(int) = localfn; 

     printf("%d\n", fptr(-1)); 
     return 0; 
} 
Cuestiones relacionadas