自定义 setjmp/longjmp 实现分段错误
custom setjmp/longjmp implemetation segmentation fault
我正在尝试为 x64 windows 实施自定义 setjmp/longjmp。
我有以下代码:
contextSave:
xorq %rdx,%rdx
movq %rdx,(%rcx)
movq %rbx,0x8(%rcx)
leaq 0x8(%rsp),%rax
movq %rax,0x10(%rcx)
movq %rbp,0x18(%rcx)
movq %rsi,0x20(%rcx)
movq %rdi,0x28(%rcx)
movq %r12,0x30(%rcx)
movq %r13,0x38(%rcx)
movq %r14,0x40(%rcx)
movq %r15,0x48(%rcx)
movq (%rsp),%rax
movq %rax,0x50(%rcx)
movdqa %xmm6,0x60(%rcx)
movdqa %xmm7,0x70(%rcx)
movdqa %xmm8,0x80(%rcx)
movdqa %xmm9,0x90(%rcx)
movdqa %xmm10,0xa0(%rcx)
movdqa %xmm11,0xb0(%rcx)
movdqa %xmm12,0xc0(%rcx)
movdqa %xmm13,0xd0(%rcx)
movdqa %xmm14,0xe0(%rcx)
movdqa %xmm15,0xf0(%rcx)
xorq %rax,%rax
retq
contextRestore:
movq ,%rax
movq 0x8(%rcx),%rbx
movq 0x18(%rcx),%rbp
movq 0x20(%rcx),%rsi
movq 0x28(%rcx),%rdi
movq 0x30(%rcx),%r12
movq 0x38(%rcx),%r13
movq 0x40(%rcx),%r14
movq 0x48(%rcx),%r15
movdqa 0x60(%rcx),%xmm6
movdqa 0x70(%rcx),%xmm7
movdqa 0x80(%rcx),%xmm8
movdqa 0x90(%rcx),%xmm9
movdqa 0xa0(%rcx),%xmm10
movdqa 0xb0(%rcx),%xmm11
movdqa 0xc0(%rcx),%xmm12
movdqa 0xd0(%rcx),%xmm13
movdqa 0xe0(%rcx),%xmm14
movdqa 0xf0(%rcx),%xmm15
movq 0x50(%rcx),%rdx
movq 0x10(%rcx),%rsp
jmp *%rdx
执行上下文保存在以下结构中:
typedef struct Float128{
unsigned long part[2];
}Float128 __attribute__((aligned(16)));
typedef struct ContextData{
long frame;
long rbx;
long rsp;
long rbp;
long rsi;
long rdi;
long r12;
long r13;
long r14;
long r15;
long rip;
long spare;
Float128 Xmm6;
Float128 Xmm7;
Float128 Xmm8;
Float128 Xmm9;
Float128 Xmm10;
Float128 Xmm11;
Float128 Xmm12;
Float128 Xmm13;
Float128 Xmm14;
Float128 Xmm15;
}ContextData;
的修改版本
gdb 显示以下错误消息:
#0 0x000000000040231e in contextRestore () Backtrace stopped: Cannot access memory at address 0xbaadf00dbaadf00d
Info registers 显示 0xbaadf00dbaadf00d 存储在许多寄存器中。 contextSave 未按预期工作。
更新:
看来问题出在显示的代码之外。我创建了一个简单的代码,其中包含用于隔离问题的函数。它导致以下错误。
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
注册似乎没问题。
ContextData context;
if(contextSave(context)==1){
puts("context restored");
exit(0);
}
contextRestore(context);
更新 2
调试显示 rsp、rpb 和 rip 在 ContextData 结构中为零。
所以它们没有被 contextSave 正确保存。
好的,看来结构是问题所在。我不知道功能是否正确
实施。我决定暂时只使用结构和标准库。
正确的类型:
typedef struct Float128{
unsigned long long data[2]
}Float128 __attribute__((aligned(16)));
typedef Float128 Context[16];
我正在尝试为 x64 windows 实施自定义 setjmp/longjmp。 我有以下代码:
contextSave:
xorq %rdx,%rdx
movq %rdx,(%rcx)
movq %rbx,0x8(%rcx)
leaq 0x8(%rsp),%rax
movq %rax,0x10(%rcx)
movq %rbp,0x18(%rcx)
movq %rsi,0x20(%rcx)
movq %rdi,0x28(%rcx)
movq %r12,0x30(%rcx)
movq %r13,0x38(%rcx)
movq %r14,0x40(%rcx)
movq %r15,0x48(%rcx)
movq (%rsp),%rax
movq %rax,0x50(%rcx)
movdqa %xmm6,0x60(%rcx)
movdqa %xmm7,0x70(%rcx)
movdqa %xmm8,0x80(%rcx)
movdqa %xmm9,0x90(%rcx)
movdqa %xmm10,0xa0(%rcx)
movdqa %xmm11,0xb0(%rcx)
movdqa %xmm12,0xc0(%rcx)
movdqa %xmm13,0xd0(%rcx)
movdqa %xmm14,0xe0(%rcx)
movdqa %xmm15,0xf0(%rcx)
xorq %rax,%rax
retq
contextRestore:
movq ,%rax
movq 0x8(%rcx),%rbx
movq 0x18(%rcx),%rbp
movq 0x20(%rcx),%rsi
movq 0x28(%rcx),%rdi
movq 0x30(%rcx),%r12
movq 0x38(%rcx),%r13
movq 0x40(%rcx),%r14
movq 0x48(%rcx),%r15
movdqa 0x60(%rcx),%xmm6
movdqa 0x70(%rcx),%xmm7
movdqa 0x80(%rcx),%xmm8
movdqa 0x90(%rcx),%xmm9
movdqa 0xa0(%rcx),%xmm10
movdqa 0xb0(%rcx),%xmm11
movdqa 0xc0(%rcx),%xmm12
movdqa 0xd0(%rcx),%xmm13
movdqa 0xe0(%rcx),%xmm14
movdqa 0xf0(%rcx),%xmm15
movq 0x50(%rcx),%rdx
movq 0x10(%rcx),%rsp
jmp *%rdx
执行上下文保存在以下结构中:
typedef struct Float128{
unsigned long part[2];
}Float128 __attribute__((aligned(16)));
typedef struct ContextData{
long frame;
long rbx;
long rsp;
long rbp;
long rsi;
long rdi;
long r12;
long r13;
long r14;
long r15;
long rip;
long spare;
Float128 Xmm6;
Float128 Xmm7;
Float128 Xmm8;
Float128 Xmm9;
Float128 Xmm10;
Float128 Xmm11;
Float128 Xmm12;
Float128 Xmm13;
Float128 Xmm14;
Float128 Xmm15;
}ContextData;
的修改版本
gdb 显示以下错误消息:
#0 0x000000000040231e in contextRestore () Backtrace stopped: Cannot access memory at address 0xbaadf00dbaadf00d
Info registers 显示 0xbaadf00dbaadf00d 存储在许多寄存器中。 contextSave 未按预期工作。
更新:
看来问题出在显示的代码之外。我创建了一个简单的代码,其中包含用于隔离问题的函数。它导致以下错误。
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
注册似乎没问题。
ContextData context;
if(contextSave(context)==1){
puts("context restored");
exit(0);
}
contextRestore(context);
更新 2
调试显示 rsp、rpb 和 rip 在 ContextData 结构中为零。
所以它们没有被 contextSave 正确保存。
好的,看来结构是问题所在。我不知道功能是否正确 实施。我决定暂时只使用结构和标准库。
正确的类型:
typedef struct Float128{
unsigned long long data[2]
}Float128 __attribute__((aligned(16)));
typedef Float128 Context[16];