预处理 编译器 汇编器 链接 符号解析 重定位 下条指令地址 转移目标地址 可执行文件加载

 

程序的执行:周而复始地执行一条条指令

指令周期:CPU取出并执行一条指令的时间

 

 

 

jmp *0x8049590  0x8049590中的地址 08048352 

 

延迟绑定 延迟重定位

 

 

 

延迟绑定 lazy binding  减少指令条数

procedure linkage table 过程链接表

 

 

 

如果静态链接,1条mov即可

 

寄存器溢出

 

全局偏移表 GOT global offset table

 

 

 

 

 

 

 

 

  

 

 

动态链接器接口 dlopen dlsymh  dlclose 

.interp段

 

 

 

myproc 磁盘 

区别.a .so

静态链接器 ld

动态链接器 ld-linux.so

 

 

 

1)共享代码的位置可以是不确定的

2)即使共享代码的长度发生变化,也不会影响调用它的程序

位置无关代码 position independent code PIC

gcc -c a.c b.c

gcc -shared -fPIC -o mylib.o a.o b.o

 

 

 

load-time linking

run-time linking

 

 

静态库 动态库

动态链接库  dynamic link libraries  .dll

静态共享对象 dynamic shared objects .so 

在磁盘和内存中都只有一个备份

 

 

 

 

 

 

entry point address 入口地址,不是0x8048000是ELF起始位置

fork

 

 

 

 

 

在当前进程上下文中加载并运行一个新程序

 

 

可执行文件加载:通过调用execve系统调用函数来调用加载器

 

栈地址 高位向低位增城

堆        低       高

 

 

 

 

 

 

 

 

 

 

 

 

 

00 00 00 00  重定位 合并后,地址

 

 

bufp0 重定位前 0 0 0 0 

后 20 96 04 08 (8049620)

     28 29 3a 3b   

 

 

 

4KB 0x08048000 0x08049000 

 

 

 

 

R_386_32  绝对地址类型

绝对地址重定位

 

 

 

R_386_PC32 PC相对地址方式

重定位计算公式 ADDR(r_sym)-((ADDR(.text)+r_offset)-init)

 

转移目标地址=当前PC+偏移地址

 

0x12B 

 

6: e8 fc ff ff ff

     6  7  8  9  a

main  字节数 0x12B 

小端 01 00 00 00 00 02 00 00 00 

int buf[2]={1,2};

 

 .rel.text 重定位条目

r_offset=0x7 第7字节开始

r_sym=10 绑定的符号是第10个符号

r_type=R_386_PC32 类型为

 

 

 

PC相对地址重定位 

 

and $0xffffff0,%esp 使栈顶地址为16的倍数

显示重定位条目

readelf -r a.o

 

 

 

 

 

 

 

 

符号解析后,进行重定位 

1、合并相同的节

2、对集合D中的定义符号进行重定位

3、对引用符号进行重定位

 

 

 

 

 

互相调用

 

 

 

链接器对外部引用的解析算法

gcc -L libtest.o -lmine

 

 

 

 

命令行顺序

链接顺序:应该按照调用顺序来指定 

链接器符号解析过程

 

 

 

 

 

 

静态库 .a archive files 存档文件

创建 

归档程序ar

ar rcs libc.a a.o b.o 

允许增量更新 ar rs libc.a z.o

ar -t libc.a | sort 查看

 

gcc  -c a.c b.c

ar rcs libc.a a.o b.o 

 

 

 

尽量使用本地变量static

全局变量要赋初值,使其成为强符号,易查出可能的链接错误

 

 

 

两个重复定义的变量具有不同类型是,出现的问题

浮点计算

3FF0 0000

3FFF FFFF =2^30-1

000F FFFF = 2^20-1

 

 

 

 

 

 

 

多重定义符号的解析举例

链接器对符号的解析规则

 

 

gcc -fno-common 

全局符号的强弱属性

强符号 弱符号

 

 

 

 

 

符号解析:symbol resolution 符号绑定

函数名: 其代码所在区

变量名:其所占的静态数据区

符号解析:将每个模块中引用符号与某个目标模块中的定义符号建立关联。

 

 

 

int but[1]={1,2}; size 4*2B=size 8

 

 

st_size 符号对应目标的字节数,比如:int 4B,short 2B,函数所占字节数

字符串存放在.strtab节

 

符号对应字符串,在.strtab节中的偏移量:4字节

 

 

global symbols 全局符号

external symbols 外部符号

local symbols 局部符号

 

 

 

 

链接符号的类型

 

 

 

 

 

 

 

 

 

符号定义

符号引用

  

 

 

 

symbol resolution 符号解析

定义的符号 引用的符号

将符号的引用存放在重定位节  .rel.text .rel.data

 

 

 

 

 

 

 

 

align 0x1000 2^12=4kB 按4kB对齐装入

 

 

 

 

虚拟空间中的地址

 

 

 

 

 

 

 

2's complement  2的补码

 

 

 

_init 函数 初始化工作

可执行目标文件

e_entry 程序执行时第一条指令地址

在可重定位文件中为0

segment header table 程序头表 段头表

section header table 节头表

 

 

 

 

440=

16^2+16*11+8

=1b8

 

 

ELF 52字节头信息

readelf -l a.o 程序头表信息

readelf -h a.o 头信息

readelf -S a.o 节头表信息

 

 

REL relocatable 可重定位

45 E 4c L 46 F

