我正在尝试将我的堆栈指针移动到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编译)
答案 0 :(得分:4)
Linux(或一般的UN * X)已经具有函数来执行这种上下文替换:
如果您使用这些,您可以通过设置合适的ucontext_t
/ struct sigcontext
(uc_mcontext
ucontext_t
成员来替换整个初始寄存器集(包括堆栈指针) })。然后调用setcontext()
变得类似于扩展longjmp()
。
可以在Wikipedia article on setcontext()
.
对于ucontext_t
的Linux定义,请参阅:
ucontext_t
:Linux sourcecode, struct sigcontext
:Linux sourcecode, x86 architecture definition, 答案 1 :(得分:2)
所以问题实际上是mmap在堆栈的相反方向上增长(遗憾的是,我忘记了)。所以要分配指针,我只需要分配(mmaped_stack + stack_size)而不仅仅是指针。