Linux 内核模块符号信息以及strip命令

编程之家收集整理的这篇文章主要介绍了Linux 内核模块符号信息以及strip命令编程之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

本文是内核模块符号表的一些内容以及strip命令的使用。,下方主要介绍关于Linux 内核模块符号信息以及strip命令的全文内容,希望对你有所帮助。

前言

最近学习了linux内核模块的符号信息和 strip 命令,总结一下。

一、strip

1.1 GNU Binutils

GNU Binutils 是二进制工具的集合。 主要有:

ld - the GNU linker.
as - the GNU assembler.

其他常用的一些工具:

ar - A utility for creating, modifying and extracting from archives.
nm - Lists symbols from object files.
objcopy - copIEs and translates object files.
objdump - displays information from object files.
readelf - displays information from any ELF format object file.
size - Lists the section sizes of an object or archive file.
strings - Lists printable strings from files.
strip - discards symbols.
......

binutils 已被移植到大多数主要的 Unix variants 中,是为GNU系统(以及GNU/linux)提供编译和链接程序的工具。

本文主要介绍strip命令的使用

1.2 strip

(1)

strip - discard symbols from object files.

discard 目标文件 objfile 中的符号。

(2)

 -s
 --strip-all
      Remove all symbols.

 -g
 -S
 -d
 --strip-deBUG
     Remove deBUGging symbols only.

(3)

 --info
     display a List showing all architectures and object formats available.

在这里插入图片描述

二、使用步骤

2.1 demo

我以一个简单的内核模块为例子:

#include <linux/kernel.h>
#include <linux/module.h>

//内核模块初始化函数
static int __init hello_init(voID)
{
	printk(KERN_EMERG "Hello World\n");
	return 0;
}

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

module_init(hello_init);
module_exit(hello_exit);

MODulE_liCENSE("GPL");

编译出来的内核模块:

在这里插入图片描述


可以看出内核模块带有deBUG_info信息,所以导致文件大小比较大。

readelf -S helloworld.ko 

在这里插入图片描述

有很多带deBUG的Section。

2.2 strip --strip-deBUG

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

strip --strip-deBUG helloworld.ko

在这里插入图片描述


可见调试信息没有了,内核模块一下小了很多。

readelf -S helloworld.ko

在这里插入图片描述


没有带有deBUG的Section。

依然能够正常使用内核模块:

在这里插入图片描述

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.

在这里插入图片描述

nm helloworld.ko 

在这里插入图片描述

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

去除模块的所有符号:

在这里插入图片描述


二进制模块的符号信息全部被strip,如下所示:

在这里插入图片描述


去除所有模块后,内核模块不能正常加载:

在这里插入图片描述

三、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

INSTALL_MOD_STRIP,如果已定义,将导致模块在安装后内核模块的deBUG信息被去除掉。 如果 INSTALL_MOD_STRIP 为 ‘1’,则将使用选项 --strip-deBUG。 否则,INSTALL_MOD_STRIP 值将用作 strip 命令的选项

总结

本文是内核模块符号表的一些内容以及strip命令的使用

参考资料

深入linux内核架构
https://www.gnu.org/software/binutils/

总结

以上是编程之家为你收集整理的Linux 内核模块符号信息以及strip命令全部内容,希望文章能够帮你解决Linux 内核模块符号信息以及strip命令所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

Linux文章

通常我们在使用vim编辑器的时候,需要显示和隐藏行号隐藏行号:1.首先我们vim&nbsp;&nbsp; 1.txt&nbsp;&nbsp; (进入我们编辑的文档),如下,此时是显示行号的2.按一下esc键,并输入:(冒号),完成效果如下3.输入se...
Linux Supervisor的安装与使用入门&nbsp; &nbsp; &nbsp; &nbsp;在linux或者unix操作系统中,守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。由...
&nbsp;linux mysq 无法启动 apache 无法启动Starting&nbsp;MySQL.The&nbsp;server&nbsp;quit&nbsp;without&nbsp;updating&nbsp;PID&nbsp;file&nbsp;(/[FAILED]nux/mysql-5.6.42/data/iZ2zei52xv66ff8zrs71zkZ.pid)....
git设置秘钥,git shh秘钥一、设置用户名、邮箱git config --global user.name &quot;username&quot;git config --global user.email &quot;*****@163.com&quot;二 、查看是否存在ssh keys#&nbsp;&nbsp;cd&nbsp;~/.s...
ffmpeg安装4.2版本, ffmpeg安装, ffmpeg静态包,简单不用在编译直接使用一、下载文件:1.ffprode 链接: https://pan.baidu.com/s/18zT9hDePu0G12GKWPvGN9Q 提取码: 8rnu2.ffmpeg&nbsp;链接: https://pan.baidu.com/s...
填写远程和本地项目路径,这样就会将服务器上项目代码克隆到本地了。git&nbsp;-c&nbsp;diff.mnemonicprefix=false&nbsp;-c&nbsp;core.quotepath=false&nbsp;clone&nbsp;--recursive&nbsp;https://git.coding.net/gam...
ffprobe视频提取json格式文件,ffprobe提取视频流信息json格式的文件,ffprobe视频tc文件ffprobe&nbsp;-print_format&nbsp;json&nbsp;-select_streams&nbsp;v&nbsp;-show_frames&nbsp;视频路径&nbsp;&gt;&nbsp;01.json...
linux解决Inodes满了,解决Inodes满了网站无法访问1.查看Inodes&nbsp;df&nbsp;-i2.查看inodes 占用空间最大的文件加路径for&nbsp;i&nbsp;in&nbsp;/*&nbsp;;&nbsp;do&nbsp;echo&nbsp;$i;&nbsp;find&nbsp;$i&nbsp;|&nb...
微信公众号搜索 “ 程序精选 ” ,选择关注!
微信公众号搜 "程序精选"关注