ELF重定位类型分析(1-3, 总结)加评版

ELF文件执行过程中, 重定位和动态链接是两个重要的步骤;

本文原文描述了重定位类型对应的原C程序的语句情景, 和重定位类型指示linker editor和dynamic llinker尤其是前者所做的重定位修正. 可以做为ELF File Format文章的辅助研究文章. 熟悉重定位, 对于了解动态链接有重要的意义; 特别是了解了R_386_GLOB_DAT和R_386_JMP_SLOT两个类型后, 加上PLT和GOT, 动态链接也就有基本轮廓了.

本加评版参考ELF File Format对一些细节做了评注, 增加了R_386_JMP_SLOT重定位类型的描述, 增加了对动态链接的描述, 加上.plt和.got.plt的关系, 动态链接的行为就可以把握了.

为了便于分析, 把原文中分析使用的附件文件内容提前, 小部分内容做了调整.

随着编译器的发展, 编译出的实际的ELF的节区也有了小量改变, 如.rel.plt / .rel.dyn / .got.plt等

一些基础知识, 可以参考经典老牌: <<linker and loaders>>

重定位过程涉及的点:

对目标文件, 绝大部分是根据.rel.text对.text做重定文, 其余还有.data / .rodata / ...等

对可执行文件和共享库文件主要是根据.rel.dyn / .rel.plt对访问.got和.plt的代码做修正, 使对绝对地址符号的引用都集中到.got / .got.plt中, 使GOT执行逻辑之前都是位置无关代码.

原文链接: http://blog.chinaunix.net/uid-725631-id-253156.html

 

重定位类型分析(1-3, 总结)

重定位目标文件:位置相关 gcc -c 1.c -o 1.o
PIC
重定位目标文件:位置无关
gcc -fPIC -c 1.c -o 1.o
静态库文件:多个重定位目标文件的集合
ar c lib.a 1.o 2.o
共享库:动态链接库
ld -shared 1.o -o 1.so
可执行文件:静态链接
gcc 2.o 1.o -o 3 or gcc 2.o lib.a -o 3
可执行文件:动态链接 gcc 2.o 1.so -o 3

 

重定位分两个步骤
目标文件中的重定位信息,指导ld如何连接时重定位(静态
)
可执行文件中的重定位信息,指导/lib/ld-linux.so.2如何执行时重定位(动态)

 

重定位类型解析(1)

由于是重定位目标文件,所以Offset是相对于节的偏移。.rel.text说明要重定位的节是.text.
找节表,.rel.text节的Info指向1节,即.text.(可发现Addr0)

 Info字段分成两部分,第八位为重定位类型,高24位为符号表索引,据此可找到重定位的符号。这里的符号表是.symtab.

附件1

 1.c.txt

[root@proxy ~/3]# cat 1.c
#include <stdio.h>

char *s="hello World!\n";
char *t="abc\n";

void f()
{
printf(s);
}

void g()
{
printf(t);
}
[root@proxy ~/3]# gcc -c 1.c -o 1.o

[root@proxy ~/3]# objdump -dj .text 1.o

1.o:     file format elf32-i386

Disassembly of section .text:

00000000 <f>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 08                sub    $0x8,%esp
   6:   83 ec 0c                sub    $0xc,%esp
   9:   ff 35 00 00 00 00       pushl  0x0
   f:   e8 fc ff ff ff          call   10 <f+0x10>
  14:   83 c4 10                add    $0x10,%esp
  17:   c9                      leave 
  18:   c3                      ret   
  19:   8d 76 00                lea    0x0(%esi),%esi

0000001c <g>:
  1c:   55                      push   %ebp
  1d:   89 e5                   mov    %esp,%ebp
  1f:   83 ec 08                sub    $0x8,%esp
  22:   83 ec 0c                sub    $0xc,%esp
  25:   ff 35 00 00 00 00       pushl  0x0
  2b:   e8 fc ff ff ff          call   2c <g+0x10>
  30:   83 c4 10                add    $0x10,%esp
  33:   c9                      leave 
  34:   c3                      ret   
  35:   8d 76 00                lea    0x0(%esi),%esi
 
[root@proxy ~/3]# readelf -a 1.o
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          296 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         12
  Section header string table index: 9

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000038 00  AX  0   0  4
  [ 2] .rel.text         REL             00000000 00040c 000020 08     10   1  4
  [ 3] .data             PROGBITS        00000000 00006c 000008 00  WA  0   0  4
  [ 4] .rel.data         REL             00000000 00042c 000010 08     10   3  4
  [ 5] .bss              NOBITS          00000000 000074 000000 00  WA  0   0  4
  [ 6] .note             NOTE            00000000 000074 000014 00      0   0  1
  [ 7] .rodata           PROGBITS        00000000 000088 000013 00   A  0   0  1
  [ 8] .comment          PROGBITS        00000000 00009b 000036 00      0   0  1
  [ 9] .shstrtab         STRTAB          00000000 0000d1 000057 00      0   0  1
  [10] .symtab           SYMTAB          00000000 000308 0000e0 10     11   9  4
  [11] .strtab           STRTAB          00000000 0003e8 000023 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There are no program headers in this file.

There is no dynamic segment in this file.

Relocation section '.rel.text' at offset 0x40c contains 4 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  0000000b  00901 R_386_32              00000000  s                       
  00000010  00c02 R_386_PC32            00000000  printf                  
  00000027  00a01 R_386_32              00000004  t                       
  0000002c  00c02 R_386_PC32            00000000  printf                  

Relocation section '.rel.data' at offset 0x42c contains 2 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  00000000  00601 R_386_32              00000000  .rodata                 
  00000004  00601 R_386_32              00000000  .rodata                 

There are no unwind sections in this file.

Symbol table '.symtab' contains 14 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS 1.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    5
     5: 00000000     0 NOTYPE  LOCAL  DEFAULT    1 gcc2_compiled.
     6: 00000000     0 SECTION LOCAL  DEFAULT    7
     7: 00000000     0 SECTION LOCAL  DEFAULT    6
     8: 00000000     0 SECTION LOCAL  DEFAULT    8
     9: 00000000     4 OBJECT  GLOBAL DEFAULT    3 s
    10: 00000004     4 OBJECT  GLOBAL DEFAULT    3 t
    11: 00000000    25 FUNC    GLOBAL DEFAULT    1 f
    12: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
    13: 0000001c    25 FUNC    GLOBAL DEFAULT    1 g

No version information found in this file.

附件2

3.c.txt

[root@proxy ~/3]# cat 3.c
void f();

int main()
{
f();
g();
return 0;
}
[root@proxy ~/3]# gcc -c 3.c -o 3.o
[root@proxy ~/3]# objdump -dj .text 3.o

3.o:     file format elf32-i386

Disassembly of section .text:

00000000 <main>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   83 ec 08                sub    $0x8,%esp
   6:   e8 fc ff ff ff          call   7 <main+0x7>
   b:   e8 fc ff ff ff          call   c <main+0xc>
  10:   b8 00 00 00 00          mov    $0x0,%eax
  15:   c9                      leave 
  16:   c3                      ret   
  17:   90                      nop  
[root@proxy ~/3]# readelf -a 3.o
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          220 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         10
  Section header string table index: 7

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000018 00  AX  0   0  4
  [ 2] .rel.text         REL             00000000 00033c 000010 08      8   1  4
  [ 3] .data             PROGBITS        00000000 00004c 000000 00  WA  0   0  4
  [ 4] .bss              NOBITS          00000000 00004c 000000 00  WA  0   0  4
  [ 5] .note             NOTE            00000000 00004c 000014 00      0   0  1
  [ 6] .comment          PROGBITS        00000000 000060 000036 00      0   0  1
  [ 7] .shstrtab         STRTAB          00000000 000096 000045 00      0   0  1
  [ 8] .symtab           SYMTAB          00000000 00026c 0000b0 10      9   8  4
  [ 9] .strtab           STRTAB          00000000 00031c 00001d 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There are no program headers in this file.

There is no dynamic segment in this file.

Relocation section '.rel.text' at offset 0x33c contains 2 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  00000007  00902 R_386_PC32            00000000  f                       
  0000000c  00a02 R_386_PC32            00000000  g                       

There are no unwind sections in this file.

Symbol table '.symtab' contains 11 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS 3.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    4
     5: 00000000     0 NOTYPE  LOCAL  DEFAULT    1 gcc2_compiled.
     6: 00000000     0 SECTION LOCAL  DEFAULT    5
     7: 00000000     0 SECTION LOCAL  DEFAULT    6
     8: 00000000    23 FUNC    GLOBAL DEFAULT    1 main
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND f
    10: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND g

No version information found in this file.

 

附件3

4.out.txt

 [root@proxy ~/3]# gcc 1.o 3.o -o 4
[root@proxy ~/3]# ./4
hello World!
abc
[root@proxy ~/3]# objdump -dj .text 4

4:     file format elf32-i386

Disassembly of section .text:

08048360 <_start>:
 8048360:       31 ed                   xor    %ebp,%ebp
 8048362:       5e                      pop    %esi
 8048363:       89 e1                   mov    %esp,%ecx
 8048365:       83 e4 f0                and    $0xfffffff0,%esp
 8048368:       50                      push   %eax
 8048369:       54                      push   %esp
 804836a:       52                      push   %edx
 804836b:       68 f0 84 04 08          push   $0x80484f0
 8048370:       68 e4 82 04 08          push   $0x80482e4
 8048375:       51                      push   %ecx
 8048376:       56                      push   %esi
 8048377:       68 98 84 04 08          push   $0x8048498
 804837c:       e8 ab ff ff ff          call   804832c <_init+0x48>
 8048381:       f4                      hlt   
 8048382:       89 f6                   mov    %esi,%esi

08048384 <call_gmon_start>:
 8048384:       55                      push   %ebp
 8048385:       89 e5                   mov    %esp,%ebp
 8048387:       53                      push   %ebx
 8048388:       50                      push   %eax
 8048389:       e8 00 00 00 00          call   804838e <call_gmon_start+0xa>
 804838e:       5b                      pop    %ebx
 804838f:       81 c3 ca 11 00 00       add    $0x11ca,%ebx
 8048395:       8b 83 20 00 00 00       mov    0x20(%ebx),%eax
 804839b:       85 c0                   test   %eax,%eax
 804839d:       74 02                   je     80483a1 <call_gmon_start+0x1d>
 804839f:       ff d0                   call   *%eax
 80483a1:       8b 5d fc                mov    0xfffffffc(%ebp),%ebx
 80483a4:       c9                      leave 
 80483a5:       c3                      ret   
 80483a6:       89 f6                   mov    %esi,%esi
 80483a8:       90                      nop   
 80483a9:       90                      nop   
 80483aa:       90                      nop   
 80483ab:       90                      nop   
 80483ac:       90                      nop   
 80483ad:       90                      nop   
 80483ae:       90                      nop   
 80483af:       90                      nop   

080483b0 <__do_global_dtors_aux>:
 80483b0:       55                      push   %ebp
 80483b1:       89 e5                   mov    %esp,%ebp
 80483b3:       83 ec 08                sub    $0x8,%esp
 80483b6:       8b 15 38 95 04 08       mov    0x8049538,%edx
 80483bc:       85 d2                   test   %edx,%edx
 80483be:       75 49                   jne    8048409 <__do_global_dtors_aux+0x59>
 80483c0:       8b 15 34 95 04 08       mov    0x8049534,%edx
 80483c6:       8b 02                   mov    (%edx),%eax
 80483c8:       85 c0                   test   %eax,%eax
 80483ca:       74 1a                   je     80483e6 <__do_global_dtors_aux+0x36>
 80483cc:       8d 74 26 00             lea    0x0(%esi,1),%esi
 80483d0:       8d 42 04                lea    0x4(%edx),%eax
 80483d3:       a3 34 95 04 08          mov    %eax,0x8049534
 80483d8:       ff 12                   call   *(%edx)
 80483da:       8b 15 34 95 04 08       mov    0x8049534,%edx
 80483e0:       8b 0a                   mov    (%edx),%ecx
 80483e2:       85 c9                   test   %ecx,%ecx
 80483e4:       75 ea                   jne    80483d0 <__do_global_dtors_aux+0x20>
 80483e6:       b8 1c 83 04 08          mov    $0x804831c,%eax
 80483eb:       85 c0                   test   %eax,%eax
 80483ed:       74 10                   je     80483ff <__do_global_dtors_aux+0x4f>
 80483ef:       83 ec 0c                sub    $0xc,%esp
 80483f2:       68 44 95 04 08          push   $0x8049544
 80483f7:       e8 20 ff ff ff          call   804831c <_init+0x38>
 80483fc:       83 c4 10                add    $0x10,%esp
 80483ff:       b8 01 00 00 00          mov    $0x1,%eax
 8048404:       a3 38 95 04 08          mov    %eax,0x8049538
 8048409:       89 ec                   mov    %ebp,%esp
 804840b:       5d                      pop    %ebp
 804840c:       c3                      ret   
 804840d:       8d 76 00                lea    0x0(%esi),%esi

08048410 <fini_dummy>:
 8048410:       55                      push   %ebp
 8048411:       89 e5                   mov    %esp,%ebp
 8048413:       83 ec 08                sub    $0x8,%esp
 8048416:       89 ec                   mov    %ebp,%esp
 8048418:       5d                      pop    %ebp
 8048419:       c3                      ret   
 804841a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi

08048420 <frame_dummy>:
 8048420:       55                      push   %ebp
 8048421:       b8 0c 83 04 08          mov    $0x804830c,%eax
 8048426:       89 e5                   mov    %esp,%ebp
 8048428:       83 ec 08                sub    $0x8,%esp
 804842b:       85 c0                   test   %eax,%eax
 804842d:       74 15                   je     8048444 <frame_dummy+0x24>
 804842f:       83 ec 08                sub    $0x8,%esp
 8048432:       68 44 96 04 08          push   $0x8049644
 8048437:       68 44 95 04 08          push   $0x8049544
 804843c:       e8 cb fe ff ff          call   804830c <_init+0x28>
 8048441:       83 c4 10                add    $0x10,%esp
 8048444:       89 ec                   mov    %ebp,%esp
 8048446:       5d                      pop    %ebp
 8048447:       c3                      ret   
 8048448:       90                      nop   
 8048449:       8d b4 26 00 00 00 00    lea    0x0(%esi,1),%esi

08048450 <init_dummy>:
 8048450:       55                      push   %ebp
 8048451:       89 e5                   mov    %esp,%ebp
 8048453:       83 ec 08                sub    $0x8,%esp
 8048456:       89 ec                   mov    %ebp,%esp
 8048458:       5d                      pop    %ebp
 8048459:       c3                      ret   
 804845a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi

08048460 <f>:
 8048460:       55                      push   %ebp
 8048461:       89 e5                   mov    %esp,%ebp
 8048463:       83 ec 08                sub    $0x8,%esp
 8048466:       83 ec 0c                sub    $0xc,%esp
 8048469:       ff 35 3c 95 04 08       pushl  0x804953c
 804846f:       e8 c8 fe ff ff          call   804833c <_init+0x58>
 8048474:       83 c4 10                add    $0x10,%esp
 8048477:       c9                      leave 
 8048478:       c3                      ret   
 8048479:       8d 76 00                lea    0x0(%esi),%esi

0804847c <g>:
 804847c:       55                      push   %ebp
 804847d:       89 e5                   mov    %esp,%ebp
 804847f:       83 ec 08                sub    $0x8,%esp
 8048482:       83 ec 0c                sub    $0xc,%esp
 8048485:       ff 35 40 95 04 08       pushl  0x8049540
 804848b:       e8 ac fe ff ff          call   804833c <_init+0x58>
 8048490:       83 c4 10                add    $0x10,%esp
 8048493:       c9                      leave 
 8048494:       c3                      ret   
 8048495:       8d 76 00                lea    0x0(%esi),%esi

08048498 <main>:
 8048498:       55                      push   %ebp
 8048499:       89 e5                   mov    %esp,%ebp
 804849b:       83 ec 08                sub    $0x8,%esp
 804849e:       e8 bd ff ff ff          call   8048460 <f>
 80484a3:       e8 d4 ff ff ff          call   804847c <g>
 80484a8:       b8 00 00 00 00          mov    $0x0,%eax
 80484ad:       c9                      leave 
 80484ae:       c3                      ret   
 80484af:       90                      nop   

080484b0 <__do_global_ctors_aux>:
 80484b0:       55                      push   %ebp
 80484b1:       89 e5                   mov    %esp,%ebp
 80484b3:       53                      push   %ebx
 80484b4:       83 ec 04                sub    $0x4,%esp
 80484b7:       a1 48 95 04 08          mov    0x8049548,%eax
 80484bc:       bb 48 95 04 08          mov    $0x8049548,%ebx
 80484c1:       83 f8 ff                cmp    $0xffffffff,%eax
 80484c4:       74 16                   je     80484dc <__do_global_ctors_aux+0x2c>
 80484c6:       8d 76 00                lea    0x0(%esi),%esi
 80484c9:       8d bc 27 00 00 00 00    lea    0x0(%edi,1),%edi
 80484d0:       83 eb 04                sub    $0x4,%ebx
 80484d3:       ff d0                   call   *%eax
 80484d5:       8b 03                   mov    (%ebx),%eax
 80484d7:       83 f8 ff                cmp    $0xffffffff,%eax
 80484da:       75 f4                   jne    80484d0 <__do_global_ctors_aux+0x20>
 80484dc:       58                      pop    %eax
 80484dd:       5b                      pop    %ebx
 80484de:       5d                      pop    %ebp
 80484df:       c3                      ret   

