asm-offset.c : 自动生成宏及其工作原理

转载地址:http://blog.chinaunix.net/uid-25000873-id-4134037.html

在arch/xxx/kernel下有一个奇怪的文件:asm-offset.c。这个文件里面有一个main函数,而且里面的正文全是DEFINE(xxx, xxxx)的格式。这让阅读源码的人会感到困惑,这个文件的作用是什么呢?不卖关子:这个文件的目的是生成include/generated/asm-offsets.h。

include/generated/asm-offsets.h这个文件,里面定义了一些结构体内变量的相对便宜。通过这个宏,就可以在汇编代码访问到结构体内的某一个地址。

拿asm-offset.c中一个语句来分析:
  DEFINE(TSK_ACTIVE_MM,         offsetof(struct task_struct, active_mm));
在这个语句里面的两个宏定义是:
#define DEFINE(sym, val) \
        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#sym就是直接把sym格式化为字符串。
offsetof这个宏其目的就是为了找出结构体中某一个元素的偏移量。
把  DEFINE(TSK_ACTIVE_MM,         offsetof(struct task_struct, active_mm));这个语句做了宏展开就成了:
->TSK_ACTIVE_MM 336 offsetof(struct task_struct, active_mm)     // 
asm-offset.c的展开就在其目录下的asm-offset.s文件里面,相关的生成规则在Kbuild文件里面。

核心的两个函数在于:
cmd_cc_s_c       = $(CC) $(c_flags) -fverbose-asm -S -o $@ $<

define sed-y
        "/^->/{s:->#\(.*\):/* \1 */:; \
        s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \
        s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
        s:->::; p;}"
endef

define cmd_offsets
        (set -e; \
         echo "#ifndef __ASM_OFFSETS_H__"; \
         echo "#define __ASM_OFFSETS_H__"; \
         echo "/*"; \
         echo " * DO NOT MODIFY."; \
         echo " *"; \
         echo " * This file was generated by Kbuild"; \
         echo " *"; \
         echo " */"; \ 
         echo ""; \
         sed -ne $(sed-y) $<; \
         echo ""; \
         echo "#endif" ) > $@
endef   

最后就在include/generated/asm-offsets.h中生成了
#define TSK_ACTIVE_MM 336 /* offsetof(struct task_struct, active_mm)    // */
这样汇编代码中,就可以通过指针+偏移的方式访问到task_struct->active_mm变量了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值