学习链接的动手(1)

main.c


int fun(int a, int b);

int main(void)
{
    int a = 1;
    int b = 2;
    int c;
    c = fun(a, b);
    return 0;
}


fun.c


int fun(int a, int b)
{
    return a + b;  
}


预编译后的main.i


# 1 "main.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "main.c"
int fun(int a, int b);

int main(void)
{
 int a = 1;
 int b = 2;
 int c;
 c = fun(a, b);
 return 0;
}


编译后的main.s


    .file    "main.c"
    .text
.globl main
    .type    main, @function
main:
    pushl    %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $32, %esp
    movl    $1, 28(%esp)
    movl    $2, 24(%esp)
    movl    24(%esp), %eax
    movl    %eax, 4(%esp)
    movl    28(%esp), %eax
    movl    %eax, (%esp)
    call    fun
    movl    %eax, 20(%esp)
    movl    $0, %eax
    leave
    ret
    .size    main, .-main
    .ident    "GCC: (Ubuntu 4.4.1-4ubuntu8) 4.4.1"
    .section    .note.GNU-stack,"",@progbits


汇编后生成main.o文件,用OBJDUMP工具生成的代码如下

 

00000000 <main>:
   0:    55                       push   %ebp
   1:    89 e5                    mov    %esp,%ebp
   3:    83 e4 f0                 and    $0xfffffff0,%esp
   6:    83 ec 20                 sub    $0x20,%esp
   9:    c7 44 24 1c 01 00 00     movl   $0x1,0x1c(%esp)
  10:    00
  11:    c7 44 24 18 02 00 00     movl   $0x2,0x18(%esp)
  18:    00
  19:    8b 44 24 18              mov    0x18(%esp),%eax
  1d:    89 44 24 04              mov    %eax,0x4(%esp)
  21:    8b 44 24 1c              mov    0x1c(%esp),%eax
  25:    89 04 24                 mov    %eax,(%esp)
  28:    e8 fc ff ff ff           call   29 <main+0x29>
  2d:    89 44 24 14              mov    %eax,0x14(%esp)
  31:    b8 00 00 00 00           mov    $0x0,%eax
  36:    c9                       leave
  37:    c3                       ret


地址偏移28处数据fc ff ff ff ==  0x ff ff ff fc == 十进制-4 是为了PC相关重定位所进行的计算的特殊值。


上面显示的应该是.text节的信息,用READELF工具-a选项操作main.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 000038 00  AX  0   0  4
  [ 2] .rel.text         REL             00000000 000310 000008 08      8   1  4
  [ 3] .data             PROGBITS        00000000 00006c 000000 00  WA  0   0  4
  [ 4] .bss              NOBITS          00000000 00006c 000000 00  WA  0   0  4
  [ 5] .comment          PROGBITS        00000000 00006c 000024 01  MS  0   0  1
  [ 6] .note.GNU-stack   PROGBITS        00000000 000090 000000 00      0   0  1
  [ 7] .shstrtab         STRTAB          00000000 000090 000049 00      0   0  1
  [ 8] .symtab           SYMTAB          00000000 00026c 000090 10      9   7  4
  [ 9] .strtab           STRTAB          00000000 0002fc 000011 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 section groups in this file.

There are no program headers in this file.

Relocation section '.rel.text' at offset 0x310 contains 1 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00000029  00000802 R_386_PC32        00000000   fun

There are no unwind sections in this file.

Symbol table '.symtab' contains 9 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS main.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 SECTION LOCAL  DEFAULT    6
     6: 00000000     0 SECTION LOCAL  DEFAULT    5
     7: 00000000    56 FUNC    GLOBAL DEFAULT    1 main
     8: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND fun

No version information found in this file.


其中


节头部表:


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 000310 000008 08      8   1  4
  [ 3] .data             PROGBITS        00000000 00006c 000000 00  WA  0   0  4
  [ 4] .bss              NOBITS          00000000 00006c 000000 00  WA  0   0  4
  [ 5] .comment          PROGBITS        00000000 00006c 000024 01  MS  0   0  1
  [ 6] .note.GNU-stack   PROGBITS        00000000 000090 000000 00      0   0  1
  [ 7] .shstrtab         STRTAB          00000000 000090 000049 00      0   0  1
  [ 8] .symtab           SYMTAB          00000000 00026c 000090 10      9   7  4
  [ 9] .strtab           STRTAB          00000000 0002fc 000011 00      0   0  1



符号表:


