读书人

从C资料到可执行elf文件

发布时间: 2013-09-28 10:01:20 作者: rapoo

从C文件到可执行elf文件
摘要:本文主要为你解释一个C文件是如何被一步步处理成可执行的elf格式文件的。
本文来源: 从C文件到ELF
说明:所有本文的用例是以下hello.c程序:

#include<stdio.h>int main(int argc, char *argv[]){  printf("hello world\n");  return 0;}

1.预处理
作用:预处理器是在真正的编译开始之前由编译器调用的独立程序。预处理器可以删除注释、包含其他文件以及执行宏(宏macro是一段重复文字的简短描写)替代。我们来看看hello.c经过预处理以后的结果:gcc -E hello.c -o hello.i
gcc -S hello.i -o hello.s

gcc的-S选项,表示在程序编译期间,在生成汇编代码后,停止,-o输出汇编代码文件。我们同样可以用vim打开观看:

gcc -c hello.s -o hello.o
说明,这一步将程序划分为若干段(数据段,代码段等),可以用objdump命令来查看这些目标文件的内容。
$ objdump -x hello.o hello.o:     file format elf32-i386hello.oarchitecture: i386, flags 0x00000011:HAS_RELOC, HAS_SYMSstart address 0x00000000Sections:Idx Name          Size      VMA       LMA       File off  Algn  0 .text         0000001c  00000000  00000000  00000034  2**2                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE  1 .data         00000000  00000000  00000000  00000050  2**2                  CONTENTS, ALLOC, LOAD, DATA  2 .bss          00000000  00000000  00000000  00000050  2**2                  ALLOC  3 .rodata       0000000c  00000000  00000000  00000050  2**0                  CONTENTS, ALLOC, LOAD, READONLY, DATA  4 .comment      0000002b  00000000  00000000  0000005c  2**0                  CONTENTS, READONLY  5 .note.GNU-stack 00000000  00000000  00000000  00000087  2**0                  CONTENTS, READONLY  6 .eh_frame     00000038  00000000  00000000  00000088  2**2                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATASYMBOL TABLE:00000000 l    df *ABS*00000000 hello.c00000000 l    d  .text00000000 .text00000000 l    d  .data00000000 .data


4连接(Linking)

链接:连接器的目的主要是进行重定位和符号解析,gcc连接器是gas提供的,负责将程序的目标文件与所需的所有附加的目标文件连接起来,最终生成可执行文件。附加的目标文件包括静态连接库和动态连接库。

对于上一小节中生成的test.o,将其与C标准输入输出库进行连接,最终生成程序test

gcc hello.o -o hello

可以用readelf命令查看elf文件的详细内容:

Histogram for `.gnu.hash' bucket list length (total of 2 buckets): Length  Number     % of total  Coverage      0  1          ( 50.0%)      1  1          ( 50.0%)    100.0%Version symbols section '.gnu.version' contains 5 entries: Addr: 0000000008048266  Offset: 0x000266  Link: 5 (.dynsym)  000:   0 (*local*)       2 (GLIBC_2.0)     0 (*local*)       2 (GLIBC_2.0)    004:   1 (*global*)   Version needs section '.gnu.version_r' contains 1 entries: Addr: 0x0000000008048270  Offset: 0x000270  Link: 6 (.dynstr)  000000: Version: 1  File: libc.so.6  Cnt: 1  0x0010:   Name: GLIBC_2.0  Flags: none  Version: 2Notes at offset 0x00000168 with length 0x00000020:  Owner                 Data sizeDescription  GNU                  0x00000010NT_GNU_ABI_TAG (ABI version tag)    OS: Linux, ABI: 2.6.24


在命令行窗口中,执行./hello, 让它说HelloWorld吧!

读书人网 >其他相关

热点推荐