..1. 目录
..2. 准备工具和基础汇编知识
- readelf -a 查看elf信息
 - objdump -S 查看汇编指令
 - ldd 查看动态加载
 - xxd - make a hexdump or do the reverse.
 - gdb  
- gdb 通过
layout regs打开寄存器显示, 通过set disassemble-next-line on打开汇编 - gdb 通过peda插件字节显示汇编和寄存器 和上面的原生方式选择一个即可
 - gdb关闭ASLR:
- set disable-randomization on
 
 - 开启ASLR:
- set disable-randomization off
 
 - 查看ASLR状态:
- show disable-randomization
 
 - disas反汇编命令,直接disas是反汇编当前函数
- disas /r (显示汇编指令对应十六进制值)
 - disas /m (如果有源码,显示对应行源码)
 
 - intel语法
- set disassembly-flavor intel
 - set disassembly-flavor att
 
 
 - gdb 通过
 - 详细工具和汇编的基础知识见上一篇文章: 汇编语法/寻址/寄存器/代码模型(GNU assembler)
 
..3. 编译链接过程的基本原理和流程
C和C++均使用分离编译来支持多源文件模块化机制, 因此也带来了静态和动态的链接问题, 本文主要梳理了静态库的链接过程和动态链接过程.
..3.1. gcc中编译一个源文件可以拆分为4个部分
- 预处理 -E
 - 编译器 -S
 - 目标文件 -C
 - 链接为共享库或者可执行程序
 
..3.2. 编译单元(Translation environment), 编译的转换阶段 :
[ISO/IEC 9899:1999]A C program need not all be translated at the same time.The text of the program is kept in units called source files, (or preprocessing files) in this International Standard.A source file together with all the headers and source files included via the preprocessing directive #include is known as a preprocessing translation unit. After preprocessing, a preprocessing translation unit is called a translation unit.
Previously translated translation units may be preserved individually or in libraries. The separate translation units of a program communicate by (for example) calls to functions whose identifiers have external linkage, manipulation of objects whose identifiers have external linkage, or manipulation of data files. Translation units may be separately translated and then later linked to produce an executable program.
C语言的程序不需要一同时间翻译, 在这个国际标准中, 程序的文本内容以源文件(或者预处理文件)为单位保存, 一个源文件连同所有通过预处理指令#include包含的头文件和源文件被称为预处理翻译单元, 经过预处理后的翻译单元称为翻译单元. 翻译单位可以单独保存,也可以打包在程序库里. 程序的独立翻译单元通过(例如) 调用具有外部链接标识的函数, 处理具有外部链接标识的对象完成连接过程. 翻译单元可以独立翻译然后通过链接生成可执行程序.
..3.3. PIC PIE 位置无关代码
编译出的二进制指令不使用绝对地址而使用相对地址称为PIC 技术
PIE和PIC的区别在于PIE假定了代码最终会被直接链接为可执行程序    
..3.4. GOT PLT 全局偏移表 链接过程表
这两个表完成了上面编译单元中所说的处理过程
..3.5. 符号表和符号
..3.5.1. 全局符号和局部符号
符号的全局和局部是相对于编译单元而言的,  例如添加了static前缀的全局变量或者函数只在当前的编译单元可见, 因此是局部的 .
重定位不关心局部符号,  而对于在函数内声明的局部变量的名字并不会存储到符号表 完全由运行时栈来维护,(-g选项可以在.debug中找到符号).
符号表是为了编译单元之间建立联系使用的, 比如重定位.   
..3.5.2. 外部符号和内部符号
外部符号是指的当前编译单元使用但是却不在当前编译单元定义的符号.
..3.5.3. 和字符串表的关系
符号表的name字段是字符串表的索引,  也就是说, 符号表本身并不存储符号的’字符串’名.
字符串表除了保存符号名外, 还保存常量字符串的值  
..3.6. 静态链接过程
- 编译阶段  
- 建立字符串表,符号表, 保存符号对应的声明信息.
 - 建立重定位表, 对全局符号的访问都标记出准确的偏移地址
 
 - 链接生成阶段  
- 合并目标文件中相同的节, 确定虚拟内存地址(pic技术只确定相对地址)
 - 重建重定位表和符号表
 - 使用重定位表和符号表中记录的数据对代码段和数据段进行修改.
 
 - 运行时  
- 所有地址已经完成重定位 对全局符号的访问不存在中间过程
 - 如果未非位置无关代码, 则对全局符号的访问为立即数即为分配好的实际地址
 - 如果是位置无关代码, 则对全局符号的访问需要用rip计算相对偏移.
 
 
..3.7. 动态链接过程
动态链接和静态链接的区别在于, 动态链接把重定位的时机放在了动态库被加载到内存之后.
- 编译阶段  
- 建立字符串表,符号表, 保存符号对应的声明信息.
 - 建立重定位表, 对全局符号的访问都标记出准确的偏移地址
 
 - 链接生成阶段  
- 合并目标文件中相同的节 确定虚拟内存地址(pic技术只确定相对地址)
 - 重建重定位表和符号表
 - 使用重定位表和符号表中记录的数据对代码段和数据段进行修改.
 - 保存全局符号到动态符号表(符号表中有全部符号数据 此为优化)
 - 建立动态重定位表, 对全局变量的访问走GOT表, 动态重定位表记录了符号名和对应数据段中的编号(该数据段被标记为.got节).
 - 建立链接过程表, 对全局函数的访问生成plt代码(.plt), 链接过程重定位表(.rela.plt)记录了每个全局函数的符号名以及在保存实际函数地址的数据段的地址. (.got.plt节), .got.plt表中存储的指针默认是   
- .got.plt中所有函数的地址都会默认保存为第 个元素的内容, 该地址为_dl_runtime_resolve , 通过符号表找到真正的函数地址后填充.got.plt并执行函数.
 
 - 对于内部符号的访问是否会进行优化 取决于代码模型, 例如对于小型代码模型中, 可执行程序中会直接访问全局变量的地址(被优化,但仍然保留GOT机制的有效性). 但是共享库中对全局变量的访问即使是当前库中的也一定会走got表.
 
 - 运行时  
- 加载共享库   
- 完成got, got.plt的填充
 - 如果有repolr技术则设置内存段的只读
 
 - 运行过程中  
- 对全局变量的访问需要通过got表找到真正的地址
 - 对函数的访问每次都会走plt, 第一次访问会跳转到符号解析函数找到真正的函数地址, 后续plt则会省略解析流程, 此为惰性加载机制.
 
 
 - 加载共享库   
 
