diff options
| author | Irene Knapp <ireneista@irenes.space> | 2026-05-07 17:57:28 -0700 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2026-05-07 17:57:28 -0700 |
| commit | 0c7e96417a3691f59807243a9841c6f5e631edfa (patch) | |
| tree | 115559261cd5ac6674bd9d59dca4ff26ac99d1ae | |
| parent | d33ffd64d77b3d8e088f7dfd01794d683bb9ea47 (diff) | |
refactored the label code and ELF template into their own files
nice, right? :) modular programming! :D Force-Push: yes Change-Id: I56dd219fd2147850a0bb5b4a8cb3f9760e787215
| -rw-r--r-- | elf.e | 57 | ||||
| -rw-r--r-- | hello.e | 35 | ||||
| -rw-r--r-- | labels.e (renamed from make-hello.e) | 109 |
3 files changed, 92 insertions, 109 deletions
diff --git a/elf.e b/elf.e new file mode 100644 index 0000000..4224b50 --- /dev/null +++ b/elf.e @@ -0,0 +1,57 @@ +~ ~~ +~ ~~ 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 + + L' start use-label origin + pack64 ~ entry point + ~ This includes the origin, intentionally. + + L' program-header use-label 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 + current-offset L' program-header set-label + 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) + + L' total-size use-label pack64 ~ size in file + L' total-size use-label pack64 ~ size in memory + + 0 pack64 ~ segment alignment + ~ for relocation, but this doesn't apply to us + ; + diff --git a/hello.e b/hello.e new file mode 100644 index 0000000..63f19c4 --- /dev/null +++ b/hello.e @@ -0,0 +1,35 @@ +~ cat labels.e elf.e hello.e | ./quine > hello && chmod 755 hello && ./hello + +: output-start-routine + current-offset L' start set-label + 1 :rax mov-reg64-imm32 + 1 :rdi mov-reg64-imm64 + origin L' greeting use-label + :rsi mov-reg64-imm64 + L' greeting-size use-label :rdx mov-reg64-imm64 + syscall + 60 :rax mov-reg64-imm32 + 0 :rdi mov-reg64-imm32 + syscall + ; + +: output-greeting + current-offset dup L' greeting set-label 3unroll + s" Hello, Irenes!" packstring + current-offset 4 roll - L' greeting-size set-label ; + +~ (output memory start, current output point +~ -- output memory start, current output point) +~ +~ Everything directly called by all-contents has this same interface. +~ +: all-contents + elf-file-header + elf-program-header + output-start-routine + output-greeting + current-offset L' total-size set-label + ; + +' all-contents entry-to-execution-token label-loop +swap sys-write bye + diff --git a/make-hello.e b/labels.e index c4bbb9e..9c91fb6 100644 --- a/make-hello.e +++ b/labels.e @@ -140,112 +140,3 @@ init-labels reset-labels } while drop drop drop ." Failed after " . ." iterations." newline ; -~ ~~ -~ ~~ 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 - L' start use-label origin + pack64 - ~ This includes the origin, intentionally. - - L' program-header use-label pack64 - ~ 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 - current-offset L' program-header set-label - 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) - - L' total-size use-label pack64 ~ size in file - L' total-size use-label pack64 ~ size in memory - - 0 pack64 ~ segment alignment - ~ for relocation, but this doesn't apply to us - ; - -: output-start-routine - current-offset L' start set-label - 1 :rax mov-reg64-imm32 - 1 :rdi mov-reg64-imm64 - origin L' greeting use-label + :rsi mov-reg64-imm64 - L' greeting-size use-label :rdx mov-reg64-imm64 - syscall - 60 :rax mov-reg64-imm32 - 0 :rdi mov-reg64-imm32 - syscall - ; - -: output-greeting - current-offset dup L' greeting set-label 3unroll - s" Hello, Irenes!" packstring - current-offset 4 roll - L' greeting-size set-label ; - -~ (output memory start, current output point -~ -- output memory start, current output point) -~ -~ Everything directly called by all-contents has this same interface. -~ -: all-contents - elf-file-header - elf-program-header - output-start-routine - output-greeting - current-offset L' total-size set-label - ; - -~ 0x1000 allocate dup -~ output memory start, current output point - -~ all-contents -~ check-labels-converged . newline -~ list-labels reset-labels list-labels - -~ The two-pass magick: Reset the output offset to the beginning of the block. -~ drop dup - -~ all-contents -~ check-labels-converged . newline -~ list-labels reset-labels list-labels - -~ output memory start, current output point -~ over - swap sys-write bye -' all-contents entry-to-execution-token label-loop -swap sys-write bye - |