about summary refs log tree commit diff
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2026-09-10 02:31:08 -0700
committerIrene Knapp <ireneista@irenes.space>2026-09-10 02:31:08 -0700
commite2362acc76e4b689efe50ca7da40867336efd53c (patch)
tree9b4eb84a8a6d7910f43b079f3269c67a7b92f6e3
parentd36a2ffefd9206ee6dcc537d02ac4ecb3d8fe85c (diff)
fix all leaks and incorrect parameter counts in amd64.e
this required adding a new magic-comment command, drop-subitem, because there's a couple cases, in indexed addressing mode helpers, where a hardcoded register value is used as part of preparing an sib word, and that value shouldn't become a subitem for the assembly word that calls the helper.

notably, a lot of the disp8 and indexed assembly words had incorrect parameter counts that needed adjusting

parameter ORDERS still need a close read to make sure they're correct.  also, as future work, substring entries should be renamed to subitem entries.

Force-Push: yes
Change-Id: I419243855751416377d0ea0c5062fa1ba9e62a8d
-rw-r--r--amd64.e31
-rw-r--r--transform.e35
2 files changed, 49 insertions, 17 deletions
diff --git a/amd64.e b/amd64.e
index e647f9b..ba78bc4 100644
--- a/amd64.e
+++ b/amd64.e
@@ -496,7 +496,10 @@ s" :cc-greater" keyword
     reg64 0 3unroll modrm
     ~ (equality result, output point)
     ~ If the R/M register was rsp, we need an SIB byte; otherwise, skip it.
-    swap { 0 4 :rsp reg64 sib } if
+    swap {
+      0 4 :rsp reg64 sib
+      ~ : drop-subitem
+    } if
     exit
   } if
   ." R/M parameter to addressing-indirect-reg64 is :rbp." 1 sys-exit ;
@@ -511,7 +514,10 @@ s" :cc-greater" keyword
   4 unroll
   reg64 1 3unroll modrm
   ~ If the R/M register was rsp, we need an SIB byte; otherwise, skip it.
-  3roll { 0 4 :rsp reg64 sib } if
+  3roll {
+    0 4 :rsp reg64 sib
+    ~ : drop-subitem
+  } if
   ~ The displacement byte.
   swap
   ~ : 1 adjust-length
@@ -528,7 +534,10 @@ s" :cc-greater" keyword
   4 unroll
   reg64 2 3unroll modrm
   ~ If the R/M register was rsp, we need an SIB byte; otherwise, skip it.
-  3roll { 0 4 :rsp reg64 sib } if
+  3roll {
+    0 4 :rsp reg64 sib
+    ~ : drop-subitem
+  } if
   ~ The displacement value.
   swap
   ~ : 4 adjust-length
@@ -584,20 +593,20 @@ s" :cc-greater" keyword
 
 ~ (output point, source register -- output point)
 : push-reg64
-  ~ : 0 push-reg64
+  ~ : 0 # push-reg64
   reg64 0x50 opcodereg ;
 : push-extrareg64
-  ~ : 0 push-extrareg64
+  ~ : 0 # push-extrareg64
   swap rex-b swap extrareg64 0x50 opcodereg ;
   ~   Note the use of the B rex bit here; this instruction puts the register
   ~ number in the opcode field, so it uses Table 3-1.
 
 ~ (output point, target register -- output point)
 : pop-reg64
-  ~ : 1 pop-reg64
+  ~ : 1 # pop-reg64
   reg64 0x58 opcodereg ;
 : pop-extrareg64
-  ~ : 2 pop-extrareg64
+  ~ : 2 # pop-extrareg64
   swap rex-b swap extrareg64 0x58 opcodereg ;
   ~   Note the use of the B rex bit here; this instruction puts the register
   ~ number in the opcode field, so it uses Table 3-1.
@@ -627,7 +636,7 @@ s" :cc-greater" keyword
 ~  source base register, source index register, source index scale factor,
 ~  target register -- output point)
 : lea-reg64-indexed-reg64
-  ~ : 1 # # # lea-reg64-indexed-reg64
+  ~ : 1 # # # # lea-reg64-indexed-reg64
   5 roll rex-w 0x8D pack8 5 unroll
   reg64 4 unroll 3unroll swap addressing-indexed-reg64 ;
 
@@ -636,7 +645,7 @@ s" :cc-greater" keyword
 ~  source displacement value,
 ~  target register -- output point)
 : lea-reg64-disp8-indexed-reg64
-  ~ : 1 # # # # lea-reg64-disp8-indexed-reg64
+  ~ : 1 # # # # # lea-reg64-disp8-indexed-reg64
   6 roll rex-w 0x8D pack8 6 unroll
   reg64 5 unroll 3 roll 4 roll 3 roll addressing-disp8-indexed-reg64 ;
 
@@ -714,7 +723,7 @@ s" :cc-greater" keyword
 ~  source base register, source index register, source index scale factor,
 ~  target register -- output point)
 : mov-reg64-indexed-reg64
-  ~ : 1 # # # mov-reg64-indexed-reg64
+  ~ : 1 # # # # mov-reg64-indexed-reg64
   5 roll rex-w 0x8B pack8 5 unroll
   reg64 4 unroll 3unroll swap addressing-indexed-reg64 ;
 
