Chap-4 Section 4.2.4 指令修正方式
對于X86平臺下的ELF文件的重定位入口所修正的指令尋址方式只有兩種:絕對近址32尋址和相對近址32尋址。
這兩種指令修正方式每個被修正的位置的長度都為32位,即4個字節,而且都是近址尋址,不用考慮Intel的段間遠址尋址。r_info成員的低8位表示重定位入口的類型。
X86基本重定位類型
宏定義 ? ? ? ? ? ? ? ? ? ? ? ?值 ?重定位修正方法
R_386_32 1 絕對尋址修正 ?S + A
R_386_PC32 2 相對尋址修正 ?S + A - P
A = 保存在指令中被修正位置的值
P = 被修正的位置(相對于段開始的偏移量或者虛擬地址),該值可以通過r_offset計算得到。
S = 符號的實際地址,即由r_info的高24位指定的符號的實際地址。
因為a.o中shared和swap需要地址重定位,以此為例子說明重定位地址修正方法。用objdump -r a.o可以得到a.o中需要重定位的符號如圖4.2.7所示:
***圖4.2.7(同4.2.4相同)***
從圖中可知,shared的重定位類型為R_386_32,因此為絕對尋址修正方式。那么S的值怎么得到,可以從a.o,b.o鏈接成的可執行文件的符號表中得到,可執行文件的符號表如圖4.2.8:
***圖4.2.8***
從圖中看出shared的實際地址為0x08049158,即是S的值。從a.o反匯編指令中可知A的值,如圖4.2.9所示:
***圖4.2.9***
從圖4.2.7中得知shared相對段開始的偏移為0x15,所以A的值是0x0。那么shared重定位后的地址為S + A = 0x08049158 + 0x0 = 0x08049158。怎樣驗證該數值的正確性?可以通過可執行文件的反匯編代碼驗證,如圖4.2.10所示:
***圖4.2.10***
注意:圖中的地址為小端格式,即數值的高位存放在低地址,低位在高地址。
而swap的重定位方式為相對尋址修正,swap的S值從圖4.2.8中可知為0x080480c0,A的值為0xfffffffc,為-4的補碼。P的值為符號swap的偏移量加上該段的起始地址,swap的偏移量為0x21,該段的起始地址符號main的地址,即為0x08048094。因此最終swap的地址為0x080480c0 - 0x04 - (0x08048094 + 0x21)= 0x07。從圖4.2.10可以看到call指令被修正后的地址確實為0x07。而call指令的調用地址是修正后的地址加上下一條指令的地址,0x07 + 0x080480b9 = 0x080480c0,該地址即為swap函數的地址。
***圖4.2.11***
轉載于:https://www.cnblogs.com/miaoyong/p/3505590.html
總結
以上是生活随笔為你收集整理的Chap-4 Section 4.2.4 指令修正方式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: atoi简析
- 下一篇: Throwable 结构图