080484e0 <init_dummy>:
 80484e0:       55                      push   %ebp
 80484e1:       89 e5                   mov    %esp,%ebp
 80484e3:       83 ec 08                sub    $0x8,%esp
 80484e6:       89 ec                   mov    %ebp,%esp
 80484e8:       5d                      pop    %ebp
 80484e9:       c3                      ret   
 80484ea:       8d b6 00 00 00 00       lea    0x0(%esi),%esi
 [root@proxy ~/3]# readelf -a 4
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x8048360
  Start of program headers:          52 (bytes into file)
  Start of section headers:          10844 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         6
  Size of section headers:           40 (bytes)
  Number of section headers:         30
  Section header string table index: 27

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        080480f4 0000f4 000013 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            08048108 000108 000020 00   A  0   0  4
  [ 3] .hash             HASH            08048128 000128 000034 04   A  4   0  4
  [ 4] .dynsym           DYNSYM          0804815c 00015c 000080 10   A  5   1  4
  [ 5] .dynstr           STRTAB          080481dc 0001dc 000095 00   A  0   0  1
  [ 6] .gnu.version      VERSYM          08048272 000272 000010 02   A  4   0  2
  [ 7] .gnu.version_r    VERNEED         08048284 000284 000030 00   A  5   1  4
  [ 8] .rel.dyn          REL             080482b4 0002b4 000008 08   A  4   0  4
  [ 9] .rel.plt          REL             080482bc 0002bc 000028 08   A  4   b  4
  [10] .init             PROGBITS        080482e4 0002e4 000018 00  AX  0   0  4
  [11] .plt              PROGBITS        080482fc 0002fc 000060 04  AX  0   0  4
  [12] .text             PROGBITS        08048360 000360 000190 00  AX  0   0 16
  [13] .fini             PROGBITS        080484f0 0004f0 00001e 00  AX  0   0  4
  [14] .rodata           PROGBITS        08048510 000510 00001b 00   A  0   0  4
  [15] .data             PROGBITS        0804952c 00052c 000018 00  WA  0   0  4
  [16] .eh_frame         PROGBITS        08049544 000544 000004 00  WA  0   0  4
  [17] .ctors            PROGBITS        08049548 000548 000008 00  WA  0   0  4
  [18] .dtors            PROGBITS        08049550 000550 000008 00  WA  0   0  4
  [19] .got              PROGBITS        08049558 000558 000024 04  WA  0   0  4
  [20] .dynamic          DYNAMIC         0804957c 00057c 0000c8 08  WA  5   0  4
  [21] .sbss             PROGBITS        08049644 000644 000000 00   W  0   0  1
  [22] .bss              NOBITS          08049644 000644 000018 00  WA  0   0  4
  [23] .stab             PROGBITS        00000000 000644 0007a4 0c     24   0  4
  [24] .stabstr          STRTAB          00000000 000de8 001983 00      0   0  1
  [25] .comment          PROGBITS        00000000 00276b 00017a 00      0   0  1
  [26] .note             NOTE            00000000 0028e5 00008c 00      0   0  1
  [27] .shstrtab         STRTAB          00000000 002971 0000e9 00      0   0  1
  [28] .symtab           SYMTAB          00000000 002f0c 000540 10     29  3d  4
  [29] .strtab           STRTAB          00000000 00344c 000234 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x08048034 0x08048034 0x000c0 0x000c0 R E 0x4
  INTERP         0x0000f4 0x080480f4 0x080480f4 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /lib/ld-linux.so.2]
  LOAD           0x000000 0x08048000 0x08048000 0x0052b 0x0052b R E 0x1000
  LOAD           0x00052c 0x0804952c 0x0804952c 0x00118 0x00130 RW  0x1000
  DYNAMIC        0x00057c 0x0804957c 0x0804957c 0x000c8 0x000c8 RW  0x4
  NOTE           0x000108 0x08048108 0x08048108 0x00020 0x00020 R   0x4

 Section to Segment mapping:
  Segment Sections...
   00    
   01     .interp
   02     .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata
   03     .data .eh_frame .ctors .dtors .got .dynamic .bss
   04     .dynamic
   05     .note.ABI-tag

Dynamic segment at offset 0x57c contains 20 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x0000000c (INIT)                       0x80482e4
 0x0000000d (FINI)                       0x80484f0
 0x00000004 (HASH)                       0x8048128
 0x00000005 (STRTAB)                     0x80481dc
 0x00000006 (SYMTAB)                     0x804815c
 0x0000000a (STRSZ)                      127 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000015 (DEBUG)                      0x0
 0x00000003 (PLTGOT)                     0x8049558
 0x00000002 (PLTRELSZ)                   40 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x80482bc
 0x00000011 (REL)                        0x80482b4
 0x00000012 (RELSZ)                      8 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffe (VERNEED)                    0x8048284
 0x6fffffff (VERNEEDNUM)                 1
 0x6ffffff0 (VERSYM)                     0x8048272
 0x00000000 (NULL)                       0x0

Relocation section '.rel.dyn' at offset 0x2b4 contains 1 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  08049578  00706 R_386_GLOB_DAT        00000000  __gmon_start__          

Relocation section '.rel.plt' at offset 0x2bc contains 5 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  08049564  00107 R_386_JUMP_SLOT       0804830c  __register_frame_info   
  08049568  00207 R_386_JUMP_SLOT       0804831c  __deregister_frame_info 
  0804956c  00307 R_386_JUMP_SLOT       0804832c  __libc_start_main       
  08049570  00407 R_386_JUMP_SLOT       0804833c  printf                  
  08049574  00507 R_386_JUMP_SLOT       0804834c  __cxa_finalize          

There are no unwind sections in this file.

Symbol table '.dynsym' contains 8 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0804830c   129 FUNC    WEAK   DEFAULT  UND
__register_frame_info@GLIBC_2.0 (2)
     2: 0804831c   172 FUNC    WEAK   DEFAULT  UND
__deregister_frame_info@GLIBC_2.0 (2)
     3: 0804832c   202 FUNC    GLOBAL DEFAULT  UND
__libc_start_main@GLIBC_2.0 (2)
     4: 0804833c    50 FUNC    GLOBAL DEFAULT  UND
printf@GLIBC_2.0 (2)
     5: 0804834c   157 FUNC    WEAK   DEFAULT  UND
__cxa_finalize@GLIBC_2.1.3 (3)
     6: 08048514     4 OBJECT  GLOBAL DEFAULT   14 _IO_stdin_used
     7: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__

Symbol table '.symtab' contains 84 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 080480f4     0 SECTION LOCAL  DEFAULT    1
     2: 08048108     0 SECTION LOCAL  DEFAULT    2
     3: 08048128     0 SECTION LOCAL  DEFAULT    3
     4: 0804815c     0 SECTION LOCAL  DEFAULT    4
     5: 080481dc     0 SECTION LOCAL  DEFAULT    5
     6: 08048272     0 SECTION LOCAL  DEFAULT    6
     7: 08048284     0 SECTION LOCAL  DEFAULT    7
     8: 080482b4     0 SECTION LOCAL  DEFAULT    8
     9: 080482bc     0 SECTION LOCAL  DEFAULT    9
    10: 080482e4     0 SECTION LOCAL  DEFAULT   10
    11: 080482fc     0 SECTION LOCAL  DEFAULT   11
    12: 08048360     0 SECTION LOCAL  DEFAULT   12
    13: 080484f0     0 SECTION LOCAL  DEFAULT   13
    14: 08048510     0 SECTION LOCAL  DEFAULT   14
    15: 0804952c     0 SECTION LOCAL  DEFAULT   15
    16: 08049544     0 SECTION LOCAL  DEFAULT   16
    17: 08049548     0 SECTION LOCAL  DEFAULT   17
    18: 08049550     0 SECTION LOCAL  DEFAULT   18
    19: 08049558     0 SECTION LOCAL  DEFAULT   19
    20: 0804957c     0 SECTION LOCAL  DEFAULT   20
    21: 08049644     0 SECTION LOCAL  DEFAULT   21
    22: 08049644     0 SECTION LOCAL  DEFAULT   22
    23: 00000000     0 SECTION LOCAL  DEFAULT   23
    24: 00000000     0 SECTION LOCAL  DEFAULT   24
    25: 00000000     0 SECTION LOCAL  DEFAULT   25
    26: 00000000     0 SECTION LOCAL  DEFAULT   26
    27: 00000000     0 SECTION LOCAL  DEFAULT   27
    28: 00000000     0 SECTION LOCAL  DEFAULT   28
    29: 00000000     0 SECTION LOCAL  DEFAULT   29
    30: 00000000     0 FILE    LOCAL  DEFAULT  ABS initfini.c
    31: 08048384     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    32: 08048384     0 FUNC    LOCAL  DEFAULT   12 call_gmon_start
    33: 00000000     0 FILE    LOCAL  DEFAULT  ABS init.c
    34: 00000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    35: 080483b0     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    36: 08049534     0 OBJECT  LOCAL  DEFAULT   15 p.0
    37: 08049550     0 OBJECT  LOCAL  DEFAULT   18 __DTOR_LIST__
    38: 08049538     0 OBJECT  LOCAL  DEFAULT   15 completed.1
    39: 080483b0     0 FUNC    LOCAL  DEFAULT   12 __do_global_dtors_aux
    40: 08049544     0 OBJECT  LOCAL  DEFAULT   16 __EH_FRAME_BEGIN__
    41: 08048410     0 FUNC    LOCAL  DEFAULT   12 fini_dummy
    42: 08049644    24 OBJECT  LOCAL  DEFAULT   22 object.2
    43: 08048420     0 FUNC    LOCAL  DEFAULT   12 frame_dummy
    44: 08048450     0 FUNC    LOCAL  DEFAULT   12 init_dummy
    45: 0804953c     0 OBJECT  LOCAL  DEFAULT   15 force_to_data
    46: 08049548     0 OBJECT  LOCAL  DEFAULT   17 __CTOR_LIST__
    47: 00000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    48: 080484b0     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    49: 080484b0     0 FUNC    LOCAL  DEFAULT   12 __do_global_ctors_aux
    50: 0804954c     0 OBJECT  LOCAL  DEFAULT   17 __CTOR_END__
    51: 080484e0     0 FUNC    LOCAL  DEFAULT   12 init_dummy
    52: 08049544     0 OBJECT  LOCAL  DEFAULT   15 force_to_data
    53: 08049554     0 OBJECT  LOCAL  DEFAULT   18 __DTOR_END__
    54: 08049544     0 OBJECT  LOCAL  DEFAULT   16 __FRAME_END__
    55: 00000000     0 FILE    LOCAL  DEFAULT  ABS initfini.c
    56: 080484f0     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    57: 00000000     0 FILE    LOCAL  DEFAULT  ABS 1.c
    58: 08048460     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    59: 00000000     0 FILE    LOCAL  DEFAULT  ABS 3.c
    60: 08048498     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    61: 08049540     4 OBJECT  GLOBAL DEFAULT   15 t
    62: 0804957c     0 OBJECT  GLOBAL DEFAULT   20 _DYNAMIC
    63: 08048460    25 FUNC    GLOBAL DEFAULT   12 f
    64: 0804830c   129 FUNC    WEAK   DEFAULT  UND
__register_frame_info@@GLIBC_2.0
    65: 08048510     4 NOTYPE  GLOBAL DEFAULT   14 _fp_hw
    66: 0804847c    25 FUNC    GLOBAL DEFAULT   12 g
    67: 080482e4     0 FUNC    GLOBAL DEFAULT   10 _init
    68: 0804831c   172 FUNC    WEAK   DEFAULT  UND
__deregister_frame_info@@GLIBC_2.0
    69: 08048360     0 FUNC    GLOBAL DEFAULT   12 _start
    70: 08049644     0 OBJECT  GLOBAL DEFAULT  ABS __bss_start
    71: 08048498    23 FUNC    GLOBAL DEFAULT   12 main
    72: 0804832c   202 FUNC    GLOBAL DEFAULT  UND
__libc_start_main@@GLIBC_2.0
    73: 0804952c     0 NOTYPE  WEAK   DEFAULT   15 data_start
    74: 0804833c    50 FUNC    GLOBAL DEFAULT  UND
printf@@GLIBC_2.0
    75: 080484f0     0 FUNC    GLOBAL DEFAULT   13 _fini
    76: 0804953c     4 OBJECT  GLOBAL DEFAULT   15 s
    77: 0804834c   157 FUNC    WEAK   DEFAULT  UND
__cxa_finalize@@GLIBC_2.1.3
    78: 08049644     0 OBJECT  GLOBAL DEFAULT  ABS _edata
    79: 08049558     0 OBJECT  GLOBAL DEFAULT   19 _GLOBAL_OFFSET_TABLE_
    80: 0804965c     0 OBJECT  GLOBAL DEFAULT  ABS _end
    81: 08048514     4 OBJECT  GLOBAL DEFAULT   14 _IO_stdin_used
    82: 0804952c     0 NOTYPE  GLOBAL DEFAULT   15 __data_start
    83: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__

Histogram for bucket list length (total of 3 buckets):
 Length  Number     % of total  Coverage
      0  0          (  0.0%)
      1  1          ( 33.3%)     14.3%
      2  0          (  0.0%)     14.3%
      3  2          ( 66.7%)    100.0%

Version symbols section '.gnu.version' contains 8 entries:
 Addr: 0000000008048272  Offset: 0x000272  Link: 4 (.dynsym)
  000:   0 (*local*)       2 (GLIBC_2.0)     2 (GLIBC_2.0)     2 (GLIBC_2.0) 
  004:   2 (GLIBC_2.0)     3 (GLIBC_2.1.3)   1 (*global*)      0 (*local*)   

Version needs section '.gnu.version_r' contains 1 entries:
 Addr: 0x0000000008048284  Offset: 0x000284  Link to section: 5 (.dynstr)
  000000: Version: 1  File: libc.so.6  Cnt: 2
  0x0010: Name: GLIBC_2.1.3  Flags: none  Version: 3
  0x0020: Name: GLIBC_2.0  Flags: none  Version: 2

 

本节分析开始处:

s变量:  0000000b  00901 R_386_32              00000000  s         
可见009.symtab索引到的项为
   
     9: 00000000     4 OBJECT  GLOBAL DEFAULT    3 s
名字为s, st_value值为0,大小为4字节(指针变量),节索引为3,即在.data节中
.
 t
变量:
00000027  00a01 R_386_32              00000004  t
可见00a.symtab索引到的项为
   
    10: 00000004     4 OBJECT  GLOBAL DEFAULT    3 t     
名字为t, st_value值为4,大小为4字节(指针变量),节索引为3,即在.data节中
.
(
还可以发现符号表中f()g()的大小正好等于其代码长度, f大小25,代码长度0~0x18,...)

这里的值指的是该符号在所在的节中的偏移。

 [root@proxy ~/3]# objdump -sj .data 1.o

1.o:     file format elf32-i386

Contents of section .data:
 0000 00000000 0e000000                    ........ 
 
可见,s指向的值是0,t指向的值是0xe.这就是变量的st的值。
实际上,这两个值是指向.rodata节的偏移。

[root@proxy ~/3]# objdump -sj .rodata 1.o

1.o:     file format elf32-i386

Contents of section .rodata:
 0000 68656c6c 6f20576f 726c6421 0a006162  hello World!..ab
 0010 630a00                               c..          
 
 
s指向hello world!  t指向abc;  和程序中的意思一样。
                
再看看重定位中的偏移
Offset.
Relocation section '.rel.text' at offset 0x40c contains 4 entries:
  Offset         Info  Type                         Symbol's Value  Symbol's Name
  0000000b  00901 R_386_32              00000000            s                       
  00000010  00c02 R_386_PC32          00000000            printf                  
  00000027  00a01 R_386_32              00000004             t                       
  0000002c  00c02 R_386_PC32          00000000            printf
可以在objdump -dj .text 1.o中查找对应的位置
 
 
假设现在1.o要和另一个目标文件2.o连接成可执行文件,由于ld要合并相同的节,1.o中符号原来的地址变成无效地址了,因此1.o中的符号必须被重定位

R_386_32重定位方法:.data节被合并到新的地址处,假设为x, s的值就修正为x+0, t的值被修正为x+4(此时是地址,而不再是节偏移), 然后把该值写入Offset

参看3.o调用1.ofg
R_386_PC32
重定位方法: .text节被合并到新的地址处,假设为y,f的值被修正为y+0,g的值被修正为y+0x1c. 然后把该值和Offset之差写入Offset处。

因此就不难理解下面的意思了
R_386_NONE  0 none      none
R_386_32        1 word32  S + A
R_386_PC32  2 word32   S + A - P

S即修正后的符号值(变量地址)AOffset处值,POffset

[] =>

ELF File Format规范Relocation的下面一段中,

It first decides how to combine and locate the input files,

then updates the symbol values, and

finally performs the relocation.

可知所有符号都根据combination做了更新, 最后要做的是对引用符号的受影响的地方做重定位.

S是符号的更新后的相对于ModuleBasest_value; AAddent, Offset处的值; POffsetsection重定位后的地址。

注意,重定位类型为R_386_PC32, Addent0xFFFFFFFC, 这是因为相对跳转/调用指令的偏移是相对于跳转/偏移指令的下一条指令, Offset是指令的操作数开始, 所以需要减4, Addent-4. 一般针对i386体系是__x86.get_thunk_pc.bx/cx