@@ -722,7 +731,7 @@ s" :cc-greater" keyword
 ~  target base register, target index register, target index scale factor
 ~  -- output point)
 : mov-indexed-reg64-reg64
-  ~ : 1 # # # mov-indexed-reg64-reg64
+  ~ : 1 # # # # mov-indexed-reg64-reg64
   5 roll rex-w 0x89 pack8 5 unroll
   4 roll reg64 4 unroll
   3unroll swap addressing-indexed-reg64 ;
diff --git a/transform.e b/transform.e
index 95475c2..9a2cb21 100644
--- a/transform.e
+++ b/transform.e
@@ -2785,6 +2785,7 @@ allocate-transformation-state s" transformation-state" variable
 ~   ~ : provide-hex32
 ~   ~ : provide-hex64
 ~   ~ : provide-keyword
+~   ~ : drop-subitem
 ~
 ~   By the way, the reason it's possible to write these examples is that
 ~ they're all embedded within an outer comment, the text you're reading, so
@@ -3072,11 +3073,13 @@ allocate-transformation-state s" transformation-state" variable
 ~
 ~   Where do those items come from? Well, there's a separate stack, the
 ~ substring entry stack, which is kept in the hex output metadata header. The
-~ substring entry stack has an extremely small, fixed maximum depth. Unusually
-~ for Evocation, if you underflow or overflow it, you'll get a friendly error
-~ message rather than a segfault - how nice! Of course, the error message will
-~ appear in the middle of your regular output and corrupt it, but you can't
-~ have everything...
+~ substring entry stack has an extremely small, fixed maximum depth. The
+~ maximum depth is deliberately small, so that any leaks onto it will be
+~ detected somewhere close to their root causes, for ease  of diagnosis.
+~ Unusually for Evocation, if you underflow or overflow it, you'll get a
+~ friendly error message rather than a segfault - how nice! Of course, the
+~ error message will appear in the middle of your regular output and corrupt
+~ it, but you can't have everything...
 ~
 ~   Each time a comment template is being filled and encounters a #
 ~ placeholder, an item is popped off the substring entry stack and formatted
@@ -3133,6 +3136,11 @@ allocate-transformation-state s" transformation-state" variable
 ~ entry pops it off the substring entry stack and pretty-prints the value it
 ~ holds.
 ~
+~   With all this context, it likely doesn't need much explanation, but the
+~ drop-subitem command will create an -entry-type-drop-substring entry. When
+~ this entry is executed, it will discard an item from the substring entry
+~ stack.
+~
 ~   One more thing: The order in which provide-* commands execute will most
 ~ likely match the order in which the corresponding bytes are output. This may
 ~ not always match the order in which the comment template wants to
@@ -3173,7 +3181,7 @@ allocate-transformation-state s" transformation-state" variable
 : hex-output-metadata-current-column 7 8 * + ;
 : hex-output-metadata-substring-entry-stack-depth 8 8 * + ;
 : hex-output-metadata-substring-entry-stack-zero 9 8 * + ;
-: hex-output-metadata-substring-entry-stack-capacity 3 ;
+: hex-output-metadata-substring-entry-stack-capacity 8 ;
 : hex-output-metadata-first-entry
   9 hex-output-metadata-substring-entry-stack-capacity + 8 * + ;
 : hex-output-metadata-entry-data-start ;
@@ -3196,6 +3204,7 @@ allocate-transformation-state s" transformation-state" variable
 : hex-output-metadata-entry-type-push-substring-hex32 11 ;
 : hex-output-metadata-entry-type-push-substring-hex64 12 ;
 : hex-output-metadata-entry-type-push-substring-string 13 ;
+: hex-output-metadata-entry-type-drop-substring 14 ;
 
 ~   Initialize the contents of the output metadata to all zeroes. This is
 ~ called from hex-transform at its top level, at the very start, to make sure
@@ -3243,6 +3252,7 @@ allocate-transformation-state s" transformation-state" variable
   || ;
 
 : is-push-substring-entry
+  ~ Notably, -entry-type-drop-substring is not a push-substring entry.
   hex-output-metadata-entry-type @
   dup hex-output-metadata-entry-type-push-substring-decimal = swap
   dup hex-output-metadata-entry-type-push-substring-hex8 = 3roll || swap
@@ -3979,6 +3989,11 @@ allocate-transformation-state s" transformation-state" variable
         dup is-push-substring-entry {
           dup push-substring-entry-stack
         } if
+
+        dup hex-output-metadata-entry-type @
+        hex-output-metadata-entry-type-drop-substring = {
+          pop-substring-entry-stack drop
+        } if
       } if
       hex-output-metadata-next-entry
     } while
@@ -4860,6 +4875,14 @@ allocate-transformation-state s" transformation-state" variable
     add-hex-output-metadata-entry
     exit
   } if
+  dup s" drop-subitem" stringcmp 0 = {
+    ~ Create a new "drop substring" entry.
+    drop drop
+    2 pick execution-token-to-entry entry-to-name
+    hex-output-metadata-entry-type-drop-substring swap
+    add-hex-output-metadata-entry
+    exit
+  } if
 
   ~   If it's flagged as a suffix by the logic above, create a new
   ~ suffix-comment entry.