当前位置: 首页 > news >正文

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

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

  • 一、目标文件_存储格式
    • 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.ohello.o:     文件格式 elf64-x86-64Contents 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   %rbp1:	48 89 e5             	mov    %rsp,%rbp4:	48 83 ec 10          	sub    $0x10,%rsp8:	89 7d fc             	mov    %edi,-0x4(%rbp)b:	8b 45 fc             	mov    -0x4(%rbp),%eaxe:	89 c6                	mov    %eax,%esi10:	bf 00 00 00 00       	mov    $0x0,%edi15:	b8 00 00 00 00       	mov    $0x0,%eax1a:	e8 00 00 00 00       	callq  1f <show+0x1f>1f:	c9                   	leaveq 20:	c3                   	retq   0000000000000021 <main>:21:	55                   	push   %rbp22:	48 89 e5             	mov    %rsp,%rbp25:	48 83 ec 10          	sub    $0x10,%rsp29:	c7 45 fc 01 00 00 00 	movl   $0x1,-0x4(%rbp)30:	8b 45 fc             	mov    -0x4(%rbp),%eax33:	89 c7                	mov    %eax,%edi35:	e8 00 00 00 00       	callq  3a <main+0x19>3a:	b8 ff ff ff ff       	mov    $0xffffffff,%eax3f:	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.ohello.o:     文件格式 elf64-x86-64