..4. 跟踪调测
编译选项为
- 位置无关代码
 - 禁止优化
 - 禁止假设代码模型
 
..4.1. 测试源码
lib.cpp
1  | int g_static_lib_bss = 0;  | 
so.cpp
1  | int lib_func(int a, int b);  | 
main.cpp
1  | int so_child_func(int a, int b);  | 
..4.2. 位置有关的重定位分析
1  | g++ -c so.cpp -O0 -mcmodel=large -fno-pic  | 
..4.2.1. 分析结论如下:
so.cpp中所有非static的全局变量和函数都存在符号表中
- 符号表的起始偏移为00000200 大小为198
 - 字符串表的起始偏移为00000398 大小为a4
 
通过xxd命令可以观察到存储所有所有符号名的位置为 0x398处开始分别是字符串:
- null
 - so.cpp
 - _ZL15g_local_so_data
 - …
 
字符串表中的字符串均为标准的c-style风格的null为结尾(0x00)的字符串
符号表的所在位置0x00000200则为规整的数组 没有字符串信息
局部变量出现在目标对象的符号表中但对其访问的代码位置未出现在重定位表中
局部变量在符号中的类型是LOCAL
无论外部符号还是内部符号, 对于全局符号的访问均在重定位表中指明了具体的符号和偏移数据
R_X86_64_64类型或者PC类型均为直接修改访问代码来完成重定位
对于外部的符号 无论是函数还是数据 在符号表中 均为
NOTYPE GLOBAL UND的一行占位数据对于内部定义的全局函数, 则记录了再文本节中的具体的地址偏移,大小,类型等信息.
对于内部定义的全局变量, 则记录了该变量的序号, 大小, 类型信息.
.data字段为16字节 内容分别是 a086 0100 0000 0000, 00ff 00ff 0000 0000
- 对应为long long g_static_so_data = 100000; 和static long long g_local_so_data = 0xff00ff00;
 
访问全局数据
1  | int so_func(int a, int b)  | 
这里的g_static_so_bss 对应的汇编为:
1  | 55: 48 b8 00 00 00 00 00 movabs $0x0,%rax  | 
其意思是
- 用64位立即数0来设置rax寄存器
 - 解引用rax 并把内容保存到rax寄存器
 - rax的内容+1 (这里利用了lea寻址完成++)并保存到rdx寄存器
这里问题就来了, 用C语言来描述就是 我们对地址 为0的的指针当做真实的全局变量的地址进行了解引用. 
那么我们看下经过链接后的该汇编代码:
1  | 4005d3: 48 b8 60 10 68 00 00 movabs $0x681060,%rax  | 
在这里, 这个立即数已经变成了合并完.data后, g_static_so_bss的真实地址.
这个立即数指令所在的地址偏移为0x57 然后我们查看重定位表即可发现完成该过程所需要的重定位信息:  
1  | 000000000057 000a00000001 R_X86_64_64 0000000000000000 g_static_so_bss + 0  | 
备注:
这里我们看到最终链接出的地址4005da: 说明该程序并非pic代码, 对全局变量的访问没有任何相对计算以及读表过程.    
..4.2.2. 系统源码参考:
1  | /* $begin elfsymbol */  | 
..4.2.3. 字符串数据
1  | 00000390: 0000 0000 0000 0000 0073 6f2e 6370 7000 .........so.cpp.  | 
..4.2.4. 节信息
1  | ELF 头:  | 
..4.2.5. text数据
1  | so.o: 文件格式 elf64-x86-64  | 
..4.3. 位置无关的重定位分析
1  | g++ -c so.cpp -O0 -mcmodel=large -fPIC  | 
1  | g++-6 -c so.cpp -O0 -mcmodel=large -fPIC  | 
..4.3.1. 分析说明
PIC的代码在编译为目标对象时, 所用的重定位方法和非PIC在方法上并没有差别
指明代码段中访问全局符号的操作数位置
在编译阶段用正确的地址替换掉占位用的空地址
与非PIC的差别我们会看到访问所有数据最终最终都会通过GOT表, 所以这部分的立即数会首先被替换成GOT表的地址
本段分析中主要分析动态链接的关键部分GOT/PLT/LOAD/FIXSYMBO部分分析, 对上述部分不再贴细节分析代码.
- so中的重定位表分别是.rela.dyn .rela.plt, 和目标文件中的记录格式类似但有明显不同  
- 无论是对全局数据的访问还是对全局函数的访问, 其重定位的地址都不在是代码段中的位置, 而是位于数据段   
- 对全局变量的访问, 重定位地址在.got段 数据段
 - 对全局函数的访问, 重定位地址在.got.plt段 数据段
 
 
 - 无论是对全局数据的访问还是对全局函数的访问, 其重定位的地址都不在是代码段中的位置, 而是位于数据段   
 - 重定位不在涉及修改.txt段中的内容, 所以共享库的文本段是可以跨进程安全共享的
 
..4.3.2. 全局数据访问代码分析
访问全局数据
1  | int so_func(int a, int b)  | 
这里的g_static_so_bss++ 对应的汇编为:
1  | 8a3: 48 8d 1d f9 ff ff ff lea -0x7(%rip),%rbx # 8a3 <_Z7so_funcii+0xb>  | 
其意思是
- 8a3这行指令+0x20075d偏移保存到%rbx
 - 计算出最终地址(%rbx + xffffffffffffffe0 (-20) * 1)并取值到rax  
- rbx的值为0x201000该地址对应的是节.got.plt 也是.got + sizeof(.got)的位置
 - -20位则表示在.got中 最终的地址为0x200fe0
 - 查找.dyn表可以知道该位置为000000200fe0 g_static_so_bss + 0
 - 查看该位置的内存为0
 - 那么如果在运行时没有进行动态填充, 则这里会出现对地址0进行解引用的操作.
 - rbx寄存器会复用 专门用来保存got表的入口偏移, 也就是浪费了一个通用寄存器来实现地址无关代码
 
 - 我们进入gdb调试
 
