在x86-64 linux中,必须提供sa_restorer而你还没有这样做.
/* x86-64 should always use SA_RESTORER. */
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
put_user_ex(ksig->ka.sa.sa_restorer, &frame->pretcode);
} else {
/* could use a vstub here */
err |= -EFAULT;
}
kact.sa_flags = act->sa_flags | SA_RESTORER;
kact.sa_restorer = &restore_rt;
使用更新后的代码确实有一个恢复器,但是你有两个问题:它已经坏了,你传了错.看看上面提到的C库源代码,你可以find this comment:
/* The difference here is that the sigaction structure used in the
kernel is not the same as we use in the libc. Therefore we must
translate it here. */
此外,由于函数序言,您不能将C函数用作还原器.此外,不支持从信号处理程序调用printf(但在此处有效).最后,正如David Wohlferd指出的那样,你的咒语是错误的.总而言之,以下可能是一个返工版本:
#include
#include
#include
void handler(int){
const char msg[] = "handler\n";
write(0, msg, sizeof(msg));
}
extern "C" void restorer();
asm volatile("restorer:mov $15,%rax\nsyscall");
struct kernel_sigaction {
void (*k_sa_handler) (int);
unsigned long sa_flags;
void (*sa_restorer) (void);
unsigned long sa_mask;
};
struct kernel_sigaction act{handler};
timespec ts{10,0};
int main(){
act.sa_flags=0x04000000;
act.sa_restorer=&restorer;
asm volatile("\
mov $13,%%rax\n\
mov %0,%%rdi\n\
mov %1,%%rsi\n\
mov %2,%%rdx\n\
mov $8,%%r10\n\
syscall\n\
"::"i"(7),"p"(&act),"p"(0):"rax","rcx", "rdi","rsi","rdx","r8", "r9", "r10", "r11");
nanosleep(&ts,0);
}
它仍然是hacky,显然你不应该这样做.