在C中获取标签的地址

时间:2015-04-18 05:10:24

标签: c macros linux-kernel

我在linux内核中找到了这个宏,同时试图找出如何在C中获取标签的地址

#define _THIS_IP_  ({ __label__ __here; __here: (unsigned long)&&__here; })

它像

一样使用
(tsk)->task_state_change = _THIS_IP_; 

我们正在实施我们自己的操作系统作为Grad OS课程的一部分,我的目的是在调用schedule()后返回标签。 Linux Kernel用上面的宏以某种方式实现了这个目的。

难道不是这样吗? (请假设我在下面有必要的程序集来读取和写入寄存器。这只是我想要显示的伪代码,以强调我计划如何获取标签的地址)

register_struct.rip = &&ret; /* GCC extension '&&' */
/* register_struct is a structure that holds all the registers of 
 * a process. Its useful to save and restore a process' state
 */
schedule();
ret: /* some code here */

我真的不明白Linux内核代码是如何通过_THIS_IP_实现的。

1 个答案:

答案 0 :(得分:1)

register_struct可能是所有寄存器内容的备份。它可能指向(即包含指针)用户地址空间,而不是内核地址空间。

标准C99或GNU99无法在不使用asm的情况下分配寄存器。并且指令指针不能在x86-64上分配(你需要一些跳转指令)。

您的_THIS_IP_宏(使用多个GCC扩展程序:statement expressions& local labels& labels as values)只是一种获取方式,void*指针,当前指令的地址(或附近)。该地址可以稍后跳转到,例如间接跳转(goto *addr;