最后, s, t, f, g都是模块内的全局符号,非位置无关时重定位后直接得到地址;而printf是其他模块的外部符号,需要dynamic link,所以其call call .plt entry,见下节。

重定位类型分析(2)

本节分析R_386_GOTPC, R_386_GOT32, R_386_GLOB_DATR_386_PLT32

 PIC位置无关代码,使用-fPIC参数就可以编译得到

 

附件1

1.c.txt

[root@proxy ~/3]# cat 1.c
#include <stdio.h>

char *s="hello World!\n";
char *t="abc\n";

void f()
{
printf(s);
}

void g()
{
printf(t);
}
[root@proxy ~/3]# gcc -fPIC -S 1.c       
[root@proxy ~/3]# cat 1.s
        .file   "1.c"
        .version        "01.01"
gcc2_compiled.:
.globl s
                .section        .rodata
.LC0:
        .string "hello World!\n"
.data
        .align 4
        .type    s,@object
        .size    s,4
s:
        .long   .LC0
.globl t
                .section        .rodata
.LC1:
        .string "abc\n"
.data
        .align 4
        .type    t,@object
        .size    t,4
t:
        .long   .LC1
.text
        .align 4
.globl f
        .type    f,@function
f:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        subl    $4, %esp
        call    .L3
.L3:
        popl    %ebx
        addl    $_GLOBAL_OFFSET_TABLE_+[.-.L3], %ebx
        subl    $12, %esp
        movl    s@GOT(%ebx), %eax
        pushl   (%eax)
        call    printf@PLT
        addl    $16, %esp
        movl    -4(%ebp), %ebx
        leave
        ret
.Lfe1:
        .size    f,.Lfe1-f
        .align 4
.globl g
        .type    g,@function
g:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        subl    $4, %esp
        call    .L5
.L5:
        popl    %ebx
        addl    $_GLOBAL_OFFSET_TABLE_+[.-.L5], %ebx
        subl    $12, %esp
        movl    t@GOT(%ebx), %eax
        pushl   (%eax)
        call    printf@PLT
        addl    $16, %esp
        movl    -4(%ebp), %ebx
        leave
        ret
.Lfe2:
        .size    g,.Lfe2-g
        .ident  "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-98)"

[]=>由于编译器的发展,汇编代码已经不再是大部分文章描述时的样子

xp010548@cnbjlx6066:~/test_elf$ cat 1.s

       .file "1.c"

.globl s

       .section       .rodata

.LC0:

       .string    "hello World!\n"

       .section       .data.rel.local,"aw",@progbits

       .align 8

       .type     s, @object

       .size       s, 8

s:

       .quad   .LC0

.globl t

       .section       .rodata

.LC1:

       .string    "abc\n"

       .section       .data.rel.local

       .align 8

       .type     t, @object

       .size       t, 8

t:

       .quad   .LC1

       .text

.globl f

       .type     f, @function

f:

.LFB0:

       .cfi_startproc

       pushq   %rbp

       .cfi_def_cfa_offset 16

       movq   %rsp, %rbp

       .cfi_offset 6, -16

       .cfi_def_cfa_register 6

       movq   s@GOTPCREL(%rip), %rax

       movq   (%rax), %rax

       movq   %rax, %rdi

       movl     $0, %eax

       call printf@PLT

       leave

       ret

       .cfi_endproc

.LFE0:

       .size       f, .-f

.globl g

       .type     g, @function

g:

.LFB1:

       .cfi_startproc

       pushq   %rbp

       .cfi_def_cfa_offset 16

       movq   %rsp, %rbp

       .cfi_offset 6, -16

       .cfi_def_cfa_register 6

       movq   t@GOTPCREL(%rip), %rax

       movq   (%rax), %rax

       movq   %rax, %rdi

       movl     $0, %eax

       call printf@PLT

       leave

       ret

       .cfi_endproc

.LFE1:

       .size       g, .-g

       .ident    "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"

       .section       .note.GNU-stack,"",@progbits

[root@proxy ~/3]# gcc -fPIC -c 1.c -o 1.o
[root@proxy ~/3]# objdump -dj .text 1.o

1.o:     file format elf32-i386

Disassembly of section .text:

00000000 <f>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   53                      push   %ebx
   4:   83 ec 04                sub    $0x4,%esp
   7:   e8 00 00 00 00          call   c <f+0xc>
   c:   5b                      pop    %ebx
   d:   81 c3 03 00 00 00       add    $0x3,%ebx
  13:   83 ec 0c                sub    $0xc,%esp
  16:   8b 83 00 00 00 00       mov    0x0(%ebx),%eax
  1c:   ff 30                   pushl  (%eax)
  1e:   e8 fc ff ff ff          call   1f <f+0x1f>
  23:   83 c4 10                add    $0x10,%esp
  26:   8b 5d fc                mov    0xfffffffc(%ebp),%ebx
  29:   c9                      leave 
  2a:   c3                      ret   
  2b:   90                      nop   

0000002c <g>:
  2c:   55                      push   %ebp
  2d:   89 e5                   mov    %esp,%ebp
  2f:   53                      push   %ebx
  30:   83 ec 04                sub    $0x4,%esp
  33:   e8 00 00 00 00          call   38 <g+0xc>
  38:   5b                      pop    %ebx
  39:   81 c3 03 00 00 00       add    $0x3,%ebx
  3f:   83 ec 0c                sub    $0xc,%esp
  42:   8b 83 00 00 00 00       mov    0x0(%ebx),%eax
  48:   ff 30                   pushl  (%eax)
  4a:   e8 fc ff ff ff          call   4b <g+0x1f>
  4f:   83 c4 10                add    $0x10,%esp
  52:   8b 5d fc                mov    0xfffffffc(%ebp),%ebx
  55:   c9                      leave 
  56:   c3                      ret   
  57:   90                      nop   
[root@proxy ~/3]# readelf -a 1.o
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          328 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         12
  Section header string table index: 9

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000058 00  AX  0   0  4
  [ 2] .rel.text         REL             00000000 000454 000030 08     10   1  4
  [ 3] .data             PROGBITS        00000000 00008c 000008 00  WA  0   0  4
  [ 4] .rel.data         REL             00000000 000484 000010 08     10   3  4
  [ 5] .bss              NOBITS          00000000 000094 000000 00  WA  0   0  4
  [ 6] .note             NOTE            00000000 000094 000014 00      0   0  1
  [ 7] .rodata           PROGBITS        00000000 0000a8 000013 00   A  0   0  1
  [ 8] .comment          PROGBITS        00000000 0000bb 000036 00      0   0  1
  [ 9] .shstrtab         STRTAB          00000000 0000f1 000057 00      0   0  1
  [10] .symtab           SYMTAB          00000000 000328 0000f0 10     11   9  4
  [11] .strtab           STRTAB          00000000 000418 000039 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There are no program headers in this file.

There is no dynamic segment in this file.

Relocation section '.rel.text' at offset 0x454 contains 6 entries:
  Offset    Info  Type                                Symbol's Value  Symbol's Name
  0000000f
  00c0a R_386_GOTPC           00000000  _GLOBAL_OFFSET_TABLE_   
  00000018  00903 R_386_GOT32           00000000  s                       
  0000001f  00d04 R_386_PLT32           00000000  printf                  
  0000003b  00c0a R_386_GOTPC           00000000  _GLOBAL_OFFSET_TABLE_   
  00000044  00a03 R_386_GOT32           00000004  t                       
  0000004b  00d04 R_386_PLT32           00000000  printf   
               

Relocation section '.rel.data' at offset 0x484 contains 2 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  00000000  00601 R_386_32              00000000  .rodata                 
  00000004  00601 R_386_32              00000000  .rodata                 

There are no unwind sections in this file.

Symbol table '.symtab' contains 15 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS 1.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    5
     5: 00000000     0 NOTYPE  LOCAL  DEFAULT    1 gcc2_compiled.
     6: 00000000     0 SECTION LOCAL  DEFAULT    7
     7: 00000000     0 SECTION LOCAL  DEFAULT    6
     8: 00000000     0 SECTION LOCAL  DEFAULT    8
     9: 00000000     4 OBJECT  GLOBAL DEFAULT    3 s
    10: 00000004     4 OBJECT  GLOBAL DEFAULT    3 t
    11: 00000000    43 FUNC    GLOBAL DEFAULT    1 f
    12: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _GLOBAL_OFFSET_TABLE_
    13: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
    14: 0000002c    43 FUNC    GLOBAL DEFAULT    1 g

No version information found in this file.

 
 
附件2

4.out.txt

 [root@proxy ~/3]# gcc 1.o 3.o -o 4
[root@proxy ~/3]# ./4
hello World!
abc
[root@proxy ~/3]# objdump -dj .text 4

4:     file format elf32-i386

Disassembly of section .text:

080483a0 <_start>:
 80483a0:       31 ed                   xor    %ebp,%ebp
 80483a2:       5e                      pop    %esi
 80483a3:       89 e1                   mov    %esp,%ecx
 80483a5:       83 e4 f0                and    $0xfffffff0,%esp
 80483a8:       50                      push   %eax
 80483a9:       54                      push   %esp
 80483aa:       52                      push   %edx
 80483ab:       68 50 85 04 08          push   $0x8048550
 80483b0:       68 24 83 04 08          push   $0x8048324
 80483b5:       51                      push   %ecx
 80483b6:       56                      push   %esi
 80483b7:       68 f8 84 04 08          push   $0x80484f8
 80483bc:       e8 ab ff ff ff          call   804836c <_init+0x48>
 80483c1:       f4                      hlt   
 80483c2:       89 f6                   mov    %esi,%esi

080483c4 <call_gmon_start>:
 80483c4:       55                      push   %ebp
 80483c5:       89 e5                   mov    %esp,%ebp
 80483c7:       53                      push   %ebx
 80483c8:       50                      push   %eax
 80483c9:       e8 00 00 00 00          call   80483ce <call_gmon_start+0xa>
 80483ce:       5b                      pop    %ebx
 80483cf:       81 c3 ea 11 00 00       add    $0x11ea,%ebx
 80483d5:       8b 83 28 00 00 00       mov    0x28(%ebx),%eax
 80483db:       85 c0                   test   %eax,%eax
 80483dd:       74 02                   je     80483e1 <call_gmon_start+0x1d>
 80483df:       ff d0                   call   *%eax
 80483e1:       8b 5d fc                mov    0xfffffffc(%ebp),%ebx
 80483e4:       c9                      leave 
 80483e5:       c3                      ret   
 80483e6:       89 f6                   mov    %esi,%esi
 80483e8:       90                      nop   
 80483e9:       90                      nop   
 80483ea:       90                      nop   
 80483eb:       90                      nop   
 80483ec:       90                      nop   
 80483ed:       90                      nop   
 80483ee:       90                      nop   
 80483ef:       90                      nop   

080483f0 <__do_global_dtors_aux>:
 80483f0:       55                      push   %ebp
 80483f1:       89 e5                   mov    %esp,%ebp
 80483f3:       83 ec 08                sub    $0x8,%esp
 80483f6:       8b 15 98 95 04 08       mov    0x8049598,%edx
 80483fc:       85 d2                   test   %edx,%edx
 80483fe:       75 49                   jne    8048449 <__do_global_dtors_aux+0x59>
 8048400:       8b 15 94 95 04 08       mov    0x8049594,%edx
 8048406:       8b 02                   mov    (%edx),%eax
 8048408:       85 c0                   test   %eax,%eax
 804840a:       74 1a                   je     8048426 <__do_global_dtors_aux+0x36>
 804840c:       8d 74 26 00             lea    0x0(%esi,1),%esi
 8048410:       8d 42 04                lea    0x4(%edx),%eax
 8048413:       a3 94 95 04 08          mov    %eax,0x8049594
 8048418:       ff 12                   call   *(%edx)
 804841a:       8b 15 94 95 04 08       mov    0x8049594,%edx
 8048420:       8b 0a                   mov    (%edx),%ecx
 8048422:       85 c9                   test   %ecx,%ecx
 8048424:       75 ea                   jne    8048410 <__do_global_dtors_aux+0x20>
 8048426:       b8 5c 83 04 08          mov    $0x804835c,%eax
 804842b:       85 c0                   test   %eax,%eax
 804842d:       74 10                   je     804843f <__do_global_dtors_aux+0x4f>
 804842f:       83 ec 0c                sub    $0xc,%esp
 8048432:       68 a4 95 04 08          push   $0x80495a4
 8048437:       e8 20 ff ff ff          call   804835c <_init+0x38>
 804843c:       83 c4 10                add    $0x10,%esp
 804843f:       b8 01 00 00 00          mov    $0x1,%eax
 8048444:       a3 98 95 04 08          mov    %eax,0x8049598
 8048449:       89 ec                   mov    %ebp,%esp
 804844b:       5d                      pop    %ebp
 804844c:       c3                      ret   
 804844d:       8d 76 00                lea    0x0(%esi),%esi

08048450 <fini_dummy>:
 8048450:       55                      push   %ebp
 8048451:       89 e5                   mov    %esp,%ebp
 8048453:       83 ec 08                sub    $0x8,%esp
 8048456:       89 ec                   mov    %ebp,%esp
 8048458:       5d                      pop    %ebp
 8048459:       c3                      ret   
 804845a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi

08048460 <frame_dummy>:
 8048460:       55                      push   %ebp
 8048461:       b8 4c 83 04 08          mov    $0x804834c,%eax
 8048466:       89 e5                   mov    %esp,%ebp
 8048468:       83 ec 08                sub    $0x8,%esp
 804846b:       85 c0                   test   %eax,%eax
 804846d:       74 15                   je     8048484 <frame_dummy+0x24>
 804846f:       83 ec 08                sub    $0x8,%esp
 8048472:       68 ac 96 04 08          push   $0x80496ac
 8048477:       68 a4 95 04 08          push   $0x80495a4
 804847c:       e8 cb fe ff ff          call   804834c <_init+0x28>
 8048481:       83 c4 10                add    $0x10,%esp
 8048484:       89 ec                   mov    %ebp,%esp
 8048486:       5d                      pop    %ebp
 8048487:       c3                      ret   
 8048488:       90                      nop   
 8048489:       8d b4 26 00 00 00 00    lea    0x0(%esi,1),%esi

08048490 <init_dummy>:
 8048490:       55                      push   %ebp
 8048491:       89 e5                   mov    %esp,%ebp
 8048493:       83 ec 08                sub    $0x8,%esp
 8048496:       89 ec                   mov    %ebp,%esp
 8048498:       5d                      pop    %ebp
 8048499:       c3                      ret   
 804849a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi

080484a0 <f>:
 80484a0:       55                      push   %ebp
 80484a1:       89 e5                   mov    %esp,%ebp
 80484a3:       53                      push   %ebx
 80484a4:       83 ec 04                sub    $0x4,%esp
 80484a7:       e8 00 00 00 00          call   80484ac <f+0xc>
 80484ac:       5b                      pop    %ebx
 80484ad:       81 c3 0c 11 00 00       add    $0x110c,%ebx
 80484b3:       83 ec 0c                sub    $0xc,%esp
 80484b6:       8b 83 24 00 00 00       mov    0x24(%ebx),%eax
 80484bc:       ff 30                   pushl  (%eax)
 80484be:       e8 b9 fe ff ff          call   804837c <_init+0x58>
 80484c3:       83 c4 10                add    $0x10,%esp
 80484c6:       8b 5d fc                mov    0xfffffffc(%ebp),%ebx
 80484c9:       c9                      leave 
 80484ca:       c3                      ret   
 80484cb:       90                      nop   

080484cc <g>:
 80484cc:       55                      push   %ebp
 80484cd:       89 e5                   mov    %esp,%ebp
 80484cf:       53                      push   %ebx
 80484d0:       83 ec 04                sub    $0x4,%esp
 80484d3:       e8 00 00 00 00          call   80484d8 <g+0xc>
 80484d8:       5b                      pop    %ebx
 80484d9:       81 c3 e0 10 00 00       add    $0x10e0,%ebx
 80484df:       83 ec 0c                sub    $0xc,%esp
 80484e2:       8b 83 20 00 00 00       mov    0x20(%ebx),%eax
 80484e8:       ff 30                   pushl  (%eax)
 80484ea:       e8 8d fe ff ff          call   804837c <_init+0x58>
 80484ef:       83 c4 10                add    $0x10,%esp
 80484f2:       8b 5d fc                mov    0xfffffffc(%ebp),%ebx
 80484f5:       c9                      leave 
 80484f6:       c3                      ret   
 80484f7:       90                      nop   

080484f8 <main>:
 80484f8:       55                      push   %ebp
 80484f9:       89 e5                   mov    %esp,%ebp
 80484fb:       83 ec 08                sub    $0x8,%esp
 80484fe:       e8 9d ff ff ff          call   80484a0 <f>
 8048503:       e8 c4 ff ff ff          call   80484cc <g>
 8048508:       b8 00 00 00 00          mov    $0x0,%eax
 804850d:       c9                      leave 
 804850e:       c3                      ret   
 804850f:       90                      nop   