hello.o
体系结构:i386:x86-64,标志 0x00000011:
HAS_RELOC, HAS_SYMS
起始地址 0x0000000000000000节:
Idx Name          Size      VMA               LMA               File off  Algn0 .text         00000041  0000000000000000  0000000000000000  00000040  2**0CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE1 .data         00000008  0000000000000000  0000000000000000  00000084  2**2CONTENTS, ALLOC, LOAD, DATA2 .bss          00000004  0000000000000000  0000000000000000  0000008c  2**2ALLOC3 .rodata       00000004  0000000000000000  0000000000000000  0000008c  2**0CONTENTS, ALLOC, LOAD, READONLY, DATA4 .comment      0000002e  0000000000000000  0000000000000000  00000090  2**0CONTENTS, READONLY5 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000be  2**0CONTENTS, READONLY6 .eh_frame     00000058  0000000000000000  0000000000000000  000000c0  2**3CONTENTS, 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 mainContents 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   %rbp1:	48 89 e5             	mov    %rsp,%rbp4:	48 83 ec 10          	sub    $0x10,%rsp8:	89 7d fc             	mov    %edi,-0x4(%rbp)b:	8b 45 fc             	mov    -0x4(%rbp),%eaxe:	89 c6                	mov    %eax,%esi10:	bf 00 00 00 00       	mov    $0x0,%edi11: R_X86_64_32	.rodata15:	b8 00 00 00 00       	mov    $0x0,%eax1a:	e8 00 00 00 00       	callq  1f <show+0x1f>1b: R_X86_64_PC32	printf-0x41f:	c9                   	leaveq 20:	c3                   	retq   0000000000000021 <main>:21:	55                   	push   %rbp22:	48 89 e5             	mov    %rsp,%rbp25:	48 83 ec 10          	sub    $0x10,%rsp29:	c7 45 fc 01 00 00 00 	movl   $0x1,-0x4(%rbp)30:	8b 45 fc             	mov    -0x4(%rbp),%eax33:	89 c7                	mov    %eax,%edi35:	e8 00 00 00 00       	callq  3a <main+0x19>36: R_X86_64_PC32	show-0x43a:	b8 ff ff ff ff       	mov    $0xffffffff,%eax3f:	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 VABI 版本:                          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  000000000000000000000000  0000000000000000           0     0     0[ 1] .text             PROGBITS         0000000000000000  000000400000000000000041  0000000000000000  AX       0     0     1[ 2] .rela.text        RELA             0000000000000000  000002f80000000000000048  0000000000000018   I      10     1     8[ 3] .data             PROGBITS         0000000000000000  000000840000000000000008  0000000000000000  WA       0     0     4[ 4] .bss              NOBITS           0000000000000000  0000008c0000000000000004  0000000000000000  WA       0     0     4[ 5] .rodata           PROGBITS         0000000000000000  0000008c0000000000000004  0000000000000000   A       0     0     1[ 6] .comment          PROGBITS         0000000000000000  00000090000000000000002e  0000000000000001  MS       0     0     1[ 7] .note.GNU-stack   PROGBITS         0000000000000000  000000be0000000000000000  0000000000000000           0     0     1[ 8] .eh_frame         PROGBITS         0000000000000000  000000c00000000000000058  0000000000000000   A       0     0     8[ 9] .rela.eh_frame    RELA             0000000000000000  000003400000000000000030  0000000000000018   I      10     8     8[10] .symtab           SYMTAB           0000000000000000  000001180000000000000180  0000000000000018          11    11     8[11] .strtab           STRTAB           0000000000000000  00000298000000000000005d  0000000000000000           0     0     1[12] .shstrtab         STRTAB           0000000000000000  000003700000000000000061  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 mainU 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 VABI 版本:                          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  000000000000000000000000  0000000000000000           0     0     0[ 1] .text             PROGBITS         0000000000000000  000000400000000000000041  0000000000000000  AX       0     0     1[ 2] .rela.text        RELA             0000000000000000  000002f80000000000000048  0000000000000018   I      10     1     8[ 3] .data             PROGBITS         0000000000000000  000000840000000000000008  0000000000000000  WA       0     0     4[ 4] .bss              NOBITS           0000000000000000  0000008c0000000000000004  0000000000000000  WA       0     0     4[ 5] .rodata           PROGBITS         0000000000000000  0000008c0000000000000004  0000000000000000   A       0     0     1[ 6] .comment          PROGBITS         0000000000000000  00000090000000000000002e  0000000000000001  MS       0     0     1[ 7] .note.GNU-stack   PROGBITS         0000000000000000  000000be0000000000000000  0000000000000000           0     0     1[ 8] .eh_frame         PROGBITS         0000000000000000  000000c00000000000000058  0000000000000000   A       0     0     8[ 9] .rela.eh_frame    RELA             0000000000000000  000003400000000000000030  0000000000000018   I      10     8     8[10] .symtab           SYMTAB           0000000000000000  000001180000000000000180  0000000000000018          11    11     8[11] .strtab           STRTAB           0000000000000000  00000298000000000000005d  0000000000000000           0     0     1[12] .shstrtab         STRTAB           0000000000000000  000003700000000000000061  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 + 21The 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 Name0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND 1: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS hello.c2: 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.21847: 0000000000000004     4 OBJECT  LOCAL  DEFAULT    3 static_var.21838: 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_var12: 0000000000000004     4 OBJECT  GLOBAL DEFAULT  COM global_uninit_var13: 0000000000000000    33 FUNC    GLOBAL DEFAULT    1 show14: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND printf15: 0000000000000021    32 FUNC    GLOBAL DEFAULT    1 mainNo 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.ohello.o:     文件格式 elf64-x86-64节:
Idx Name          Size      VMA               LMA               File off  Algn0 .text         00000041  0000000000000000  0000000000000000  00000040  2**0CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE1 .data         00000008  0000000000000000  0000000000000000  00000084  2**2CONTENTS, ALLOC, LOAD, DATA2 .bss          00000004  0000000000000000  0000000000000000  0000008c  2**2ALLOC3 .rodata       00000004  0000000000000000  0000000000000000  0000008c  2**0CONTENTS, ALLOC, LOAD, READONLY, DATA4 .debug_info   00000129  0000000000000000  0000000000000000  00000090  2**0CONTENTS, RELOC, READONLY, DEBUGGING5 .debug_abbrev 000000a9  0000000000000000  0000000000000000  000001b9  2**0CONTENTS, READONLY, DEBUGGING6 .debug_aranges 00000030  0000000000000000  0000000000000000  00000262  2**0CONTENTS, RELOC, READONLY, DEBUGGING7 .debug_line   00000041  0000000000000000  0000000000000000  00000292  2**0CONTENTS, RELOC, READONLY, DEBUGGING8 .debug_str    00000119  0000000000000000  0000000000000000  000002d3  2**0CONTENTS, READONLY, DEBUGGING9 .comment      0000002e  0000000000000000  0000000000000000  000003ec  2**0CONTENTS, READONLY10 .note.GNU-stack 00000000  0000000000000000  0000000000000000  0000041a  2**0CONTENTS, READONLY11 .eh_frame     00000058  0000000000000000  0000000000000000  00000420  2**3CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

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

