用户堆栈上的机器代码 - 操作系统
Machine code on user stack - Operating Systems
我正在使用 xv6 操作系统,我的 class 正在为它实现信号。
我已经弄清楚如何在内核中实现处理程序(这是前两个练习),但现在我必须弄清楚如何 运行 用户定义的处理程序。
程序调用如下所示的信号函数
signal(int signum, void (*handler)(int))
用户程序,比如 alarmtest3.c,将其用户函数作为第二个参数传递:
signal (14, snooze); // 14 is the signum for alarm
我需要弄清楚的是一旦in signal,如何让内核调用另一个系统调用sigret()。我相信需要这个系统调用来存储内核堆栈的陷阱帧的副本。重点是在一切发生后返回用户 space。
用户堆栈应如下所示:
|other stack frames|
|a few bytes of machine code to call sys_sigret|
|signum parameter for the handler function|
|address of the first byte of the code above|
我知道要存储什么机器代码,我在汇编文件中找到了它。我就是不知道"a few bytes of machine code to call sys_sigret"是什么意思。如何将此机器代码存储在堆栈中?
感谢您的帮助!
将代码存储在堆栈上不一定是个好主意,但如果您需要这样做,那就这样吧。至于方法:只需在内核内存中创建所述机器代码,然后将其连同其自己的地址简单地复制到用户堆栈,以便在信号处理程序 returns.
时执行
linux 是这样做的:
static const struct {
u16 poplmovl;
u32 val;
u16 int80;
} __attribute__((packed)) retcode = {
0xb858, /* popl %eax; movl $..., %eax */
__NR_sigreturn,
0x80cd, /* int [=10=]x80 */
};
/*
* This is popl %eax ; movl $__NR_sigreturn, %eax ; int [=10=]x80
*
* WE DO NOT USE IT ANY MORE! It's only left here for historical
* reasons and because gdb uses it as a signature to notice
* signal handler stack frames.
*/
err |= __put_user(*((u64 *)&retcode), (u64 *)frame->retcode);
我正在使用 xv6 操作系统,我的 class 正在为它实现信号。
我已经弄清楚如何在内核中实现处理程序(这是前两个练习),但现在我必须弄清楚如何 运行 用户定义的处理程序。
程序调用如下所示的信号函数
signal(int signum, void (*handler)(int))
用户程序,比如 alarmtest3.c,将其用户函数作为第二个参数传递:
signal (14, snooze); // 14 is the signum for alarm
我需要弄清楚的是一旦in signal,如何让内核调用另一个系统调用sigret()。我相信需要这个系统调用来存储内核堆栈的陷阱帧的副本。重点是在一切发生后返回用户 space。
用户堆栈应如下所示:
|other stack frames|
|a few bytes of machine code to call sys_sigret|
|signum parameter for the handler function|
|address of the first byte of the code above|
我知道要存储什么机器代码,我在汇编文件中找到了它。我就是不知道"a few bytes of machine code to call sys_sigret"是什么意思。如何将此机器代码存储在堆栈中?
感谢您的帮助!
将代码存储在堆栈上不一定是个好主意,但如果您需要这样做,那就这样吧。至于方法:只需在内核内存中创建所述机器代码,然后将其连同其自己的地址简单地复制到用户堆栈,以便在信号处理程序 returns.
时执行linux 是这样做的:
static const struct {
u16 poplmovl;
u32 val;
u16 int80;
} __attribute__((packed)) retcode = {
0xb858, /* popl %eax; movl $..., %eax */
__NR_sigreturn,
0x80cd, /* int [=10=]x80 */
};
/*
* This is popl %eax ; movl $__NR_sigreturn, %eax ; int [=10=]x80
*
* WE DO NOT USE IT ANY MORE! It's only left here for historical
* reasons and because gdb uses it as a signature to notice
* signal handler stack frames.
*/
err |= __put_user(*((u64 *)&retcode), (u64 *)frame->retcode);