目标文件是什么鬼?

     目标文件就是源代码编译后但未进行链接的那些中间文件。


COFF、ELF、PE又是什么?

COFF(Common file format)又称通用目标文件格式,是一种用于可执行文件、目标代码、共享库(shared library)的文件格式,使用于类UNIX系统上。它最早使用于UNIX System V上,用来取代先前的a.out格式,后来又发展出XCOFF与ECOFF。COFF最主要的贡献是引入了“段”的机制,不通的目标文件可以拥有不同数量及不同类型的“段”


ELF (Executable and Linkable Format)可执行与可链接格式 常被称为ELF格式,在计算机科学中,是一种用于可执行文件、目标文件、共享库和核心转储的标准文件格式。COFF变种  LINUX使用ELF


PE (Portable Execuable)可移植性可执行文件是一种用于可执行文件、目标文件和动态链接库的文件格式,主要使用在32位和64位的Windows操作系统上。COFF变种   WINDOWS使用


目标文件格式


ELF文件类型说明实例
可重定位文件(Relocatable File)

这类文件包含了代码和数据,可以被用来
链接成可执行文件或共享目标文件,静态
链接库也可以归为这一类

Linux的.o

windows的.obj

可执行文件(Executable File)

这类文件包含了可以直接执行的程序,它
的代表就是ELF可执行文件,它们一般都
没有扩展名

如:Liunx /bin/bash

windows .exe 

共享目标文件(Shared Object File)

1、首先链接编辑器可以将它和其它可重定位文件和共享目标文件一起处理, 生成另外一个目标文件。

2、其次动态链接器(Dynamic Linker)可能将它与某 个可执行文件以及其它共享目标一起组合,创建进程映像。

如:Linuxx下的.so

widnows的DLL

核心转存文件(Code Dump File)

当进程意外终止时,系统可以将该进程的
地址空间的内容及终止时的一些其他信息
转储到核心转储文件

Linux下的core dump


Linux下查看文件格式

重定位文件

[root@localhost ~]# file /usr/lib64/crt1.o
/usr/lib64/crt1.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.32, not stripped


可执行文件

[root@localhost ~]# file /bin/bash
/bin/bash: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared lib       s), for GNU/Linux 2.6.32, BuildID[sha1]=9223530b1aa05d3dbea7e72738b28b1e9d82fbad, stripped



目标共享文件

[root@localhost ~]# file /lib/ld-2.17.so
/lib/ld-2.17.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=33446bb2067122aef759b21f15245840c26afa0a, not stripped



目标文件样子

image

     上面少的.bss Section,未初始化的全局变量和局部变量一般放在.bss中,未初始化的变量默认值为0,实际上可以放在data段中,但是没啥意义还需要占用些内存。BSS中只是给变量预留位置并不占用内存

      总体来说,程序源代码编译以后主要分成两个段,程序指令和程序数据。代码段属于程序指令,而数据段和.BSS都属于程序数据


实战分析

  实验代码:

  1 int printf( const char* format, ... );
  2 
  3 int global_init_var = 84;
  4 int global_uninit_var;
  5 
  6 void func1( int i ) {
  7     printf( "%d\n", i );
  8 }
  9 
 10 int main( void ) {
 11     static int static_var = 85;
 12     static int static_var2;
 13     int a = 1;
 14     int b;
 15     func1( static_var + static_var2 + a + b );
 16     return a;
 17 }
View Code

生成目标文件

[root@localhost ~]# gcc -c test1.c


查看目标文件结构和内容(-x选项输出更多内容)

[root@localhost ~]# objdump -h test1.o

image

补充其它段信息:

.rodata 只读数据段

.comment 注释信息段

.note.GNU-stack 堆栈提示段


段格式

Size  段的长度

File off 段所在位置

CONTENTS  表示该段在文件中存在

ALLOC  表示段的各种属性


查看ELF代码段、数据段、BSS段(dec表示三个段长度和的十进制,hex表示三个段长度和的十六进制)

[root@localhost ~]# size test1.o
    text    data     bss     dec     hex filename
     176       8       4     188      bc test1.o

  


[root@localhost ~]# objdump -s -d test1.o

执行结果
 
     
  

-s 以十六进制显示

-d 反汇编包含所有指令的段

大致说下结果:

最左面一侧是偏移量,中间4列是十六进制内容,最后右面一列是text段的ASCII码,


data段(初始化全局和局部变量)

Contents of section .data:
  0000 54000000 55000000                    T...U...

54000000对应是84,55000000 对应的是85

int global_init_var = 84;

static int static_var = 85;


bss段(未初始化全局变量和局部变量)

.bss          00000004  0000000000000000  0000000000000000  0000009c  2**2

00000004=4字节  代码global_uninit_var; static int static_var2; 前面4个字节但是这里有2个变量,显然有问题。实际在.bss段中只有static_var2。查看 SYMBOL TABLE  发现global_uninit_var没有存在任何地方 只是一个*COM*符号,这其实跟不同的语言与不同编译器有关系,有些编译器会将未初始化全局变量放在.bss中


详细查看ELF文件头

[root@localhost ~]# readelf -h test1.o
ELF Header:
   Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
   Class:                             ELF64
   Data:                              2's complement, little endian
   Version:                           1 (current)
   OS/ABI:                            UNIX - System V
   ABI Version:                       0
   Type:                              REL (Relocatable file)
   Machine:                           Advanced Micro Devices X86-64
   Version:                           0x1
   Entry point address:               0x0
   Start of program headers:          0 (bytes into file)
   Start of section headers:          1048 (bytes into file)
   Flags:                             0x0
   Size of this header:               64 (bytes)
   Size of program headers:           0 (bytes)
   Number of program headers:         0
   Size of section headers:           64 (bytes)
   Number of section headers:         13
   Section header string table index: 12





转载于:https://www.cnblogs.com/menkeyi/p/11508457.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值