相关文章:

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

【编译和链接六】汇编——目标文件 一、目标文件_存储格式1、生成目标文件2、目标文件存储格式3、file查看文件格式 二、查看目标文件的内部结构——objdump三、代码段四、 数据段和只读数据段五、 ELF文件结构描述1、头文件2、段表2.1、重定位表2.2、字符串表2.3、查看重定位表…...

王道计算机考研408计算机组成原理汇总(下)

提示:真正的英雄是明白世界的残酷,也遭受了社会带给他的苦难,他依然能用心的说“我热爱这个世界,我愿竭尽所能去为我的世界而好好战斗 文章目录 前言4.1.1 指令格式4.1.2 扩展操作码指令格式4.2.1 指令寻址4.2.2 数据寻址4.2.3 偏移寻址4.2.4 堆栈寻址汇总前言4.3.1 高级语…...

偏向锁、轻量级锁、重量级锁、自旋锁、自适应自旋锁

1. 偏向锁 偏向锁就是在运行过程中&#xff0c;对象的锁偏向某个线程。即在开启偏向锁机制的情况下&#xff0c;某个线程获得锁&#xff0c;当该线程下次再想要获得锁时&#xff0c;不需要重新申请获得锁&#xff08;即忽略synchronized关键词&#xff09;&#xff0c;直接就可…...

Delta 一个新的 git diff 对比显示工具

目录 介绍git diff 介绍delta介绍 一、安装1.下载 Git2.下载 delta3.解压4.修改配置文件5. 修改主题6.其他配置和说明 二、对比命令1.在项目中 git diff 常用命令2.对比电脑上两个文件3.对比电脑上的两个文件夹 三、在Git 命令行中使用效果四、在idea 的Terminal命令行中使用效…...

C# 二进制序列化和反序列化示例

.NET框架提供了两种种串行化的方式&#xff1a; 1、是使用BinaryFormatter进行串行化&#xff1b; 2、使用XmlSerializer进行串行化。 第一种方式提供了一个简单的二进制数据流以及某些附加的类型信息&#xff0c;而第二种将数据流格式化为XML存储。可以使用[Serializable]属…...

【CSS】文字扫光 | 渐变光

