題一:符號解析
考察可重定位目標文件各個節的內容,本質分類,那就分類:
linux
節 | 內容 |
---|---|
.text | 已編譯程序的機器代碼,函數 |
.data | 已初始化的全局 C 變量,包括已初始化的extend,帶static 屬性的本地變量,不帶static的全局變量 |
.bss | 未初始化的全局 C 變量,包括未初始化的不帶static的全局變量,帶static 屬性的本地變量 |
- 注意帶有static屬性的變量或函數都被認爲是本地變量或函數Local
分析過程以下:
① buf由關鍵字extend引入,是外部變量,swap.o.symtab條目中會存放由其餘模塊定義並被模塊 m 引用的全局符號,這個外部是指的main.o,查看CSAPP前面的main.c代碼能夠發現buf是已經被初始化的全局變量,所以保存在節.data中
② bufp0是定義在全局的已初始化變量,所以會被swap.o.symtab條目存放;它在swap.o中定義,存放於.data節
③ bufp1是帶static屬性的靜態未初始化全局變量,所以會被swap.o.symtab條目存放;因爲它只能在模塊內使用,所以屬於local類型變量。它在swap.o中定義,存放於.bss節
④ swap是非靜態的全局函數,定義在swap.o中,而且會被swap.o.symtab條目存放,函數存放在.text代碼節
⑤ temp是局部變量,不會被Swap.o.symtab條目存放;局部 C 變量在運 行時保存在棧中,既不出如今 .data 節中,也不出如今 .bss 節中
⑥ incr是帶有static屬性的本地函數符號,會被Swap.o.symtab條目存放,類型爲本地,存放在text中
⑦ count是帶有static屬性的一已初始化靜態局部變量,會被Swap.o.symtab條目存放,類型爲本地,因爲已經初始化,所以保存在.data中。
函數
符號 | Swap.o.symtab條目 | 符號類型 | 定義符號的模塊 | 節 |
---|---|---|---|---|
buf | 是 | extend | main.o | .data |
bufp0 | 是 | global | swap.o | .data |
bufp1 | 是 | local | swap.o | .bss |
swap | 是 | global | swap.o | .text |
temp | 否 | ----- | ------ | ------ |
incr | 是 | local | swap.o | .text |
count | 是 | Local | swap.o | .data |
除了以上的逐個分析方法以外,還能夠經過READELF工具查看,如圖:工具
linux> gcc -c 7.6.c linux> readelf -a 7.6.o
題二 重定位絕對引用
這道題我在網上看了解答,基本上全部的答案都認爲存儲器的地址是指的運行時PC的位置,存儲器的值是符號的地址。可是這和書上P464頁的絕對引用處理有些出入,仍須要更深刻的思考:
① 在line3出現符號bufp0,對應到圖7-10是15行,看到彙編指令 mov 0x804945c,%edx獲得運行時存儲器的值是0x0804945C,運行時存儲器的是地址是0x80483C9+2=0x080483CB
② 在line5的重定向buf[1],對應到圖7-10是16行,運行時存儲器的是地址是0x80483CF+1=0x80483D0,看到彙編指令 mov 0x8049458,%eax獲得存儲器的值是
0x8049458
③ 在line10的重定向bufp1,對應到圖7-10是18行,運行時存儲器的是地址是0x080483D6+2=0x80483D8,看到機器指令c7 05 48 95 04 08 58獲得存儲器的值是0x8049548
④ 在line11的重定向buf[1],對應到圖7-10是18行,運行時存儲器的是地址是0x080483D6+2+4=0x80483DC,看到機器指令c7 05 48 95 04 08 58 94 04 08獲得存儲器的值是0x08049458
⑤ 在line16的重定向bufp1,對應到圖7-10是23行,運行時存儲器的是地址是0x080483E6+1=0x80483E7,看到彙編指令mov 0x8049548,%eax獲得存儲器的值是0x8049548
spa
符號 | 行號 | 運行時存儲器地址 | 值 |
---|---|---|---|
bufp0 | 15 | 0x080483CB | 0x0804945C |
buf[1] | 16 | 0x80483D0 | 0x08049458 |
bufp1 | 18 | 0x080483D8 | 0x08049548 |
buf[1] | 18 | 0x080483DC | 0x08049458 |
bufp1 | 23 | 0x080483E7 | 0x08049548 |
題三:重定位相對引用
A:.text節共有三處須要重定位。
① Line12:能夠看到在line12 call 指令調用函數,因爲調用函數,由PC計算被調用函數的位置,所以須要重定位。節偏移爲0x12,重定位爲PC 相對引用類型R386_PC32
② Line14:在line14行將0x0存放在%eax,可是因爲全局變量x被存放在了絕對地址中,所以對於x的引用也須要重定位。0x0須要被重定位爲絕對地址。能夠直接查看左側可重定向的運行地址是18,加上機器指令a1,全部節偏移爲0x19,重定位爲絕對引用類型R_386_32
③ Line17:在line17 call 指令調用函數,因爲調用函數,由PC計算被調用函數的位置,所以須要重定位。節偏移爲0x21,重定位爲PC相對引用類型R_386_PC32
3d
行號 | 符號名字 | 節偏移 | 重定位類型 |
---|---|---|---|
12 | P3 | 0x12 | R_386_PC32(相對) |
14 | Xp | 0x19 | R_386_32(絕對) |
17 | p2 | 0x21 | R_386_PC32(相對) |
B:因爲x符號不是引用符號因此不須要被重定位,而xp須要被重定位爲x的地址。所以,其節偏移爲0x4,類型爲絕對類型。code
行號 | 符號名字 | 節偏移 | 重定位類型 |
---|---|---|---|
12 | x | 0x4 | R_386_32(絕對) |