ELF Header:

  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 

  Class:                             ELF64

  Data:                              2's complement, little endian

  Version:                           1 (current)

  OS/ABI:                            UNIX - System V

  ABI Version:                       0

  Type:                              DYN (Position-Independent Executable file)

  Machine:                           Advanced Micro Devices X86-64

  Version:                           0x1

  Entry point address:               0x1060

  Start of program headers:          64 (bytes into file)

  Start of section headers:          14752 (bytes into file)

  Flags:                             0x0

  Size of this header:               64 (bytes)

  Size of program headers:           56 (bytes)

  Number of program headers:         13

  Size of section headers:           64 (bytes)

  Number of section headers:         37

  Section header string table index: 36

 

 

52B ELF 

2B Elf32_half 

4B Elf32_Word Elf32_Addr Elf32_Off

16B EI_NIDENT

 

 

 

ELF头 节头表 section header table

 

 

.symtab 存放函数名和全局变量(符号表)信息

 

 

 

bss节不占磁盘空间 block started by symbol

.rodata 只读数据,如 printf格式串、switch、调转表

 

 

 

 

 

 

 

 

ELF-执行视图:可重定位目标文件

ELF-链接视图:可重定位目标文件

.data 已初始化的全局变量和局部静态变量

.bss 未初始化的全局变量和局部静态变量

 

 

 

 

ELF excutable aand linkable format 可执行可链接

PE portable excutable 可移植可执行

 

目标文件 object code

目标文件 object file

共享目标文件:特殊的可重定位目标文件,能在装入或运行时被装入到内存并被链接

 

 

 

可执行目标文件:包含的代码和数据可以直接被复制到内存并执行

 

 

可执行文件存储映像

gcc -O2 -g -o a main.c

O2 2级优化

-g 生成调试信息

 

 

 

只读代码段

读写代码段

 

合并到虚拟空间

0x08048000

rodata read only

  链接本质:合并相同节 section

 

 

 

 

 

 局部变量分配在栈中,不会在过程(函数)外被引用,因此不是符号定义。

 

 

 

1符号解析: 确定符号引用关系

2合并.o文件

3确定每个符号的地址

4在指令中填入新地址

---》代码+数据

 

 

 

链接器由来

子程序其实地址、变量起始地址:符号的定义

调用子程序和使用变量:符号的引用

链接时在符号引用处填入定义的地址

 

链接:早于高级语言

纸袋 卡片

 

 

 

 

链接: 多个可重定位文件

静态、动态链接

 

 

 

 

 

编译器 汇编器

 

可重定位文件

 

 

 

 

 

预处理程序 cpp
编译器 cc1
汇编程序 as

 

汇编指令 机器指令 一一对应
 

 

 

 

gcc -E hello.c -o hello.i
cpp  hello.c > hello.i
 
条件编译
行号
#pragma
不包含宏定义
 

 

#include <sys/syscall.h>

.globl _start
_start:
  movq $SYS_write, %rax   # write(
  movq $1,         %rdi   #   fd=1,
  movq $st,        %rsi   #   buf=st,
  movq $(ed - st), %rdx   #   count=ed-st
  syscall                 # );

  movq $SYS_exit,  %rax   # exit(
  movq $1,         %rdi   #   status=1
  syscall                 # );

st:
  .ascii "\033[01;31mHello, OS World\033[0m\n"
ed:

 

执行:

gcc -c minimal.S -o m.o;ld m.o -o m.out;./m.out

Hello, OS World

 

as minimal.S -o m1.o;ld m1.o -o m1.out;./m1.out

ld: m1.o: in function `_start':
(.text+0x3): undefined reference to `SYS_write'
ld: (.text+0x21): undefined reference to `SYS_exit'
-bash: ./m1.out: No such file or directory

 

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          480 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           64 (bytes)
  Number of section headers:         8
  Section header string table index: 7
 
readelf m.o
Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .text             PROGBITS         0000000000000000  00000040
       000000000000004a  0000000000000000  AX       0     0     1
  [ 2] .rela.text        RELA             0000000000000000  00000160
       0000000000000048  0000000000000018   I       5     1     8
  [ 3] .data             PROGBITS         0000000000000000  0000008a
       0000000000000000  0000000000000000  WA       0     0     1
  [ 4] .bss              NOBITS           0000000000000000  0000008a
       0000000000000000  0000000000000000  WA       0     0     1
  [ 5] .symtab           SYMTAB           0000000000000000  00000090
       00000000000000a8  0000000000000018           6     4     8
  [ 6] .strtab           STRTAB           0000000000000000  00000138
       0000000000000021  0000000000000000           0     0     1
  [ 7] .shstrtab         STRTAB           0000000000000000  000001a8
       0000000000000031  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), l (large), p (processor specific)
 
Relocation section '.rela.text' at offset 0x160 contains 3 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000003  00050000000b R_X86_64_32S      0000000000000000 SYS_write + 0
000000000011  00010000000b R_X86_64_32S      0000000000000000 .text + 2e
000000000021  00060000000b R_X86_64_32S      0000000000000000 SYS_exit + 0
No processor specific unwind information to decode

Symbol table '.symtab' contains 7 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 SECTION LOCAL  DEFAULT    1 .text
     2: 000000000000002e     0 NOTYPE  LOCAL  DEFAULT    1 st
     3: 000000000000004a     0 NOTYPE  LOCAL  DEFAULT    1 ed
     4: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT    1 _start
     5: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND SYS_write
     6: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND SYS_exit
 
readelf m1.o 

 

 

 

 
 
 

 

 

posted @ 2019-02-20 23:30  papering  阅读(1813)  评论(0编辑  收藏  举报