1  | 0x7ffff7bd68a3 lea -0x7(%rip),%rbx # 0x7ffff7bd68a3 <_Z7so_funcii+11>  | 
带入计算:
1  | 该位置位于加载so.so的内存中, 对应为只读的got表  | 
00007ffff7bd6000      4K r-x– so.so
00007ffff7bd7000   2044K —– so.so
00007ffff7dd6000      4K r—- so.so
00007ffff7dd7000      4K rw— so.so
1  | 推算got表在内存中的实际位置为 0x7FFFF7DD6FE0 - 28 = 0x7FFFF7DD6FB8  | 
(gdb) x /9ag 0x7FFFF7DD6FB8
0x7ffff7dd6fb8: 0x7ffff6f27c30 <__cxa_finalize>
0x7ffff7dd6fc0: 0x555555755030 
0x7ffff7dd6fc8: 0x5555557d5044 
0x7ffff7dd6fd0: 0x0
0x7ffff7dd6fd8: 0x7ffff7dd7030 
0x7ffff7dd6fe0: 0x7ffff7dd7048 
0x7ffff7dd6fe8: 0x0
0x7ffff7dd6ff0: 0x0
0x7ffff7dd6ff8: 0x0
1  | 
  | 
0x7ffff7dd7048 
0x7ffff7dd7030 
1  | 值也正确.  | 
int so_func(int a, int b)
{
  g_static_so_bss ++;
  g_static_so_data ++;
  int ret = lib_func(g_static_so_bss, g_static_so_data);
  ret += so_child_func(g_static_lib_data, g_static_lib_bss);
  ret += so_local_func();
  return ret;
}
1  | 对应的汇编码如下:  | 
 934:   48 b8 00 f7 df ff ff    movabs $0xffffffffffdff700,%rax
 93b:   ff ff ff
 93e:   48 01 d8                add    %rbx,%rax
 941:   ff d0                   callq  *%rax
1  | 这里callq的实际地址为 8a3 + 0x20075d -0x900 = 0x200700  | 
00000000000006e0 <.plt>:
 6e0:   ff 35 22 09 20 00   pushq  0x200922(%rip)  # 201008 <GOT_+0x8> link_map
 6e6:   ff 25 24 09 20 00   jmpq   *0x200924(%rip) # 201010 <GOT+0x10> _dl_runtime_resolve_xsavec
 6ec:   0f 1f 40 00             nopl   0x0(%rax)
00000000000006f0 <_Z13so_child_funcii@plt>:
 6f0:   ff 25 22 09 20 00       jmpq   *0x200922(%rip)        # 201018 <_Z13so_child_funcii@@Base+0x2007f8>
 6f6:   68 00 00 00 00          pushq  $0x0
 6fb:   e9 e0 ff ff ff          jmpq   6e0 <.plt>
0000000000000700 <_Z8lib_funcii@plt>:
 700:   ff 25 1a 09 20 00       jmpq   *0x20091a(%rip)        # 201020 <_Z8lib_funcii>
 706:   68 01 00 00 00          pushq  $0x1
 70b:   e9 d0 ff ff ff          jmpq   6e0 <.plt>
1  | 
  | 
0x7ffff7bd6700 <_Z8lib_funcii@plt>              jmpq   *0x20091a(%rip)        # 0x7ffff7dd7020
0x7ffff7bd6706 <_Z8lib_funcii@plt+6>            pushq  $0x1
0x7ffff7bd670b <_Z8lib_funcii@plt+11>           jmpq   0x7ffff7bd66e0
0x7ffff7bd6710                                  jmpq   *0x2008a2(%rip)        # 0x7ffff7dd6fb8  
(gdb) x /1ag 0x7ffff7dd7020
0x7ffff7dd7020: 0x7ffff7bd6706 <_Z8lib_funcii@plt+6>  
(gdb) x /5ag 0x7ffff7dd7000
0x7ffff7dd7000: 0x200dc8
0x7ffff7dd7008: 0x7ffff7ff6000
0x7ffff7dd7010: 0x7ffff7ded310 <_dl_runtime_resolve_xsavec>
0x7ffff7dd7018: 0x7ffff7bd66f6 <_Z13so_child_funcii@plt+6>
0x7ffff7dd7020: 0x7ffff7bd6706 <_Z8lib_funcii@plt+6>
1  | 
  | 
