文章目录

  • 前言
  • 一、strip
    • 1.1 GNU Binutils
    • 1.2 strip
  • 二、使用步骤
    • 2.1 demo
    • 2.2 strip --strip-debug
    • 2.3 符号信息
      • 2.3.1 查看模块的符号信息
      • 2.3.2 符号表
      • 2.3.3 strip -s
  • 三、Linux内核中的使用
  • 总结
  • 参考资料

前言

最近学习了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-allRemove all symbols.-g-S-d--strip-debugRemove debugging symbols only.

(3)

 --infoDisplay 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--symsDisplays 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命令相关推荐

  1. linux shell 版本信息,查看各种Linux系统版本信息的Shell命令

    几种查看Linux版本信息的方法: 1. uname -a 2. cat /proc/version 3. cat /etc/issue 4. lsb_release -a 详解 lsb_releas ...

  2. Linux查看BIOS信息:dmidecode命令以及SMBIOS、DMI等

    做Linux系统底层的测试,有时候需要关注BIOS的信息(包括基本信息.检测到的CPU和内存等).除了在开机启动时进入到BIOS之外,还可以在Linux系统中直接查看BIOS的信息,一般可以使用dmi ...

  3. linux中quota信息查看,quota命令_Linux quota命令使用详解:显示磁盘已使用的空间与限制...

    quota命令用于显示用户或者工作组的磁盘配额信息.输出信息包括磁盘使用和配额限制. 语法 quota(选项)(参数) 选项 -g:列出群组的磁盘空间限制: -q:简明列表,只列出超过限制的部分: - ...

  4. linux内核模块调试信息,linux内核模块调试

    1. 开启虚拟机,虚拟机运行到 kgdb: Waiting for connection from remote gdb 2. 在Host机上运行: socat tcp-listen:8888 /tm ...

  5. linux内核模块调试信息,linux 内核模块调试

    1. 开启虚拟机,虚拟机运行到 kgdb: Waiting for connection from remote gdb 2. 在Host机上运行: socat tcp-listen:8888 /tm ...

  6. Linux 命令(60)—— strip 命令

    1.命令简介 strip 命令是 GNU Binutils 中的一员,用于剥掉目标文件中一些符号信息和调试信息,使文件变小. 2.命令格式 strip [-F bfdname |--target=bf ...

  7. nm 命令 程序符号信息查看

    http://www.cnblogs.com/wangkangluo1/archive/2012/07/02/2572438.html 用途 显示关于对象文件.可执行文件以及对象文件库里的符号信息. ...

  8. linux中的strip命令简介------给文件脱衣服

            作为一名linux开发人员, 如果没有听说过strip命令, 那是很不应该的. strip这个单词, 大家应该早就学过了, 你就记住是脱衣服就行了, 别的不要多想. 在linux中, ...

  9. linux strip作用,linux gcc strip命令简介

    阅读目录 strip简介 strip经常用来去除目标文件中的一些符号表.调试符号表信息,以减小静态库.动态库和程序的大小. strip支持的选项可通过如下命令查看: strip --help stri ...

最新文章

  1. 机器学习中的标签泄漏介绍及其如何影响模型性能
  2. python数据库操作之pymysql模块和sqlalchemy模块(项目必备)
  3. linux screen 进程,screen 命令使用
  4. C++从屏幕输入数字以空格分割,存入整型数组
  5. linux查看系统版本_谈一谈在Linux中使用df命令查看文件系统
  6. OPEN CASCADE Curve Continuity
  7. 什么是软件工程?它有哪些本质特征?怎样用软件工程消除软件危机?
  8. MySQL基本数据类型
  9. 认识Http协议(超文本传输协议)
  10. 数字标签转化为one-hot形式的tensor
  11. ros入门启动小海龟(ros2版本)
  12. 卡塔尔世界杯:带“芯片”的智能足球亮相!背后藏着哪些技术原理?
  13. 互斥锁的应用与pthread_mutex_destory的出错
  14. Java 16 藏刀而来,Java 8 面不改色 | 它强任它强,我用 Java 8,嘿嘿
  15. Linux磁盘与分区命名:sda, sdb, sdc, sda1, sda2
  16. 按广义表表示二叉树结构生成二叉树链表的算法
  17. Mybatis 查询总数
  18. 干货!2019年你确定要错过这份优秀Web字体清单吗?
  19. hbuilderx 底部_如何在Hbuilder中制作app底部导航栏
  20. Keynote for Mac(PPT制作模板)

热门文章

  1. css-loader和style-loader
  2. 集成测试和回归测试,确定测试
  3. 共模电感的原理、作用和使用示例
  4. 应用程序在后台运行,在后台执行startActivity后会强制把界面带到前端解决方案...
  5. 解读:LED照明设备出口沙特需要什么认证?法规要求!
  6. wow服务器合并信息,《魔兽世界》一区合并服务器正式通告
  7. 1.8-20:反反复复
  8. 【面试题集 —— No.01】常见图片格式BMP、JPG/JPEG、PNG、GIF、TIFF、SVG的区别
  9. Python非常适合副业,以私单的形式接一些小型项目
  10. 高校的论文查重系统有哪些?