diff options
| author | Irene Knapp <ireneista@irenes.space> | 2026-09-10 02:31:08 -0700 |
|---|---|---|
| committer | Irene Knapp <ireneista@irenes.space> | 2026-09-10 02:31:08 -0700 |
| commit | e2362acc76e4b689efe50ca7da40867336efd53c (patch) | |
| tree | 9b4eb84a8a6d7910f43b079f3269c67a7b92f6e3 | |
| parent | d36a2ffefd9206ee6dcc537d02ac4ecb3d8fe85c (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.e | 31 | ||||
| -rw-r--r-- | transform.e | 35 |
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. |