1  | ```C++  | 
1  | /Elf64_Sym  | 
libc/elf/dl-runtime.c
1  | __attribute ((noinline)) ARCH_FIXUP_ATTRIBUTE _dl_fixup (  | 
elf/dl-lookup.c
1  | /* Search loaded objects' symbol tables for a definition of the symbol  | 
1  | 
  | 
static inline Elf64_Addr
elf_machine_fixup_plt (struct link_map *map, lookup_t t,
               const Elf64_Rela *reloc,
               Elf64_Addr *reloc_addr, Elf64_Addr value)
{
  return *reloc_addr = value;
}
1  | 
  | 
zsummer@debian:~/symbo$ xxd -s+0x00000fb8 -l0x0000000000000048  so.so
00000fb8: 0000 0000 0000 0000 0000 0000 0000 0000  …………….
00000fc8: 0000 0000 0000 0000 0000 0000 0000 0000  …………….
00000fd8: 0000 0000 0000 0000 0000 0000 0000 0000  …………….
00000fe8: 0000 0000 0000 0000 0000 0000 0000 0000  …………….
00000ff8: 0000 0000 0000 0000                      ……..
1  | 
  | 
zsummer@debian:~/symbo$ xxd -s+0x00001000 -l0x0000000000000028  so.so
00001000: c80d 2000 0000 0000 0000 0000 0000 0000  .. ………….
00001010: 0000 0000 0000 0000 f606 0000 0000 0000  …………….
00001020: 0607 0000 0000 0000                      ……..
1  | 
  | 
zsummer@debian:~/symbo$ xxd -s+0x00001028 -l0x0000000000000018  so.so
00001028: 2810 2000 0000 0000 a086 0100 0000 0000  (. ………….
00001038: 00ff 00ff 0000 0000                      ……..
1  | 
  | 
zsummer@debian:~/symbo$ pmap 9208
9208:   /home/zsummer/symbo/a.out
0000555555554000      4K r-x– a.out
0000555555754000      4K r—- a.out
0000555555755000    516K rw— a.out
00005555557d6000    132K rw—   [ anon ]
00007ffff6ef0000   1732K r-x– libc-2.27.so
00007ffff70a1000   2044K —– libc-2.27.so
00007ffff72a0000     16K r—- libc-2.27.so
00007ffff72a4000      8K rw— libc-2.27.so
00007ffff72a6000     16K rw—   [ anon ]
00007ffff72aa000     92K r-x– libgcc_s.so.1
00007ffff72c1000   2044K —– libgcc_s.so.1
00007ffff74c0000      4K r—- libgcc_s.so.1
00007ffff74c1000      4K rw— libgcc_s.so.1
00007ffff74c2000   1608K r-x– libm-2.27.so
00007ffff7654000   2044K —– libm-2.27.so
00007ffff7853000      4K r—- libm-2.27.so
00007ffff7854000      4K rw— libm-2.27.so
00007ffff7855000   1480K r-x– libstdc++.so.6.0.25
00007ffff79c7000   2048K —– libstdc++.so.6.0.25
00007ffff7bc7000     40K r—- libstdc++.so.6.0.25
00007ffff7bd1000      8K rw— libstdc++.so.6.0.25
00007ffff7bd3000     12K rw—   [ anon ]
00007ffff7bd6000      4K r-x– so.so
00007ffff7bd7000   2044K —– so.so
00007ffff7dd6000      4K r—- so.so
00007ffff7dd7000      4K rw— so.so
00007ffff7dd8000    148K r-x– ld-2.27.so
00007ffff7fd6000     20K rw—   [ anon ]
00007ffff7ff6000      8K rw—   [ anon ]
00007ffff7ff8000      8K r—-   [ anon ]
00007ffff7ffa000      8K r-x–   [ anon ]
00007ffff7ffc000      4K r—- ld-2.27.so
00007ffff7ffd000      4K rw— ld-2.27.so
00007ffff7ffe000      4K rw—   [ anon ]
00007ffffffde000    132K rw—   [ stack ]
ffffffffff600000      4K r-x–   [ anon ]
 total            16260K
1  | 
  | 
ELF 头:
  Magic:  7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  类别:                              ELF64
  数据:                              2 补码,小端序 (little endian)
  版本:                              1 (current)
  OS/ABI:                            UNIX - System V
  ABI 版本:                          0
  类型:                              DYN (共享目标文件)
  系统架构:                          Advanced Micro Devices X86-64
  版本:                              0x1
  入口点地址:              0x720
  程序头起点:              64 (bytes into file)
  Start of section headers:          6544 (bytes into file)
  标志:             0x0
  本头的大小:       64 (字节)
  程序头大小:       56 (字节)
  Number of program headers:         7
  节头大小:         64 (字节)
  节头数量:         28
  字符串表索引节头: 27
节头:
  [号] 名称              类型             地址              偏移量
       大小              全体大小          旗标   链接   信息   对齐
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .note.gnu.build-i NOTE             00000000000001c8  000001c8
       0000000000000024  0000000000000000   A       0     0     4
  [ 2] .gnu.hash         GNU_HASH         00000000000001f0  000001f0
       0000000000000048  0000000000000000   A       3     0     8
  [ 3] .dynsym           DYNSYM           0000000000000238  00000238
       00000000000001b0  0000000000000018   A       4     1     8
  [ 4] .dynstr           STRTAB           00000000000003e8  000003e8
       000000000000013d  0000000000000000   A       0     0     1
  [ 5] .gnu.version      VERSYM           0000000000000526  00000526
       0000000000000024  0000000000000002   A       3     0     2
  [ 6] .gnu.version_r    VERNEED          0000000000000550  00000550
       0000000000000020  0000000000000000   A       4     1     8
  [ 7] .rela.dyn         RELA             0000000000000570  00000570
       0000000000000120  0000000000000018   A       3     0     8
  [ 8] .rela.plt         RELA             0000000000000690  00000690
       0000000000000030  0000000000000018  AI       3    21     8
  [ 9] .init             PROGBITS         00000000000006c0  000006c0
       0000000000000017  0000000000000000  AX       0     0     4
  [10] .plt              PROGBITS         00000000000006e0  000006e0
       0000000000000030  0000000000000010  AX       0     0     16
  [11] .plt.got          PROGBITS         0000000000000710  00000710
       0000000000000008  0000000000000000  AX       0     0     8
  [12] .text             PROGBITS         0000000000000720  00000720
       0000000000000282  0000000000000000  AX       0     0     16
  [13] .fini             PROGBITS         00000000000009a4  000009a4
       0000000000000009  0000000000000000  AX       0     0     4
  [14] .eh_frame_hdr     PROGBITS         00000000000009b0  000009b0
       0000000000000034  0000000000000000   A       0     0     4
  [15] .eh_frame         PROGBITS         00000000000009e8  000009e8
       00000000000000c4  0000000000000000   A       0     0     8
  [16] .init_array       INIT_ARRAY       0000000000200db0  00000db0
       0000000000000008  0000000000000008  WA       0     0     8
  [17] .fini_array       FINI_ARRAY       0000000000200db8  00000db8
       0000000000000008  0000000000000008  WA       0     0     8
  [18] .jcr              PROGBITS         0000000000200dc0  00000dc0
       0000000000000008  0000000000000000  WA       0     0     8
  [19] .dynamic          DYNAMIC          0000000000200dc8  00000dc8
       00000000000001f0  0000000000000010  WA       4     0     8
  [20] .got              PROGBITS         0000000000200fb8  00000fb8
       0000000000000048  0000000000000008  WA       0     0     8
  [21] .got.plt          PROGBITS         0000000000201000  00001000
       0000000000000028  0000000000000008  WA       0     0     8
  [22] .data             PROGBITS         0000000000201028  00001028
       0000000000000018  0000000000000000  WA       0     0     8
  [23] .bss              NOBITS           0000000000201040  00001040
       0000000000000010  0000000000000000  WA       0     0     8
  [24] .comment          PROGBITS         0000000000000000  00001040
       000000000000002d  0000000000000001  MS       0     0     1
  [25] .symtab           SYMTAB           0000000000000000  00001070
       00000000000005e8  0000000000000018          26    46     8
  [26] .strtab           STRTAB           0000000000000000  00001658
       0000000000000246  0000000000000000           0     0     1
  [27] .shstrtab         STRTAB           0000000000000000  0000189e
       00000000000000ee  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),
  l (large), p (processor specific)
There are no section groups in this file.
程序头:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000aac 0x0000000000000aac  R E    0x200000
  LOAD           0x0000000000000db0 0x0000000000200db0 0x0000000000200db0
                 0x0000000000000290 0x00000000000002a0  RW     0x200000
  DYNAMIC        0x0000000000000dc8 0x0000000000200dc8 0x0000000000200dc8
                 0x00000000000001f0 0x00000000000001f0  RW     0x8
  NOTE           0x00000000000001c8 0x00000000000001c8 0x00000000000001c8
                 0x0000000000000024 0x0000000000000024  R      0x4
  GNU_EH_FRAME   0x00000000000009b0 0x00000000000009b0 0x00000000000009b0
                 0x0000000000000034 0x0000000000000034  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x0000000000000db0 0x0000000000200db0 0x0000000000200db0
                 0x0000000000000250 0x0000000000000250  R      0x1
 Section to Segment mapping:
  段节…
   00     .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .plt.got .text .fini .eh_frame_hdr .eh_frame
   01     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
   02     .dynamic
   03     .note.gnu.build-id
   04     .eh_frame_hdr
   05
   06     .init_array .fini_array .jcr .dynamic .got 
Dynamic section at offset 0xdc8 contains 27 entries:
  标记        类型                         名称/值
 0x0000000000000001 (NEEDED)             共享库:[libstdc++.so.6]
 0x0000000000000001 (NEEDED)             共享库:[libm.so.6]
 0x0000000000000001 (NEEDED)             共享库:[libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             共享库:[libc.so.6]
 0x000000000000000c (INIT)               0x6c0
 0x000000000000000d (FINI)               0x9a4
 0x0000000000000019 (INIT_ARRAY)         0x200db0
 0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
 0x000000000000001a (FINI_ARRAY)         0x200db8
 0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
 0x000000006ffffef5 (GNU_HASH)           0x1f0
 0x0000000000000005 (STRTAB)             0x3e8
 0x0000000000000006 (SYMTAB)             0x238
 0x000000000000000a (STRSZ)              317 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x201000
 0x0000000000000002 (PLTRELSZ)           48 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x690
 0x0000000000000007 (RELA)               0x570
 0x0000000000000008 (RELASZ)             288 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffe (VERNEED)            0x550
 0x000000006fffffff (VERNEEDNUM)         1
 0x000000006ffffff0 (VERSYM)             0x526
 0x000000006ffffff9 (RELACOUNT)          3
 0x0000000000000000 (NULL)               0x0
重定位节 ‘.rela.dyn’ 位于偏移量 0x570 含有 12 个条目:
  偏移量          信息           类型           符号值        符号名称 + 加数
000000200db0  000000000008 R_X86_64_RELATIVE                    7f0
000000200db8  000000000008 R_X86_64_RELATIVE                    7b0
000000201028  000000000008 R_X86_64_RELATIVE                    201028
000000200fb8  000100000006 R_X86_64_GLOB_DAT 0000000000000000 cxa_finalize@GLIBC_2.2.5 + 0
000000200fc0  000200000006 R_X86_64_GLOB_DAT 0000000000000000 g_static_lib_data + 0
000000200fc8  000300000006 R_X86_64_GLOB_DAT 0000000000000000 g_static_lib_bss + 0
000000200fd0  000400000006 R_X86_64_GLOB_DAT 0000000000000000 _Jv_RegisterClasses + 0
000000200fd8  001100000006 R_X86_64_GLOB_DAT 0000000000201030 g_static_so_data + 0
000000200fe0  000d00000006 R_X86_64_GLOB_DAT 0000000000201048 g_static_so_bss + 0
000000200fe8  000500000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_deregisterTMClone + 0
000000200ff0  000700000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start + 0
000000200ff8  000800000006 R_X86_64_GLOB_DAT 0000000000000000 _ITM_registerTMCloneTa + 0
重定位节 ‘.rela.plt’ 位于偏移量 0x690 含有 2 个条目:
  偏移量          信息           类型           符号值        符号名称 + 加数
000000201018  001000000007 R_X86_64_JUMP_SLO 0000000000000820 _Z13so_child_funcii + 0
000000201020  000600000007 R_X86_64_JUMP_SLO 0000000000000000 _Z8lib_funcii + 0
The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
Symbol table ‘.dynsym’ contains 18 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND cxa_finalize@GLIBC_2.2.5 (2)
     2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND g_static_lib_data
     3: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND g_static_lib_bss
     4: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
     5: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
     6: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _Z8lib_funcii
     7: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start
     8: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
     9: 0000000000201040     0 NOTYPE  GLOBAL DEFAULT   22 _edata
    10: 0000000000201050     0 NOTYPE  GLOBAL DEFAULT   23 _end
    11: 00000000000006c0     0 FUNC    GLOBAL DEFAULT    9 _init
    12: 0000000000201040     0 NOTYPE  GLOBAL DEFAULT   23 __bss_start
    13: 0000000000201048     8 OBJECT  GLOBAL DEFAULT   23 g_static_so_bss
    14: 0000000000000898   266 FUNC    GLOBAL DEFAULT   12 _Z7so_funcii
    15: 00000000000009a4     0 FUNC    GLOBAL DEFAULT   13 _fini
    16: 0000000000000820    80 FUNC    GLOBAL DEFAULT   12 _Z13so_child_funcii
    17: 0000000000201030     8 OBJECT  GLOBAL DEFAULT   22 g_static_so_data
Symbol table ‘.symtab’ contains 63 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000000001c8     0 SECTION LOCAL  DEFAULT    1
     2: 00000000000001f0     0 SECTION LOCAL  DEFAULT    2
     3: 0000000000000238     0 SECTION LOCAL  DEFAULT    3
     4: 00000000000003e8     0 SECTION LOCAL  DEFAULT    4
     5: 0000000000000526     0 SECTION LOCAL  DEFAULT    5
     6: 0000000000000550     0 SECTION LOCAL  DEFAULT    6
     7: 0000000000000570     0 SECTION LOCAL  DEFAULT    7
     8: 0000000000000690     0 SECTION LOCAL  DEFAULT    8
     9: 00000000000006c0     0 SECTION LOCAL  DEFAULT    9
    10: 00000000000006e0     0 SECTION LOCAL  DEFAULT   10
    11: 0000000000000710     0 SECTION LOCAL  DEFAULT   11
    12: 0000000000000720     0 SECTION LOCAL  DEFAULT   12
    13: 00000000000009a4     0 SECTION LOCAL  DEFAULT   13
    14: 00000000000009b0     0 SECTION LOCAL  DEFAULT   14
    15: 00000000000009e8     0 SECTION LOCAL  DEFAULT   15
    16: 0000000000200db0     0 SECTION LOCAL  DEFAULT   16
    17: 0000000000200db8     0 SECTION LOCAL  DEFAULT   17
    18: 0000000000200dc0     0 SECTION LOCAL  DEFAULT   18
    19: 0000000000200dc8     0 SECTION LOCAL  DEFAULT   19
    20: 0000000000200fb8     0 SECTION LOCAL  DEFAULT   20
    21: 0000000000201000     0 SECTION LOCAL  DEFAULT   21
    22: 0000000000201028     0 SECTION LOCAL  DEFAULT   22
    23: 0000000000201040     0 SECTION LOCAL  DEFAULT   23
    24: 0000000000000000     0 SECTION LOCAL  DEFAULT   24
    25: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    26: 0000000000200dc0     0 OBJECT  LOCAL  DEFAULT   18 JCR_LIST
    27: 0000000000000720     0 FUNC    LOCAL  DEFAULT   12 deregister_tm_clones
    28: 0000000000000760     0 FUNC    LOCAL  DEFAULT   12 register_tm_clones
    29: 00000000000007b0     0 FUNC    LOCAL  DEFAULT   12 do_global_dtors_aux
    30: 0000000000201040     1 OBJECT  LOCAL  DEFAULT   23 completed.6972
    31: 0000000000200db8     0 OBJECT  LOCAL  DEFAULT   17 _do_global_dtors_aux_fin
    32: 00000000000007f0     0 FUNC    LOCAL  DEFAULT   12 frame_dummy
    33: 0000000000200db0     0 OBJECT  LOCAL  DEFAULT   16 __frame_dummy_init_array
    34: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS so.cpp
    35: 0000000000201038     8 OBJECT  LOCAL  DEFAULT   22 _ZL15g_local_so_data
    36: 0000000000000870    40 FUNC    LOCAL  DEFAULT   12 _ZL13so_local_funcv
    37: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    38: 0000000000000aa8     0 OBJECT  LOCAL  DEFAULT   15 __FRAME_END
    39: 0000000000200dc0     0 OBJECT  LOCAL  DEFAULT   18 JCR_END
    40: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS
    41: 00000000000009b0     0 NOTYPE  LOCAL  DEFAULT   14 GNU_EH_FRAME_HDR
    42: 0000000000201028     0 OBJECT  LOCAL  DEFAULT   22 __dso_handle
    43: 0000000000200dc8     0 OBJECT  LOCAL  DEFAULT   19 _DYNAMIC
    44: 0000000000201040     0 OBJECT  LOCAL  DEFAULT   22 __TMC_END
    45: 0000000000201000     0 OBJECT  LOCAL  DEFAULT   21 GLOBAL_OFFSET_TABLE
    46: 0000000000201040     0 NOTYPE  GLOBAL DEFAULT   22 edata
    47: 0000000000000000     0 FUNC    WEAK   DEFAULT  UND _cxa_finalize@@GLIBC_2.2
    48: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND g_static_lib_data
    49: 00000000000009a4     0 FUNC    GLOBAL DEFAULT   13 _fini
    50: 0000000000000820    80 FUNC    GLOBAL DEFAULT   12 _Z13so_child_funcii
    51: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND g_static_lib_bss
    52: 00000000000006c0     0 FUNC    GLOBAL DEFAULT    9 _init
    53: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
    54: 0000000000201030     8 OBJECT  GLOBAL DEFAULT   22 g_static_so_data
    55: 0000000000201050     0 NOTYPE  GLOBAL DEFAULT   23 _end
    56: 0000000000201040     0 NOTYPE  GLOBAL DEFAULT   23 __bss_start
    57: 0000000000201048     8 OBJECT  GLOBAL DEFAULT   23 g_static_so_bss
    58: 0000000000000898   266 FUNC    GLOBAL DEFAULT   12 _Z7so_funcii
    59: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_deregisterTMCloneTab
    60: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _Z8lib_funcii
    61: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start
    62: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND _ITM_registerTMCloneTable
Histogram for `.gnu.hash’ bucket list length (total of 3 buckets):
 Length  Number     % of total  Coverage
      0  0          (  0.0%)
      1  0          (  0.0%)      0.0%
      2  1          ( 33.3%)     22.2%
      3  1          ( 33.3%)     55.6%
      4  1          ( 33.3%)    100.0%
