計算機系統篇之鏈接(8):PIC 數據引用在 Linux 上的 X86-64 示例
Author:stormQ
Wednesday, 15. April 2020 04:35PM
step 1: 生成共享庫
1)第一個共享庫的源文件——add.cpp:
int g_sum = 0;
int add(int a, int b)
{
g_sum = a + b;
return g_sum;
}
生成第一個共享庫——libadd_debug.so
$ g++ -fpic -shared -g -o libadd_debug.so add.cpp
2)第二個共享庫的源文件——sub.cpp:
int g_sub = 0;
int sub(int a, int b)
{
g_sub = a - b;
return g_sub;
}
生成第二個共享庫——libsub_debug.so
$ g++ -fpic -shared -g -o libsub_debug.so sub.cpp
step 2: 生成測試程序(用於調用以上兩個共享庫)——main_mix
測試程序的源文件——main_mix.cpp:
extern int add(int, int);
extern int sub(int, int);
int main()
{
add(0xb, 0xc);
add(0xb, 0xc);
sub(0xf, 0xd);
sub(0xf, 0xd);
return 0;
}
生成測試程序——main_mix
$ g++ -o main_mix main_mix.cpp ./libadd_debug.so ./libsub_debug.so -g
step 3: 查看共享庫的代碼段
1)查看共享庫libadd_debug.so的代碼段
# 查看共享庫中可執行的sections(包含了.text section)
$ objdump -d libadd_debug.so
輸出結果爲(只保留add()函數的彙編代碼):
; ...... Skip
Disassembly of section .text:
; ...... Skip
0000000000000640 <_Z3addii>:
640: 55 push %rbp
641: 48 89 e5 mov %rsp,%rbp
644: 89 7d fc mov %edi,-0x4(%rbp)
647: 89 75 f8 mov %esi,-0x8(%rbp)
64a: 8b 55 fc mov -0x4(%rbp),%edx
64d: 8b 45 f8 mov -0x8(%rbp),%eax
650: 01 c2 add %eax,%edx
652: 48 8b 05 7f 09 20 00 mov 0x20097f(%rip),%rax # 200fd8 <_DYNAMIC+0x158>
659: 89 10 mov %edx,(%rax)
65b: 48 8b 05 76 09 20 00 mov 0x200976(%rip),%rax # 200fd8 <_DYNAMIC+0x158>
662: 8b 00 mov (%rax),%eax
664: 5d pop %rbp
665: c3 retq
; ...... Skip
輸出結果分析:
-
mov 0x20097f(%rip),%rax
的作用:將共享庫libadd_debug.so的GOT[1]的內容——即全局變量 g_sum 的地址傳送到 %rax 寄存器中。 -
mov %edx,(%rax)
的作用:將%edx寄存器的值(存放着a+b的計算結果)賦值給全局變量g_sum。
推導過程:…
關注公衆號,即可查看完整內容。