Symbol table '.symtab' contains 9 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FILE    LOCAL  DEFAULT  ABS main.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 SECTION LOCAL  DEFAULT    6
     6: 00000000     0 SECTION LOCAL  DEFAULT    5
     7: 00000000    56 FUNC    GLOBAL DEFAULT    1 main
     8: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND fun


重定位表:


Relocation section '.rel.text' at offset 0x310 contains 1 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00000029  00000802 R_386_PC32        00000000   fun

因为fun是在fun.c里面定义的,所以它需要在链接的时候重新定位。

R_386_PC32指出它是PC相关的,即修改后二进制代码里的地址是下一条执行指令地址的相对地址。


由objdump生成的反汇编代码可以看到 call   29 <main+0x29>里面的29和Offset值00000029是对应的。它在可重定位目标文件.text节中偏移量是29。



使用连接器ld生成a.out

a.out的readelf输出为

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:               0x8048074
  Start of program headers:          52 (bytes into file)
  Start of section headers:          264 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         2
  Size of section headers:           40 (bytes)
  Number of section headers:         6
  Section header string table index: 3

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        08048074 000074 000046 00  AX  0   0  4
  [ 2] .comment          PROGBITS        00000000 0000ba 000023 01  MS  0   0  1
  [ 3] .shstrtab         STRTAB          00000000 0000dd 00002a 00      0   0  1
  [ 4] .symtab           SYMTAB          00000000 0001f8 0000b0 10      5   5  4
  [ 5] .strtab           STRTAB          00000000 0002a8 000036 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 section groups in this file.

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x08048000 0x08048000 0x000ba 0x000ba R E 0x1000
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4

 Section to Segment mapping:
  Segment Sections...
   00     .text
   01    

There is no dynamic section in this file.

There are no relocations in this file.

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: 08048074     0 SECTION LOCAL  DEFAULT    1
     2: 00000000     0 SECTION LOCAL  DEFAULT    2
     3: 00000000     0 FILE    LOCAL  DEFAULT  ABS main.c
     4: 00000000     0 FILE    LOCAL  DEFAULT  ABS fun.c
     5: 080480ac    14 FUNC    GLOBAL DEFAULT    1 fun
     6: 00000000     0 NOTYPE  GLOBAL DEFAULT  UND _start
     7: 080490ba     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
     8: 08048074    56 FUNC    GLOBAL DEFAULT    1 main
     9: 080490ba     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
    10: 080490bc     0 NOTYPE  GLOBAL DEFAULT  ABS _end

No version information found in this file.

a.out的objdump输出为:

a.out:     file format elf32-i386


Disassembly of section .text:

08048074 <main>:
 8048074:    55                       push   %ebp
 8048075:    89 e5                    mov    %esp,%ebp
 8048077:    83 e4 f0                 and    $0xfffffff0,%esp
 804807a:    83 ec 20                 sub    $0x20,%esp
 804807d:    c7 44 24 1c 01 00 00     movl   $0x1,0x1c(%esp)
 8048084:    00
 8048085:    c7 44 24 18 02 00 00     movl   $0x2,0x18(%esp)
 804808c:    00
 804808d:    8b 44 24 18              mov    0x18(%esp),%eax
 8048091:    89 44 24 04              mov    %eax,0x4(%esp)
 8048095:    8b 44 24 1c              mov    0x1c(%esp),%eax
 8048099:    89 04 24                 mov    %eax,(%esp)
 804809c:    e8 0b 00 00 00           call   80480ac <fun>
 80480a1:    89 44 24 14              mov    %eax,0x14(%esp)
 80480a5:    b8 00 00 00 00           mov    $0x0,%eax
 80480aa:    c9                       leave 
 80480ab:    c3                       ret   

080480ac <fun>:
 80480ac:    55                       push   %ebp
 80480ad:    89 e5                    mov    %esp,%ebp
 80480af:    8b 45 0c                 mov    0xc(%ebp),%eax
 80480b2:    8b 55 08                 mov    0x8(%ebp),%edx
 80480b5:    8d 04 02                 lea    (%edx,%eax,1),%eax
 80480b8:    5d                       pop    %ebp
 80480b9:    c3                       ret

可以看到804809c位置的call指令的函数地址变成了0b 00 00 00,这是小端法表示实际上值为0x0b,再看fun函数的地址是080480ac,它减去call下一条指令的地址也就是80480a1就是0x0b。
因为这时候a.out已经是可执行文件,所以已经重定位过了。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值