Version symbols section ‘.gnu.version’ contains 18 entries:
 地址:0000000000000526  Offset: 0x000526  Link: 3 (.dynsym)
  000:   0 (本地)       2 (GLIBC_2.2.5)   0 (本地)       0 (本地)
  004:   0 (本地)       0 (本地)       0 (本地)       0 (本地)
  008:   0 (本地)       1 (全局)      1 (全局)      1 (全局)
  00c:   1 (全局)      1 (全局)      1 (全局)      1 (全局)
  010:   1 (全局)      1 (全局)   
Version needs section ‘.gnu.version_r’ contains 1 entries:
 地址:0x0000000000000550  Offset: 0x000550  Link: 4 (.dynstr)
  000000: 版本: 1  文件:libc.so.6  计数:1
  0x0010:名称:GLIBC_2.2.5  标志:无  版本:2
Displaying notes found in: .note.gnu.build-id
  所有者             Data size  Description
  GNU                  0x00000014       NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: 09ce242e3867431b496a7f5928e9817fa91d242a
1  | 
  | 
so.so: 文件格式 elf64-x86-64
Disassembly of section .init:
00000000000006c0 <init>:
 6c0:   48 83 ec 08             sub    $0x8,%rsp
 6c4:   48 8b 05 25 09 20 00    mov    0x200925(%rip),%rax        # 200ff0 <_gmon_start>
 6cb:   48 85 c0                test   %rax,%rax
 6ce:   74 02                   je     6d2 <_init+0x12>
 6d0:   ff d0                   callq  *%rax
 6d2:   48 83 c4 08             add    $0x8,%rsp
 6d6:   c3                      retq   
