linux elf 视频,linux 实例讲解elf文件
elf是一種文件格式,用于存儲linux程序,它內部有什么信息呢?大概包括編制好的計算機指令,數據,計算機在需要的時候把這個文件讀取到內存中,cpu就可以從內存中一條一條的讀取指令來執行。要想明白elf的格式,應該先了解下計算機執行程序需要哪些信息,對此我們先來回顧下計算機系統的一些基礎知識:
虛擬內存
對于32位的總線,linux系統給每個進程分配了4g的空間,其中 0xC0000000到0xFFFFFFFF 這個地址段是留給系統使用的,主要用于linux內核程序的運行, 用戶可以使用3GB的空間從(0x00000000-0xBFFFFFFF)。當然這4g的內存是虛擬內存,一個系統有那么多進程,要是物理內存那還得了,操作系統的虛擬性也是其一重大特征,使用虛擬內存的好處就是各個進程之間的運行空間看起來是獨立的,彼此相互不干擾。那么一個進程的創建過程是什么樣的呢?
程序執行過程
用戶請求運行程序時,操作系統會讀取存儲在磁盤上的可執行文件,(對于linux系統,這個文件就是elf格式文件),然后為用戶分配4g的虛擬內存空間。
根據可執行文件的信息指示,把不同的文件內容放到為你分配的這3g虛擬內存。
根據可執行文件的信息指示,系統設置代碼段和數據段寄存器
根據可執行文件的信息指示,跳轉到用戶的代碼入口地址(一般就是我們的main函數)
從main開始,cpu一條條執行我們給的指令,處理我們的數據,直到程序結束。
我們看到在執行指令前有多次“根據可執行文件提示”,而學習elf就是學習到底是指示了哪些信息。
可執行的elf文件
elf文件分三種類型: 目標文件(.o)、可執行文件、動態庫(.so),可執行文件一般分成,elf文件頭、segment表、section表。下面我們通過一個例子一一介紹下:
elf文件頭: 這個文件是對elf文件整體信息的描述,在32位系統下是56的字節,在64位系統下是64個字節。
segment表:這個表是加載指示器。
.section .data
.global data_item
data_item:
.long 3,67,28
.section .text
.global _start
_start:
mov $1,%eax
mov $4,%ebx
int $0x80
上面是一段簡單的匯編代碼,編譯: as -o hello.o hello.s 鏈接: ld -o hello hello.o 完成之后執行readelf -h hello (-h 表示讀取elf文件頭的命令)
readelf -h hello
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: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x4000b0 // 程序的入口地址
Start of program headers: 64 (bytes into file)
Start of section headers: 472 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes) // 頭長度是56字節(32位系統是56字節)
Number of program headers: 2
Size of section headers: 64 (bytes)
Number of section headers: 6
Section header string table index: 3
對于程序的裝載,我們關心這三項:
Entry point address: 0x4000b0 // 程序入口地址
Start of program headers: 64 (bytes into file) // segment表在文件64字節偏移處
Size of program headers: 56 (bytes)
上面內容告訴我們segment表在文件的64字節處,我們看看64字節處有什么內容:
執行readelf -l hello 輸出segments信息,(-l 表示讀取segment)
readelf -l hello
Elf file type is EXEC (Executable file)
Entry point 0x4000b0
There are 2 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000000bc 0x00000000000000bc R E 200000
LOAD 0x00000000000000bc 0x00000000006000bc 0x00000000006000bc
0x000000000000000c 0x000000000000000c RW 200000
Section to Segment mapping:
Segment Sections...
00 .text
01 .data
我們看到程序有兩個segment,分別是.text和.data,
.text的Offset是0,FileSiz是0x0,MemSiz是0xbc, VirtAddr是0x400000,Flags是R E,表示加載起將把elf文件中從0字節開始直到oxbc處的內容加載到虛擬內存中的0x400000處,占用0xbc長度的內存,設置該內存的權限是RE(可讀,可執行),這一段的內容正好是elf頭,segments table,和代碼段,而elfheader的entry地址是0x4000b0,這個地址是代碼段的起始地址。
.data的Offset是0,FileSiz是0xbc,MemSiz是0x0c, VirtAddr是0x6000bc,Flags是R W,表示加載起將把elf文件中從bc字節開始直到oxbc + 0xc處的內容加載到虛擬內存中的0x6000bc處,占用0x0c長度的內存。設置該內存的權限是RE(可讀,可執行)
這樣系統就可以根據elf文件提供的這些信息創建進程了。
總結
以上是生活随笔為你收集整理的linux elf 视频,linux 实例讲解elf文件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python动态_python --动态
- 下一篇: 网站备案靠谱吗_网站外包靠谱吗目前都是什