码来 可调整角度与颜色值来改变效果 <p class"gf-gx-color">我是帅哥</p> <style>.gf-gx-color {background: -webkit-linear-gradient(135deg,red,red 25%,red 50%,#fff 55%,red 60%,red 80%,red 95%,red);-webkit-text-fill-color: transparen…...

Overhaul Distillation(ICCV 2019)原理与代码解析

paper&#xff1a;A Comprehensive Overhaul of Feature Distillation official implementation&#xff1a;GitHub - clovaai/overhaul-distillation: Official PyTorch implementation of "A Comprehensive Overhaul of Feature Distillation" (ICCV 2019) 本文的…...

<Linux开发>驱动开发 -之-内核定时器与中断

&#xff1c;Linux开发&#xff1e;驱动开发 -之-内核定时器与中断 交叉编译环境搭建&#xff1a; &#xff1c;Linux开发&#xff1e; linux开发工具-之-交叉编译环境搭建 uboot移植可参考以下&#xff1a; &#xff1c;Linux开发&#xff1e; -之-系统移植 uboot移植过程详…...

希尔贝壳邀您参加2023深圳国际人工智能展览会

2023深圳国际人工智能展览会“AIE”将于2023年5月16-18日在深圳国际会展中心 (宝安)举办&#xff0c;希尔贝壳受邀参加&#xff0c;展位号&#xff1a;A331。 伴随着智能行业的快速发展&#xff0c;展会已被越来越多的企业列入每年必选展会&#xff0c;也成为各采购商选购的理…...

设计优质微信小程序的实用指南!

微信小程序是一种快速发展的应用形式&#xff0c;设计良好的小程序能够提升用户体验并吸引更多的用户。在设计微信小程序时&#xff0c;有一些关键的指南可以帮助我们做出出色的设计。以下是即时设计总结的一些设计指南&#xff0c;希望能对准备设计微信小程序的人有所帮助。 …...

大数据期末总结

文章目录 一、这学期分别学习了Scala、spark、spring、SpringMvc、SpringBoot1、scala2、spark3、spring4、SpringMvc5、SpringBoot 二、总结 一、这学期分别学习了Scala、spark、spring、SpringMvc、SpringBoot 1、scala Scala是一门基于JVM的编程语言&#xff0c;具有强大的…...

selenium面试题总结

今天有同学问到seleinum面试的时候会问到的问题&#xff0c;随便想了想&#xff0c;暂时纪录一下。欢迎大家在评论中提供更多问题。 1.selenium中如何判断元素是否存在&#xff1f; selenium中没有提供原生的方法判断元素是否存在&#xff0c;一般我们可以通过定位元素异常捕获…...

⑧电子产品拆解分析-1拖4USB拓展坞

⑧电子产品拆解分析-1拖4USB拓展坞 一、功能介绍二、电路分析以及器件作用1、内部电路拆解三、参考资料学习一、功能介绍 ①USB2.0一拖四通讯;②具备OTG功能,可适配大部分USB接口设备;二、电路分析以及器件作用 1、内部电路拆解 分析:❤️ ❤️ ❤️ 主控是MA8601 USB 2.0…...

月度精华汇总 | 最新XR行业资讯、场景案例、活动都在这一篇里啦!

​ 在过去的一个月中&#xff0c;平行云为您带来了关于XR领域的一系列精彩文章&#xff0c;涵盖了行业资讯、应用案例&#xff0c;市场互动&#xff0c;帮助您掌握XR领域最新动态&#xff0c;了解实时云渲染、Cloud XR技术的价值&#xff0c;以及平行云实时云渲染解决方案LarkX…...

Redis实战案例1-短信登录

Redis的共享session应用 1. 项目的相关工作 导入sql文件 找到对应的sql文件即可 基本表的信息 基本架构 导入对应的项目文件&#xff0c;启动相关的service服务; 在nginx-1.18.0目录下启动命令行start nginx.exe&#xff1b; 2. 基于session实现登录的流程 这里利用到Javaweb中…...

华为OD机试真题 JavaScript 实现【找终点】【2023 B卷 100分】,附详细解题思路

一、题目描述 给定一个正整数数组&#xff0c;设为nums&#xff0c;最大为100个成员&#xff0c;求从第一个成员开始&#xff0c;正好走到数组最后一个成员&#xff0c;所使用的最少步骤数。 要求&#xff1a; 第一步必须从第一元素开始&#xff0c;且1 < 第一步的步长 &…...

详解数据仓库数据湖及湖仓一体

比别人更快接收好文章 随着近几年数据湖概念的兴起&#xff0c;业界对于数据仓库和数据湖的对比甚至争论就一直不断。有人说数据湖是下一代大数据平台&#xff0c;各大云厂商也在纷纷的提出自己的数据湖解决方案&#xff0c;一些云数仓产品也增加了和数据湖联动的特性。 但是…...

基于注解切换、Hikari实现的SpringBoot动态数据源(支持JNDI)

实现效果 先说效果&#xff0c;要实现方法级别注解切换当前数据源&#xff0c;不设置注解时走默认数据源&#xff0c;同时支持JNDI源。 总体思路 Spring框架中存在一个抽象类AbstractRoutingDataSource&#xff0c;他是一个可以动态选择当前DataSource的路由类&#xff0c;我…...

Java中的动态链接VS操作系统动态链接

在操作系统OS中为了优化内存的使用会采用一种动态链接方式&#xff0c;一个文件想要在操作系统中运行必须经过编译、汇编译、链接、装载等步骤。可以参考Java程序是怎么跑起来的。本篇主要讲解Java栈帧中动态链接部分与操作系统的的动态链接的区别与联系 操纵系统为什么需要动态…...

深入理解Linux虚拟内存管理(七)

系列文章目录 Linux 内核设计与实现 深入理解 Linux 内核 Linux 设备驱动程序 Linux设备驱动开发详解 深入理解Linux虚拟内存管理&#xff08;一&#xff09; 深入理解Linux虚拟内存管理&#xff08;二&#xff09; 深入理解Linux虚拟内存管理&#xff08;三&#xff09; 深入理…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error

在前端开发中&#xff0c;JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作&#xff08;如 Promise、async/await 等&#xff09;&#xff0c;开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝&#xff08;r…...

Oracle11g安装包

Oracle 11g安装包 适用于windows系统&#xff0c;64位 下载路径 oracle 11g 安装包...