Ubuntu16.04中的可重定位目標文件

最近在看《CSAPP》這本神書,其中看到了第七章鏈接中的可重定位目標文件,自己動手在ubuntu16.04上試了一試,發現有很多都做了一些改動,在此記錄

1.源程序

main.c

static int a = 1;
int buf[2] = {1,2};
void swap();
int main()
{
    a = 2;
    swap();
    return 0;
}

swap.c

extern int buf[];
int *p0 = &buf[0];
static int* p1;
static int p3 = 1;
void swap()
{
    int temp;
    p1 = &buf[1];
    temp = *p0;
    *p0 = *p1;
    *p1 = temp;
}

我現在要看的就是代碼中的每個符號定義以及引用在經過編譯彙編後分別位於.o文件的哪個節中

2.編譯與彙編

分別執行

gcc -c main.c

gcc -c swap.c

得到main.o與swap.o

3.以swap.o爲例,查看各個節

首先 ,ELF文件的結構

Section


  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000000000 000040 00003c 00  AX  0   0  1
  [ 2] .rela.text        RELA            0000000000000000 000258 000090 18   I 11   1  8
  [ 3] .data             PROGBITS        0000000000000000 000080 00000c 00  WA  0   0  8
  [ 4] .rela.data        RELA            0000000000000000 0002e8 000018 18   I 11   3  8
  [ 5] .bss              NOBITS          0000000000000000 000090 000008 00  WA  0   0  8
  [ 6] .comment          PROGBITS        0000000000000000 000090 000036 01  MS  0   0  1
  [ 7] .note.GNU-stack   PROGBITS        0000000000000000 0000c6 000000 00      0   0  1
  [ 8] .eh_frame         PROGBITS        0000000000000000 0000c8 000038 00   A  0   0  8
  [ 9] .rela.eh_frame    RELA            0000000000000000 000300 000018 18   I 11   8  8
  [10] .shstrtab         STRTAB          0000000000000000 000318 00005e 00      0   0  1
  [11] .symtab           SYMTAB          0000000000000000 000100 000138 18     12  10  8
  [12] .strtab           STRTAB          0000000000000000 000238 00001a 00      0   0  1

查看符號表

SYMBOL TABLE:
0000000000000000 l    df *ABS*	0000000000000000 swap.c
0000000000000000 l    d  .text	0000000000000000 .text
0000000000000000 l    d  .data	0000000000000000 .data
0000000000000000 l    d  .bss	0000000000000000 .bss
0000000000000000 l     O .bss	0000000000000008 p1
0000000000000008 l     O .data	0000000000000004 p3
0000000000000000 l    d  .note.GNU-stack	0000000000000000 .note.GNU-stack
0000000000000000 l    d  .eh_frame	0000000000000000 .eh_frame
0000000000000000 l    d  .comment	0000000000000000 .comment
0000000000000000 g     O .data	0000000000000008 p0
0000000000000000         *UND*	0000000000000000 buf
0000000000000000 g     F .text	000000000000003c swap

可以看到,buf由於是外部變量在這裏僅僅是一個重定位項(這一點與CSAPP給的課後題目答案非常不一樣,CSAPP給出的是buf在.data節這是不對的),p0,p3由於顯示初始化了所以在.data節

同時, readelf -a swap.o可以得到重定位節中的相關信息

重定位節 '.rela.text' 位於偏移量 0x258 含有 6 個條目:
  偏移量          信息           類型           符號值        符號名稱 + 加數
000000000007  000400000002 R_X86_64_PC32     0000000000000000 .bss - 8
00000000000b  000b0000000b R_X86_64_32S      0000000000000000 buf + 4
000000000012  000a00000002 R_X86_64_PC32     0000000000000000 p0 - 4
00000000001e  000a00000002 R_X86_64_PC32     0000000000000000 p0 - 4
000000000025  000400000002 R_X86_64_PC32     0000000000000000 .bss - 4
000000000030  000400000002 R_X86_64_PC32     0000000000000000 .bss - 4

重定位節 '.rela.data' 位於偏移量 0x2e8 含有 1 個條目:
  偏移量          信息           類型           符號值        符號名稱 + 加數
000000000000  000b00000001 R_X86_64_64       0000000000000000 buf + 0

重定位節 '.rela.eh_frame' 位於偏移量 0x300 含有 1 個條目:
  偏移量          信息           類型           符號值        符號名稱 + 加數
000000000020  000200000002 R_X86_64_PC32     0000000000000000 .text + 0

swap.c中與外部符號有關的部分:

extern int buf[];
int *p0 = &buf[0];

p0與buf需要在鏈接的時候進行重定位

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章