關於目標檔案裡的東西

2021-08-08 03:51:38 字數 3865 閱讀 6590

另外這個也是讀後感 

目標檔案是什麼 在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下...