summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-05-07 17:57:28 -0700
committerIrene Knapp <ireneista@irenes.space>2026-05-07 17:57:28 -0700
commit0c7e96417a3691f59807243a9841c6f5e631edfa (patch)
tree115559261cd5ac6674bd9d59dca4ff26ac99d1ae
parentd33ffd64d77b3d8e088f7dfd01794d683bb9ea47 (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.e57
-rw-r--r--hello.e35
-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
-