2024年运维最全Linux 内核模块符号信息以及strip命令_strip -s,一起“干完”这份300页1000道面试题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前在阿里

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化的资料的朋友,可以点击这里获取!

}

//内核模块退出函数
static void __exit hello_exit(void)
{
printk(KERN_DEBUG “exit\n”);
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE(“GPL”);


编译出来的内核模块:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/0b992d0ec9504f1dbcf0178440d1da49.png)  
 可以看出内核模块带有debug\_info信息,所以导致文件大小比较大。



readelf -S helloworld.ko


![在这里插入图片描述](https://img-blog.csdnimg.cn/a52f286d7b784ce8a9bd6f5602432d4f.png)


有很多带debug的Section。


### 2.2 strip --strip-debug


我用 strip --strip-debug 命令去除内核模块的调试信息:



strip --strip-debug helloworld.ko


![在这里插入图片描述](https://img-blog.csdnimg.cn/29db175bece6434db3f7ec937f9259b7.png)  
 可见调试信息没有了,内核模块一下小了很多。



readelf -S helloworld.ko


![在这里插入图片描述](https://img-blog.csdnimg.cn/a746715a572c40f2923f9410dfdcee58.png)  
 没有带有debug的Section。


依然能够正常使用内核模块:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/89dd6644b2474c999086bf8bd9c98b9e.png)


### 2.3 符号信息


#### 2.3.1 查看模块的符号信息



readelf -s helloworld.ko
-s
–symbols
–syms
Displays the entries in symbol table section of the file, if it has one.


![在这里插入图片描述](https://img-blog.csdnimg.cn/12db601b8a8646b5aaaf64cccdc5ee8d.png)



nm helloworld.ko


![在这里插入图片描述](https://img-blog.csdnimg.cn/6dcf7edbbadf4050b9e05a4119273ea8.png)


#### 2.3.2 符号表


(1)  
 symtab 保存了二进制文件的符号表,符号表保存了查找程序符号、为符合赋值,重定位符号所需要的全部信息。有一个专门的section来保存符号表。符号表表项的格式由下列数据结构表示:



/* Symbol table entry. */

typedef struct
{
Elf64_Word st_name; /* Symbol name (string tbl index) */
unsigned char st_info; /* Symbol type and binding */
unsigned char st_other; /* Symbol visibility */
Elf64_Section st_shndx; /* Section index */
Elf64_Addr st_value; /* Symbol value */
Elf64_Xword st_size; /* Symbol size */
} Elf64_Sym;


符号的主要任务是将一个字符串和一个值关联起来。


(2)  
 一个符号的确切用途由st\_info定义,由两部分组成:Symbol type 和 Symbol binding。



/* How to extract and insert information held in the st_info field. */

#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
#define ELF32_ST_TYPE(val) ((val) & 0xf)
#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))

/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */
#define ELF64_ST_BIND(val) ELF32_ST_BIND (val)
#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val)
#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type))


(3)  
 Symbol type:



/* Legal values for ST_TYPE subfield of st_info (symbol type). */

#define STT_NOTYPE 0 /* Symbol type is unspecified */
#define STT_OBJECT 1 /* Symbol is a data object */
#define STT_FUNC 2 /* Symbol is a code object */
#define STT_SECTION 3 /* Symbol associated with a section */
#define STT_FILE 4 /* Symbol’s name is file name */
#define STT_COMMON 5 /* Symbol is a common data object */
#define STT_TLS 6 /* Symbol is thread-local data object*/
#define STT_NUM 7 /* Number of defined types. */
#define STT_LOOS 10 /* Start of OS-specific */
#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */
#define STT_HIOS 12 /* End of OS-specific */
#define STT_LOPROC 13 /* Start of processor-specific */
#define STT_HIPROC 15 /* End of processor-specific */


主要说明三个:  
 STT\_NOTYPE:表示符号的类型未指定,用于未定义引用。  
 STT\_OBJECT:表示符号关联到一个数据对象,比如变量、数组或指针。  
 STT\_FUNC:表示符号关联到一个代码对象,比如函数或过程。


(4)  
 Symbol binding:



/* Legal values for ST_BIND subfield of st_info (symbol binding). */

#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* Weak symbol */
#define STB_NUM 3 /* Number of defined types. */
#define STB_LOOS 10 /* Start of OS-specific */
#define STB_GNU_UNIQUE 10 /* Unique symbol. */
#define STB_HIOS 12 /* End of OS-specific */
#define STB_LOPROC 13 /* Start of processor-specific */
#define STB_HIPROC 15 /* End of processor-specific */


主要说明三个:  
 STB\_LOCAL:局部符号,只在目标文件内部可见,在与其它程序的其它部分合并时,是不可见的。如果一个程序的几个目标文件都定义相同的符号名,也不会有问题。局部符号互不干扰。


STB\_GLOBAL:全局符号,在定义的目标文件内部可见,也可以由构成的其他目标文件引用。每个全局符号在一个程序内部都只能定义一次,否则链接器将报告错误。  
 指向符号的未定义引用,将在重定位期间确定相关符号的位置。如果对全局符号的未定义引用无法解决,则拒绝程序执行或静态绑定。


STB\_WEAK:整个程序内可见,但可以有多个定义。如果程序中一个全局符号和一个局部符号名字相同,全局符号优先处理。  
 即使一个弱符号未定义,程序也可以静态或动态链接,并将符号指定为0值。


#### 2.3.3 strip -s



strip -s helloworld.ko


去除模块的所有符号:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/9fde959a72ac4444a9b9df781f6be20a.png)  
 二进制模块的符号信息全部被strip,如下所示:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/df989735101648589b7ff08713470452.png)  
 去除所有模块后,内核模块不能正常加载:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/5025676faebb4b829856df7c33e85176.png)


## 三、Linux内核中的使用


内核头文件中的顶层Makefile根据 INSTALL\_MOD\_STRIP是否被定义来决定是否去除掉模块的debug信息。



// /usr/src/5.4.0-26-generic/linux-headers-5.4.0-26-generic/Makefile

INSTALL_MOD_STRIP, if defined, will cause modules to be

stripped after they are installed. If INSTALL_MOD_STRIP is ‘1’, then

the default option --strip-debug will be used. Otherwise,

INSTALL_MOD_STRIP value will be used as the options to the strip command.

ifdef INSTALL_MOD_STRIP
ifeq ($(INSTALL_MOD_STRIP),1)
mod_strip_cmd = $(STRIP) --strip-debug
else
mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)
endif # INSTALL_MOD_STRIP=1
else
mod_strip_cmd = true
endif # INSTALL_MOD_STRIP
export mod_strip_cmd

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值