08048510 <__do_global_ctors_aux>:
 8048510:       55                      push   %ebp
 8048511:       89 e5                   mov    %esp,%ebp
 8048513:       53                      push   %ebx
 8048514:       83 ec 04                sub    $0x4,%esp
 8048517:       a1 a8 95 04 08          mov    0x80495a8,%eax
 804851c:       bb a8 95 04 08          mov    $0x80495a8,%ebx
 8048521:       83 f8 ff                cmp    $0xffffffff,%eax
 8048524:       74 16                   je     804853c <__do_global_ctors_aux+0x2c>
 8048526:       8d 76 00                lea    0x0(%esi),%esi
 8048529:       8d bc 27 00 00 00 00    lea    0x0(%edi,1),%edi
 8048530:       83 eb 04                sub    $0x4,%ebx
 8048533:       ff d0                   call   *%eax
 8048535:       8b 03                   mov    (%ebx),%eax
 8048537:       83 f8 ff                cmp    $0xffffffff,%eax
 804853a:       75 f4                   jne    8048530 <__do_global_ctors_aux+0x20>
 804853c:       58                      pop    %eax
 804853d:       5b                      pop    %ebx
 804853e:       5d                      pop    %ebp
 804853f:       c3                      ret   

08048540 <init_dummy>:
 8048540:       55                      push   %ebp
 8048541:       89 e5                   mov    %esp,%ebp
 8048543:       83 ec 08                sub    $0x8,%esp
 8048546:       89 ec                   mov    %ebp,%esp
 8048548:       5d                      pop    %ebp
 8048549:       c3                      ret   
 804854a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi
[root@proxy ~/3]# readelf -a 4
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x80483a0
  Start of program headers:          52 (bytes into file)
  Start of section headers:          10948 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         6
  Size of section headers:           40 (bytes)
  Number of section headers:         30
  Section header string table index: 27

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        080480f4 0000f4 000013 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            08048108 000108 000020 00   A  0   0  4
  [ 3] .hash             HASH            08048128 000128 00003c 04   A  4   0  4
  [ 4] .dynsym           DYNSYM          08048164 000164 0000a0 10   A  5   1  4
  [ 5] .dynstr           STRTAB          08048204 000204 000099 00   A  0   0  1
  [ 6] .gnu.version      VERSYM          0804829e 00029e 000014 02   A  4   0  2
  [ 7] .gnu.version_r    VERNEED         080482b4 0002b4 000030 00   A  5   1  4
  [ 8] .rel.dyn          REL             080482e4 0002e4 000018 08   A  4   0  4
  [ 9] .rel.plt          REL             080482fc 0002fc 000028 08   A  4   b  4
  [10] .init             PROGBITS        08048324 000324 000018 00  AX  0   0  4
  [11] .plt              PROGBITS        0804833c 00033c 000060 04  AX  0   0  4
  [12] .text             PROGBITS        080483a0 0003a0 0001b0 00  AX  0   0 16
  [13] .fini             PROGBITS        08048550 000550 00001e 00  AX  0   0  4
  [14] .rodata           PROGBITS        08048570 000570 00001b 00   A  0   0  4
  [15] .data             PROGBITS        0804958c 00058c 000018 00  WA  0   0  4
  [16] .eh_frame         PROGBITS        080495a4 0005a4 000004 00  WA  0   0  4
  [17] .ctors            PROGBITS        080495a8 0005a8 000008 00  WA  0   0  4
  [18] .dtors            PROGBITS        080495b0 0005b0 000008 00  WA  0   0  4
  [19] .got              PROGBITS        080495b8 0005b8 00002c 04  WA  0   0  4
  [20] .dynamic          DYNAMIC         080495e4 0005e4 0000c8 08  WA  5   0  4
  [21] .sbss             PROGBITS        080496ac 0006ac 000000 00   W  0   0  1
  [22] .bss              NOBITS          080496ac 0006ac 000018 00  WA  0   0  4
  [23] .stab             PROGBITS        00000000 0006ac 0007a4 0c     24   0  4
  [24] .stabstr          STRTAB          00000000 000e50 001983 00      0   0  1
  [25] .comment          PROGBITS        00000000 0027d3 00017a 00      0   0  1
  [26] .note             NOTE            00000000 00294d 00008c 00      0   0  1
  [27] .shstrtab         STRTAB          00000000 0029d9 0000e9 00      0   0  1
  [28] .symtab           SYMTAB          00000000 002f74 000540 10     29  3d  4
  [29] .strtab           STRTAB          00000000 0034b4 000234 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x08048034 0x08048034 0x000c0 0x000c0 R E 0x4
  INTERP         0x0000f4 0x080480f4 0x080480f4 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /lib/ld-linux.so.2]
  LOAD           0x000000 0x08048000 0x08048000 0x0058b 0x0058b R E 0x1000
  LOAD           0x00058c 0x0804958c 0x0804958c 0x00120 0x00138 RW  0x1000
  DYNAMIC        0x0005e4 0x080495e4 0x080495e4 0x000c8 0x000c8 RW  0x4
  NOTE           0x000108 0x08048108 0x08048108 0x00020 0x00020 R   0x4

 Section to Segment mapping:
  Segment Sections...
   00    
   01     .interp
   02     .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata
   03     .data .eh_frame .ctors .dtors .got .dynamic .bss
   04     .dynamic
   05     .note.ABI-tag

Dynamic segment at offset 0x5e4 contains 20 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x0000000c (INIT)                       0x8048324
 0x0000000d (FINI)                       0x8048550
 0x00000004 (HASH)                       0x8048128
 0x00000005 (STRTAB)                     0x8048204
 0x00000006 (SYMTAB)                     0x8048164
 0x0000000a (STRSZ)                      131 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000015 (DEBUG)                      0x0
 0x00000003 (PLTGOT)                     0x80495b8
 0x00000002 (PLTRELSZ)                   40 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x80482fc
 0x00000011 (REL)                        0x80482e4
 0x00000012 (RELSZ)                      24 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffe (VERNEED)                    0x80482b4
 0x6fffffff (VERNEEDNUM)                 1
 0x6ffffff0 (VERSYM)                     0x804829e
 0x00000000 (NULL)                       0x0

Relocation section '.rel.dyn' at offset 0x2e4 contains 3 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  080495d8  00106 R_386_GLOB_DAT        080495a0  t                       
  080495dc  00606 R_386_GLOB_DAT        0804959c  s                       
  080495e0  00906 R_386_GLOB_DAT        00000000  __gmon_start__          

Relocation section '.rel.plt' at offset 0x2fc contains 5 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  080495c4  00207 R_386_JUMP_SLOT       0804834c  __register_frame_info   
  080495c8  00307 R_386_JUMP_SLOT       0804835c  __deregister_frame_info 
  080495cc  00407 R_386_JUMP_SLOT       0804836c  __libc_start_main       
  080495d0  00507 R_386_JUMP_SLOT       0804837c  printf                  
  080495d4  00707 R_386_JUMP_SLOT       0804838c  __cxa_finalize          

There are no unwind sections in this file.

Symbol table '.dynsym' contains 10 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 080495a0     4 OBJECT  GLOBAL DEFAULT   15 t
     2: 0804834c   129 FUNC    WEAK   DEFAULT  UND
__register_frame_info@GLIBC_2.0 (2)
     3: 0804835c   172 FUNC    WEAK   DEFAULT  UND
__deregister_frame_info@GLIBC_2.0 (2)
     4: 0804836c   202 FUNC    GLOBAL DEFAULT  UND
__libc_start_main@GLIBC_2.0 (2)
     5: 0804837c    50 FUNC    GLOBAL DEFAULT  UND
printf@GLIBC_2.0 (2)
     6: 0804959c     4 OBJECT  GLOBAL DEFAULT   15 s
     7: 0804838c   157 FUNC    WEAK   DEFAULT  UND
__cxa_finalize@GLIBC_2.1.3 (3)
     8: 08048574     4 OBJECT  GLOBAL DEFAULT   14 _IO_stdin_used
     9: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__

Symbol table '.symtab' contains 84 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 080480f4     0 SECTION LOCAL  DEFAULT    1
     2: 08048108     0 SECTION LOCAL  DEFAULT    2
     3: 08048128     0 SECTION LOCAL  DEFAULT    3
     4: 08048164     0 SECTION LOCAL  DEFAULT    4
     5: 08048204     0 SECTION LOCAL  DEFAULT    5
     6: 0804829e     0 SECTION LOCAL  DEFAULT    6
     7: 080482b4     0 SECTION LOCAL  DEFAULT    7
     8: 080482e4     0 SECTION LOCAL  DEFAULT    8
     9: 080482fc     0 SECTION LOCAL  DEFAULT    9
    10: 08048324     0 SECTION LOCAL  DEFAULT   10
    11: 0804833c     0 SECTION LOCAL  DEFAULT   11
    12: 080483a0     0 SECTION LOCAL  DEFAULT   12
    13: 08048550     0 SECTION LOCAL  DEFAULT   13
    14: 08048570     0 SECTION LOCAL  DEFAULT   14
    15: 0804958c     0 SECTION LOCAL  DEFAULT   15
    16: 080495a4     0 SECTION LOCAL  DEFAULT   16
    17: 080495a8     0 SECTION LOCAL  DEFAULT   17
    18: 080495b0     0 SECTION LOCAL  DEFAULT   18
    19: 080495b8     0 SECTION LOCAL  DEFAULT   19
    20: 080495e4     0 SECTION LOCAL  DEFAULT   20
    21: 080496ac     0 SECTION LOCAL  DEFAULT   21
    22: 080496ac     0 SECTION LOCAL  DEFAULT   22
    23: 00000000     0 SECTION LOCAL  DEFAULT   23
    24: 00000000     0 SECTION LOCAL  DEFAULT   24
    25: 00000000     0 SECTION LOCAL  DEFAULT   25
    26: 00000000     0 SECTION LOCAL  DEFAULT   26
    27: 00000000     0 SECTION LOCAL  DEFAULT   27
    28: 00000000     0 SECTION LOCAL  DEFAULT   28
    29: 00000000     0 SECTION LOCAL  DEFAULT   29
    30: 00000000     0 FILE    LOCAL  DEFAULT  ABS initfini.c
    31: 080483c4     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    32: 080483c4     0 FUNC    LOCAL  DEFAULT   12 call_gmon_start
    33: 00000000     0 FILE    LOCAL  DEFAULT  ABS init.c
    34: 00000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    35: 080483f0     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    36: 08049594     0 OBJECT  LOCAL  DEFAULT   15 p.0
    37: 080495b0     0 OBJECT  LOCAL  DEFAULT   18 __DTOR_LIST__
    38: 08049598     0 OBJECT  LOCAL  DEFAULT   15 completed.1
    39: 080483f0     0 FUNC    LOCAL  DEFAULT   12 __do_global_dtors_aux
    40: 080495a4     0 OBJECT  LOCAL  DEFAULT   16 __EH_FRAME_BEGIN__
    41: 08048450     0 FUNC    LOCAL  DEFAULT   12 fini_dummy
    42: 080496ac    24 OBJECT  LOCAL  DEFAULT   22 object.2
    43: 08048460     0 FUNC    LOCAL  DEFAULT   12 frame_dummy
    44: 08048490     0 FUNC    LOCAL  DEFAULT   12 init_dummy
    45: 0804959c     0 OBJECT  LOCAL  DEFAULT   15 force_to_data
    46: 080495a8     0 OBJECT  LOCAL  DEFAULT   17 __CTOR_LIST__
    47: 00000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    48: 08048510     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    49: 08048510     0 FUNC    LOCAL  DEFAULT   12 __do_global_ctors_aux
    50: 080495ac     0 OBJECT  LOCAL  DEFAULT   17 __CTOR_END__
    51: 08048540     0 FUNC    LOCAL  DEFAULT   12 init_dummy
    52: 080495a4     0 OBJECT  LOCAL  DEFAULT   15 force_to_data
    53: 080495b4     0 OBJECT  LOCAL  DEFAULT   18 __DTOR_END__
    54: 080495a4     0 OBJECT  LOCAL  DEFAULT   16 __FRAME_END__
    55: 00000000     0 FILE    LOCAL  DEFAULT  ABS initfini.c
    56: 08048550     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    57: 00000000     0 FILE    LOCAL  DEFAULT  ABS 1.c
    58: 080484a0     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    59: 00000000     0 FILE    LOCAL  DEFAULT  ABS 3.c
    60: 080484f8     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    61: 080495a0     4 OBJECT  GLOBAL DEFAULT   15 t
    62: 080495e4     0 OBJECT  GLOBAL DEFAULT   20 _DYNAMIC
    63: 080484a0    43 FUNC    GLOBAL DEFAULT   12 f
    64: 0804834c   129 FUNC    WEAK   DEFAULT  UND
__register_frame_info@@GLIBC_2.0
    65: 08048570     4 NOTYPE  GLOBAL DEFAULT   14 _fp_hw
    66: 080484cc    43 FUNC    GLOBAL DEFAULT   12 g
    67: 08048324     0 FUNC    GLOBAL DEFAULT   10 _init
    68: 0804835c   172 FUNC    WEAK   DEFAULT  UND
__deregister_frame_info@@GLIBC_2.0
    69: 080483a0     0 FUNC    GLOBAL DEFAULT   12 _start
    70: 080496ac     0 OBJECT  GLOBAL DEFAULT  ABS __bss_start
    71: 080484f8    23 FUNC    GLOBAL DEFAULT   12 main
    72: 0804836c   202 FUNC    GLOBAL DEFAULT  UND
__libc_start_main@@GLIBC_2.0
    73: 0804958c     0 NOTYPE  WEAK   DEFAULT   15 data_start
    74: 0804837c    50 FUNC    GLOBAL DEFAULT  UND
printf@@GLIBC_2.0
    75: 08048550     0 FUNC    GLOBAL DEFAULT   13 _fini
    76: 0804959c     4 OBJECT  GLOBAL DEFAULT   15 s
    77: 0804838c   157 FUNC    WEAK   DEFAULT  UND
__cxa_finalize@@GLIBC_2.1.3
    78: 080496ac     0 OBJECT  GLOBAL DEFAULT  ABS _edata
    79: 080495b8     0 OBJECT  GLOBAL DEFAULT   19 _GLOBAL_OFFSET_TABLE_
    80: 080496c4     0 OBJECT  GLOBAL DEFAULT  ABS _end
    81: 08048574     4 OBJECT  GLOBAL DEFAULT   14 _IO_stdin_used
    82: 0804958c     0 NOTYPE  GLOBAL DEFAULT   15 __data_start
    83: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__

Histogram for bucket list length (total of 3 buckets):
 Length  Number     % of total  Coverage
      0  0          (  0.0%)
      1  1          ( 33.3%)     11.1%
      2  0          (  0.0%)     11.1%
      3  0          (  0.0%)     11.1%
      4  2          ( 66.7%)    100.0%

Version symbols section '.gnu.version' contains 10 entries:
 Addr: 000000000804829e  Offset: 0x00029e  Link: 4 (.dynsym)
  000:   0 (*local*)       1 (*global*)      2 (GLIBC_2.0)     2 (GLIBC_2.0) 
  004:   2 (GLIBC_2.0)     2 (GLIBC_2.0)     1 (*global*)      3 (GLIBC_2.1.3)
  008:   1 (*global*)      0 (*local*)   

Version needs section '.gnu.version_r' contains 1 entries:
 Addr: 0x00000000080482b4  Offset: 0x0002b4  Link to section: 5 (.dynstr)
  000000: Version: 1  File: libc.so.6  Cnt: 2
  0x0010: Name: GLIBC_2.1.3  Flags: none  Version: 3
  0x0020: Name: GLIBC_2.0  Flags: none  Version: 2

 

本节分析开始处:

R_386_GOTPC

[]=>通常是_GLOBAL_OFFSET_TABLE_.

看看第一个重定位符号的重定位信息(此处是引用s@GOT的汇编指令)

 在汇编源文件中:

        call    .L3 //.L3地址压栈
.L3:
        popl    %ebx //.L3
地址弹到ebx
        addl    $_GLOBAL_OFFSET_TABLE_+[.-.L3], %ebx //计算got的地址到ebx

        subl    $12, %esp
        movl    s@GOT(%ebx), %eax

[]=>

在此处直接解释这段汇编代码的意义, 列在此处,后面能更方便说明原文的错误.

首先call/popl组合是得到运行时.L3标号的PC, 这是自定位程序典型的汇编代码使用技巧;

[.-.L3]是编译时当前指令和.L3的偏移, 此处是popl指令的长度,1;

$_GLOBAL_OFFSET_TABLE_符号的意义是当前指令到GOT表的偏移, 此处是addl指令到GOT的偏移, 生成目标文件时没有GOT, 这个是需要链接时才能确定的;

所以$_GLOBAL_OFFSET_TABLE_加上[.-.L3]构成[.L3]popl指令到GOT的偏移, 而加上运行时[.L3]PC即得到运行时GOT的地址.

在目标文件中:

   7:   e8 00 00 00 00          call   c <f+0xc>
   c:   5b                      pop    %ebx
   d:   81 c3 03 00 00 00       add    $0x3, %ebx

  13:   83 ec 0c                sub    $0xc,%esp
  16:   8b 83 00 00 00 00       mov    0x0(%ebx),%eax
[
]=>

此处add指令中的3是重定位时的Addent, 当然并不是[.-.L3], 而是重定位Offset运行时的地址与%ebx的偏差, 是编译器做为Addent记录在这儿, 并不是编译时$_GLOBAL_OFFSET_TABLE_+[.-.L3]的值, 因为编译目标文件时还没有GOT, $_GLOBAL_OFFSET_TABLE_符号还根本没有意义. 此处先解释到这个程度.

.rel.text中的项:

  0000000f  00c0a R_386_GOTPC           00000000  _GLOBAL_OFFSET_TABLE_   

 在链接生成的可执行文件中:

