c - 在C中获取标签的地址

标签 c macros linux-kernel

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

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

它的用法是这样的

(tsk)->task_state_change = _THIS_IP_; 

作为 Grad OS 类(class)的一部分,我们正在实现我们自己的操作系统,我的目的是在调用 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 */

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

最佳答案

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

在标准 C99 或 GNU99 中,不使用 asm 就无法分配寄存器。并且指令指针在 x86-64 上不可分配(您需要一些跳转指令)。

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

关于c - 在C中获取标签的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29713187/

相关文章:

c - 我不明白函数传递的一维数组处理

c - 数独生成器导致段错误

linux - 如何修改现有的 Linux 内核模块

c - 三元级联宏

linux - 如何导出修改后的内核头文件

android - Android 和未知重定位的 Hello world 内核模块 : 27 when insmod

我可以假设 sizeof(uint8_t) = 1 吗?

将二叉树转换为链表

c - C 中的宏 foreach 循环

C 宏预处理器将数字映射到类型