使堆栈指针返回到mmap返回的指针。 (Linux,32位VM)

时间:2011-05-13 07:42:45

标签: c linux pointers assembly stack

我正在尝试将我的堆栈指针移动到mmap-ed区域来模拟上下文切换,但不知何故下面的代码总是会出现分段错误:

C:

struct savectx {
    void *regs[JB_SIZE];
};

struct savectx* initctx=(struct savectx*)malloc(sizeof(savectx));
void *newsp;
if ((newsp=mmap(0,STACK_SIZE,PROT_READ|PROT_WRITE,
    MAP_PRIVATE|MAP_ANONYMOUS,0,0))==MAP_FAILED){
    perror("mmap failed");
}
initctx->regs[4]=newsp;
restorectx(initctx,0);

86:

 restorectx:
 movl   4(%esp),%ecx        /*Move jump buffer addr to ecx */
 movl   8(%esp),%eax        /*Longjmp return value */
 movl   (JB_SP*4)(%ecx),%esp    /*JB_SP is defined to be 4,*/

程序在程序集的最后一行失败。

对于malloc,我知道我可能需要向指针添加0x000f0000,但是mmap呢?或者我们如何使堆栈调整到mmapp-ed位置。 (mmap的手册页:http://linux.die.net/man/3/mmap,在ubuntu上用GCC编译)

2 个答案:

答案 0 :(得分:4)

Linux(或一般的UN * X)已经具有函数来执行这种上下文替换:

如果您使用这些,您可以通过设置合适的ucontext_t / struct sigcontextuc_mcontext ucontext_t成员来替换整个初始寄存器集(包括堆栈指针) })。然后调用setcontext()变得类似于扩展longjmp()

可以在Wikipedia article on setcontext().

中找到用法示例

对于ucontext_t的Linux定义,请参阅:

答案 1 :(得分:2)

所以问题实际上是mmap在堆栈的相反方向上增长(遗憾的是,我忘记了)。所以要分配指针,我只需要分配(mmaped_stack + stack_size)而不仅仅是指针。