Disassembly of section .plt:
00000000000006e0 <.plt>:
 6e0:   ff 35 22 09 20 00       pushq  0x200922(%rip)        # 201008 <GLOBAL_OFFSET_TABLE+0x8>
 6e6:   ff 25 24 09 20 00       jmpq   *0x200924(%rip)        # 201010 <GLOBAL_OFFSET_TABLE+0x10>
 6ec:   0f 1f 40 00             nopl   0x0(%rax)
00000000000006f0 <_Z13so_child_funcii@plt>:
 6f0:   ff 25 22 09 20 00       jmpq   *0x200922(%rip)        # 201018 <_Z13so_child_funcii@@Base+0x2007f8>
 6f6:   68 00 00 00 00          pushq  $0x0
 6fb:   e9 e0 ff ff ff          jmpq   6e0 <.plt>
0000000000000700 <_Z8lib_funcii@plt>:
 700:   ff 25 1a 09 20 00       jmpq   *0x20091a(%rip)        # 201020 <_Z8lib_funcii>
 706:   68 01 00 00 00          pushq  $0x1
 70b:   e9 d0 ff ff ff          jmpq   6e0 <.plt>
Disassembly of section .plt.got:
0000000000000710 <.plt.got>:
 710:   ff 25 a2 08 20 00       jmpq   *0x2008a2(%rip)        # 200fb8 <__cxa_finalize@GLIBC_2.2.5>
 716:   66 90                   xchg   %ax,%ax
