注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Tsecer的回音岛

Tsecer的博客

 
 
 

日志

 
 

Linux内核中asm-offset的定义  

2011-09-06 21:52:17|  分类: Linux内核 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

一、问题的引出

在PowerpC的汇编代码的过程中,发现有一些宏找不到直接的定义,例如就是其中出现的,例如linux-2.6.37.1\arch\powerpc\kernel\head_32.S文件中

#define EXCEPTION_PROLOG_2 \
 CLR_TOP32(r11);  \
 stw r10,_CCR(r11);  /* save registers */ \
 stw r12,GPR12(r11); \
 stw r9,GPR9(r11); \

其中的GPR9就没有找到该宏的定义。

二、动态生成位置

在内核的根目录下存在一个构建文件 linux-2.6.37.1\Kbuild,其中列出了关于这个文件的动态生成方法:

offsets-file := include/generated/asm-offsets.h

always  += $(offsets-file)
targets += $(offsets-file)
targets += arch/$(SRCARCH)/kernel/asm-offsets.s
# Default sed regexp - multiline due to syntax constraints
define sed-y
 "/^->/{s:->#\(.*\):/* \1 */:; \
 s:^->\([^ ]*\) [\$$#]*\([-0-9]*\) \(.*\):#define \1 \2 /* \3 */:; \
 s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:
; \ 这里生成#MACRO VAL /*Comment*/的C语言宏
 s:->::; p;}"
endef

quiet_cmd_offsets = GEN     $@
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

# We use internal kbuild rules to avoid the "is up to date" message from make
arch/$(SRCARCH)/kernel/asm-offsets.s: arch/$(SRCARCH)/kernel/asm-offsets.c \
                                      $(obj)/$(bounds-file) FORCE
 $(Q)mkdir -p $(dir $@)
 $(call if_changed_dep,cc_s_c)

$(obj)/$(offsets-file): arch/$(SRCARCH)/kernel/asm-offsets.s Kbuild
 $(call cmd,offsets)
三、源文件的定义

linux-2.6.37.1\arch\x86\kernel\asm-offsets_32.c

void foo(void)
{
 OFFSET(IA32_SIGCONTEXT_ax, sigcontext, ax);
 OFFSET(IA32_SIGCONTEXT_bx, sigcontext, bx);
 OFFSET(IA32_SIGCONTEXT_cx, sigcontext, cx);
 OFFSET(IA32_SIGCONTEXT_dx, sigcontext, dx);
 OFFSET(IA32_SIGCONTEXT_si, sigcontext, si);
 OFFSET(IA32_SIGCONTEXT_di, sigcontext, di);
 OFFSET(IA32_SIGCONTEXT_bp, sigcontext, bp);
 OFFSET(IA32_SIGCONTEXT_sp, sigcontext, sp);

#define DEFINE(sym, val) \
        asm volatile("\n->" #sym " %0 " #val : : "i" (val))

#define BLANK() asm volatile("\n->" : : )

#define OFFSET(sym, str, mem) \
 DEFINE(sym, offsetof(struct str, mem))

#define COMMENT(x) \
 asm volatile("\n->#" x)

所以,对于这个.c文件首先生成一个汇编文件。上面的val由于是一个编译时常量(其修饰符"i"说明该值是一个立即数),它的值在编译时就可以确定,所以生成的汇编指令中就会有这个常数的值,而对于其他的字符串则不做任何修改写入生成的汇编文件中,而这个生成的常量值就是上面sed表达式中的第二个反向引用符\2,从而得到常量值

四、原因

虽然C语言代码可以方便的识别出offset的定义,但是由于这些变量时需要在汇编中使用的,所以offset这种宏无法在汇编中使用,而预处理本身是不识别数据结构和类型的,所以只能生成代码来确定最终生成的各个变量的偏移,这个也是生成编译时常量的一个好的方法。

它的优点就是尽可能少得进行源文件的转换,不需要生成.o或者.exe文件,只生成汇编文件即可

  评论这张
 
阅读(1134)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017