Relocation of OBJ files
[Wzhou @ dcmp10 ~] $ Cat hello. c
# Include <stdio. h>
# Include <unistd. h>
Int main (INT argc, char ** argv)
{
Getuid ();
Getchar ();
Return 0;
}
Gcc-C hello. C-O hello. o
Generate the OBJ file.
[Wzhou @ dcmp10 ~] $ Readelf-s hello. o
There are 10 section headers, starting at offset 0xe0:
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 running 2D 00 ax 0 0 4
[2]. Rel. Text rel 00000000 000330 000010 08 8 1 4
[3]. Data progbits 00000000 000064 000000 00 wa 0 0 4
[4]. BSS nobits 00000000 000064 000000 00 wa 0 0 4
[5]. note. GNU-stack PROGBITS 00000000 000064 000000 00 0 0 1
[6]. comment PROGBITS 00000000 000064 000031 00 0 0 1
[7]. shstrtab STRTAB 00000000 000095 000049 00 0 0 1
[8]. symtab SYMTAB 00000000 000270 running A0 10 9 7 4
[9]. strtab STRTAB 00000000 000310 running 1D 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)
[Wzhou @ dcmp10 ~] $
Dump. rel. text section
[Wzhou @ dcmp10 ~] $ Hexdump-C-s 0x330-n 16 hello. o
00000330 1d 00 00 00 02 08 00 00 22 00 00 02 09 00 00 | ...... "......" ...... |
Two entries.
Typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info;
} Elf32_Rel;
1. r_offset = 0x1d, r_info = (sym, type) = (08, 02) = (08, r_1__pc32)
2. r_offset = 0x22, r_info = (sym, type) = (09, 02) = (09, r_1__pc32)
Here, sym is the index pointing to the symbol table.
Dump. symtab section
[Wzhou @ dcmp10 ~] $ Hexdump-C-s 0x270-n 160 hello. o
00000270 00 00 00 00 00 00 00 00 00 00 00 00 | ...... |
00000280 01 00 00 00 00 00 00 00 00 00 04 00 f1 ff | ...... |
00000290 00 00 00 00 00 00 00 00 00 00 03 00 01 00 | ...... |
000002a0 00 00 00 00 00 00 00 00 00 00 03 00 03 00 | ...... |
000002b0 00 00 00 00 00 00 00 00 00 03 00 04 00 | ...... |
000002c0 00 00 00 00 00 00 00 00 00 00 03 00 05 00 | ...... |
000002d0 00 00 00 00 00 00 00 00 00 03 00 06 00 | ...... |
000002e0 09 00 00 00 00 00 00 2d 00 00 00 12 00 01 00 | ...... |
000002f0 0e 00 00 00 00 00 00 00 00 10 00 00 00 00 | ................ | relocation item with sym 8
00000300 15 00 00 00 00 00 00 00 00 00 00 00 00 | ................ | relocation item for which sym is 9
The offset of the first relocation item name in. strtab section 0x0e
The second relocation item name offset 0x15 in. strtab section
Dump. strtab section content
[Wzhou @ dcmp10 ~] $ Hexdump-C-s 0x310-n 29 hello. o
00000310 00 68 65 6c 6c 6f 2e 63 00 6d 61 69 6e 00 67 65 |. hello. c. main. ge |
00000320 74 75 69 64 00 67 65 74 63 68 61 72 00 | tuid. getchar. |
That is, the first relocation item is named "getuid"
That is, the second relocation item is named "getchar"
1. r_offset = 0x1d, r_info = ("getuid", r_1__pc32)
2. r_offset = 0x22, r_info = ("getchar", r_1__pc32)
R_offset is the offset in. text section.
[Wzhou @ dcmp10 ~] $ Objdump-d hello. o
Hello. 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: 83 e4 f0 and $0xfffffff0, % esp
9: b8 00 00 00 mov $0x0, % eax
E: 83 c0 0f add $ 0xf, % eax
11: 83 c0 0f add $ 0xf, % eax
14: c1 e8 04 shr $0x4, % eax
17: c1 e0 04 shl $0x4, % eax
1a: 29 c4 sub % eax, % esp
1c: e8 ① fc ff call 1d <main + 0x1d>
21: e8 ② fc ff call 22 <main + 0x22>
26: b8 00 00 00 mov $0x0, % eax
2b: c9 leave
2c: c3 ret
The first is the offset 0x1d, while the second is the offset 0x22. This is exactly where two functions are called.
That is, the following two lines in the source code need to be relocated.
Int main (int argc, char ** argv)
{
① Getuid ();
② Getchar ();
Return 0;
}
Linker will fix the address based on the relocation item.
It can be verified using readelf.
[Wzhou @ dcmp10 ~] $ Readelf-r hello. o
Relocation section '. rel. text' at offset 0x330 contains 2 entries:
Offset Info Type Sym. Value Sym. Name
2017001d 00000802 r_0000_pc32 00000000 getuid
00000022 00000902 r_0000_pc32 00000000 getchar
Migration of obj files (called relocatable file in ELF Specification, which I translated into relocated files) and executable and shared object file
The relocation in is different.
The relocation of obj files is in the static period (that is, the relocation during the compilation period), while the relocation of executable and shared object files is in the runtime period (that is, when it is loaded.
For example, the following simple example:
[Wzhou @ dcmp10 ~] $ Cat test1.c
Int func1 (void );
Int main ()
{
Func1 ();
Return 0;
}
Compile only without Link (in this case, the link will not succeed, and the func1 function is unknown)
Gcc-c test1.c-o test1.o
[Wzhou @ dcmp10 ~] $ Readelf-r test1.o
Check the relocation table. There is only one item.
Relocation section '. rel. text' at offset 0x30c contains 1 entries:
Offset Info Type Sym. Value Sym. Name
2017001d 00000802 r_1__pc32 00000000 func1
[Wzhou @ dcmp10 ~] $
[Wzhou @ dcmp10 ~] $ Objdump-d test1.o
Test1.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: 83 e4 f0 and $0xfffffff0, % esp
9: b8 00 00 00 mov $0x0, % eax
E: 83 c0 0f add $ 0xf, % eax
11: 83 c0 0f add $ 0xf, % eax
14: c1 e8 04 shr $0x4, % eax
17: c1 e0 04 shl $0x4, % eax
1a: 29 c4 sub % eax, % esp
1c: e8 1fc ff call 1d <main + 0x1d>
21: b8 00 00 00 mov $0x0, % eax
26: c9 leave
27: c3 ret
[Wzhou @ dcmp10 ~] $
That is to say, calling func1 () cannot be fixed during the compilation period, so it can only indicate the need for relocation.
1 here is the location where the offset in the. text section pointed out by the relocation item is 0x1d.
. Text section
Test1.o
Func1 ()
Where is func1?
Er, what else
Don't know
Relocated by the obj file
Item to indicate that there is
Func1 () call
[Wzhou @ dcmp10 ~] $ Cat test2.c func1 () is defined in test2.c.
Int func1 (void)
{
Return 2;
}
[Wzhou @ dcmp10 ~] $ Gcc-c test2.c-o test2.o compiled but not linked to test2.c
[Wzhou @ dcmp10 ~] $ Readelf-r test2.o
There are no relocations in this file.
The obj file does not have any uncertain items, and naturally there is no relocation item.
[Wzhou @ dcmp10 ~] $ Gcc-O test test1.o test2.o
[Wzhou @ dcmp10 ~] $ Readelf-r Test
Relocation section '. Rel. dyn' at offset 0x244 contains 1 entries:
Offset info type sym. Value sym. Name
08049528 00000406 r_1__glob_dat 00000000 _ gmon_start __
Relocation section '. Rel. PLT' At offset 0x24c contains 1 entries:
Offset info type sym. Value sym. Name
08049538 00000107 r_0000_jump_slot 00000000 _ libc_start_main
In the generated test, there is no relocation item originally marked as func1 () call.
[Wzhou @ dcmp10 ~] $ Objdump-D Test
08048334 <main>:
8048334: 55 push % EBP
8048335: 89 E5 mov % ESP, % EBP
8048337: 83 EC 08 Sub $0x8, % ESP
804833a: 83 E4 F0 and $0xfffffff0, % ESP
804833d: B8 00 00 00 mov $0x0, % eax
8048342: 83 C0 0f add $ 0xf, % eax
8048345: 83 c0 0f add $ 0xf, % eax
8048348: c1 e8 04 shr $0x4, % eax
804834b: c1 e0 04 shl $0x4, % eax
804834e: 29 c4 sub % eax, % esp
8048350: e8 07 00 00 00 call 804835c <func1> here is a near call, which is a call relative to 0x8048355 + 0x07.
8048355: b8 00 00 00 mov $0x0, % eax
804835a: c9 leave
804835b: c3 ret
0804835c <func1>:
804835c: 55 push % ebp
804835d: 89 e5 mov % esp, % ebp
804835f: b8 02 00 00 00 mov $0x2, % eax
8048364: c9 leave
8048365: c3 ret
8048366: 90 nop
8048367: 90 nop
In the final executable file, the call to func1 () is completely settled, and there is no need for "relocation ".
. Text section
Test1.o
Func1 ()
??? . Text section
Int func1 (void)
{
Return 2;
}
Test2.o
Test
. Text section
Test1.o. text
Section
Test2.o. text
Section
Linker uses the relocation item to fix the call to func1. The user of the relocation item of the obj file is linker,
In addition, the address is relocated in the linking phase. For example, here we use the two same parameters in test1.o and test2.o.
The name. text section is merged, resulting in a change in the position of the func1 () function. It turns out that func1 () is in test2.o
The. text section in is in the header. after merging, the natural position changes and the position needs to be relocated. Embodied in Commands
Call near + 0x7
Of course, the above example can be "located" only during the compilation period. If it cannot be located in the link stage, such as calling functions of other shared libraries, the relocation item should be retained to be loaded by ELF loader.
When the executable file is loaded, the relocation is different from the relocation of the obj file.
Walter Zhou
Mailto: z-l-dragon@hotmail.com
Week
Dragon