【问题标题】:Machine code on user stack - Operating Systems用户堆栈上的机器代码 - 操作系统
【发布时间】:2015-06-18 21:36:48
【问题描述】:

我正在使用 xv6 操作系统,我的班级正在为它实现信号。

我已经弄清楚了如何在内核中实现处理程序(这是前两个练习),但现在我必须弄清楚如何运行用户定义的处理程序。

程序调用一个像这样的信号函数

signal(int signum, void (*handler)(int))

用户程序,比如alarmtest3.c,将其用户函数作为第二个参数传递:

signal (14, snooze); // 14 is the signum for alarm 

我需要弄清楚的是一旦有信号,如何让内核调用另一个系统调用 sigret()。我相信需要这个系统调用来存储内核堆栈的陷阱帧的副本。关键是在一切发生后返回用户空间。

用户堆栈应如下所示:

|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|

我知道要存储什么机器代码,我在汇编文件中找到了它。我只是不知道“调用 sys_sigret 的几字节机器代码”是什么意思。如何将此机器码存储在堆栈中?

感谢您的帮助!

【问题讨论】:

    标签: c assembly operating-system stack kernel


    【解决方案1】:

    在堆栈上存储代码不一定是一个好主意,但如果您需要这样做,那就这样吧。至于如何:只需在内核内存中创建所述机器代码,然后简单地将其连同自己的地址一起复制到用户堆栈,以便在信号处理程序返回时执行。

    这就是linux的做法:

    static const struct {
            u16 poplmovl;
            u32 val;
            u16 int80;
    } __attribute__((packed)) retcode = {
            0xb858,         /* popl %eax; movl $..., %eax */
            __NR_sigreturn,
            0x80cd,         /* int $0x80 */
    };
    
    /*
     * This is popl %eax ; movl $__NR_sigreturn, %eax ; int $0x80
     *
     * 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);
    

    【讨论】:

    • "只需在内核内存中创建所述机器代码" -- 所以,如果我已经有了需要执行的机器代码(因为它是系统调用,我找到了 sys_sigret 的机器代码() 在 .asm 文件中),那么我只需将结构的各个区域初始化为相应的机器代码片段?
    • sys_sigret 是系统调用的实际内核处理程序,我假设。 你不想这样。无论您的操作系统使用何种方式,您都需要一段代码来调用该系统调用。在 linux 上,eax 被设置为系统调用号之后,这是一个 int 0x80 调用。
    • 我有 8 个字节的机器码,我在想,而不是 'u32 val; u16 int80;' (我不完全确定结构内的变量在做什么)我可以将我的机器代码存储到两个整数中吗?此外,如果 sys_sigret 调用 sigret(),那必然是一件坏事。我必须问,否则我不会明白。
    • 您可以随意存储您的代码。该结构只是为了将实际的系统调用号分隔到它自己的字段中。我不明白你关于 sys_sigretsigret 的问题(我什至不知道你的代码中的 sigret 是什么)。
    • 我明白了。凉爽的。哦,关于 sys_sigret/sigret——我需要弄清楚如何正确地实现它。但是你的回答很有帮助!谢谢!
    猜你喜欢
    • 2014-05-27
    • 2020-09-26
    • 1970-01-01
    • 2011-08-15
    • 2015-09-05
    • 2014-07-21
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多