《程序员的自我修养——链接、装载与库》读书笔记—— 4.1-4.2 空间与地址分配、符号解析与重定位

两步链接法(Two-pass Linking)

  1. 空间与地址分配,也就是合并不同文件中相同的段
  2. 符号解析与重定位,读取输入文件中段的数据、重定位信息,井且进行符号解析与重定位、调整代码中的地址等

测试程序

/*a.c*/
extern int shared;
int main()
{
    int a = 100;
    swap(&a, &shared);
}

/*b.c*/
int shared = 1;
void swap(int *a, int *b)
{
    *a ^= *b ^=*a ^= *b;
}
  1. 编译gcc -c a.c b.c -fno-stack-protector(-fno-stack-protector 为取消栈保护,否则链接时会有__stack_chk_fail 错误)。
  2. 链接ld a.o b.o -e main -o ab

查看链接前后的变化

zqxl@ubuntu:/work/myprojects/code4-1$ objdump -h a.o

a.o:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         0000002e  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
  1 .data         00000000  0000000000000000  0000000000000000  0000006e  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  0000000000000000  0000000000000000  0000006e  2**0
                  ALLOC
  3 .comment      0000002c  0000000000000000  0000000000000000  0000006e  2**0
                  CONTENTS, READONLY
  4 .note.GNU-stack 00000000  0000000000000000  0000000000000000  0000009a  2**0
                  CONTENTS, READONLY
  5 .eh_frame     00000038  0000000000000000  0000000000000000  000000a0  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA


zqxl@ubuntu:/work/myprojects/code4-1$ objdump -h b.o

b.o:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         0000004b  0000000000000000  0000000000000000  00000040  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000004  0000000000000000  0000000000000000  0000008c  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  0000000000000000  0000000000000000  00000090  2**0
                  ALLOC
  3 .comment      0000002c  0000000000000000  0000000000000000  00000090  2**0
                  CONTENTS, READONLY
  4 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000bc  2**0
                  CONTENTS, READONLY
  5 .eh_frame     00000038  0000000000000000  0000000000000000  000000c0  2**3
                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA


zqxl@ubuntu:/work/myprojects/code4-1$ objdump -h ab

ab:     file format elf64-x86-64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         00000079  00000000004000e8  00000000004000e8  000000e8  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .eh_frame     00000058  0000000000400168  0000000000400168  00000168  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .data         00000004  0000000000601000  0000000000601000  00001000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  3 .comment      0000002b  0000000000000000  0000000000000000  00001004  2**0
                  CONTENTS, READONLY


zqxl@ubuntu:/work/myprojects/code4-1$ readelf -s ab

Symbol table '.symtab' contains 13 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000004000e8     0 SECTION LOCAL  DEFAULT    1
     2: 0000000000400168     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000601000     0 SECTION LOCAL  DEFAULT    3
     4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4
     5: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS a.c
     6: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS b.c
     7: 0000000000400116    75 FUNC    GLOBAL DEFAULT    1 swap
     8: 0000000000601000     4 OBJECT  GLOBAL DEFAULT    3 shared
     9: 0000000000601004     0 NOTYPE  GLOBAL DEFAULT    3 __bss_start
    10: 00000000004000e8    46 FUNC    GLOBAL DEFAULT    1 main
    11: 0000000000601004     0 NOTYPE  GLOBAL DEFAULT    3 _edata
    12: 0000000000601008     0 NOTYPE  GLOBAL DEFAULT    3 _end

观察上述打印结果
  1. 其中,VMA 表示Virtual Memory Address, 即虚拟地址, LMA 表示Load Memory Address,即加载地址。可以看出来,只有ab文件有VMA,而elf文件没有虚拟地址。
  2. 可执行文件"ab" 的".text" 分配到0x00000000004000e8。这是由于ELF可执行文件的默认地址就是0x00000000004000e8(32位系统是0x08048000)。

你可能感兴趣的:(《程序员的自我修养——链接,装载与库》读书笔记)