【编译、链接、装载六】汇编——目标文件

news2024/11/25 10:33:36

【编译和链接六】汇编——目标文件

  • 一、目标文件_存储格式
    • 1、生成目标文件
    • 2、目标文件存储格式
    • 3、file查看文件格式
  • 二、查看目标文件的内部结构——objdump
  • 三、代码段
  • 四、 数据段和只读数据段
  • 五、 ELF文件结构描述
    • 1、头文件
    • 2、段表
      • 2.1、重定位表
      • 2.2、字符串表
      • 2.3、查看重定位表 和 字符串表
  • 六、调试信息

一、目标文件_存储格式

  • 目标文件就是源代码编译后但未进行链接的那些中间文件(Windows的.obj和Linux下的.o)

1、生成目标文件

  • 代码
#include<stdio.h>

int global_init_var = 123;
int global_uninit_var;

void show( int i )
{
	printf( "%d\n", i );
}

int main()
{
	static int static_var = 456;
	static int static_var2;

	int a = 1;
	int b;

	show(a);

	return -1;
}
  • 生成目标文件的指令
gcc -c hello.c -o hello.o

2、目标文件存储格式

目标文件跟可执行文件的内容与结构很相似,所以一般跟可执行文件格式一起采用一种格式存储。
在Windows下,我们可以统称它们为PECOFF文件格式。
在Linux下,我们可以将它们统称为ELF文件。
其他不太常见的可执行文件格式还有Intel/Microsoft的OMF(Object Module Format)、Unix a.out格式和MS-DOS .COM格式等。

不光是可执行文件(Windows的.exe和Linux下的ELF可执行文件)按照可执行文件格式存储。动态链接库(DLL,Dynamic Linking Library)(Windows的.dll和Linux的.so)及静态链接库(Static Linking Library)(Windows的.lib和Linux的.a)文件都按照可执行文件格式存储。它们在Windows下都按照PE-COFF格式存储,Linux下按照ELF格式存储。静态链接库稍有不同,它是把很多目标文件捆绑在一起形成一个文件,再加上一些索引,你可以简单地把它理解为一个包含有很多目标文件的文件包。
在这里插入图片描述

3、file查看文件格式

  • file:查看文件格式
$file hello.o

二、查看目标文件的内部结构——objdump

一般目标文件将这些信息按不同的属性,以“节”(Section)的形式存储,有时候也叫“段”(Segment).

在一般情况下,它们都表示一个一定长度的区域,基本上不加以区别,唯一的区别是在ELF的链接视图和装载视图的时候,后面会专门提到。

  • objdump指令,参数“-h”就是把ELF文件的各个段的基本信息打印出来。我们也可以使用“objdump –x”把更多的信息打印出来.
$objdump -h hello.o
$objdump -x hello.o

在这里插入图片描述

如上图,目标文件的格式是ELF,从图中可以看到,ELF文件的开头是一个“文件头”,它描述了整个文件的文件属性,包括文件是否可执行、是静态链接还是动态链接及入口地址(如果是可执行文件)、目标硬件、目标操作系统等信息,文件头还包括一个段表(Section Table),段表其实是一个描述文件中各个段的数组。段表描述了文件中各个段在文件中的偏移位置及段的属性等,从段表里面可以得到每个段的所有信息。文件头后面就是各个段的内容,比如代码段保存的就是程序的指令,数据段保存的就是程序的静态变量

段名解释
.code或.text代码段程序源代码编译后的机器指令经常被放在代码段(Code Section)里
.data数据段全局变量和局部静态变量数据经常放在数据段(Data Section)。让我们
.bss数据段未初始化的全局变量和局部静态变量一般放在一个叫.“bss”的段里。
.rodata数据段只读数据段,const的全局变量,#define定义的常量,以及诸如“Hello World”的字符串常量
.comment注释信息段没太懂
.note.GNU-stack编译信息编译器的版本信息段
.en_frame调试信息调试时,栈回溯时用到

const修饰的全局变量在常量区;const修饰的局部变量只是为了防止修改,没有放入常量区(代码区.text)。

