從C檔案到可執行elf檔案
摘要:本文主要為你解釋一個C檔案是如何被一步步處理成可執行的elf格式檔案的。
本文來源: 從C檔案到ELF
說明:所有本文的用例是以下hello.c程式:
#include<stdio.h>
int main(int argc, char *argv[])
{
printf("hello world\n");
return 0;
}
1.預處理
我們來看看hello.c經過預處理以後的結果:gcc -E hello.c -o hello.i
extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
# 940 "/usr/include/stdio.h" 3 4
# 2 "hello.c" 2
int main(int argc, char *argv[])
{
printf("hello world\n");
return 0;
}
變化:預處理結果就是將stdio.h 檔案中的內容插入到hello.c中了,檔案變成了855行
2編譯為彙編程式碼(Compilation)
編譯:編譯器的作用是預處理之後,可直接對生成的hello.i檔案編譯,生成彙編程式碼:
gcc -S hello.i -o hello.s
gcc的-S選項,表示在程式編譯期間,在生成彙編程式碼後,停止,-o輸出彙編程式碼檔案。我們同樣可以用vim開啟觀看:
1 .file "hello.c"
2 .section .rodata
3 .LC0:
4 .string "hello world"
5 .text
6 .globl main
7 .type main, @function
8 main:
9 .LFB0:
10 .cfi_startproc
11 pushl %ebp
12 .cfi_def_cfa_offset 8
13 .cfi_offset 5, -8
14 movl %esp, %ebp
15 .cfi_def_cfa_register 5
16 andl $-16, %esp
17 subl $16, %esp
18 movl $.LC0, (%esp)
19 call puts
20 movl $0, %eax
21 leave
22 .cfi_restore 5
23 .cfi_def_cfa 4, 4
24 ret
25 .cfi_endproc
26 .LFE0:
27 .size main, .-main
28 .ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
29 .section .note.GNU-stack,"",@progbits
3彙編(Assembly)
彙編:彙編器對於上一小節中生成的彙編程式碼檔案hello.s,gas彙編器負責將其編譯為目標檔案,如下:
gcc -c hello.s -o hello.o
說明,這一步將程式劃分為若干段(資料段,程式碼段等),可以用objdump命令來檢視這些目標檔案的內容。
$ objdump -x hello.o
hello.o: file format elf32-i386
hello.o
architecture: i386, flags 0x00000011:
HAS_RELOC, HAS_SYMS
start address 0x00000000
Sections:
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, DATA
SYMBOL TABLE:
00000000 l df *ABS* 00000000 hello.c
00000000 l d .text 00000000 .text
00000000 l d .data 00000000 .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: 2
Notes at offset 0x00000168 with length 0x00000020:
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
OS: Linux, ABI: 2.6.24
在命令列視窗中,執行./hello, 讓它說HelloWorld吧!
總結一下:原始檔name.c,經過-s處理,在編譯之前停下,生成彙編程式碼,當然有intel 和AT&T等彙編格式可選;
然後經過-o,編譯成目的碼,目的碼已經基本上是一些機器程式碼和重定位等資訊了,典型的目的碼有text , data, bss等幾個段構成
然後經過連結,生成可執行目標檔案,這已經是完完全全的機器程式碼了(包含一些裝載器所需要的定位資訊)
相關文章
- Linux可執行檔案格式-ELF結構詳解Linux
- Java解析ELF檔案:ELF檔案格式規範Java
- 淺談從原始碼檔案到二進位制可執行檔案的過程原始碼
- elf檔案格式
- C語言判斷檔案是否存在,判斷檔案可讀可寫可執行C語言
- ubuntu 把檔案設定為可執行檔案Ubuntu
- 從原始檔到可執行檔案:原始檔的預處理、編譯、彙編、連結編譯
- ELF檔案逆向分析
- matlab (.m)檔案生成 windows 可執行(.exe)檔案MatlabWindows
- C++程式怎樣呼叫exe可執行檔案C++
- Mach-O 可執行檔案Mac
- maven 打包可執行 jar 檔案MavenJAR
- MATLAB生成可執行檔案Matlab
- Java執行exe,bat等可執行檔案JavaBAT
- 扒一扒ELF檔案
- elf檔案處理工具
- 建立可執行檔案build.shUI
- Linux可執行的檔案(轉)Linux
- 把可執行jar打包成exe檔案JAR
- 怎麼生成可執行的.jar檔案???????????JAR
- 0171-建立核心可執行檔案
- 上傳執行sql檔案到linuxSQLLinux
- ELF檔案的四種分類
- Python 打包 windows 可執行的 exe 檔案PythonWindows
- Linux檔案讀、寫、執行許可權Linux
- 如何用pkg打包nodejs可執行檔案NodeJS
- 移動資料檔案從ASM到檔案系統ASM
- 執行react build 檔案ReactUI
- redis執行lua檔案Redis
- 目標檔案和ELF格式詳解
- ELF檔案中的各個節區
- readelf命令和ELF檔案詳解
- 關於ELF檔案格式的實驗
- Unix/ELF檔案格式及病毒分析(轉)
- Unix/ELF檔案格式及病毒分析 (轉)
- electron+puppeteer 封裝成exe可執行檔案封裝
- Python如何生成windows可執行的exe檔案PythonWindows
- 將Python指令碼打包成可執行檔案Python指令碼