Disassembly of section .text:
0000000000000720 
 720:   48 8d 3d 19 09 20 00    lea    0x200919(%rip),%rdi        # 201040 <_edata>
 727:   48 8d 05 19 09 20 00    lea    0x200919(%rip),%rax        # 201047 <_edata+0x7>
 72e:   55                      push   %rbp
 72f:   48 29 f8                sub    %rdi,%rax
 732:   48 89 e5                mov    %rsp,%rbp
 735:   48 83 f8 0e             cmp    $0xe,%rax
 739:   76 15                   jbe    750 <deregister_tm_clones+0x30>
 73b:   48 8b 05 a6 08 20 00    mov    0x2008a6(%rip),%rax        # 200fe8 <_ITM_deregisterTMCloneTable>
 742:   48 85 c0                test   %rax,%rax
 745:   74 09                   je     750 <deregister_tm_clones+0x30>
 747:   5d                      pop    %rbp
 748:   ff e0                   jmpq   *%rax
 74a:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
 750:   5d                      pop    %rbp
 751:   c3                      retq
 752:   0f 1f 40 00             nopl   0x0(%rax)
 756:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
 75d:   00 00 00 
0000000000000760 
 760:   48 8d 3d d9 08 20 00    lea    0x2008d9(%rip),%rdi        # 201040 <_edata>
 767:   48 8d 35 d2 08 20 00    lea    0x2008d2(%rip),%rsi        # 201040 <_edata>
 76e:   55                      push   %rbp
 76f:   48 29 fe                sub    %rdi,%rsi
 772:   48 89 e5                mov    %rsp,%rbp
 775:   48 c1 fe 03             sar    $0x3,%rsi
 779:   48 89 f0                mov    %rsi,%rax
 77c:   48 c1 e8 3f             shr    $0x3f,%rax
 780:   48 01 c6                add    %rax,%rsi
 783:   48 d1 fe                sar    %rsi
 786:   74 18                   je     7a0 <register_tm_clones+0x40>
 788:   48 8b 05 69 08 20 00    mov    0x200869(%rip),%rax        # 200ff8 <_ITM_registerTMCloneTable>
 78f:   48 85 c0                test   %rax,%rax
 792:   74 0c                   je     7a0 <register_tm_clones+0x40>
 794:   5d                      pop    %rbp
 795:   ff e0                   jmpq   *%rax
 797:   66 0f 1f 84 00 00 00    nopw   0x0(%rax,%rax,1)
 79e:   00 00
 7a0:   5d                      pop    %rbp
 7a1:   c3                      retq
 7a2:   0f 1f 40 00             nopl   0x0(%rax)
 7a6:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
 7ad:   00 00 00 
00000000000007b0 <do_global_dtors_aux>:
 7b0:   80 3d 89 08 20 00 00    cmpb   $0x0,0x200889(%rip)        # 201040 <_edata>
 7b7:   75 27                   jne    7e0 <do_global_dtors_aux+0x30>
 7b9:   48 83 3d f7 07 20 00    cmpq   $0x0,0x2007f7(%rip)        # 200fb8 <cxa_finalize@GLIBC_2.2.5>
 7c0:   00
 7c1:   55                      push   %rbp
 7c2:   48 89 e5                mov    %rsp,%rbp
 7c5:   74 0c                   je     7d3 <do_global_dtors_aux+0x23>
 7c7:   48 8b 3d 5a 08 20 00    mov    0x20085a(%rip),%rdi        # 201028 <__dso_handle>
 7ce:   e8 3d ff ff ff          callq  710 <.plt.got>
 7d3:   e8 48 ff ff ff          callq  720 
 7d8:   5d                      pop    %rbp
 7d9:   c6 05 60 08 20 00 01    movb   $0x1,0x200860(%rip)        # 201040 <_edata>
 7e0:   f3 c3                   repz retq
 7e2:   0f 1f 40 00             nopl   0x0(%rax)
 7e6:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
 7ed:   00 00 00 
00000000000007f0 
 7f0:   48 8d 3d c9 05 20 00    lea    0x2005c9(%rip),%rdi        # 200dc0 <JCR_END>
 7f7:   48 83 3f 00             cmpq   $0x0,(%rdi)
 7fb:   75 0b                   jne    808 <frame_dummy+0x18>
 7fd:   e9 5e ff ff ff          jmpq   760 
 802:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
 808:   48 8b 05 c1 07 20 00    mov    0x2007c1(%rip),%rax        # 200fd0 <_Jv_RegisterClasses>
 80f:   48 85 c0                test   %rax,%rax
 812:   74 e9                   je     7fd <frame_dummy+0xd>
 814:   55                      push   %rbp
 815:   48 89 e5                mov    %rsp,%rbp
 818:   ff d0                   callq  *%rax
 81a:   5d                      pop    %rbp
 81b:   e9 40 ff ff ff          jmpq   760 
0000000000000820 <_Z13so_child_funcii>:
 820:   55                      push   %rbp
 821:   48 89 e5                mov    %rsp,%rbp
 824:   48 8d 05 f9 ff ff ff    lea    -0x7(%rip),%rax        # 824 <_Z13so_child_funcii+0x4>
 82b:   49 bb dc 07 20 00 00    movabs $0x2007dc,%r11
 832:   00 00 00
 835:   4c 01 d8                add    %r11,%rax
 838:   89 7d fc                mov    %edi,-0x4(%rbp)
 83b:   89 75 f8                mov    %esi,-0x8(%rbp)
 83e:   8b 4d fc                mov    -0x4(%rbp),%ecx
 841:   8b 55 f8                mov    -0x8(%rbp),%edx
 844:   01 ca                   add    %ecx,%edx
 846:   89 d1                   mov    %edx,%ecx
 848:   48 ba e0 ff ff ff ff    movabs $0xffffffffffffffe0,%rdx
 84f:   ff ff ff
 852:   48 8b 14 10             mov    (%rax,%rdx,1),%rdx
 856:   48 8b 12                mov    (%rdx),%rdx
 859:   01 d1                   add    %edx,%ecx
 85b:   48 ba d8 ff ff ff ff    movabs $0xffffffffffffffd8,%rdx
 862:   ff ff ff
 865:   48 8b 04 10             mov    (%rax,%rdx,1),%rax
 869:   48 8b 00                mov    (%rax),%rax
 86c:   01 c8                   add    %ecx,%eax
 86e:   5d                      pop    %rbp
 86f:   c3                      retq   