未初始化的全局变量和局部静态变量默认值都为0,本来它们也可以被放在.data段的,但是因为它们都是0,所以为它们在.data段分配空间并且存放数据0是没有必要的。程序运行的时候它们的确是要占内存空间的,并且可执行文件必须记录所有未初始化的全局量和局部静态变量的大小总和,记为.bss段。所以.bss段只是为未初始化的全局变量和局部静态变量预留位置而已,它并没有内容,所以它在文件中也不占据空间。

数据段,.bss、.rdata、.data
导出数据段,.edata
导入数据段,.idata
段是导入数据,.idata
.edata段包含了应用程序或DLL的导出数据。在这个段出现的时候,它会包含一个到达导出信息的导出目录。

  • 查看目标文件详细信息

$objdump -x hello.o

在这里插入图片描述

  • size命令
    做“size”,它可以用来查看ELF文件的代码段、数据段和BSS段的长度(dec表示3个段长度的和的十进制,hex表示长度和的十六进制):
    在这里插入图片描述

三、代码段

  • objdump的 “-s”参数可以将所有段的内容以十六进制的方式打印出来 ,“-d ”参数可以将所有包含指令的段反汇编。
$gcc -c hello.c -o hello.o
[dev1@localhost test01]$ gcc -c hello.c -o hello.o
[dev1@localhost test01]$ objdump -s -d hello.o

hello.o:     文件格式 elf64-x86-64

Contents of section .text:
 0000 554889e5 4883ec10 897dfc8b 45fc89c6  UH..H....}..E...
 0010 bf000000 00b80000 0000e800 000000c9  ................
 0020 c3554889 e54883ec 10c745fc 01000000  .UH..H....E.....
 0030 8b45fc89 c7e80000 0000b8ff ffffffc9  .E..............
 0040 c3                                   .               
