1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
~ current output point, string pointer
: pack-raw-string
{ unpack8 dup } { 3roll swap pack8 swap } while drop drop ;
: origin 0x08000000 ;
heap hexdump latest @ .hex space here @ .hex newline
latest @ @ word-heading latest @ @ hexdump
latest @ word-heading latest @ hexdump
: foo
latest @ word-heading latest @ hexdump
~ s" labels" create
8 allocate s" labels" variable
;
foo
latest @ word-heading latest @ hexdump
s" labels" find .hex bye
~ ~~
~ ~~ ELF header
~ ~~
~ ~~ This is the top-level ELF header, for the entire file. An ELF always
~ ~~ has exactly one of this header, which is always at the start of the file.
~ ~~
: elf-file-header
0x7f pack8 s" ELF" pack-raw-string ~ magic number
2 pack8 ~ 64-bit
1 pack8 ~ little-endian
1 pack8 ~ ELF header format v1
0 pack8 ~ System-V ABI
0 pack64 ~ (padding)
2 pack16 ~ executable
0x3e pack16 ~ Intel x86-64
1 pack32 ~ ELF format version
~ Compute the entry pointer.
origin 0x78 + pack64 ~ entry point
~ This includes the origin, intentionally.
0 pack64 ~ program header offset
~ We place the program header immediately after the ELF header. This
~ offset is from the start of the file.
0 pack64 ~ section header offset
0 pack32 ~ processor flags
64 pack16 ~ ELF header size
56 pack16 ~ program header entry size
1 pack16 ~ number of program header entries
0 pack16 ~ section header entry size
0 pack16 ~ number of section header entries
0 pack16 ~ section name string table index
;
~ ~~
~ ~~ Program header
~ ~~
~ ~~ An ELF program header consists of any number of these entries; they are
~ ~~ always consecutive, but may be anywhere in the file. We always have
~ ~~ exactly one, and it's always right after the ELF file header.
~ ~~
: elf-program-header
1 pack32 ~ "loadable" segment type
0x05 pack32 ~ read+execute permission
0 pack64 ~ offset in file
origin pack64 ~ virtual address
~ required, but can be anything, subject to alignment
0 pack64 ~ physical address (ignored)
~ Fill in 0 as the file size for now, to avoid uninitialized memory.
0 pack64 ~ size in file
~ TODO call use-label here
0 pack64 ~ size in memory
~ TODO call use-label here
0 pack64 ~ segment alignment
~ for relocation, but this doesn't apply to us
;
: output-start-routine
~ lit 1 :rax mov-reg64-imm32
;
: all-contents
~ current output point
elf-file-header
elf-program-header
output-start-routine
;
0x1000 allocate dup
~ output memory start, current output point
all-contents
~ output memory start, current output point
over - swap sys-write bye
|