movl $0, %ebx ==>
xorl %ebx, %ebx
編譯出來結果雖然總體檔案不變(一樣為268 byte大小,是因為執行檔中byte alignment原因),但如此產生的machine code會更小(少3個byte):
mov $0, %ebx ==> 0xBB 0x00 0x00 0x00 0x00
xor %ebx, %ebx ==> 0x31 0xDB
接下來以hexdump命令觀察執行檔的內容:
$ hexdump -C -v helloworld2
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 03 00 01 00 00 00 54 80 04 08 34 00 00 00 |........T...4...|
00000020 94 00 00 00 00 00 00 00 34 00 20 00 01 00 28 00 |........4. ...(.|
00000030 03 00 02 00 01 00 00 00 00 00 00 00 00 80 04 08 |................|
00000040 00 80 04 08 80 00 00 00 80 00 00 00 05 00 00 00 |................|
00000050 00 10 00 00 ba 0d 00 00 00 b9 73 80 04 08 bb 01 |..........s.....|
00000060 00 00 00 b8 04 00 00 00 cd 80 31 db b8 01 00 00 |..........1.....|
00000070 00 cd 80 48 65 6c 6c 6f 20 77 6f 72 6c 64 0a 00 |...Hello world..|
00000080 00 2e 73 68 73 74 72 74 61 62 00 2e 74 65 78 74 |..shstrtab..text|
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 0b 00 00 00 |................|
000000c0 01 00 00 00 06 00 00 00 54 80 04 08 54 00 00 00 |........T...T...|
000000d0 2c 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 |,...............|
000000e0 00 00 00 00 01 00 00 00 03 00 00 00 00 00 00 00 |................|
000000f0 00 00 00 00 80 00 00 00 11 00 00 00 00 00 00 00 |................|
00000100 00 00 00 00 01 00 00 00 00 00 00 00 |............|
0000010c
在對應執行檔的Spec
。於Figure 1-1: Object File Format中提到,若一個ELF檔案為執行檔時,其檔案起始為ELF header以及Program header table。也就是說:
這裡一個很簡的此兩個資料結構的parser:
1 #include <unistd.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <elf.h>
5
6 Elf32_Ehdr e;
7 Elf32_Phdr p;
8
9 #define member_p(t, s, m, o) printf(#s"."#m"(0x%08x,%d)....0x%08X\n", (unsigned int)&(((t *) 0)->m) + o, sizeof(s.m), s.m);
10
11 int main(void)
12 {
13 read(STDIN_FILENO, &e, sizeof(e));
14
15 member_p(Elf32_Ehdr, e, e_type , 0);
16 member_p(Elf32_Ehdr, e, e_machine , 0);
17 member_p(Elf32_Ehdr, e, e_version , 0);
18 member_p(Elf32_Ehdr, e, e_entry , 0);
19 member_p(Elf32_Ehdr, e, e_phoff , 0);
20 member_p(Elf32_Ehdr, e, e_shoff , 0);
21 member_p(Elf32_Ehdr, e, e_flags , 0);
22 member_p(Elf32_Ehdr, e, e_ehsize , 0);
23 member_p(Elf32_Ehdr, e, e_phentsize , 0);
24 member_p(Elf32_Ehdr, e, e_phnum , 0);
25 member_p(Elf32_Ehdr, e, e_shentsize , 0);
26 member_p(Elf32_Ehdr, e, e_shnum , 0);
27 member_p(Elf32_Ehdr, e, e_shstrndx , 0);
28
29 printf("\n");
30
31 read(STDIN_FILENO, &p, sizeof(p));
32
33 member_p(Elf32_Phdr, p, p_type , sizeof(e));
34 member_p(Elf32_Phdr, p, p_offset , sizeof(e));
35 member_p(Elf32_Phdr, p, p_vaddr , sizeof(e));
36 member_p(Elf32_Phdr, p, p_paddr , sizeof(e));
37 member_p(Elf32_Phdr, p, p_filesz , sizeof(e));
38 member_p(Elf32_Phdr, p, p_memsz , sizeof(e));
39 member_p(Elf32_Phdr, p, p_flags , sizeof(e));
40 member_p(Elf32_Phdr, p, p_align , sizeof(e));
41
42 return (0);
43 }
44
$
$ gcc elf.c -o elf
$ ./elf < helloworld2
e.e_type(0x00000010,2)....0x00000002
e.e_machine(0x00000012,2)....0x00000003
e.e_version(0x00000014,4)....0x00000001
e.e_entry(0x00000018,4)....0x08048054
e.e_phoff(0x0000001c,4)....0x00000034
e.e_shoff(0x00000020,4)....0x00000094
e.e_flags(0x00000024,4)....0x00000000
e.e_ehsize(0x00000028,2)....0x00000034
e.e_phentsize(0x0000002a,2)....0x00000020
e.e_phnum(0x0000002c,2)....0x00000001
e.e_shentsize(0x0000002e,2)....0x00000028
e.e_shnum(0x00000030,2)....0x00000003
e.e_shstrndx(0x00000032,2)....0x00000002
p.p_type(0x00000034,4)....0x00000001
p.p_offset(0x00000038,4)....0x00000000
p.p_vaddr(0x0000003c,4)....0x08048000
p.p_paddr(0x00000040,4)....0x08048000
p.p_filesz(0x00000044,4)....0x00000080
p.p_memsz(0x00000048,4)....0x00000080
p.p_flags(0x0000004c,4)....0x00000005
p.p_align(0x00000050,4)....0x00001000
$
ㄧ個ELF的執行檔於最簡單形式時(例如helloworld.s編譯出來的執行檔),這兩個資料結構及程式本身是最基本的。
或者覺得太麻煩,可以用以下方式讀取更詳細的資料:
$
$ readelf -a helloworld2
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: 0x8048054
Start of program headers: 52 (bytes into file)
Start of section headers: 148 (bytes into file)
Flags: 0x0
Size of this header: 52 (bytes)
Size of program headers: 32 (bytes)
Number of program headers: 1
Size of section headers: 40 (bytes)
Number of section headers: 3
Section header string table index: 2
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 08048054 000054 00002c 00 AX 0 0 4
[ 2] .shstrtab STRTAB 00000000 000080 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.
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0x000000 0x08048000 0x08048000 0x00080 0x00080 R E 0x1000
Section to Segment mapping:
Segment Sections...
00 .text
There is no dynamic section in this file.
There are no relocations in this file.
There are no unwind sections in this file.
No version information found in this file.
$
$
這邊只需要ELF header,Program header table以及.text區段,其餘可以刪除:
$
$ hexdump -C -v helloworld2.bin
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 03 00 01 00 00 00 54 80 04 08 34 00 00 00 |........T...4...|
00000020 94 00 00 00 00 00 00 00 34 00 20 00 01 00 28 00 |........4. ...(.|
00000030 03 00 02 00 01 00 00 00 00 00 00 00 00 80 04 08 |................|
00000040 00 80 04 08 80 00 00 00 80 00 00 00 05 00 00 00 |................|
00000050 00 10 00 00 ba 0d 00 00 00 b9 73 80 04 08 bb 01 |..........s.....|
00000060 00 00 00 b8 04 00 00 00 cd 80 31 db b8 01 00 00 |..........1.....|
00000070 00 cd 80 48 65 6c 6c 6f 20 77 6f 72 6c 64 0a 00 |...Hello world..|
00000080
$
$ chmod a+x helloworld2.bin
$ ./helloworld2.bin
Hello world
$
$ ls -l helloworld2.bin
-rwxr-xr-x 1 lungswu lungswu 128 2010-03-02 11:23 helloworld2.bin
$
$
最後一個Hello World的檔案被縮減到剩下128 bytes。
No comments:
Post a Comment