Contents of section .data:
 0000 7b000000 c8010000                    {.......        
Contents of section .rodata:
 0000 25640a00                             %d..            
Contents of section .comment:
 0000 00474343 3a202847 4e552920 342e382e  .GCC: (GNU) 4.8.
 0010 35203230 31353036 32332028 52656420  5 20150623 (Red 
 0020 48617420 342e382e 352d3434 2900      Hat 4.8.5-44).  
Contents of section .eh_frame:
 0000 14000000 00000000 017a5200 01781001  .........zR..x..
 0010 1b0c0708 90010000 1c000000 1c000000  ................
 0020 00000000 21000000 00410e10 8602430d  ....!....A....C.
 0030 065c0c07 08000000 1c000000 3c000000  .\..........<...
 0040 00000000 20000000 00410e10 8602430d  .... ....A....C.
 0050 065b0c07 08000000                    .[......        

Disassembly of section .text:

0000000000000000 <show>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 83 ec 10          	sub    $0x10,%rsp
   8:	89 7d fc             	mov    %edi,-0x4(%rbp)
   b:	8b 45 fc             	mov    -0x4(%rbp),%eax
   e:	89 c6                	mov    %eax,%esi
  10:	bf 00 00 00 00       	mov    $0x0,%edi
  15:	b8 00 00 00 00       	mov    $0x0,%eax
  1a:	e8 00 00 00 00       	callq  1f <show+0x1f>
  1f:	c9                   	leaveq 
  20:	c3                   	retq   

0000000000000021 <main>:
  21:	55                   	push   %rbp
  22:	48 89 e5             	mov    %rsp,%rbp
  25:	48 83 ec 10          	sub    $0x10,%rsp
  29:	c7 45 fc 01 00 00 00 	movl   $0x1,-0x4(%rbp)
  30:	8b 45 fc             	mov    -0x4(%rbp),%eax
  33:	89 c7                	mov    %eax,%edi
  35:	e8 00 00 00 00       	callq  3a <main+0x19>
  3a:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
  3f:	c9                   	leaveq 
  40:	c3                   	retq   
[dev1@localhost test01]$ 

跟前面我们了解到的“.text”段长度相符合,最左面一列是偏移量,中间4列是十六进制内容,最右面一列是.text段的ASCII码形式。对照下面的反汇编结果,可以很明显地看到,.text段里所包含的正是hello.c里两个函数 func1() 和 main() 的指令

四、 数据段和只读数据段

  • .data段保存的是那些已经初始化了的全局静态变量和局部静态变量。前面的SimpleSection.c代码里面一共有两个这样的变量,分别是global_init_varabal 与 static_var 。这两个变量每个4个字节,一共刚好8个字节,所以“.data”这个段的大小为8个字节。
  • SimpleSection.c里面我们在调用“printf”的时候,用到了一个字符串常量“%d\n”,它是一种只读数据,所以它被放到了“.rodata”段,我们可以从输出结果看到“.rodata”这个段的4个字节刚好是这个字符串常量的ASCII字节序,最后以\0结尾。
  • “.rodata”段存放的是只读数据,一般是程序里面的只读变量(如const修饰的变量)和字符串常量。单独设立“.rodata”段有很多好处,不光是在语义上支持了C++的const关键字,而且操作系统在加载的时候可以将“.rodata”段的属性映射成只读,

有时候编译器会把字符串常量放到“.data”段,而不会单独放在“.rodata”段。

objdump -x -s -d hello.o
[dev1@localhost test01]$ objdump -x -s -d hello.o

hello.o:     文件格式 elf64-x86-64
hello.o
体系结构:i386:x86-64,标志 0x00000011:
HAS_RELOC, HAS_SYMS
起始地址 0x0000000000000000

节:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00000041  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000008  0000000000000000  0000000000000000  00000084  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000004  0000000000000000  0000000000000000  0000008c  2**2
                  ALLOC
  3 .rodata       00000004  0000000000000000  0000000000000000  0000008c  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .comment      0000002e  0000000000000000  0000000000000000  00000090  2**0
                  CONTENTS, READONLY
  5 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000be  2**0
                  CONTENTS, READONLY
  6 .eh_frame     00000058  0000000000000000  0000000000000000  000000c0  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA
SYMBOL TABLE:
0000000000000000 l    df *ABS*	0000000000000000 hello.c
0000000000000000 l    d  .text	0000000000000000 .text
0000000000000000 l    d  .data	0000000000000000 .data
0000000000000000 l    d  .bss	0000000000000000 .bss
0000000000000000 l    d  .rodata	0000000000000000 .rodata
0000000000000000 l     O .bss	0000000000000004 static_var2.2184
0000000000000004 l     O .data	0000000000000004 static_var.2183
0000000000000000 l    d  .note.GNU-stack	0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame	0000000000000000 .eh_frame
0000000000000000 l    d  .comment	0000000000000000 .comment
0000000000000000 g     O .data	0000000000000004 global_init_var
0000000000000004       O *COM*	0000000000000004 global_uninit_var
0000000000000000 g     F .text	0000000000000021 show
0000000000000000         *UND*	0000000000000000 printf
0000000000000021 g     F .text	0000000000000020 main


Contents of section .text:
 0000 554889e5 4883ec10 897dfc8b 45fc89c6  UH..H....}..E...
 0010 bf000000 00b80000 0000e800 000000c9  ................
 0020 c3554889 e54883ec 10c745fc 01000000  .UH..H....E.....
 0030 8b45fc89 c7e80000 0000b8ff ffffffc9  .E..............
 0040 c3                                   .               
Contents of section .data:
 0000 7b000000 c8010000                    {.......        
Contents of section .rodata:
 0000 25640a00                             %d..            
Contents of section .comment:
 0000 00474343 3a202847 4e552920 342e382e  .GCC: (GNU) 4.8.
 0010 35203230 31353036 32332028 52656420  5 20150623 (Red 
 0020 48617420 342e382e 352d3434 2900      Hat 4.8.5-44).  
Contents of section .eh_frame:
 0000 14000000 00000000 017a5200 01781001  .........zR..x..
 0010 1b0c0708 90010000 1c000000 1c000000  ................
 0020 00000000 21000000 00410e10 8602430d  ....!....A....C.
 0030 065c0c07 08000000 1c000000 3c000000  .\..........<...
 0040 00000000 20000000 00410e10 8602430d  .... ....A....C.
 0050 065b0c07 08000000                    .[......        

Disassembly of section .text:

0000000000000000 <show>:
   0:	55                   	push   %rbp
   1:	48 89 e5             	mov    %rsp,%rbp
   4:	48 83 ec 10          	sub    $0x10,%rsp
   8:	89 7d fc             	mov    %edi,-0x4(%rbp)
   b:	8b 45 fc             	mov    -0x4(%rbp),%eax
   e:	89 c6                	mov    %eax,%esi
  10:	bf 00 00 00 00       	mov    $0x0,%edi
			11: R_X86_64_32	.rodata
  15:	b8 00 00 00 00       	mov    $0x0,%eax
  1a:	e8 00 00 00 00       	callq  1f <show+0x1f>
			1b: R_X86_64_PC32	printf-0x4
  1f:	c9                   	leaveq 
  20:	c3                   	retq   

0000000000000021 <main>:
  21:	55                   	push   %rbp
  22:	48 89 e5             	mov    %rsp,%rbp
  25:	48 83 ec 10          	sub    $0x10,%rsp
  29:	c7 45 fc 01 00 00 00 	movl   $0x1,-0x4(%rbp)
  30:	8b 45 fc             	mov    -0x4(%rbp),%eax
  33:	89 c7                	mov    %eax,%edi
  35:	e8 00 00 00 00       	callq  3a <main+0x19>
			36: R_X86_64_PC32	show-0x4
  3a:	b8 ff ff ff ff       	mov    $0xffffffff,%eax
  3f:	c9                   	leaveq 
  40:	c3                   	retq   
[dev1@localhost test01]$ 

下一篇文章,详细的展示下全局变量、局部变量、常量、static、const,分别存储在哪儿?

五、 ELF文件结构描述

1、头文件

我们已经通过SimpleSection.o的结构大致了解了ELF文件的轮廓,接着就来看看ELF文件的结构格式。
ELF目标文件格式的最前部是ELF文件头(ELF Header),它包含了描述整个文件的基本属性,比如ELF文件版本、目标机器型号、程序入口地址等。

  • 我们可以用readelf命令来详细查看ELF文件
[dev1@localhost test01]$ readelf -h hello.o
ELF 头:
  Magic:  7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  类别:                              ELF64
  数据:                              2 补码,小端序 (little endian)
  版本:                              1 (current)
  OS/ABI:                            UNIX - System V
  ABI 版本:                          0
  类型:                              REL (可重定位文件)
  系统架构:                          Advanced Micro Devices X86-64
  版本:                              0x1
  入口点地址:              0x0
  程序头起点:              0 (bytes into file)
  Start of section headers:          984 (bytes into file)
  标志:             0x0
  本头的大小:       64 (字节)
  程序头大小:       0 (字节)
  Number of program headers:         0
  节头大小:         64 (字节)
  节头数量:         13
  字符串表索引节头: 12

从上面输出的结果可以看到,ELF的文件头中定义了ELF魔数、文件机器字节长度、数据存储方式、版本、运行平台、ABI版本、ELF重定位类型、硬件平台、硬件平台版本、入口地址、程序头入口和长度、段表的位置和长度及段的数量等。
在这里插入图片描述

  • 类型
    在这里插入图片描述

2、段表

我们知道ELF文件中有很多各种各样的段,这个段表(Section Header Table)就是保存这些段的基本属性的结构。

前文中我们使用了“objudmp -h”来查看ELF文件中包含的段,结果是SimpleSection里面看到了总共有6个段,分别是 “.code”、“.data”、“.bss ”、“.rodata ”、“. comment ”和“. note.GNU-stack ”。实际上的情况却有所不同,“objdump -h”命令只是把ELF文件中关键的段显示了出来,而省略了其他的辅助性的段,比如:符号表、字符串表、段名字符串表、重定位表等。我们可以使用readelf工具来查看ELF文件的段,它显示出来的结果才是真正的段表结构:

注意:这是大写的-S

[dev1@localhost test01]$ readelf -S hello.o
共有 13 个节头,从偏移量 0x3d8 开始:

节头:
  [] 名称              类型             地址              偏移量
       大小              全体大小          旗标   链接   信息   对齐
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       0000000000000041  0000000000000000  AX       0     0     1
  [ 2] .rela.text        RELA             0000000000000000  000002f8
       0000000000000048  0000000000000018   I      10     1     8
  [ 3] .data             PROGBITS         0000000000000000  00000084
       0000000000000008  0000000000000000  WA       0     0     4
  [ 4] .bss              NOBITS           0000000000000000  0000008c
       0000000000000004  0000000000000000  WA       0     0     4
  [ 5] .rodata           PROGBITS         0000000000000000  0000008c
       0000000000000004  0000000000000000   A       0     0     1
  [ 6] .comment          PROGBITS         0000000000000000  00000090
       000000000000002e  0000000000000001  MS       0     0     1
  [ 7] .note.GNU-stack   PROGBITS         0000000000000000  000000be
       0000000000000000  0000000000000000           0     0     1
  [ 8] .eh_frame         PROGBITS         0000000000000000  000000c0
       0000000000000058  0000000000000000   A       0     0     8
  [ 9] .rela.eh_frame    RELA             0000000000000000  00000340
       0000000000000030  0000000000000018   I      10     8     8
  [10] .symtab           SYMTAB           0000000000000000  00000118
       0000000000000180  0000000000000018          11    11     8
  [11] .strtab           STRTAB           0000000000000000  00000298
       000000000000005d  0000000000000000           0     0     1
  [12] .shstrtab         STRTAB           0000000000000000  00000370
       0000000000000061  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

  • 目标文件——常用段名
常用段名Value
.text代码段,存放代码和局部const变量
.rela.text重定位表,重定位的信息
.data保存的是那些已经初始化了的全局静态变量和局部静态变量
.bbs存放的是未初始化的全局变量和局部静态变量
.rodataread only data 。存放的是只读数据,比如字符串常量,全局const变量。
.comment存放的是编译器的版本信息,比如字符串:
.note额外的编译器信息。比如程序的公司名,发布版本号等。
.en_frame调用栈信息
.rela…en_frame重定位的调用栈信息
.systabsymbol table 符号表
.strtabstring table ,字符串表,用于存储ELE文件中用到的字符串
.shstrtabsection string table 段名表

2.1、重定位表

链接器在处理目标文件时,须要对目标文件中某些部位进行重定位,即代码段和数据段中那些对绝对地址的引用的位置。这些重定位的信息都记录在ELF文件的重定位表里面,对于每个须要重定位的代码段或数据段,都会有一个相应的重定位表。

“.data”段则没有对绝对地址的引用,它只包含了几个常量,所以hello.o中没有针对“.data”段的重定位表“.rel.data”

2.2、字符串表

常见的段名为“.strtab”或“.shstrtab”。这两个字符串表分别为字符串表(String Table)和段表字符串表(Section Header String Table)。

  • 字符串表用来保存普通的字符串,比如符号的名字;
  • 段表字符串表用来保存段表中用到的字符串,最常见的就是段名( sh_name )。

我们可以使用很多工具来查看ELF文件的符号表,比如readelf、objdump、nm等,比如使用“nm”来查看“hello.o”的符号结果如下

[dev1@localhost test01]$ nm hello.o
0000000000000000 D global_init_var
0000000000000004 C global_uninit_var
0000000000000021 T main
                 U printf
0000000000000000 T show
0000000000000004 d static_var.2183
0000000000000000 b static_var2.2184
[dev1@localhost test01]$

2.3、查看重定位表 和 字符串表

[dev1@localhost test01]$ readelf -a hello.o
ELF 头:
  Magic:  7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  类别:                              ELF64
  数据:                              2 补码,小端序 (little endian)
  版本:                              1 (current)
  OS/ABI:                            UNIX - System V
  ABI 版本:                          0
  类型:                              REL (可重定位文件)
  系统架构:                          Advanced Micro Devices X86-64
  版本:                              0x1
  入口点地址:              0x0
  程序头起点:              0 (bytes into file)
  Start of section headers:          984 (bytes into file)
  标志:             0x0
  本头的大小:       64 (字节)
  程序头大小:       0 (字节)
  Number of program headers:         0
  节头大小:         64 (字节)
  节头数量:         13
  字符串表索引节头: 12

节头:
  [] 名称              类型             地址              偏移量
       大小              全体大小          旗标   链接   信息   对齐
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       0000000000000041  0000000000000000  AX       0     0     1
  [ 2] .rela.text        RELA             0000000000000000  000002f8
       0000000000000048  0000000000000018   I      10     1     8
  [ 3] .data             PROGBITS         0000000000000000  00000084
       0000000000000008  0000000000000000  WA       0     0     4
  [ 4] .bss              NOBITS           0000000000000000  0000008c
       0000000000000004  0000000000000000  WA       0     0     4
  [ 5] .rodata           PROGBITS         0000000000000000  0000008c
       0000000000000004  0000000000000000   A       0     0     1
  [ 6] .comment          PROGBITS         0000000000000000  00000090
       000000000000002e  0000000000000001  MS       0     0     1
  [ 7] .note.GNU-stack   PROGBITS         0000000000000000  000000be
       0000000000000000  0000000000000000           0     0     1
  [ 8] .eh_frame         PROGBITS         0000000000000000  000000c0
       0000000000000058  0000000000000000   A       0     0     8
  [ 9] .rela.eh_frame    RELA             0000000000000000  00000340
       0000000000000030  0000000000000018   I      10     8     8
  [10] .symtab           SYMTAB           0000000000000000  00000118
       0000000000000180  0000000000000018          11    11     8
  [11] .strtab           STRTAB           0000000000000000  00000298
       000000000000005d  0000000000000000           0     0     1
  [12] .shstrtab         STRTAB           0000000000000000  00000370
       0000000000000061  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

There are no section groups in this file.

本文件中没有程序头。

重定位节 '.rela.text' 位于偏移量 0x2f8 含有 3 个条目:
  偏移量          信息           类型           符号值        符号名称 + 加数
000000000011  00050000000a R_X86_64_32       0000000000000000 .rodata + 0
00000000001b  000e00000002 R_X86_64_PC32     0000000000000000 printf - 4
000000000036  000d00000002 R_X86_64_PC32     0000000000000000 show - 4

重定位节 '.rela.eh_frame' 位于偏移量 0x340 含有 2 个条目:
  偏移量          信息           类型           符号值        符号名称 + 加数
000000000020  000200000002 R_X86_64_PC32     0000000000000000 .text + 0
000000000040  000200000002 R_X86_64_PC32     0000000000000000 .text + 21

The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.

Symbol table '.symtab' contains 16 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hello.c
     2: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 
     3: 0000000000000000     0 SECTION LOCAL  DEFAULT    3 
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4 
     5: 0000000000000000     0 SECTION LOCAL  DEFAULT    5 
     6: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    4 static_var2.2184
     7: 0000000000000004     4 OBJECT  LOCAL  DEFAULT    3 static_var.2183
     8: 0000000000000000     0 SECTION LOCAL  DEFAULT    7 
     9: 0000000000000000     0 SECTION LOCAL  DEFAULT    8 
    10: 0000000000000000     0 SECTION LOCAL  DEFAULT    6 
    11: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    3 global_init_var
    12: 0000000000000004     4 OBJECT  GLOBAL DEFAULT  COM global_uninit_var
    13: 0000000000000000    33 FUNC    GLOBAL DEFAULT    1 show
    14: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
    15: 0000000000000021    32 FUNC    GLOBAL DEFAULT    1 main

No version information found in this file.
[dev1@localhost test01]$ 

六、调试信息

如果我们在GCC编译时加上“-g”参数,编译器就会在产生的目标文件里面加上调试信息,我们通过readelf等工具可以看到,目标文件里多了很多“debug”相关的段:

[dev1@localhost test01]$ gcc -c hello.c -o hello.o -g
[dev1@localhost test01]$ objdump -h hello.o

hello.o:     文件格式 elf64-x86-64

节:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00000041  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000008  0000000000000000  0000000000000000  00000084  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000004  0000000000000000  0000000000000000  0000008c  2**2
                  ALLOC
  3 .rodata       00000004  0000000000000000  0000000000000000  0000008c  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .debug_info   00000129  0000000000000000  0000000000000000  00000090  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING
  5 .debug_abbrev 000000a9  0000000000000000  0000000000000000  000001b9  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_aranges 00000030  0000000000000000  0000000000000000  00000262  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING
  7 .debug_line   00000041  0000000000000000  0000000000000000  00000292  2**0
                  CONTENTS, RELOC, READONLY, DEBUGGING
  8 .debug_str    00000119  0000000000000000  0000000000000000  000002d3  2**0
                  CONTENTS, READONLY, DEBUGGING
  9 .comment      0000002e  0000000000000000  0000000000000000  000003ec  2**0
                  CONTENTS, READONLY
 10 .note.GNU-stack 00000000  0000000000000000  0000000000000000  0000041a  2**0
                  CONTENTS, READONLY
 11 .eh_frame     00000058  0000000000000000  0000000000000000  00000420  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

参考
1、《程序员的自我修养链接装载与库》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/644221.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信号完整性:反射 初步认识

反射是怎么形成的 信号的反射和互连线的阻抗密切相关。反射的最直接原因是互连线的阻抗发生了突然变化&#xff0c;只要互连线的阻抗不连续的点&#xff0c;该处就会发生反射。 信号是以电磁波的形式在走线中传播的&#xff0c;如果从传统的电路理论角度去看&#xff0c;是无…

ZipList(压缩链表)

基本概述 ZipList 是一种特殊的“双端链表” &#xff0c;由一系列特殊编码的连续内存块组成。可以在任意一端进行压入/弹出操作, 并且该操作的时间复杂度为 O(1)。 基本结构&#xff1a; 各部分所占字节、基本介绍&#xff1a; entry&#xff0c;节点占用字节不固定&#xff0…

计算机图形学与opengl C++版 学习笔记 第9章 天空和背景

目录 9.1 天空盒9.2 天空穹顶9.3 实现天空盒9.3.1 从头开始构建天空盒9.3.2 使用OpenGL立方体贴图 9.4 环境贴图补充说明 对于室外3D场景&#xff0c;通常可以通过在地平线上创造一些逼真的效果&#xff0c;来增强其真实感。当我们极目远眺&#xff0c;目光越过附近的建筑和森林…

【认知提升思维篇】之 心智模式--人类的行为纪元

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;普本…

国产FPGA:替代ATLERAEP4CE10E22的AG10KL144

背景 AG10K用于PIN TO PIN替代ATLERA EP4CE10E22、EP3C10E144的FPGA&#xff0c;其资源介绍如下&#xff1a; 引脚对应如下&#xff1a; 一般Quartus II开发方式 新建工程 FPGA使用Quartus II开发&#xff0c;开发的整体流程如下&#xff1a; 新建工程时选用Cyclone II…

Liunx系统重修二【常用指令】

LIunx主要做服务器端的操作系统&#xff0c;不会做PC端操作系统的原因是因为&#xff1a; 第一图形化不好&#xff0c;第二软件生态不强&#xff01; 在Liunx系统中都是使用命令来操作&#xff01; Liunx系统中常用的指令并不多&#xff01;一天就可以学完&#xff01; 6&…

chatgpt赋能python:Python如何将图片文件上传至服务器

Python如何将图片文件上传至服务器 在现代网站设计中&#xff0c;图片的使用非常重要&#xff0c;因此将图片文件上传至服务器是一个很常见的操作。Python是一种广泛使用的编程语言&#xff0c;其拥有强大的图像处理能力&#xff0c;并提供了丰富的库来实现文件的上传和下载。…

【SCADA】KingSCADA实现小车移动控制

哈喽&#xff0c;大家好&#xff0c;我是雷工&#xff01; 在做SCADA项目时&#xff0c;时常会涉及到控制小车运动的情况&#xff0c;今天通过样例演示在KingSCADA中实现小车移动控制。 一、界面设计及效果演示 1、主画面 以下为测试样例的简单界面。 2、效果展示 当点击…

【Red Hat 7.9---详细安装Oracle 11g---图形化界面方式】

【Red Hat 7.9---详细安装Oracle 11g---图形化界面方式】 &#x1f53b; 一、安装前规划&#x1f53b; 二、安装前准备一&#xff08;系统参数修改&#xff09;⛳ 2.1 内核版本、系统版本查看⛳ 2.2 修改主机名-重启生效⛳ 2.3 关闭selinux⛳ 2.4 防火墙设置1521端口开放⛳ 2.5…

安全测试工具OWASP ZAP下载

下载 owasp作为一个开源免费的安全测试工具&#xff0c;集成了各种工具的渗透测试框架&#xff0c;还是非常不错滴&#xff0c;安装步骤就放在这啦 1.下载地址&#xff1a; https://www.zaproxy.org/download/ 2.进入后根据自己电脑系统自行下载 3.下载完成后&#xff0c;解压…

【OpenMMLab AI实战营二期笔记】第八天 语义分割与MMSegmentation

1.什么是语义分割 1.1 任务&#xff1a; 将图像按照物体的类别分割成不同的区域&#xff0c;相当于对每个像素进行分类。 1.2 应用&#xff1a; 无人驾驶汽车 人像分割 实时替换视频背景 智能遥感 分辨地表物体的类别&#xff0c;通过右侧分割之后的图像可以看到&#x…

高性能服务器-I/O多路复用(epoll)

系列文章目录 第一章 高性能服务器技术栈 (select) 第二章 高性能服务器技术栈 (epool/poll) 文章目录 系列文章目录前言一、epoll 接口二、epoll 原理三、epoll 触发方式四、设置阻塞方式代码 实例总结参考 前言 在网络中实现IO多路复用的技术&#xff0c;最常用的就是(sele…

linux(线程概念)

目录&#xff1a; 1.概念 2.linux线程与接口的关系 3.代码验证&#xff08;线程是进程模拟的&#xff09; ------------------------------------------------------------------------------------------------------------------------------- 1.概念 一般教材&#xff1a;…

STM32驱动Realtek RTL8189ES WiFi模块读取MAC地址并下载固件

单片机&#xff1a;STM32F103RE 接口&#xff1a;SDIO Keil 5工程下载链接&#xff1a;https://pan.baidu.com/s/1yIgUJUZcwWOL7xnwA9Rw2Q?pwdftxd Wi-Fi模块电源引脚的连接方法&#xff1a; 【RTL8189ES读取片内MAC地址的代码】 /* 显示WiFi模块参数信息 */ void WiFi_ShowI…

【力扣刷题 | 第八天】

前言&#xff1a; 本章将利用栈与队列来尝试解决实际问题。 20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&…

chatgpt赋能python:Python批量删除:简化SEO优化的过程

Python批量删除&#xff1a;简化SEO优化的过程 SEO&#xff08;Search Engine Optimization&#xff09;优化是网站运营中不可忽视的一项任务。其中涉及到对内容和网站结构的优化&#xff0c;而这些工作也离不开对数据的处理。其中一个常见问题是需要删除一批旧的或者无用的页…

《统计学习方法》——条件随机场(中)

引言 这是统计学习方法第十一章条件随机场的阅读笔记&#xff0c;包含所有公式的详细推导。 条件随机场(conditional random field,CRF)是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型&#xff0c;其特点是假设输出随机变量构成马尔可夫随机场。 建议先阅…

chatgpt赋能python:Python怎么持续输入?

Python怎么持续输入&#xff1f; Python是一个高级编程语言&#xff0c;它的简单易用性让它成为程序员们心仪的语言之一。在Python编程中&#xff0c;输入是一个非常重要的环节。 在这篇文章中&#xff0c;我们将讨论Python如何进行持续输入。我们将介绍几种不同的方法&#…

计算机图形学与opengl C++版 学习笔记 第10章 增强表面细节

假设我们想要对不规则表面的物体进行建模&#xff0c;例如橘子凹凸的表皮、葡萄干褶皱的表面或月球的陨石坑表面。我们该怎么做&#xff1f;到目前为止&#xff0c;我们已经学会了两种可能的方法&#xff1a; &#xff08;a&#xff09;我们可以对整个不规则表面进行建模&…

【期末总复习】数字图像处理知识要点

【A卷】 【选择】 1、计算机器显示彩色图像的格式 2、灰度反转后&#xff08;一副图像灰度级&#xff09;的灰度值是几 3、灰度图像浅色背景下加圆环会导致什么后果 4、图像平滑的模板有哪些 5、γ矫正指的是什么数学变换 6、一阶锐化空间滤波器有哪些 7、图像复原、图像增强…