2015-04-18 66 views
1

我发现在Linux内核中这个宏,而试图找出如何获取标签的地址用C获取标签的地址用C

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

它也用于像

(tsk)->task_state_change = _THIS_IP_; 

我们正在实施我们自己的操作系统作为Grad OS课程的一部分,我的目的是在致电schedule()后返回标签。 Linux核心以某种方式实现了上述宏。

是不是要这样做? (请假设我有必要的组件下方读写寄存器。这仅仅是伪代码,我想告诉强调我打算如何采取一个标号的地址)

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

我真不”通过_THIS_IP_了解Linux内核代码是如何实现相同的。

回答

1

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

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

_THIS_IP_宏(使用多个GCC扩展:statement expressions & local labels & labels as values)是一个简单的方式来获得,作为void*指针(或接近)当前指令的地址。这个地址可以稍后跳转到例如间接跳转(goto *addr;

+0

我没有直接分配RIP。我的确使用类似'iretq'的东西。这只是我用来显示我的标签地址的方法的伪代码。对不起,Qn! –