查看ld后的结果4.out.txt中的.got section,  got地址是080495b8
  [19] .got              PROGBITS        080495b8 0005b8 00002c 04  WA  0   0  4
 

80484a7:       e8 00 00 00 00          call   80484ac <f+0xc>
80484ac:       5b                      pop    %ebx          ; ebx<=0x80484ac
80484ad:       81 c3 0c 11 00 00       add    $0x110c,%ebx ; ebx
got地址
80484b3:       83 ec 0c                sub    $0xc,%esp
80484b6:       8b 83 24 00 00 00       mov    0x24(%ebx),%eax
80484bc:       ff 30                   pushl  (%eax)

 

执行pop    %ebx,ebx中的值为80484ac
执行add    $0x110c,%ebx后,ebx中的值是80495B8,正是got的地址

那么0x110c是怎么来的呢?
0x110c-3=0x1109,修正处的偏移是0x80484af,0x80484af+0x1109=0x80495b8,正是.got地址(0x80495b8) 所以0x110c=0x80495b8-0x0x80484af+3,即修正值为got-Offset+[.-.L3].

 

因此R_386_GOTPC的重定位方法是:

指示连接器将GOT的地址和Offset的差加上原值写入Offset处。
前面的[.-.L3]=3,5b 81 c3这几个字节的长度,因此[.-.L3]代表指令中操作数所在地址和.L3差值,而一般的.代表指令的地址.

[]=>

上面的一段中是有错误的, 首先(.-.L3)的值是1而不是3!  在汇编中,‘.’总是指当前汇编指令的PC, 而绝对不会是操作数的偏移.

上面中描述中0x110c=0x80495b8-0x0x80484af+3和指示连接器将GOT的地址和Offset的差加上原值写入Offset, 是正确的; 但是其余的却不对. 正确的对于重定位类型为R_386_GOTPC的修正是GOT+A-P; 其中GOTGOT基址, AAddent, POffset偏移.

此处使用AddentOffset可以精确地得到[.L3]的地址, 而将Addent由编译器记录在Offset, 链接时直接使用而不需要再繁琐地根据不同指令不同指令操作码长度进行修正, 比如leal $_GLOBAL_OFFSET_TABLE_+[.-.L3], %eax指令的操作码可能是1字节, 那么此时Addent就是2, 这样就避免了链接时查看指令, 而链接时需要查看指令不仅仅是没有效率, 在非执行时查看指令的设计(调试器除外)是相当拙劣的!

 

R_386_GOT32R_386_GLOB_DAT

R_386_GOT32 This relocation type computes the distance from the base of the global offset table to the symbol’s global offset table entry. It additionally instructs the link editor to build a global offset table.

在目标文件中:

        movl    s@GOT(%ebx), %eax
        pushl   (%eax)
         
  16:   8b 83 00 00 00 00       mov    0x0(%ebx),%eax
  1c:   ff 30                   pushl  (%eax)

.rel.text           
  00000018  00903 R_386_GOT32           00000000  s
 
查看ld后的结果4.out.txt
 80484b6:       8b 83 24 00 00 00       mov    0x24(%ebx),%eax
 80484bc:       ff 30                   pushl  (%eax)
 
got+0x24=0x80495DC

[]=>

使用GOT访问全局符号; 这样, 在访问GOT之前的代码都是位置无关的代码! 无需再多言.

[root@proxy ~/3]# objdump -sj .got 4

4:     file format elf32-i386

Contents of section .got:
 80495b8 e4950408 00000000 00000000 52830408  ............R...
 80495c8 62830408 72830408 82830408 92830408  b...r...........
 80495d8 00000000 00000000 00000000           ............  

可见该地址在got(GOT+s@GOT),这里该地址的值为全0. 关于R_386_GOT32就此结束

下面看R_386_GLOB_DAT.

查看4.out.txt的重定位节(exe/outso文件中只有.rel.dyn.rel.plt).

.rel.dyn:
  080495dc  00606 R_386_GLOB_DAT        0804959c  s 
重定位P(r_offset计算出)0x080495dc(GOT+s@GOT)处的值为0x0804959c(即为变量s的地址), 应该在.data中.

[评]=>

此项为.rel.got项, 较新的编译器中已经没有了.rel.got节区,对于全局变量的放在了.rel.dyn中; 对于函数的放在了.rel.plt中.

[评]=>

注意此时针对数据的重定位类型为R_386_GLOB_DAT的项, 在可执行文件或共享库文件中, 是在.rel.dyn; 与针对函数的重定位的R_386_JUMP_SLOT对比看.

ELF File Format, 针对R_386_GLOB_DAT重定位项计算方法是S, Symbol地址直接写入GOT.

下面与R_386_GLOB_DAT无关了, 即与变量的引用无关了; 再多追踪一点变量的值.

[root@proxy ~/3]# objdump -sj .data 4  

4:     file format elf32-i386

Contents of section .data:
 804958c 00000000 00000000 b4950408 00000000  ................
 804959c 78850408 86850408                    x.......      

值为08045878, 即为变量s的值,应该指向.rodata

[root@proxy ~/3]# objdump -sj .rodata 4

4:     file format elf32-i386

Contents of section .rodata:
 8048570 03000000 01000200 68656c6c 6f20576f  ........hello Wo
 8048580 726c6421 0a006162 630a00             rld!..abc..   

果然, 08045878处的值就是字符串hello world!

因此

R_386_GOT32的重定位方法是: 指示连接器将符号在GOT中的地址和GOT的地址差值写入Offset处。
R_386_GLOB_DAT的重定位方法是: 指示连接器将符号的值写入Offset处。

[]=>

此处是分两个阶段的, 更精确地说:

R_386_GOT32是指示link editor将符号在GOT中的地址和GOT的地址差值写入Offset处。
R_386_GLOB_DAT
是指示dynamic linker动态解析变量符号的地址写入Offset, Offset处为变量对应的GOT项处。

R_386_PLT32

R_386_PLT32 This relocation type computes the address of the symbol’s procedure linkage table entry and additionally instructs the link editor to build a procedure linkage table.

在目标文件中:

        call    printf@PLT
        1e:   e8 fc ff ff ff          call   1f <f+0x1f>

.rel.text:

  0000001f  00d04 R_386_PLT32           00000000  printf

在可执行文件中, 查看4.out.txt
 80484be:       e8 b9 fe ff ff          call   804837c <_init+0x58>

 填入的值是0xfffffeb9,相对跳转,0x804837c,.plt节中

 

 [root@proxy ~/3]# objdump -dj .plt 4

4:     file format elf32-i386

Disassembly of section .plt:

0804833c <.plt>:
 804833c:       ff 35 bc 95 04 08       pushl  0x80495bc
 8048342:       ff 25 c0 95 04 08       jmp    *0x80495c0
 8048348:       00 00                   add    %al,(%eax)
 804834a:       00 00                   add    %al,(%eax)
 804834c:       ff 25 c4 95 04 08       jmp    *0x80495c4
 8048352:       68 00 00 00 00          push   $0x0
 8048357:       e9 e0 ff ff ff          jmp    804833c <_init+0x18>
 804835c:       ff 25 c8 95 04 08       jmp    *0x80495c8
 8048362:       68 08 00 00 00          push   $0x8
 8048367:       e9 d0 ff ff ff          jmp    804833c <_init+0x18>
 804836c:       ff 25 cc 95 04 08       jmp    *0x80495cc
 8048372:       68 10 00 00 00          push   $0x10
 8048377:       e9 c0 ff ff ff          jmp    804833c <_init+0x18>
 804837c:       ff 25 d0 95 04 08       jmp    *0x80495d0 //<<
指向这里
 8048382:       68 18 00 00 00          push   $0x18
 8048387:       e9 b0 ff ff ff          jmp    804833c <_init+0x18>
 804838c:       ff 25 d4 95 04 08       jmp    *0x80495d4
 8048392:       68 20 00 00 00          push   $0x20
 8048397:       e9 a0 ff ff ff          jmp    804833c <_init+0x18>
 
说明R_386_PLT32的重定位方法是: 将符号在.plt节中的地址和Offset差值还要加Addent填入Offset(此处是.text中引用函数符号的地方, PLT实现位置无关).

R_386_JUMP_SLOT 用于函数,执行时重定位; [从第三节挪到此处]

应该修正为符号的实际值S(例如函数f的地址)

.rela.plt--This relocation table is similar to the one in .rela.dyn section; the difference is this one is for functions, not variables.

The relocation type of entries in this table is R_386_JMP_SLOT or R_X86_64_JUMP_SLOT and the "offset" refers to memory addresses which are inside .got.plt section.

Simply put, this table holds information to relocate entries in .got.plt section.

.plt section

This section contains trampolines for functions defined in dynamic libraries. A sample disassembly (run the command objdump -M intel -dj .plt a.out) will show the following:

4003c0 <printf@plt-0x10>:

  4003c0: push   QWORD PTR [RIP+0x2004d2]        # 600898 <_GLOBAL_OFFSET_TABLE_+0x8>

  4003c6: jmp    QWORD PTR [RIP+0x2004d4]        # 6008a0 <_GLOBAL_OFFSET_TABLE_+0x10>

  4003cc: nop    DWORD PTR [RAX+0x0]

 

4003d0 <printf@plt>:

  4003d0: jmp    QWORD PTR [RIP+0x2004d2]        # 6008a8 <_GLOBAL_OFFSET_TABLE_+0x18>

  4003d6: push   0

  4003db: jmp    4003c0 <printf@plt-0x10>

 

4003e0 <__libc_start_main@plt>:

  4003e0: jmp    QWORD PTR [RIP+0x2004ca]        # 6008b0 <_GLOBAL_OFFSET_TABLE_+0x20>

  4003e6: push   1

  4003eb: jmp    4003c0 <printf@plt-0x10>

The _GLOBAL_OFFSET_TABLE_ (labeled as R_X86_64_JUMP_SLOT and starts at address 0x600890) is located in .got.plt section (to see this, run the command objdump -h a.out |grep -A 1 600890 or the command readelf -r a.out) The data in .got.plt section look like the following during runtime (use gdb to see them)

(gdb) b *0x4003d0

(gdb) run

(gdb) x/6a 0x600890

0x600890: 0x6006e8 <_DYNAMIC>--GOT[0] 0x32696159a8 --GOT[1] link_map *

0x6008a0: 0x326950aa20 <_dl_runtime_resolve> GOT[2] 0x4003d6 <printf@plt+6>

0x6008b0: 0x326971c3f0 <__libc_start_main>       0x0

When printf is called the first time in the user program, the jump at 4003d0 will jump to 4003d6, which is just the next instruction (push 0) The it jumps to 4003c0, which does not have a function name (so it is shown as <printf@plt-0x10>). At 4003c6, it will jumps to _dl_runtime_resolve. This function (in Glibc's source file sysdeps/x86_64/dl-trampoline.S) is a trampoline to _dl_fixup (in Glibc's source file elf/dl-runtime.c). _dl_fixup again, is part of Glibc runtime linker ld.so. In particular, it will change the address stored at 6008a8 to the actual address of printf in libc.so.6. To see this, set up a hardware watchpoint

(gdb) watch *0x6008a8

(gdb) cont

Continuing.

Hardware watchpoint 2: *0x6008a8

Old value = 4195286

New value = 1769244016

0x000000326950abc2 in fixup () from /lib64/ld-linux-x86-64.so.2

If we continue execution, printf will be called, as expected. When printf is called again in the user program, the jump at 4003d0 will bounce directly to printf:

(gdb) x/6a 0x600890

0x600890: 0x6006e8 <_DYNAMIC>     0x32696159a8

0x6008a0: 0x326950aa20 <_dl_runtime_resolve>     0x3269748570 <printf>

0x6008b0: 0x326971c3f0 <__libc_start_main>       0x0

 

R_3862_JMP_SLOT The link editor creates this relocation type for dynamic linking. Its offset member gives the location of a procedure linkage table entry. The dynamic linker modifies the procedure linkage table entry to transfer control to the designated symbol’s address [see ‘‘Procedure Linkage Table’’ in Part 2].

[]=>

ELF File Format中的这段话不管其表达, 正确意思是: r_Offset给出的偏移地址是函数在GOT中对应的项; .plt entry是不被改动的, 修正的是GOT项的值. r_Offset处即GOT项初始值应该是plt项中的偏移,386上就是初始化为下条pushl的地址.

Following the steps below, the dynamic linker and the program ‘‘cooperate’’ to resolve symbolic references through the procedure linkage table and the global offset table.

1 . When first creating the memory image of the program, the dynamic linker sets the second and the third entries in the global offset table to special values. Steps below explain more about these values.

2 . If the procedure linkage table is position-independent, the address of the global offset table must reside in %ebx. Each shared object file in the process image has its own procedure linkage table, and control transfers to a procedure linkage table entry only from within the same object file. Consequently, the calling function is responsible for setting the global offset table base register before calling the procedure linkage table entry.

3 . For illustration, assume the program calls name1, which transfers control to the label .PLT1.(name1@PLT)

4 . The first instruction jumps to the address in the global offset table entry for name1 in GOT. Initially, the global offset table holds the address of the following pushl instruction, not the real address of name1.

5 . Consequently, the program pushes a relocation offset (offset) on the stack. The relocation offset is a 32-bit, non-negative byte offset into the relocation table(如果说这个offset.rel.plt中有项对应,则可以解释过去;否则该Offset对应GOT中的某一项). The designated relocation entry will have type R_386_JMP_SLOT, and its offset will specify the global offset table entry used in the previous jmp instruction(这是准确无误的). The relocation entry also contains a symbol table index, thus telling the dynamic linker what symbol is being referenced, name1 in this case.

6 . After pushing the relocation offset, the program then jumps to .PLT0, the first entry in the procedure linkage table. The pushl instruction places the value of the second global offset table entry (got_plus_4 or 4(%ebx)) on the stack, thus giving the dynamic linker one word of identifying information. The program then jumps to the address in the third global offset table entry (got_plus_8 or 8(%ebx)), which transfers control to the dynamic linker.

7 . When the dynamic linker receives control, it unwinds the stack, looks at the designated relocation entry, finds the symbol’s value, stores the ‘‘real’’ address for name1 in its global offset table entry, and transfers control to the desired destination.

8 . Subsequent executions of the procedure linkage table entry will transfer directly to name1, without calling the dynamic linker a second time. That is, the jmp instruction at .PLT1 will transfer to name1, instead of ‘‘falling through’’ to the pushl instruction.

The LD_BIND_NOW environment variable can change dynamic linking behavior. If its value is non-null, the dynamic linker evaluates procedure linkage table entries before transferring control to the program. That is, the dynamic linker processes relocation entries of type R_386_JMP_SLOT during process initialization. Otherwise, the dynamic linker evaluates procedure linkage table entries lazily, delaying symbol resolution and relocation until the first execution of a table entry.

不难理解ELF File FormatRelocation段落中的描述

R_386_GOTPC 10 word32 GOT + A - P //GOTGOT地址,AOffset处的值,POffset.
R_386_GOT32 3 word32 G + A - P //G
为符号在GOT中地址,AOffset处的值,P
Offset
R_386_GLOB_DAT 6 word32 S //S
为调整后的符号值
R_386_PLT32 4 word32 L + A - P //L为符号在plt中的地址,AOffset处的值,POffset

重定位类型分析(3)

本文分析剩下的四种类型R_386_COPY,R_386_JUMP_SLOT,R_386_RELATIVE,R_386_GOTOFF

R_386_RELATIVE 8 word32 B + A
R_386_JUMP_SLOT 7 word32 S
R_386_GOTOFF 9 word32 S + A - GOT
R_386_COPY 5 none none

附件1

1.c

[root@proxy ~/3]# cat 1.c
#include <stdio.h>

static char *s="hello World!\n";
char *t="abc";

void f()
{
printf(s);
}

void g()
{
printf(t);
}
[root@proxy ~/3]# gcc -fPIC -S 1.c
[root@proxy ~/3]# cat 1.s
        .file   "1.c"
        .version        "01.01"
gcc2_compiled.:
                .section        .rodata
.LC0:
        .string "hello World!\n"
.data
        .align 4
        .type    s,@object
        .size    s,4
s:
        .long   .LC0
.globl t
                .section        .rodata
.LC1:
        .string "abc"
.data
        .align 4
        .type    t,@object
        .size    t,4
t:
        .long   .LC1
.text
        .align 4
.globl f
        .type    f,@function
f:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        subl    $4, %esp
        call    .L3
.L3:
        popl    %ebx
        addl    $_GLOBAL_OFFSET_TABLE_+[.-.L3], %ebx
        subl    $12, %esp
        pushl   s@GOTOFF(%ebx)
        call   
printf@PLT
        addl    $16, %esp
        movl    -4(%ebp), %ebx
        leave
        ret
.Lfe1:
        .size    f,.Lfe1-f
        .align 4
.globl g
        .type    g,@function
g:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        subl    $4, %esp
        call    .L5
.L5:
        popl    %ebx
        addl    $_GLOBAL_OFFSET_TABLE_+[.-.L5], %ebx
        subl    $12, %esp
        movl    t@GOT(%ebx), %eax
        pushl   (%eax)
        call   
printf@PLT
        addl    $16, %esp
        movl    -4(%ebp), %ebx
        leave
        ret
.Lfe2:
        .size    g,.Lfe2-g
        .ident  "GCC: (GNU) 2.96 20000731 (Red Hat Linux 7.1 2.96-98)"
