从源文件到可执行程序(二)

关于目标文件

源程序经过编译器编译后生成目标文件。目标文件的格式基本和可执行文件相同,只是在进行链接之前,有些符号和函数的地址是未知的,还需要经过链接来进行调整。Linux系统中采用的可执行文件格式是ELF,因此目标文件也采用这种格式进行存储。不光目标文件,静态库文件(其实就是多个目标文件以及一些索引)和动态库文件也都采用这种格式进行存储。使用命令file可以查看文件格式。

$ file example.o
example.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
目标文件属于可重定位文件类型,这类文件(包括静态链接库)可以连接成可执行文件或者共享目标文件,通常对应于后缀名为.o的文件。(当然,linux并不以后缀名作为判断文件类型的唯一依据)
$ file /bin/bash
/bin/bash: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped
程序属于可执行文件类型,这类文件通常没有后缀名
$ file /lib/ld-2.11.1.so
/lib/ld-2.11.1.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, stripped
动态链接库属于共享文件类型,通常对应于后缀名为.so的文件。

还有另外一种文件也采用ELF文件格式进行存储,那就是core文件(Linux下文件名一般为core.pid,其中pid为进程标识符)。这类文件在调试时很有用,如果程序在运行时崩溃,系统会创建一个对应的core文件,这个文件是程序所占用内存的一个镜像,分析此文件,可以了解程序崩溃时的状态,分析并解决bug。

可以看出,虽然很多文件都采用ELF文件格式,但是其具体类型是不同的。


ELF文件一般包含很多个段,如代码段,数据段等,每一个段存储程序的不同部分。如
文件头(file header)
----文件头,描述文件属性,入口地址,目标操作系统等,其中最重要的就是一个段表。段表时描述各个段的一个数组,描述了各个段的偏移量等所有信息。
代码段(code section/text section)
----存储程序指令
数据段(data section)
----存储已初始化的全局变量和静态变量
符号段(bss section)
----未初始化的全局变量和静态变量

代码段和数据段很简单,为了更好的利用程序局部性提高性能,同时利用共享指令来节省空间,代码和数据分开存储。bss段,这个段其实并不占据执行文件的任何空间,只是记录了未初始化的全局变量和静态变量所占的空间,当文件被载入内存执行时,系统为其分配相应的空间。

 

 


这是一个示例程序sample.c,终端中输入命令gcc -c sample.c,得到其对应的目标文件sample.o。再利用命令objdump查看该目标文件。
$ objdump -h sample.o

sample.o:     file format elf32-i386

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000003c  00000000  00000000  00000034  2**2
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000008  00000000  00000000  00000070  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000004  00000000  00000000  00000078  2**2
                  ALLOC
  3 .rodata       00000004  00000000  00000000  00000078  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .comment      00000024  00000000  00000000  0000007c  2**0
                  CONTENTS, READONLY
  5 .note.GNU-stack 00000000  00000000  00000000  000000a0  2**0
                  CONTENTS, READONLY
Size和File Off分别代表每个段的长度和位置(以偏移量来表示),CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE表示段的属性。CONTENTS表示这些段在文件中存在,从这里可以进一步确定bss在文件中并不占据任何空间。最诡异的是.note.GNU-stack段,CONTENTS属性表明其存在,但Size却为0。
使用size命令可以查看文件各个段的长度。
$ size sample.o
   text       data        bss        dec        hex    filename
     64          8          4         76         4c    sample.o

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值