分享

C源文件到ELF可执行文件的生成过程

 昵称19263926 2014-09-07
 you can download from site: http://michgarfield./home


预备知识,阅读文章“as中常见伪指令.word .align .balign[lw] .macro .globl”

C源文件到ELF可执行文件的生成过程

1. 编译器的预处理

2. C源代码转换为汇编代码

3. 生成目标文件

4. 将目标文件链接为ELF可执行文件


ELF文件类型共有4种类型

1. 可重定位文件relocatable file

执行file xx.o,其中xx表示编译过程生成的目标文件

返回ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped

2. 可执行文件executable file

执行file /bin/sh

ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped

3. 共享目标文件share object file

执行file /lib/libmemusage.so

/lib/libmemusage.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, stripped

4. 核心转储文件core dump file

执行file /proc/kcore

ELF 32-bit LSB core file Intel 80386, version 1 (SYSV), SVR4-style, from '-3b3e-428f-91d0-1a730571'


  • 编写C代码

现在通过举例说明整个编译过程,首先建立show.c和mian.c文件,其中show.c文件的内容如下

#include <stdio.h>

void show()

{

printf ("this program is used to test ld\n");

}

mian.c的内容如下

extern void show();

int main()

{

show();

return 0;

}


  • C源代码转换为汇编代码

用gcc加上-save-temps选项编译完成以后,可以看到汇编文件show.s内容如下

.file "show.c"

.section .rodata

.align 4

.LC0:

.string "this program is used to test ld"

.text

.globl show

.type show, @function

show:

pushl %ebp

movl %esp, %ebp

subl $24, %esp

movl $.LC0, (%esp)

call puts

leave

ret

.size show, .-show

.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"

.section .note.GNU-stack,"",@progbits

从汇编文件show.s里可以发现汇编文件里包含了很多的伪指令,其中align4表示16字节对齐,globl是的show符号对ld可见,即全局的。所有汇编文件.text section最后都会放在ELF文件的.text section


  • 生成目标文件

对show.o进行反汇编(objdump –d show.o)

Disassembly of section .text:

00000000 <show>:

0: 55 push %ebp

1: 89 e5 mov %esp,%ebp

3: 83 ec 18 sub $0x18,%esp

6: c7 04 24 00 00 00 00 movl $0x0,(%esp)

d: e8 fc ff ff ff call e <show+0xe>

12: c9 leave


13: c3 ret

对main.o进行反汇编(objdump –d main.o)

Disassembly of section .text:

00000000 <main>:

0: 55 push %ebp

1: 89 e5 mov %esp,%ebp

3: 83 e4 f0 and $0xfffffff0,%esp

6: e8 fc ff ff ff call 7 <main+0x7>

b: b8 00 00 00 00 mov $0x0,%eax

10: 89 ec mov %ebp,%esp

12: 5d pop %ebp

13: c3 ret

而目标文件的生成也很简单,只是把汇编文件进行编译为对应机器码。该过程没有按照伪指令进行对齐边界,也没有进行的地址修正,对需要修正的地址只是在当前地址上+1.


  • 将目标文件链接为ELF可执行文件

链接器最后将所有的目标文件链接为ELF可执行文件,对ELF文件反汇编内容如下

080483e4 <main>:

80483e4: 55 push %ebp

80483e5: 89 e5 mov %esp,%ebp

80483e7: 83 e4 f0 and $0xfffffff0,%esp

80483ea: e8 09 00 00 00 call 80483f8 <show>

80483ef: b8 00 00 00 00 mov $0x0,%eax

80483f4: 89 ec mov %ebp,%esp

80483f6: 5d pop %ebp

80483f7: c3 ret


080483f8 <show>:

80483f8: 55 push %ebp

80483f9: 89 e5 mov %esp,%ebp

80483fb: 83 ec 18 sub $0x18,%esp

80483fe: c7 04 24 d0 84 04 08 movl $0x80484d0,(%esp)

8048405: e8 0e ff ff ff call 8048318 <puts@plt>

804840a: c9 leave

804840b: c3 ret

804840c: 90 nop

804840d: 90 nop

804840e: 90 nop

804840f: 90 nop

在链接器链接完成以后可以看出main函数调用show函数的地址和show函数对printf函数的地址都变成绝对地址,而且程序在最后加入了4条nop操作,使得以16字节对齐。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多