Chinaunix首页 | 论坛 | 博客
  • 博客访问: 209470
  • 博文数量: 19
  • 博客积分: 757
  • 博客等级: 军士长
  • 技术积分: 320
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-08 07:55
个人简介

醉卧沙场君莫笑

文章分类

全部博文(19)

文章存档

2016年(5)

2015年(2)

2014年(3)

2013年(1)

2012年(5)

2011年(3)

分类: LINUX

2014-03-05 21:11:36

在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变量了。



阅读(3664) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

amarant2014-05-13 09:48:32

kiongf:版主,我在x86 中看到这样的一句代码:
movl  PT_EFLAGS(%esp),%al
而PT_FLAGS使用了您所提到的OFFSET宏。

那这句代码的意思是指将esp指定偏移的内容拷贝到al中?

是的。

回复 | 举报

kiongf2014-03-27 11:16:52

版主,我在x86 中看到这样的一句代码:
movl  PT_EFLAGS(%esp),%al
而PT_FLAGS使用了您所提到的OFFSET宏。

那这句代码的意思是指将esp指定偏移的内容拷贝到al中?