[root@proxy ~/3]# gcc -fPIC -c 1.c -o 1.o
[root@proxy ~/3]# ld -shared 1.o -o 1.so
[root@proxy ~/3]# objdump -dj .text 1.o

1.o:     file format elf32-i386

Disassembly of section .text:

00000000 <f>:
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   53                      push   %ebx
   4:   83 ec 04                sub    $0x4,%esp
   7:   e8 00 00 00 00          call   c <f+0xc>
   c:   5b                      pop    %ebx
   d:   81 c3 03 00 00 00       add    $0x3,%ebx
  13:   83 ec 0c                sub    $0xc,%esp
  16:   ff b3 00 00 00 00       pushl  0x0(%ebx)
  1c:   e8 fc ff ff ff          call   1d <f+0x1d>
  21:   83 c4 10                add    $0x10,%esp
  24:   8b 5d fc                mov    0xfffffffc(%ebp),%ebx
  27:   c9                      leave 
  28:   c3                      ret   
  29:   8d 76 00                lea    0x0(%esi),%esi

0000002c <g>:
  2c:   55                      push   %ebp
  2d:   89 e5                   mov    %esp,%ebp
  2f:   53                      push   %ebx
  30:   83 ec 04                sub    $0x4,%esp
  33:   e8 00 00 00 00          call   38 <g+0xc>
  38:   5b                      pop    %ebx
  39:   81 c3 03 00 00 00       add    $0x3,%ebx
  3f:   83 ec 0c                sub    $0xc,%esp
  42:   8b 83 00 00 00 00       mov    0x0(%ebx),%eax
  48:   ff 30                   pushl  (%eax)
  4a:   e8 fc ff ff ff          call   4b <g+0x1f>
  4f:   83 c4 10                add    $0x10,%esp
  52:   8b 5d fc                mov    0xfffffffc(%ebp),%ebx
  55:   c9                      leave 
  56:   c3                      ret   
  57:   90                      nop   
[root@proxy ~/3]# readelf -a 1.o
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          328 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         12
  Section header string table index: 9

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000058 00  AX  0   0  4
  [ 2] .rel.text         REL             00000000 000454 000030 08     10   1  4
  [ 3] .data             PROGBITS        00000000 00008c 000008 00  WA  0   0  4
  [ 4] .rel.data         REL             00000000 000484 000010 08     10   3  4
  [ 5] .bss              NOBITS          00000000 000094 000000 00  WA  0   0  4
  [ 6] .note             NOTE            00000000 000094 000014 00      0   0  1
  [ 7] .rodata           PROGBITS        00000000 0000a8 000012 00   A  0   0  1
  [ 8] .comment          PROGBITS        00000000 0000ba 000036 00      0   0  1
  [ 9] .shstrtab         STRTAB          00000000 0000f0 000057 00      0   0  1
  [10] .symtab           SYMTAB          00000000 000328 0000f0 10     11   a  4
  [11] .strtab           STRTAB          00000000 000418 000039 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There are no program headers in this file.

There is no dynamic segment in this file.

Relocation section '.rel.text' at offset 0x454 contains 6 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  0000000f  00c0a R_386_GOTPC           00000000  _GLOBAL_OFFSET_TABLE_   
  00000018  00309 R_386_GOTOFF          00000000  .data                   
  0000001d  00d04 R_386_PLT32           00000000  printf                  
  0000003b  00c0a R_386_GOTPC           00000000  _GLOBAL_OFFSET_TABLE_   
  00000044  00a03 R_386_GOT32           00000004  t                       
  0000004b  00d04 R_386_PLT32           00000000  printf                  

Relocation section '.rel.data' at offset 0x484 contains 2 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  00000000  00601 R_386_32              00000000  .rodata                 
  00000004  00601 R_386_32              00000000  .rodata                 

There are no unwind sections in this file.

Symbol table '.symtab' contains 15 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS 1.c
     2: 00000000     0 SECTION LOCAL  DEFAULT    1
     3: 00000000     0 SECTION LOCAL  DEFAULT    3
     4: 00000000     0 SECTION LOCAL  DEFAULT    5
     5: 00000000     0 NOTYPE  LOCAL  DEFAULT    1 gcc2_compiled.
     6: 00000000     0 SECTION LOCAL  DEFAULT    7
     7: 00000000     4 OBJECT  LOCAL  DEFAULT    3 s
     8: 00000000     0 SECTION LOCAL  DEFAULT    6
     9: 00000000     0 SECTION LOCAL  DEFAULT    8
    10: 00000004     4 OBJECT  GLOBAL DEFAULT    3 t
    11: 00000000    41 FUNC    GLOBAL DEFAULT    1 f
    12: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _GLOBAL_OFFSET_TABLE_
    13: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
    14: 0000002c    43 FUNC    GLOBAL DEFAULT    1 g

No version information found in this file.
[root@proxy ~/3]# objdump -dj .text 1.so

1.so:     file format elf32-i386

Disassembly of section .text:

0000035c <f>:
 35c:   55                      push   %ebp
 35d:   89 e5                   mov    %esp,%ebp
 35f:   53                      push   %ebx
 360:   83 ec 04                sub    $0x4,%esp
 363:   e8 00 00 00 00          call   368 <f+0xc>
 368:   5b                      pop    %ebx
 369:   81 c3 68 10 00 00       add    $0x1068,%ebx
 36f:   83 ec 0c                sub    $0xc,%esp
 372:   ff b3 f8 ff ff ff       pushl  0xfffffff8(%ebx)
 378:   e8 cf ff ff ff          call   34c <f-0x10>
 37d:   83 c4 10                add    $0x10,%esp
 380:   8b 5d fc                mov    0xfffffffc(%ebp),%ebx
 383:   c9                      leave 
 384:   c3                      ret   
 385:   8d 76 00                lea    0x0(%esi),%esi

00000388 <g>:
 388:   55                      push   %ebp
 389:   89 e5                   mov    %esp,%ebp
 38b:   53                      push   %ebx
 38c:   83 ec 04                sub    $0x4,%esp
 38f:   e8 00 00 00 00          call   394 <g+0xc>
 394:   5b                      pop    %ebx
 395:   81 c3 3c 10 00 00       add    $0x103c,%ebx
 39b:   83 ec 0c                sub    $0xc,%esp
 39e:   8b 83 10 00 00 00       mov    0x10(%ebx),%eax
 3a4:   ff 30                   pushl  (%eax)
 3a6:   e8 a1 ff ff ff          call   34c <f-0x10>
 3ab:   83 c4 10                add    $0x10,%esp
 3ae:   8b 5d fc                mov    0xfffffffc(%ebp),%ebx
 3b1:   c9                      leave 
 3b2:   c3                      ret   
 3b3:   90                      no
 [root@proxy ~/3]# readelf -a 1.so
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x35c
  Start of program headers:          52 (bytes into file)
  Start of section headers:          1348 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         3
  Size of section headers:           40 (bytes)
  Number of section headers:         19
  Section header string table index: 16

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .hash             HASH            00000094 000094 0000b0 04   A  2   0  4
  [ 2] .dynsym           DYNSYM          00000144 000144 000190 10   A  3  10  4
  [ 3] .dynstr           STRTAB          000002d4 0002d4 000045 00   A  0   0  1
  [ 4] .rel.dyn          REL             0000031c 00031c 000018 08   A  2   0  4
  [ 5] .rel.plt          REL             00000334 000334 000008 08   A  2   6  4
  [ 6] .plt              PROGBITS        0000033c 00033c 000020 04  AX  0   0  4
  [ 7] .text             PROGBITS        0000035c 00035c 000058 00  AX  0   0  4
  [ 8] .rodata           PROGBITS        000003b4 0003b4 000012 00   A  0   0  1
  [ 9] .data             PROGBITS        000013c8 0003c8 000008 00  WA  0   0  4
  [10] .got              PROGBITS        000013d0 0003d0 000014 04  WA  0   0  4
  [11] .dynamic          DYNAMIC         000013e4 0003e4 000090 08  WA  3   0  4
  [12] .sbss             PROGBITS        00001474 000474 000000 00   W  0   0  1
  [13] .bss              NOBITS          00001474 000474 000000 00  WA  0   0  4
  [14] .comment          PROGBITS        00000000 000474 000036 00      0   0  1
  [15] .note             NOTE            00000000 0004aa 000014 00      0   0  1
  [16] .shstrtab         STRTAB          00000000 0004be 000084 00      0   0  1
  [17] .symtab           SYMTAB          00000000 00083c 0001f0 10     18  16  4
  [18] .strtab           STRTAB          00000000 000a2c 00005a 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x003c6 0x003c6 R E 0x1000
  LOAD           0x0003c8 0x000013c8 0x000013c8 0x000ac 0x000ac RW  0x1000
  DYNAMIC        0x0003e4 0x000013e4 0x000013e4 0x00090 0x00090 RW  0x4

 Section to Segment mapping:
  Segment Sections...
   00     .hash .dynsym .dynstr .rel.dyn .rel.plt .plt .text .rodata
   01     .data .got .dynamic
   02     .dynamic

Dynamic segment at offset 0x3e4 contains 14 entries:
  Tag        Type                         Name/Value
 0x00000004 (HASH)                       0x94
 0x00000005 (STRTAB)                     0x2d4
 0x00000006 (SYMTAB)                     0x144
 0x0000000a (STRSZ)                      69 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000003 (PLTGOT)                     0x13d0
 0x00000002 (PLTRELSZ)                   8 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x334
 0x00000011 (REL)                        0x31c
 0x00000012 (RELSZ)                      24 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffa (RELCOUNT)                   2
 0x00000000 (NULL)                       0x0

Relocation section '.rel.dyn' at offset 0x31c contains 3 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  000013c8  00008 R_386_RELATIVE      
  000013cc  00008 R_386_RELATIVE      
  000013e0  01006 R_386_GLOB_DAT        000013cc  t                       

Relocation section '.rel.plt' at offset 0x334 contains 1 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  000013dc  01107 R_386_JUMP_SLOT       00000000  printf                  

There are no unwind sections in this file.

Symbol table '.dynsym' contains 25 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000094     0 SECTION LOCAL  DEFAULT    1
     2: 00000144     0 SECTION LOCAL  DEFAULT    2
     3: 000002d4     0 SECTION LOCAL  DEFAULT    3
     4: 0000031c     0 SECTION LOCAL  DEFAULT    4
     5: 00000334     0 SECTION LOCAL  DEFAULT    5
     6: 0000033c     0 SECTION LOCAL  DEFAULT    6
     7: 0000035c     0 SECTION LOCAL  DEFAULT    7
     8: 000003b4     0 SECTION LOCAL  DEFAULT    8
     9: 000013c8     0 SECTION LOCAL  DEFAULT    9
    10: 000013d0     0 SECTION LOCAL  DEFAULT   10
    11: 000013e4     0 SECTION LOCAL  DEFAULT   11
    12: 00001474     0 SECTION LOCAL  DEFAULT   12
    13: 00001474     0 SECTION LOCAL  DEFAULT   13
    14: 00000000     0 SECTION LOCAL  DEFAULT   14
    15: 00000000     0 SECTION LOCAL  DEFAULT   15
    16: 000013cc     4 OBJECT  GLOBAL DEFAULT    9 t
    17: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
    18: 000013e4     0 OBJECT  GLOBAL DEFAULT  ABS _DYNAMIC
    19: 0000035c    41 FUNC    GLOBAL DEFAULT    7 f
    20: 00000388    43 FUNC    GLOBAL DEFAULT    7 g
    21: 00001474     0 OBJECT  GLOBAL DEFAULT  ABS __bss_start
    22: 00001474     0 OBJECT  GLOBAL DEFAULT  ABS _edata
    23: 000013d0     0 OBJECT  GLOBAL DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
    24: 00001474     0 OBJECT  GLOBAL DEFAULT  ABS _end

Symbol table '.symtab' contains 31 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000094     0 SECTION LOCAL  DEFAULT    1
     2: 00000144     0 SECTION LOCAL  DEFAULT    2
     3: 000002d4     0 SECTION LOCAL  DEFAULT    3
     4: 0000031c     0 SECTION LOCAL  DEFAULT    4
     5: 00000334     0 SECTION LOCAL  DEFAULT    5
     6: 0000033c     0 SECTION LOCAL  DEFAULT    6
     7: 0000035c     0 SECTION LOCAL  DEFAULT    7
     8: 000003b4     0 SECTION LOCAL  DEFAULT    8
     9: 000013c8     0 SECTION LOCAL  DEFAULT    9
    10: 000013d0     0 SECTION LOCAL  DEFAULT   10
    11: 000013e4     0 SECTION LOCAL  DEFAULT   11
    12: 00001474     0 SECTION LOCAL  DEFAULT   12
    13: 00001474     0 SECTION LOCAL  DEFAULT   13
    14: 00000000     0 SECTION LOCAL  DEFAULT   14
    15: 00000000     0 SECTION LOCAL  DEFAULT   15
    16: 00000000     0 SECTION LOCAL  DEFAULT   16
    17: 00000000     0 SECTION LOCAL  DEFAULT   17
    18: 00000000     0 SECTION LOCAL  DEFAULT   18
    19: 00000000     0 FILE    LOCAL  DEFAULT  ABS 1.c
    20: 0000035c     0 NOTYPE  LOCAL  DEFAULT    7 gcc2_compiled.
    21: 000013c8     4 OBJECT  LOCAL  DEFAULT    9 s
    22: 000013cc     4 OBJECT  GLOBAL DEFAULT    9 t
    23: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
    24: 000013e4     0 OBJECT  GLOBAL DEFAULT  ABS _DYNAMIC
    25: 0000035c    41 FUNC    GLOBAL DEFAULT    7 f
    26: 00000388    43 FUNC    GLOBAL DEFAULT    7 g
    27: 00001474     0 OBJECT  GLOBAL DEFAULT  ABS __bss_start
    28: 00001474     0 OBJECT  GLOBAL DEFAULT  ABS _edata
    29: 000013d0     0 OBJECT  GLOBAL DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
    30: 00001474     0 OBJECT  GLOBAL DEFAULT  ABS _end

Histogram for bucket list length (total of 17 buckets):
 Length  Number     % of total  Coverage
      0  9          ( 52.9%)
      1  7          ( 41.2%)     77.8%
      2  1          (  5.9%)    100.0%

No version information found in this file.

附件2

4.c

[root@proxy ~/3]# cat 2.c
#include <stdio.h>

extern char *t;

int main()
{
f();
g();
printf(t);
return 0;
}

[root@proxy ~/3]# gcc -c 2.c -o 2.o
[root@proxy ~/3]# gcc 2.o 1.so -o 4
[root@proxy ~/3]# objdump -dj .text 4

4:     file format elf32-i386

Disassembly of section .text:

08048490 <_start>:
 8048490:       31 ed                   xor    %ebp,%ebp
 8048492:       5e                      pop    %esi
 8048493:       89 e1                   mov    %esp,%ecx
 8048495:       83 e4 f0                and    $0xfffffff0,%esp
 8048498:       50                      push   %eax
 8048499:       54                      push   %esp
 804849a:       52                      push   %edx
 804849b:       68 00 86 04 08          push   $0x8048600
 80484a0:       68 ec 83 04 08          push   $0x80483ec
 80484a5:       51                      push   %ecx
 80484a6:       56                      push   %esi
 80484a7:       68 90 85 04 08          push   $0x8048590
 80484ac:       e8 a3 ff ff ff          call   8048454 <_init+0x68>
 80484b1:       f4                      hlt   
 80484b2:       89 f6                   mov    %esi,%esi

080484b4 <call_gmon_start>:
 80484b4:       55                      push   %ebp
 80484b5:       89 e5                   mov    %esp,%ebp
 80484b7:       53                      push   %ebx
 80484b8:       50                      push   %eax
 80484b9:       e8 00 00 00 00          call   80484be <call_gmon_start+0xa>
 80484be:       5b                      pop    %ebx
 80484bf:       81 c3 8e 11 00 00       add    $0x118e,%ebx
 80484c5:       8b 83 28 00 00 00       mov    0x28(%ebx),%eax
 80484cb:       85 c0                   test   %eax,%eax
 80484cd:       74 02                   je     80484d1 <call_gmon_start+0x1d>
 80484cf:       ff d0                   call   *%eax
 80484d1:       8b 5d fc                mov    0xfffffffc(%ebp),%ebx
 80484d4:       c9                      leave 
 80484d5:       c3                      ret   
 80484d6:       89 f6                   mov    %esi,%esi
 80484d8:       90                      nop   
 80484d9:       90                      nop   
 80484da:       90                      nop   
 80484db:       90                      nop   
 80484dc:       90                      nop   
 80484dd:       90                      nop   
 80484de:       90                      nop   
 80484df:       90                      nop   

