libcareplus生成热补丁文件
kpatch_gensrc汇编文件生成
汇编原始文件:
gcc -S foo.c -o foo.s
汇编修改后的文件:
gcc -S bar.c -o bar.s
由于生成的汇编文件中,会在.file节中包含源代码文件名的信息,这也是kpatch_gensrc进行汇编文件比对时,确认是在对哪个文件做补丁的依据。故在使用kpatch_gensrc处理汇编文件之前,需要先将bar.s中的bar.c修改为foo.c,否则会因文件名无法匹配而报错:
sed -i 's/bar.c/foo.c/' bar.s
然后可以使用:
kpatch_gensrc --os=rhel6 -i foo.s -i bar.s -o foobar.s
命令生成差异文件foobar.s。
在kpatch_gensrc处理的过程中,首先,将foo.s和bar.s汇编文件中的内容以字符串内容读入,分别使用kp_file结构体进行记录汇编文件中的信息,结构体定义位于kpatch_io.h头文件中。
所有的汇编指令以行为单位,存储于kp_file结构体中的lines这个字符串数组成员中。而为了防止一行字符串中出现多条指令,或是在指令后有追加的注释,也是为了在后续处理过程中便于做汇编指令的比对和处理,所以通过调用init_multilines函数对lines数组中的每一行字符串进行逐行检查并按需处理,使得每一行的字符串只包含一条指令。
紧接着,调用init_ctypes函数对每一行汇编指令的类型进行标注,每一行的指令类别标记,存储于kp_file结构体中的ctype数组中。指令的分类以宏的形式定义在kpatch_parse.h头文件中,包含DIRECTIVE_ALIGN、DIRECTIVE_TEXT等多种类型,但指令类别的宏定义出处未找到相关资料,glibc/gcc/binutils中均未见到elf.h文件中有此类定义。
接下来,调用init_sections函数对汇编文件中以节为单位进行标注。节的描述信息定义在section_desc结构体中,该结构体位于kpatch_parse.h头文件中。每一个节的标注按照汇编文件中的.bss、.text、.rodata这类节名作为关键字,将汇编文件中所有的节划分出来。并将记录节信息的所有的section_desc结构体组织成红黑树。建立红黑树的目的是为了在后续处理过程中方便使用节名来快速搜索到节的信息。
在节划分完成以后,就开始做cblock的划分和初始化。cblock才是进行汇编文件对比的基本单元。cblock被定义为结构体,当前主要划分为4类:函数、变量、属性(这里指weak、global)、其它。
当前,以.type指令中的"@functi