0000000000000870 <_ZL13so_local_funcv>:
 870:   55                      push   %rbp
 871:   48 89 e5                mov    %rsp,%rbp
 874:   48 8d 05 f9 ff ff ff    lea    -0x7(%rip),%rax        # 874 <_ZL13so_local_funcv+0x4>
 87b:   49 bb 8c 07 20 00 00    movabs $0x20078c,%r11
 882:   00 00 00
 885:   4c 01 d8                add    %r11,%rax
 888:   48 ba 38 00 00 00 00    movabs $0x38,%rdx
 88f:   00 00 00
 892:   48 8b 04 10             mov    (%rax,%rdx,1),%rax
 896:   5d                      pop    %rbp
 897:   c3                      retq   
0000000000000898 <_Z7so_funcii>:
 898:   55                      push   %rbp
 899:   48 89 e5                mov    %rsp,%rbp
 89c:   41 57                   push   %r15
 89e:   53                      push   %rbx
 89f:   48 83 ec 20             sub    $0x20,%rsp
 8a3:   48 8d 1d f9 ff ff ff    lea    -0x7(%rip),%rbx        # 8a3 <_Z7so_funcii+0xb>
 8aa:   49 bb 5d 07 20 00 00    movabs $0x20075d,%r11
 8b1:   00 00 00
 8b4:   4c 01 db                add    %r11,%rbx
 8b7:   89 7d dc                mov    %edi,-0x24(%rbp)
 8ba:   89 75 d8                mov    %esi,-0x28(%rbp)
 8bd:   48 b8 e0 ff ff ff ff    movabs $0xffffffffffffffe0,%rax
 8c4:   ff ff ff
 8c7:   48 8b 04 03             mov    (%rbx,%rax,1),%rax
 8cb:   48 8b 00                mov    (%rax),%rax
 8ce:   48 8d 50 01             lea    0x1(%rax),%rdx
 8d2:   48 b8 e0 ff ff ff ff    movabs $0xffffffffffffffe0,%rax
 8d9:   ff ff ff
 8dc:   48 8b 04 03             mov    (%rbx,%rax,1),%rax
 8e0:   48 89 10                mov    %rdx,(%rax)
 8e3:   48 b8 d8 ff ff ff ff    movabs $0xffffffffffffffd8,%rax
 8ea:   ff ff ff
 8ed:   48 8b 04 03             mov    (%rbx,%rax,1),%rax
 8f1:   48 8b 00                mov    (%rax),%rax
 8f4:   48 8d 50 01             lea    0x1(%rax),%rdx
 8f8:   48 b8 d8 ff ff ff ff    movabs $0xffffffffffffffd8,%rax
 8ff:   ff ff ff
 902:   48 8b 04 03             mov    (%rbx,%rax,1),%rax
 906:   48 89 10                mov    %rdx,(%rax)
 909:   48 b8 d8 ff ff ff ff    movabs $0xffffffffffffffd8,%rax
 910:   ff ff ff
 913:   48 8b 04 03             mov    (%rbx,%rax,1),%rax
 917:   48 8b 00                mov    (%rax),%rax
 91a:   89 c2                   mov    %eax,%edx
 91c:   48 b8 e0 ff ff ff ff    movabs $0xffffffffffffffe0,%rax
 923:   ff ff ff
 926:   48 8b 04 03             mov    (%rbx,%rax,1),%rax
 92a:   48 8b 00                mov    (%rax),%rax
 92d:   89 d6                   mov    %edx,%esi
 92f:   89 c7                   mov    %eax,%edi
 931:   49 89 df                mov    %rbx,%r15
 934:   48 b8 00 f7 df ff ff    movabs $0xffffffffffdff700,%rax
 93b:   ff ff ff
 93e:   48 01 d8                add    %rbx,%rax
 941:   ff d0                   callq  *%rax
 943:   89 45 ec                mov    %eax,-0x14(%rbp)
 946:   48 b8 c8 ff ff ff ff    movabs $0xffffffffffffffc8,%rax
 94d:   ff ff ff
 950:   48 8b 04 03             mov    (%rbx,%rax,1),%rax
 954:   48 8b 00                mov    (%rax),%rax
 957:   89 c2                   mov    %eax,%edx
 959:   48 b8 c0 ff ff ff ff    movabs $0xffffffffffffffc0,%rax
 960:   ff ff ff
 963:   48 8b 04 03             mov    (%rbx,%rax,1),%rax
 967:   48 8b 00                mov    (%rax),%rax
 96a:   89 d6                   mov    %edx,%esi
 96c:   89 c7                   mov    %eax,%edi
 96e:   49 89 df                mov    %rbx,%r15
 971:   48 b8 f0 f6 df ff ff    movabs $0xffffffffffdff6f0,%rax
 978:   ff ff ff
 97b:   48 01 d8                add    %rbx,%rax
 97e:   ff d0                   callq  *%rax
 980:   01 45 ec                add    %eax,-0x14(%rbp)
 983:   48 b8 70 f8 df ff ff    movabs $0xffffffffffdff870,%rax
 98a:   ff ff ff
 98d:   48 8d 04 03             lea    (%rbx,%rax,1),%rax
 991:   ff d0                   callq  *%rax
 993:   01 45 ec                add    %eax,-0x14(%rbp)
 996:   8b 45 ec                mov    -0x14(%rbp),%eax
 999:   48 83 c4 20             add    $0x20,%rsp
 99d:   5b                      pop    %rbx
 99e:   41 5f                   pop    %r15
 9a0:   5d                      pop    %rbp
 9a1:   c3                      retq   
Disassembly of section .fini:
00000000000009a4 <_fini>:
 9a4:   48 83 ec 08             sub    $0x8,%rsp
 9a8:   48 83 c4 08             add    $0x8,%rsp
 9ac:   c3                      retq   
### 动态库装载过程  
[linux kernel 源码](https://elixir.bootlin.com/linux/latest/source)  
#### ELF的辅助向量 AUXV   
main函数的第三个参数  char* envp[]    
LD_SHOW_AUXV=1 whoami 
#### load_elf_binary函数  
* 填充并且检查目标程序ELF头部
* load_elf_phdrs加载目标程序的程序头表
* 如果需要动态链接, 则寻找和处理解释器段
* 检查并读取解释器的程序表头
* 装入目标程序的段segment
* create_elf_tables填写目标文件的参数环境变量等必要信息
* start_kernel宏准备进入新的程序入口
</font>