添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

asm-offset.h 文件

asm-offset.h 文件是在内核编译过程中生成的,生成过程  之前整理了一份笔记 TASK_threadsp的实现及asm-offsets.h, 其中涉及sed处理包含在内核代码 /scripts/Makefile.lib的sed-offsets中,工作是将生成的asm-offset.s转化为asm-offset.h。

/scripts/Makefile.lib
# ASM offsets
# ---------------------------------------------------------------------------
# Default sed regexp - multiline due to syntax constraints
# Use [:space:] because LLVM's integrated assembler inserts <tab> around
# the .ascii directive whereas GCC keeps the <space> as-is.
define sed-offsets
	's:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:; \
	/^->/{s:->#\(.*\):/* \1 */:; \
	s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
	s:->::; p;}'
endef
  • 圆括号:replacement部分可以包含 \ n(n是1到9的数字,包括1和9,\1,\2,…\9),对应regexp中圆括号之间的匹配部分,pattern space 中第一个匹配的项标识为\1 。
  • &符号:  replacement部分可以包含未转义的&字符。&表示正匹配的
  • s命令后的任意单个符号可以替换分隔符 ‘/’,做为新的分隔符 , ‘/’ 如果要出现在regexp或replacement时前面需要增加’\’符号。

      针对 Bracket Expressions , 如[:space:] , [:alnum:] 在使用时需要增加个[], 对sed新版本不增加的话会报错,对于老版本可以不加, 匹配的是[]中的集合, 非常幸运, 我的是老版本:),验证一下。 

    ## 1. 输入1, 不包含在“:digit:”中直接输出
    [root@centosgpt generate]# echo 1|sed ' s/[:digit:]/X/'
    ## 2. 输入d, 包含在“:digit:”中替换为X
    [root@centosgpt generate]# echo d|sed ' s/[:digit:]/X/'
    ##  3. 修改正则表达式数字1被替换为X
    [root@centosgpt generate]# echo 1|sed ' s/[[:digit:]]/X/'
    ##  4. 改为输入d, 匹配失败,输出X
    [root@centosgpt generate]# echo d |sed ' s/[[:digit:]]/X/'
    ## 下面是sed手册里关于新版本Bracket Expressions为增加[]的报错信息
    # current GNU sed versions - incorrect usage rejected
    $ echo 1 | sed 's/[:digit:]/X/'
    sed: character class syntax is [[:space:]], not [:space:]
    用#命令注释

    #符号用来标识注释的开始

    用q命令退出

    退出不再处理其他指令

    用d命令删除

    删除模式空间,进入下一个周期

    用p命令打印

    打印模式空间一般与-n一起使用 -n将不再自动输出pattern space

    用n命令跳过单行
    用{command}命令组合

    设置一组命令

    ## 1. 使用q命令退出
    [root@centosgpt generate]# seq 3| sed 2q
    ## 2. 使用d命令删除
    [root@centosgpt generate]# seq 3| sed 2d
    ## 3. 使用n命令跳过使用p打印
    [root@centosgpt generate]# seq 6|sed -n  'n;n;p'
    

    sed-offsets分析:

      asm-offset.s片段:
    .ascii "->"
    # 0 "" 2
    # 16 "asm-offsets.c" 1
    .ascii "->#TASK_threadsp1"
    # 0 "" 2
    # 17 "asm-offsets.c" 1
    .ascii "->TASK_threadsp1 $0 offsetof(struct task_struct1, thread.sp)"
    # 0 "" 2
    # 18 "asm-offsets.c" 1
    .ascii "->"
    # 0 "" 2
    #NO_APP
     sed-offsets处理过程:
  • sed脚本:
  • 's:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:; \
    /^->/{s:->#\(.*\):/* \1 */:; \
    s:^->\([^ ]*\) [\$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
    s:->::; p;}'

    第一条指令属于替换指令:

     s:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:;

    regexp部分分为6部分:

  • ^[[:space:]]*   匹配0个或多个以空格,制表符,回车换行开头的行;
  •  \.ascii      匹配 “.ascii” 字符串;
  •  [[:space:]]*  匹配0个或多个以空格,制表符,回车换行符;
  • “\(.*\)”      上面匹配成功后,该行后续双引号””内部的字符串, 标记为引用 \1
  • .*          匹配双引号后的任意字符串
  • \1         引用regexp中原括号匹配的字符串
  • 处理结果:

     字符串“.ascii”对应的双引号内部的字符串替换本行如下

    ## 1.command  (由于使用-n 所以增加了一个p, 用于显示每步的输出)
    #cat asm-offsets.s |sed -ne 's:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:;p'
    ## 2.output
    # 0 "" 2
    # 16 "asm-offsets.c" 1
    ->#TASK_threadsp1
    # 0 "" 2
    # 17 "asm-offsets.c" 1
    ->TASK_threadsp1 $0 offsetof(struct task_struct1, thread.sp)
    # 0 "" 2
    # 18 "asm-offsets.c" 1
    # 0 "" 2
    #NO_APP
    
  • 第二条指令属于组合指令:
  • /^->/{s:->#\(.*\):/* \1 */:; \
    s:^->\([^ ]*\) [\$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; \
    s:->::; p;}'
  • 组合指令的第一条指令-替换指令:
  • s:->#\(.*\):/* \1 */:;

    设置”->#” 后的字符串设置为\1 ,并将\1内容放入注释段中

    ## 1.command  (由于使用-n 所以增加了一个p, 用于显示每步的输出)
    # cat asm-offsets.s |sed -ne 's:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:;/->/{s:->#\(.*\):/* \1 */:;p}'
    ## 2.output
    /* TASK_threadsp1 */
    ->TASK_threadsp1 $0 offsetof(struct task_struct1, thread.sp)
    
  • 组合指令的第二条指令-替换指令:
  • s:^->\([^ ]*\) [\$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:;

    regexp部分分为四部分:

  •  ->\([^ ]*\)    匹配将”->”开头的行,之后非空格的字符串做为第一个引用\1 ;
  • [\$#]* \([^ ]*\)   跳过一个空格后,过滤$ ,#字符后非空格的字符串做为第一个引用\2;
  •    \(.*\)     跳过一个空格,后续所有字符串设置为引用
  • :#define \1 \2 /* \3 */:; 组成C语言宏定义格式,并将\3 做为注释
  • ## 1.command  (由于使用-n 所以增加了一个p, 用于显示每步的输出)
    # cat asm-offsets.s |sed -ne 's:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:;/->/{s:->#\(.*\):/* \1 */:;s:^->\([^ ]*\) [\$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:;p}'
    ## 2.output
    /* TASK_threadsp1 */
    #define TASK_threadsp1 0 /* offsetof(struct task_struct1, thread.sp) */
    
  • 组合指令的第三条指令-替换指令:
  • s:->::

    过滤满足存在”->”行

    ## 1.command  (由于使用-n 所以增加了一个p, 用于显示每步的输出)
    #cat asm-offsets.s |sed -ne 's:^[[:space:]]*\.ascii[[:space:]]*"\(.*\)".*:\1:;/->/{s:->#\(.*\):/* \1 */:;s:^->\([^ ]*\) [\$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:;s:->::;p}'
    ## 2.output
    /* TASK_threadsp1 */
    #define TASK_threadsp1 0 /* offsetof(struct task_struct1, thread.sp) */
    

    将处理结果输出

    /* TASK_threadsp1 */
    #define TASK_threadsp1 0 /* offsetof(struct task_struct1, thread.sp) */

    至此sed的任务顺利完成。

    sed, a stream editor

    SED 简明教程

    Sed – An Introduction and Tutorial by Bruce Barnett