另外這個也是讀後感
目標檔案是什麼 在vs程式經過編譯鏈結之後可以成為可執行檔案 但是有沒有想過 只編譯不鏈結是什麼 vs上要將編譯和鏈結分開(我問了很多人都說不知道沒辦法只能在linux上實現只編譯不鏈結)
寫一段很簡單的程式如果我在linux main.c檔案中寫下面這段**
#include
int add(int,int);//這個函式是表示兩個數字相加 但是我不定義
int main()
int a=10;
int b=20;
printf("%d\n",add(a,b));
return 0;
在linux 上可以用 gcc -o main.c 來編譯一下
會出現乙個檔案就是main.o 這個.o檔案就是目標檔案 目標檔案分為4種 (可重定位檔案在linux上為.o window下為obj ,可執行檔案這個應該還是熟悉吧.exe,共享檔案linux.so window .dll,核心轉儲檔案(不知道什麼文章不講本人也不知道)ps書上就只這樣介紹了一下 程式意外終止時,系統幫忙存一下終止時的資訊)
就單說這個檔案如果在linux 上就是.o檔案 在window下也就是.obj檔案
那麼目標檔案裡面儲存了什麼 在linux上 可以用objdump -h main.o可以檢視
sections:
idx name size vma lma file off algn
0 .text 00000052 00000000 00000000 00000034 2**2
contents, alloc, load, reloc, readonly, code
1 .data 00000000 00000000 00000000 00000088 2**2
contents, alloc, load, data
2 .bss 00000000 00000000 00000000 00000088 2**2
alloc
3 .rodata 0000000a 00000000 00000000 00000088 2**0
contents, alloc, load, readonly, data
4 .comment 0000002d 00000000 00000000 00000092 2**0
contents, readonly
5 .note.gnu-stack 00000000 00000000 00000000 000000bf 2**0
contents, readonly
這個時候就可以畫一張圖 這個裡面只會列一寫常用的段
等等 但是這個是不全的 資訊都在eleheader頭裡面
所以我們得找檔案頭 readelf -h main.o
這些檔案頭記錄了乙個值為start of headers 272 也就是說這個段的起始位置存的就是個個段的資訊
272的16進製制110 這個就是段的起始位置
這個需要計算一下 用readelf -s main.o 就是段的資訊
section headers:
[nr] name type addr off size es *** lk inf al
[ 0] null 00000000 000000 000000 00 0 0 0
[ 1] .text progbits 00000000 000034 000052 00 ax 0 0 4
[ 2] .rel.text rel 00000000 000390 000028 08 9 1 4
[ 3] .data progbits 00000000 000088 000000 00 wa 0 0 4
[ 4] .bss nobits 00000000 000088 000000 00 wa 0 0 4
[ 5] .rodata progbits 00000000 000088 00000a 00 a 0 0 1
[ 6] .comment progbits 00000000 000092 00002d 01 ms 0 0 1
[ 7] .note.gnu-stack progbits 00000000 0000bf 000000 00 0 0 1
[ 8] .shstrtab strtab 00000000 0000bf 000051 00 0 0 1
[ 9] .symtab symtab 00000000 0002c8 0000b0 10 10 8 4
[10] .strtab strtab 00000000 000378 000018 00 0 0 1
就在.shstrtab 的下面bf +51=110
就在這個段的下面 裡面存的所有段資訊
再看其他的段symtab在段就是符號表放的段 也就是乙個全域性變數的符號的資訊就放在這個裡面
用readelf -s main.o小寫的s
symbol table '.symtab' contains 11 entries:
num: value size type bind vis ndx name
0: 00000000 0 notype local default und
1: 00000000 0 file local default abs main.c
2: 00000000 0 section local default 1
3: 00000000 0 section local default 3
4: 00000000 0 section local default 4
5: 00000000 0 section local default 5
6: 00000000 0 section local default 7
7: 00000000 0 section local default 6
8: 00000000 82 func global default 1 main
9: 00000000 0 notype global default und printf
10: 00000000 0 notype global default und fun
fun沒有找到那麼這個型別顯示的就是und 沒有找到
其實做乙個很簡單的例子就是
即使是這個函式永遠不會執行 他還是會報錯 也就是在鏈結時期會報錯
當你找到了這個符號那麼在全域性的符號表裡面就會有這個符號然後進行重新定位 然後就可以執行了
目標檔案裡有什麼 揭秘目標檔案
程式源 被編譯後生成的機器指令被放在 段 text 全域性變數和區域性靜態變數被放在資料段 data 除此之外還有程式裡邊的唯讀變數 如const修飾的變數 和字串常量被分配在唯讀資料段 rodata 注釋資訊段 comment 堆疊提示段 nute.gnu stack 未初始化的全域性變數和靜態區...
目標檔案裡有什麼
1.text段是 段,比如main程式就存放在這裡 data段存放已初始化的資料而且初始化不為0 bss段存放未初始化或初始化為0的資料 英文含義 以符號開始的塊 在這裡我們引發出幾個問題 1 我們都知道.bss段不佔空間,它到底不佔 的空間?虛擬位址空間還是檔案空間?答案是檔案空間,因為對於.bs...
目標檔案裡有什麼?
目標檔案從結構上講,它是已編譯後的可執行檔案格式 windows的.obj或linux的.o 只是還沒有經過鏈結的過程。它跟可執行檔案的內容和結構很類似,所以一般跟可執行檔案格式一起採用一種格式儲存。無論是linux下的elf executable linkable format 或windows下...