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已经是可执行文件,所以已经重定位过了。
学习链接的动手(1)
最新推荐文章于 2022-05-20 22:42:49 发布