080484e0 <__do_global_dtors_aux>:
 80484e0:       55                      push   %ebp
 80484e1:       89 e5                   mov    %esp,%ebp
 80484e3:       83 ec 08                sub    $0x8,%esp
 80484e6:       8b 15 34 96 04 08       mov    0x8049634,%edx
 80484ec:       85 d2                   test   %edx,%edx
 80484ee:       75 49                   jne    8048539 <__do_global_dtors_aux+0x59>
 80484f0:       8b 15 30 96 04 08       mov    0x8049630,%edx
 80484f6:       8b 02                   mov    (%edx),%eax
 80484f8:       85 c0                   test   %eax,%eax
 80484fa:       74 1a                   je     8048516 <__do_global_dtors_aux+0x36>
 80484fc:       8d 74 26 00             lea    0x0(%esi,1),%esi
 8048500:       8d 42 04                lea    0x4(%edx),%eax
 8048503:       a3 30 96 04 08          mov    %eax,0x8049630
 8048508:       ff 12                   call   *(%edx)
 804850a:       8b 15 30 96 04 08       mov    0x8049630,%edx
 8048510:       8b 0a                   mov    (%edx),%ecx
 8048512:       85 c9                   test   %ecx,%ecx
 8048514:       75 ea                   jne    8048500 <__do_global_dtors_aux+0x20>
 8048516:       b8 44 84 04 08          mov    $0x8048444,%eax
 804851b:       85 c0                   test   %eax,%eax
 804851d:       74 10                   je     804852f <__do_global_dtors_aux+0x4f>
 804851f:       83 ec 0c                sub    $0xc,%esp
 8048522:       68 38 96 04 08          push   $0x8049638
 8048527:       e8 18 ff ff ff          call   8048444 <_init+0x58>
 804852c:       83 c4 10                add    $0x10,%esp
 804852f:       b8 01 00 00 00          mov    $0x1,%eax
 8048534:       a3 34 96 04 08          mov    %eax,0x8049634
 8048539:       89 ec                   mov    %ebp,%esp
 804853b:       5d                      pop    %ebp
 804853c:       c3                      ret   
 804853d:       8d 76 00                lea    0x0(%esi),%esi

08048540 <fini_dummy>:
 8048540:       55                      push   %ebp
 8048541:       89 e5                   mov    %esp,%ebp
 8048543:       83 ec 08                sub    $0x8,%esp
 8048546:       89 ec                   mov    %ebp,%esp
 8048548:       5d                      pop    %ebp
 8048549:       c3                      ret   
 804854a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi

08048550 <frame_dummy>:
 8048550:       55                      push   %ebp
 8048551:       b8 24 84 04 08          mov    $0x8048424,%eax
 8048556:       89 e5                   mov    %esp,%ebp
 8048558:       83 ec 08                sub    $0x8,%esp
 804855b:       85 c0                   test   %eax,%eax
 804855d:       74 15                   je     8048574 <frame_dummy+0x24>
 804855f:       83 ec 08                sub    $0x8,%esp
 8048562:       68 4c 97 04 08          push   $0x804974c
 8048567:       68 38 96 04 08          push   $0x8049638
 804856c:       e8 b3 fe ff ff          call   8048424 <_init+0x38>
 8048571:       83 c4 10                add    $0x10,%esp
 8048574:       89 ec                   mov    %ebp,%esp
 8048576:       5d                      pop    %ebp
 8048577:       c3                      ret   
 8048578:       90                      nop   
 8048579:       8d b4 26 00 00 00 00    lea    0x0(%esi,1),%esi

08048580 <init_dummy>:
 8048580:       55                      push   %ebp
 8048581:       89 e5                   mov    %esp,%ebp
 8048583:       83 ec 08                sub    $0x8,%esp
 8048586:       89 ec                   mov    %ebp,%esp
 8048588:       5d                      pop    %ebp
 8048589:       c3                      ret   
 804858a:       8d b6 00 00 00 00       lea    0x0(%esi),%esi

08048590 <main>:
 8048590:       55                      push   %ebp
 8048591:       89 e5                   mov    %esp,%ebp
 8048593:       83 ec 08                sub    $0x8,%esp
 8048596:       e8 79 fe ff ff          call   8048414 <_init+0x28>
 804859b:       e8 94 fe ff ff          call   8048434 <_init+0x48>
 80485a0:       83 ec 0c                sub    $0xc,%esp
 80485a3:       ff 35 48 97 04 08       pushl  0x8049748
 80485a9:       e8 b6 fe ff ff          call   8048464 <_init+0x78>
 80485ae:       83 c4 10                add    $0x10,%esp
 80485b1:       b8 00 00 00 00          mov    $0x0,%eax
 80485b6:       c9                      leave 
 80485b7:       c3                      ret   
 80485b8:       90                      nop   
 80485b9:       90                      nop   
 80485ba:       90                      nop   
 80485bb:       90                      nop   
 80485bc:       90                      nop   
 80485bd:       90                      nop   
 80485be:       90                      nop   
 80485bf:       90                      nop   

080485c0 <__do_global_ctors_aux>:
 80485c0:       55                      push   %ebp
 80485c1:       89 e5                   mov    %esp,%ebp
 80485c3:       53                      push   %ebx
 80485c4:       83 ec 04                sub    $0x4,%esp
 80485c7:       a1 3c 96 04 08          mov    0x804963c,%eax
 80485cc:       bb 3c 96 04 08          mov    $0x804963c,%ebx
 80485d1:       83 f8 ff                cmp    $0xffffffff,%eax
 80485d4:       74 16                   je     80485ec <__do_global_ctors_aux+0x2c>
 80485d6:       8d 76 00                lea    0x0(%esi),%esi
 80485d9:       8d bc 27 00 00 00 00    lea    0x0(%edi,1),%edi
 80485e0:       83 eb 04                sub    $0x4,%ebx
 80485e3:       ff d0                   call   *%eax
 80485e5:       8b 03                   mov    (%ebx),%eax
 80485e7:       83 f8 ff                cmp    $0xffffffff,%eax
 80485ea:       75 f4                   jne    80485e0 <__do_global_ctors_aux+0x20>
 80485ec:       58                      pop    %eax
 80485ed:       5b                      pop    %ebx
 80485ee:       5d                      pop    %ebp
 80485ef:       c3                      ret   

080485f0 <init_dummy>:
 80485f0:       55                      push   %ebp
 80485f1:       89 e5                   mov    %esp,%ebp
 80485f3:       83 ec 08                sub    $0x8,%esp
 80485f6:       89 ec                   mov    %ebp,%esp
 80485f8:       5d                      pop    %ebp
 80485f9:       c3                      ret   
 80485fa:       8d b6 00 00 00 00       lea    0x0(%esi),%esi
[root@proxy ~/3]# readelf -a 4
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Intel 80386
  Version:                           0x1
  Entry point address:               0x8048490
  Start of program headers:          52 (bytes into file)
  Start of section headers:          11028 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         6
  Size of section headers:           40 (bytes)
  Number of section headers:         30
  Section header string table index: 27

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        080480f4 0000f4 000013 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            08048108 000108 000020 00   A  0   0  4
  [ 3] .hash             HASH            08048128 000128 000054 04   A  4   0  4
  [ 4] .dynsym           DYNSYM          0804817c 00017c 000100 10   A  5   1  4
  [ 5] .dynstr           STRTAB          0804827c 00027c 0000d7 00   A  0   0  1
  [ 6] .gnu.version      VERSYM          08048354 000354 000020 02   A  4   0  2
  [ 7] .gnu.version_r    VERNEED         08048374 000374 000030 00   A  5   1  4
  [ 8] .rel.dyn          REL             080483a4 0003a4 000010 08   A  4   0  4
  [ 9] .rel.plt          REL             080483b4 0003b4 000038 08   A  4   b  4
  [10] .init             PROGBITS        080483ec 0003ec 000018 00  AX  0   0  4
  [11] .plt              PROGBITS        08048404 000404 000080 04  AX  0   0  4
  [12] .text             PROGBITS        08048490 000490 000170 00  AX  0   0 16
  [13] .fini             PROGBITS        08048600 000600 00001e 00  AX  0   0  4
  [14] .rodata           PROGBITS        08048620 000620 000008 00   A  0   0  4
  [15] .data             PROGBITS        08049628 000628 000010 00  WA  0   0  4
  [16] .eh_frame         PROGBITS        08049638 000638 000004 00  WA  0   0  4
  [17] .ctors            PROGBITS        0804963c 00063c 000008 00  WA  0   0  4
  [18] .dtors            PROGBITS        08049644 000644 000008 00  WA  0   0  4
  [19] .got              PROGBITS        0804964c 00064c 00002c 04  WA  0   0  4
  [20] .dynamic          DYNAMIC         08049678 000678 0000d0 08  WA  5   0  4
  [21] .sbss             PROGBITS        08049748 000748 000000 00   W  0   0  1
  [22] .bss              NOBITS          08049748 000748 00001c 00  WA  0   0  4
  [23] .stab             PROGBITS        00000000 000748 0007a4 0c     24   0  4
  [24] .stabstr          STRTAB          00000000 000eec 001983 00      0   0  1
  [25] .comment          PROGBITS        00000000 00286f 000144 00      0   0  1
  [26] .note             NOTE            00000000 0029b3 000078 00      0   0  1
  [27] .shstrtab         STRTAB          00000000 002a2b 0000e9 00      0   0  1
  [28] .symtab           SYMTAB          00000000 002fc4 000510 10     29  3b  4
  [29] .strtab           STRTAB          00000000 0034d4 00022e 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x08048034 0x08048034 0x000c0 0x000c0 R E 0x4
  INTERP         0x0000f4 0x080480f4 0x080480f4 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /lib/ld-linux.so.2]
  LOAD           0x000000 0x08048000 0x08048000 0x00628 0x00628 R E 0x1000
  LOAD           0x000628 0x08049628 0x08049628 0x00120 0x0013c RW  0x1000
  DYNAMIC        0x000678 0x08049678 0x08049678 0x000d0 0x000d0 RW  0x4
  NOTE           0x000108 0x08048108 0x08048108 0x00020 0x00020 R   0x4

 Section to Segment mapping:
  Segment Sections...
   00    
   01     .interp
   02     .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata
   03     .data .eh_frame .ctors .dtors .got .dynamic .bss
   04     .dynamic
   05     .note.ABI-tag

Dynamic segment at offset 0x678 contains 21 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [1.so]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x0000000c (INIT)                       0x80483ec
 0x0000000d (FINI)                       0x8048600
 0x00000004 (HASH)                       0x8048128
 0x00000005 (STRTAB)                     0x804827c
 0x00000006 (SYMTAB)                     0x804817c
 0x0000000a (STRSZ)                      193 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000015 (DEBUG)                      0x0
 0x00000003 (PLTGOT)                     0x804964c
 0x00000002 (PLTRELSZ)                   56 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x80483b4
 0x00000011 (REL)                        0x80483a4
 0x00000012 (RELSZ)                      16 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x6ffffffe (VERNEED)                    0x8048374
 0x6fffffff (VERNEEDNUM)                 1
 0x6ffffff0 (VERSYM)                     0x8048354
 0x00000000 (NULL)                       0x0

Relocation section '.rel.dyn' at offset 0x3a4 contains 2 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  08049674  00f06 R_386_GLOB_DAT        00000000  __gmon_start__          
  08049748  00105 R_386_COPY            08049748  t                       

Relocation section '.rel.plt' at offset 0x3b4 contains 7 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  08049658  00307 R_386_JUMP_SLOT       08048414  f                       
  0804965c  00407 R_386_JUMP_SLOT       08048424  __register_frame_info   
  08049660  00507 R_386_JUMP_SLOT       08048434  g                       
  08049664  00607 R_386_JUMP_SLOT       08048444  __deregister_frame_info 
  08049668  00807 R_386_JUMP_SLOT       08048454  __libc_start_main       
  0804966c  00907 R_386_JUMP_SLOT       08048464  printf                  
  08049670  00a07 R_386_JUMP_SLOT       08048474  __cxa_finalize          

There are no unwind sections in this file.

Symbol table '.dynsym' contains 16 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 08049748     4 OBJECT  GLOBAL DEFAULT   22 t
     2: 08049678     0 OBJECT  GLOBAL DEFAULT  ABS _DYNAMIC
     3: 08048414    41 FUNC    GLOBAL DEFAULT  UND f
     4: 08048424   129 FUNC    WEAK   DEFAULT  UND
__register_frame_info@GLIBC_2.0 (2)
     5: 08048434    43 FUNC    GLOBAL DEFAULT  UND g
     6: 08048444   172 FUNC   WEAK   DEFAULT  UND
__deregister_frame_info@GLIBC_2.0 (2)
     7: 08049748     0 OBJECT  GLOBAL DEFAULT  ABS __bss_start
     8: 08048454   202 FUNC    GLOBAL DEFAULT  UND
__libc_start_main@GLIBC_2.0 (2)
     9: 08048464    50 FUNC    GLOBAL DEFAULT  UND
printf@GLIBC_2.0 (2)
    10: 08048474   157 FUNC    WEAK   DEFAULT  UND
__cxa_finalize@GLIBC_2.1.3 (3)
    11: 08049748     0 OBJECT  GLOBAL DEFAULT  ABS _edata
    12: 0804964c     0 OBJECT  GLOBAL DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
    13: 08049764     0 OBJECT  GLOBAL DEFAULT  ABS _end
    14: 08048624     4 OBJECT  GLOBAL DEFAULT   14 _IO_stdin_used
    15: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__

Symbol table '.symtab' contains 81 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 080480f4     0 SECTION LOCAL  DEFAULT    1
     2: 08048108     0 SECTION LOCAL  DEFAULT    2
     3: 08048128     0 SECTION LOCAL  DEFAULT    3
     4: 0804817c     0 SECTION LOCAL  DEFAULT    4
     5: 0804827c     0 SECTION LOCAL  DEFAULT    5
     6: 08048354     0 SECTION LOCAL  DEFAULT    6
     7: 08048374     0 SECTION LOCAL  DEFAULT    7
     8: 080483a4     0 SECTION LOCAL  DEFAULT    8
     9: 080483b4     0 SECTION LOCAL  DEFAULT    9
    10: 080483ec     0 SECTION LOCAL  DEFAULT   10
    11: 08048404     0 SECTION LOCAL  DEFAULT   11
    12: 08048490     0 SECTION LOCAL  DEFAULT   12
    13: 08048600     0 SECTION LOCAL  DEFAULT   13
    14: 08048620     0 SECTION LOCAL  DEFAULT   14
    15: 08049628     0 SECTION LOCAL  DEFAULT   15
    16: 08049638     0 SECTION LOCAL  DEFAULT   16
    17: 0804963c     0 SECTION LOCAL  DEFAULT   17
    18: 08049644     0 SECTION LOCAL  DEFAULT   18
    19: 0804964c     0 SECTION LOCAL  DEFAULT   19
    20: 08049678     0 SECTION LOCAL  DEFAULT   20
    21: 08049748     0 SECTION LOCAL  DEFAULT   21
    22: 08049748     0 SECTION LOCAL  DEFAULT   22
    23: 00000000     0 SECTION LOCAL  DEFAULT   23
    24: 00000000     0 SECTION LOCAL  DEFAULT   24
    25: 00000000     0 SECTION LOCAL  DEFAULT   25
    26: 00000000     0 SECTION LOCAL  DEFAULT   26
    27: 00000000     0 SECTION LOCAL  DEFAULT   27
    28: 00000000     0 SECTION LOCAL  DEFAULT   28
    29: 00000000     0 SECTION LOCAL  DEFAULT   29
    30: 00000000     0 FILE    LOCAL  DEFAULT  ABS initfini.c
    31: 080484b4     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    32: 080484b4     0 FUNC    LOCAL  DEFAULT   12 call_gmon_start
    33: 00000000     0 FILE    LOCAL  DEFAULT  ABS init.c
    34: 00000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    35: 080484e0     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    36: 08049630     0 OBJECT  LOCAL  DEFAULT   15 p.0
    37: 08049644     0 OBJECT  LOCAL  DEFAULT   18 __DTOR_LIST__
    38: 08049634     0 OBJECT  LOCAL  DEFAULT   15 completed.1
    39: 080484e0     0 FUNC    LOCAL  DEFAULT   12 __do_global_dtors_aux
    40: 08049638     0 OBJECT  LOCAL  DEFAULT   16 __EH_FRAME_BEGIN__
    41: 08048540     0 FUNC    LOCAL  DEFAULT   12 fini_dummy
    42: 0804974c    24 OBJECT  LOCAL  DEFAULT   22 object.2
    43: 08048550     0 FUNC    LOCAL  DEFAULT   12 frame_dummy
    44: 08048580     0 FUNC    LOCAL  DEFAULT   12 init_dummy
    45: 08049638     0 OBJECT  LOCAL  DEFAULT   15 force_to_data
    46: 0804963c     0 OBJECT  LOCAL  DEFAULT   17 __CTOR_LIST__
    47: 00000000     0 FILE    LOCAL  DEFAULT  ABS crtstuff.c
    48: 080485c0     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    49: 080485c0     0 FUNC    LOCAL  DEFAULT   12 __do_global_ctors_aux
    50: 08049640     0 OBJECT  LOCAL  DEFAULT   17 __CTOR_END__
    51: 080485f0     0 FUNC    LOCAL  DEFAULT   12 init_dummy
    52: 08049638     0 OBJECT  LOCAL  DEFAULT   15 force_to_data
    53: 08049648     0 OBJECT  LOCAL  DEFAULT   18 __DTOR_END__
    54: 08049638     0 OBJECT  LOCAL  DEFAULT   16 __FRAME_END__
    55: 00000000     0 FILE    LOCAL  DEFAULT  ABS initfini.c
    56: 08048600     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    57: 00000000     0 FILE    LOCAL  DEFAULT  ABS 2.c
    58: 08048590     0 NOTYPE  LOCAL  DEFAULT   12 gcc2_compiled.
    59: 08049748     4 OBJECT  GLOBAL DEFAULT   22 t
    60: 08049678     0 OBJECT  GLOBAL DEFAULT  ABS _DYNAMIC
    61: 08048414    41 FUNC    GLOBAL DEFAULT  UND f
    62: 08048424   129 FUNC    WEAK   DEFAULT  UND
