我发现当我们使用nested functions时,GCC需要trampoline code的可执行堆栈。但是,下面的代码,使用gcc编译时不会显示可执行堆栈。 (我使用execstack来验证堆栈是否可执行)
#include <stdio.h>
#include <unistd.h>
int main()
{
int add( int a, int b)
{
return a + b;
}
return add(2, 3);
}
为什么这不会导致可执行堆栈?如果它不应该,那么有人可以提供 提供可执行堆栈的代码构造示例吗?
答案 0 :(得分:5)
如果嵌套函数根本不依赖于它的“父”堆栈,那么它只是一个普通函数 - 嵌套是语法(和作用域)糖。
如果你不采用嵌套函数的地址,也不需要trampoline代码。所以你需要更多的东西才能触发所有这些。
这是一个虚拟的例子:
// 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 -Wtrampolines 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
答案 1 :(得分:3)
如您的链接中所述http://gcc.gnu.org/onlinedocs/gccint/Trampolines.html
蹦床是在运行时创建嵌套函数的地址时创建的一小段代码。它通常驻留在堆栈中,包含函数的堆栈框架中。
在你的例子中,没有采用嵌套的地址,gcc不需要使用execstack。
以下是使用蹦床的代码示例: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;
}