__register_frame_info@@GLIBC_2.0
    63: 08048620     4 NOTYPE  GLOBAL DEFAULT   14 _fp_hw
    64: 08048434    43 FUNC    GLOBAL DEFAULT  UND g
    65: 080483ec     0 FUNC    GLOBAL DEFAULT   10 _init
    66: 08048444   172 FUNC   WEAK   DEFAULT  UND
__deregister_frame_info@@GLIBC_2.0
    67: 08048490     0 FUNC    GLOBAL DEFAULT   12 _start
    68: 08049748     0 OBJECT  GLOBAL DEFAULT  ABS __bss_start
    69: 08048590    40 FUNC    GLOBAL DEFAULT   12 main
    70: 08048454   202 FUNC    GLOBAL DEFAULT  UND
__libc_start_main@@GLIBC_2.0
    71: 08049628     0 NOTYPE  WEAK   DEFAULT   15 data_start
    72: 08048464    50 FUNC    GLOBAL DEFAULT  UND
printf@@GLIBC_2.0
    73: 08048600     0 FUNC    GLOBAL DEFAULT   13 _fini
    74: 08048474   157 FUNC    WEAK   DEFAULT  UND
__cxa_finalize@@GLIBC_2.1.3
    75: 08049748     0 OBJECT  GLOBAL DEFAULT  ABS _edata
    76: 0804964c     0 OBJECT  GLOBAL DEFAULT  ABS _GLOBAL_OFFSET_TABLE_
    77: 08049764     0 OBJECT  GLOBAL DEFAULT  ABS _end
    78: 08048624     4 OBJECT  GLOBAL DEFAULT   14 _IO_stdin_used
    79: 08049628     0 NOTYPE  GLOBAL DEFAULT   15 __data_start
    80: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__

Histogram for bucket list length (total of 3 buckets):
 Length  Number     % of total  Coverage
      0  0          (  0.0%)
      1  0          (  0.0%)      0.0%
      2  0          (  0.0%)      0.0%
      3  1          ( 33.3%)     20.0%
      4  0          (  0.0%)     20.0%
      5  0          (  0.0%)     20.0%
      6  2          ( 66.7%)    100.0%

Version symbols section '.gnu.version' contains 16 entries:
 Addr: 0000000008048354  Offset: 0x000354  Link: 4 (.dynsym)
  000:   0 (*local*)       0 (*local*)       1 (*global*)      0 (*local*)   
  004:   2 (GLIBC_2.0)     0 (*local*)       2 (GLIBC_2.0)     1 (*global*)  
  008:   2 (GLIBC_2.0)     2 (GLIBC_2.0)     3 (GLIBC_2.1.3)   1 (*global*)  
  00c:   1 (*global*)      1 (*global*)      1 (*global*)      0 (*local*)   

Version needs section '.gnu.version_r' contains 1 entries:
 Addr: 0x0000000008048374  Offset: 0x000374  Link to section: 5 (.dynstr)
  000000: Version: 1  File: libc.so.6  Cnt: 2
  0x0010: Name: GLIBC_2.1.3  Flags: none  Version: 3
  0x0020: Name: GLIBC_2.0  Flags: none  Version: 2

本节分析开始处:

R_386_RELATIVE 用于局部变量,执行时重定位

R_386_RELATIVE The link editor creates this relocation type for dynamic linking. Its offset member gives a location within a shared object that contains a value representing a relative address. The dynamic linker computes the corresponding virtual address by adding the virtual address at which the shared object was loaded to the relative address. Relocation entries for this type must specify 0 for the symbol table index.

查看1.c.txt生成的1.soreadelf

  000013c8  00008 R_386_RELATIVE 
  000013cc  00008 R_386_RELATIVE 

这两项在.rel.dyn, offset 00013c8 是地址, 相对于1.so加载地址,显然是在.data节中, 没有符号名,那他们是什么呢?

  [ 9] .data             PROGBITS        000013c8 0003c8 000008 00  WA  0   0  4

[]=>

猜想可知是动态加载so, 相当于ModuleBase做重定位.

[root@proxy ~/3]# objdump -sj .data 1.so

1.so:     file format elf32-i386

Contents of section .data:
 13c8 b4030000 c2030000                    ........

值分别是03b403c2,应该是位于.rodata

[root@proxy ~/3]# objdump -sj .rodata 1.so

1.so:     file format elf32-i386

Contents of section .rodata:
 03b4 68656c6c 6f20576f 726c6421 0a006162  hello World!..ab
 03c4 6300                                 c.      

果然是的.

R_386_RELATIVE 8 word32 B + A,使用加载地址+Offset处值来重定位

验证:由于是执行时连接,需要启用gdb来调试看看
[root@proxy ~/3]# ldd 4
        1.so => /usr/lib/1.so (0x4002a000)
        libc.so.6 => /lib/i686/libc.so.6 (0x4002c000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

因此
  000013c8  00008 R_386_RELATIVE 
  000013cc  00008 R_386_RELATIVE
加载后的地址为0x4002b3c8,0x4002b3cc

[root@proxy ~/3]# cp 1.so /usr/lib
cp: overwrite `/usr/lib/1.so' y
[root@proxy ~/3]# gdb -q ./4
(gdb) b main
Breakpoint 1 at 0x8048596
(gdb) r
Starting program: /root/3/./4

Breakpoint 1, 0x08048596 in main ()
(gdb) x/w 0x4002b3c8
0x4002b3c8 <s>: 0x4002a3b4
(gdb) x/w 0x4002b3cc
0x4002b3cc <t>: 0x4002a3c2
(gdb)

Contents of section .data:
 13c8 b4030000 c2030000                    ........
分别加上0x4002a000就是上面的结果

R_386_GOTOFF 用于静态变量,链接是重定位

目标文件1.o

  00000018  00309 R_386_GOTOFF          00000000  .data       
 
  16:   ff b3 00 00 00 00       pushl  0x0(%ebx)
 
          pushl  
s@GOTOFF(%ebx)
         
生成1.so
 372:   ff b3 f8 ff ff ff       pushl  0xfffffff8(%ebx)
 
修正值为0xfffffff8,-8,got-8.

[root@proxy ~/3]# objdump -sj .data 1.so

1.so:     file format elf32-i386

Contents of section .data:
 13c8 b4030000 c2030000                    ........     

s的值为03b4,指向.rodata
[root@proxy ~/3]# objdump -sj .rodata 1.so

1.so:     file format elf32-i386

Contents of section .rodata:
 03b4 68656c6c 6f20576f 726c6421 0a006162  hello World!..ab
 03c4 6300                                 c.     

所以R_386_GOTOFF的修正方式是: 将符号地址和GOT地址差值加上Offset处的值存入Offset. ELF文档中的S + A – GOT

[]=>

1.sosections表可以看到, .got之前即为.data, got本身就放在.data; .got-8就是s变量的地址, 所以使用GOT地址做负偏移寻址, 形成位置无关代码. 因为sstatic, 不导出, 所以在GOT中没有对应项.

R_386_COPY,用于全局变量,执行时重定位

R_386_COPY The link editor creates this relocation type for dynamic linking. Its offset member refers to a location in a writable segment. The symbol table index specifies a symbol that should exist both in the current object file and in a shared object. During execution, the dynamic linker copies data associated with the shared object’s symbol to the location specified by the offset.

因为在4.c中有声明:

extern char *t;

在可执行文件4

  08049748  00105 R_386_COPY            08049748  t 
  [22] .bss              NOBITS          08049748 000748 00001c 00  WA  0   0  4

1.so
    16: 000013cc     4 OBJECT  GLOBAL DEFAULT    9 t
加载地址0x4002a00,所以t的值是0x4002b3cc     

abcabc[root@proxy ~/3]# gdb -q ./4
(gdb) b main
Breakpoint 1 at 0x8048596
(gdb) r
Starting program: /root/3/./4

Breakpoint 1, 0x08048596 in main ()
(gdb) x /w 0x08049748 //
4t的值
0x08049748 <t>:  0x4002a3c2
(gdb) x /w 0x4002b3cc //
1.sot的值
0x4002b3cc <t>: 0x4002a3c2
(gdb)  

两个值相等

所以R_386_COPY的修正方式是:将解析到的符号地址处的值(大小由size决定)复制到Offset处。

这实现了每个可执行文件都有独立的全局变量,而不互相干扰。

[]=>

要求的是同一个地址,而不是不相互干扰; 见总结中纠正: 而同时soGOT中该变量的地址值被改写成可执行文件中的地址

[]=>

变量tso中是有初始值的, 所以在.data section; 而以extern引用时, 由于不知道其是否有初始值, 所以只能放在.bss, 有初始值, 则再根据1.so中符号的st_value COPY一下相当于初始化.

可以发现

重定位目标文件有.symtab, 这个表是必须的, 虽然可以用strip去掉, 但是最终连接时会出错; 而动态链接库文件和可执行文件有.dynsym.symtab, .dynsym是必须的, .symtab不是,可以执行strip命令去掉.

重定位总结

总结

R_386_NONE        0    none    none

1.ld时重定位

1.1位置相关

1.1.1 R_386_32
R_386_32     1    word32  S + A //
数据,绝对地址
符号的值即变量的地址,因此变量都需要重定位
如果变量的值是普通值,则不需对值重定位
如果变量的值是地址,则需对值重定位,例如
char *="abc";
Offset    Info  Type            Symbol's Value  Symbol's Name
0000000b  00301 R_386_32              00000000  .data          
00000010  00e02 R_386_PC32            00000000  printf  

   9:   ff 35 00 00 00 00       pushl  0x0 //ff 35 将立即数压栈
   f:   e8 fc ff ff ff          call   10 <f+0x10> //e8 相对寻址
  14:   83 c4 10                add    $0x10,%esp

所以R_386_32都是对Offset处的地址值重定位

S即调整后的符号值(新的变量地址)A即原值(Offset处的地址值,需要重定位的地址)

1.1.2 R_386_PC32
R_386_PC32     2    word32  S + A - P//
代码,相对地址
P
Offset
连接时,ld会合并相同的节,假设printf被安排的地址是x,1.o.text节安排的地址是
y
x+(-4)-(y+10)=x-y-14,所以重定位的结果是
x-y-14,
cpu执行y+f:处的call指令时,ip指向y+14,call的目标地址是ip+(x-y-14)=x

1.2 位置无关(PIC)

1.2.1 R_386_GOTPC
R_386_GOTPC    10    word32  GOT + A - P
GOT
GOT地址(符号_GLOBAL_OFFSET_TABLE_的值),AOffset处值,POffset.

 Offset    Info  Type            Symbol's Value  Symbol's Name
  0000000f  00e0a R_386_GOTPC           00000000  _GLOBAL_OFFSET_TABLE_   
  00000018  00309 R_386_GOTOFF          00000000  .data                   
  0000001d  00f04 R_386_PLT32           00000000  printf                  

   7:   e8 00 00 00 00          call   c <f+0xc>
   c:   5b                      pop    %ebx
   d:   81 c3 03 00 00 00       add    $0x3,%ebx
  13:   83 ec 0c                sub    $0xc,%esp
  16:   ff b3 00 00 00 00       pushl  0x0(%ebx)
  1c:   e8 fc ff ff ff          call   1d <f+0x1d>

        call    .L3
.L3:
        popl    %ebx
        addl    $_GLOBAL_OFFSET_TABLE_+[.-.L3], %ebx
        subl    $12, %esp
        pushl  
s@GOTOFF(%ebx)
        call   
printf@PLT

1.2.2 R_386_GOTOFF
R_386_GOTOFF     9    word32  S + A - GOT//
静态(局部)变量

将符号地址和GOT地址差值加上Offset处值存入Offset.

1.2.3 R_386_GOT32
R_386_GOT32     3    word32  G + A - P//
外部(全局)变量
G为符号在GOT中地址,AOffset处值,POffset

1.2.4 R_386_PLT32
R_386_PLT32     4    word32  L + A - P//
代码

L
为符号在plt中的地址,AOffset处值,POffset

2.执行时重定位

2.1 位置相关
2.1.1 R_386_32
2.1.2 R_386_PC32

2.2 位置无关

2.2.1 R_386_RELATIVE
R_386_RELATIVE    8    word32  B + A//
局部变量

使用加载地址+Offset处值来重定位

Relocation section '.rel.dyn' at offset 0x330 contains 3 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  000013e8  00008 R_386_RELATIVE    //
字符串地址
  
  000013ec  00008 R_386_RELATIVE    //
字符串地址
  00001408  01006 R_386_GLOB_DAT        000013ec  t                       

2.2.2 R_386_GLOB_DAT
R_386_GLOB_DAT    6    word32  S //
外部全局在PIC so间共享,PIC so共享可执行文件中的变量
S为调整后的符号值写入Offset
对于本地全局变量,直接把调整后的符号值写入本地
GOT
 3b6:   8b 83 10 00 00 00       mov    0x10(%ebx),%eax//%eax
中地址值指向.data
 3bc:   ff 30                   pushl  (%eax)//.data节中的变量值入栈
对于外部全局变量,解析该符号值(即变量地址),写入本地GOT<<<<<

2.2.3 R_386_COPY
R_386_COPY     5    none    none//
外部全局变量
可执行文件共享PIC so中变量
,
由于所有的可执行文件都不需要重定位,所以为可执行文件共享动态链接库中的全局变量单独设置这个属性,在本地的bss中分配空间,置R_386_COPY定位类型,而不使用R_386_32定位类型(那样需使代码段可写,且COW,耗费内存)

6.c
extern char * s;
extern int t;
1.c
char *s="abc";
int t=1;

6.o
Relocation section '.rel.text' at offset 0x38c contains 5 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  0000000b  00901 R_386_32              00000000  s                       
  00000010  00a02 R_386_PC32            00000000  printf                  
  00000019  00b01 R_386_32              00000000  t                       
  0000001e  00c02 R_386_PC32            00000000  g                       
  00000024  00d01 R_386_32              00000004  u

Symbol table '.symtab' contains 14 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     9: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND s
    10: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND printf
    11: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND t
    12: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND g
    13: 00000004     4 OBJECT  GLOBAL DEFAULT  COM u


gcc 1.so 6.o -o 6
而可执行文件6中就变成了
Relocation section '.rel.dyn' at offset 0x3f4 contains 3 entries:
  Offset    Info  Type            Symbol's Value  Symbol's Name
  080496b0  01006 R_386_GLOB_DAT        00000000  __gmon_start__          
  08049784  00105 R_386_COPY            08049784  t                       
  08049788  00905 R_386_COPY            08049788  s

    1: 08049784     4 OBJECT  GLOBAL DEFAULT   22 t
    9: 08049788     4 OBJECT  GLOBAL DEFAULT   22 s
可见s,tNdx不是UND,而是位于.bss

将解析到的符号地址处的值(大小由size决定)复制到Offset处。
而同时soGOT中该变量的地址值被改写成可执行文件中的地址

R_386_COPY read a string of bytes from the "symbol" address and deposit a copy into this dword; the "symbol" object contains the length; this is used to copy initialized data
from a library to the main app data space

 On i386 the most important ones are the R_386_COPY type, meaning "just copy the address of the symbol to that address"


2.2.4 R_386_JMP_SLOT
R_386_JMP_SLOT    7    word32  S//
代码


其他:
1.
如果文件使用了动态链接库,则该文件就有
GOT
2.GOT
中的信息
[root@proxy ~/3]# objdump -sj .got 6  

6:     file format elf32-i386

Contents of section .got:
 804968c b4960408 00000000 00000000 6a840408  ............j...
 804969c 7a840408 8a840408 9a840408 aa840408  z...............
 80496ac ba840408 00000000  
GOT[0]
.dynsym节的地址
 
[20] .dynamic          DYNAMIC         080496b4 0006b4 0000d0 08  WA  5   0  4
GOT[1]
是动态链接库自身的struct link_map*的指针
GOT[2]_dl_runtime_resolve的地址
GOT[3]..,函数解析前指向.plt中,解析后执行真正的函数地址
变量加载时解析,指向全局变量地址

3.plt
位置相关
:
08048454 <.plt>:
 8048454:       ff 35 90 96 04 08       pushl  0x8049690
 804845a:       ff 25 94 96 04 08       jmp    *0x8049694
 8048460:       00 00                   add    %al,(%eax)
 8048462:       00 00                   add    %al,(%eax)
 8048464:       ff 25 98 96 04 08       jmp    *0x8049698
 804846a:       68 00 00 00 00          push   $0x0
 804846f:       e9 e0 ff ff ff          jmp    8048454 <_init+0x18>
 8048474:       ff 25 9c 96 04 08       jmp    *0x804969c
 804847a:       68 08 00 00 00          push   $0x8
 804847f:       e9 d0 ff ff ff          jmp    8048454 <_init+0x18>
 8048484:       ff 25 a0 96 04 08       jmp    *0x80496a0
PIC:
00000370 <.plt>:
 370:   ff b3 04 00 00 00       pushl  0x4(%ebx)
 376:   ff a3 08 00 00 00       jmp    *0x8(%ebx)
 37c:   00 00                   add    %al,(%eax)
 37e:   00 00                   add    %al,(%eax)
 380:   ff a3 0c 00 00 00       jmp    *0xc(%ebx)
 386:   68 00 00 00 00          push   $0x0
 38b:   e9 e0 ff ff ff          jmp    370 <f-0x20>

其中push $0x0是符号在rel节中的索引数0(字节偏移)

 

你可能感兴趣的:(ELF重定位类型分析(1-3, 总结)加评版)