about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--elf.e99
-rw-r--r--transform.e119
2 files changed, 165 insertions, 53 deletions
diff --git a/elf.e b/elf.e
index a149a0f..82af2f5 100644
--- a/elf.e
+++ b/elf.e
@@ -8,6 +8,10 @@
 ~
 ~   This relies on the label facility defined in labels.e. Make sure to load
 ~ that first.
+~
+~   This file makes use of magic comments for the hex transform, described in
+~ detail in transform.e, but its use is trivial and doesn't require accounting
+~ conventions.
 
 ~ ~~~~~~~~~~~~~~~~~~~~~
 ~ ~~ ELF file header ~~
@@ -25,40 +29,47 @@
 : elf-file-header
   ~ : blank-line
   ~ : ELF file header
-  ~ * denotes mandatory fields according to breadbox
+  ~ : indent
+  ~ : * denotes mandatory fields according to breadbox
   current-offset 3unroll
 
-  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)
+  ~ : 1 suppress
+  0x7f pack8 s" ELF" pack-raw-string  ~ : -4 *magic number
+  2 pack8                             ~ : -1 64-bit
+  1 pack8                             ~ : -1 little-endian
+  1 pack8                             ~ : -1 ELF header format v1
+  0 pack8                             ~ : -1 System-V ABI
+  0 pack64                            ~ : -8 (padding)
+  ~ : blank-line
 
-  2 pack16                              ~ *executable
-  0x3e pack16                           ~ *Intel x86-64
-  1 pack32                              ~ ELF format version
+  2 pack16                            ~ : -2 *executable
+  0x3e pack16                         ~ : -2 *Intel x86-64
+  1 pack32                            ~ : -4 ELF format version
+  ~ : blank-line
 
-  L@' cold-start L@' origin + pack64        ~ *entry point
+  L@' cold-start L@' origin + pack64  ~ : -8 *entry point
     ~ This includes the origin, intentionally.
 
-  L@' elf-program-header pack64         ~ *program header offset
+  L@' elf-program-header pack64       ~ : -8 *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
+  0 pack64                            ~ : -8 section header offset
+  0 pack32                            ~ : -4 processor flags
+  ~ : blank-line
 
-  L@' elf-header-size pack16            ~ ELF header size
-  L@' elf-program-header-size 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
+  L@' elf-header-size pack16          ~ : -2 ELF header size
+  L@' elf-program-header-size pack16  ~ : -2 *program header entry size
+  1 pack16                            ~ : -2 *number of program header entries
+  0 pack16                            ~ : -2 section header entry size
+  0 pack16                            ~ : -2 number of section header entries
+  0 pack16                            ~ : -2 section name string table index
 
   ~   Though hardcoding the size of this header would work fine, it's easier
   ~ to use the label system to keep track of its size. The only place this is
   ~ actually referenced is right here in the header.
-  current-offset 4 roll - L!' elf-header-size ;
+  current-offset 4 roll - L!' elf-header-size
+  ~ : deindent
+  ;
 
 
 ~ ~~~~~~~~~~~~~~~~~~~~~~~~
@@ -90,26 +101,31 @@
 : elf-program-header
   ~ : blank-line
   ~ : ELF program header
+  ~ : indent
   ~ * denotes mandatory fields according to breadbox
   current-offset L!' elf-program-header
   current-offset 3unroll
 
-  1 pack32                              ~ *"loadable" segment type
-  0x05 pack32                           ~ *read+execute permission
-  0 pack64                              ~ *offset in file
-  L@' origin pack64                     ~ *virtual address
+  1 pack32                            ~ : -4 *"loadable" segment type
+  0x05 pack32                         ~ : -4 *read+execute permission
+  0 pack64                            ~ : -8 *offset in file
+  L@' origin pack64                   ~ : -8 *virtual address
     ~ required, but can be anything, subject to alignment
-  0 pack64                              ~ physical address (ignored)
+  0 pack64                            ~ : -8 physical address (ignored)
+  ~ : blank-line
 
-  L@' total-size pack64                 ~ *size in file
-  L@' total-size pack64                 ~ *size in memory
+  L@' total-size pack64               ~ : -8 *size in file
+  L@' total-size pack64               ~ : -8 *size in memory
+  ~ : blank-line
 
-  0 pack64                              ~ segment alignment
+  0 pack64                            ~ : 8 segment alignment
     ~ for relocation, but this doesn't apply to us
 
   ~   As with the file header, we use the label system to keep track of the
   ~ program header's size.
-  current-offset 4 roll - L!' elf-program-header-size ;
+  current-offset 4 roll - L!' elf-program-header-size
+  ~ : deindent
+  ;
 
 
 ~   This alternate version of the program header isn't used by evoke.e, but
@@ -118,26 +134,31 @@
 : elf-program-header-writable
   ~ : blank-line
   ~ : ELF program header
+  ~ : indent
   ~ * denotes mandatory fields according to breadbox
   current-offset L!' elf-program-header
   current-offset 3unroll
 
-  1 pack32                              ~ *"loadable" segment type
-  0x07 pack32                           ~ *read+write+execute permission
-  0 pack64                              ~ *offset in file
-  L@' origin pack64                     ~ *virtual address
+  1 pack32                            ~ : -4 *"loadable" segment type
+  0x07 pack32                         ~ : -4 *read+write+execute permission
+  0 pack64                            ~ : -8 *offset in file
+  L@' origin pack64                   ~ : -8 *virtual address
     ~ required, but can be anything, subject to alignment
-  0 pack64                              ~ physical address (ignored)
+  0 pack64                            ~ : -8 physical address (ignored)
+  ~ : blank-line
 
-  L@' total-size pack64                 ~ *size in file
-  L@' total-size pack64                 ~ *size in memory
+  L@' total-size pack64               ~ : -8 *size in file
+  L@' total-size pack64               ~ : -8 *size in memory
+  ~ : blank-line
 
-  0 pack64                              ~ segment alignment
+  0 pack64                            ~ : -8 segment alignment
     ~ for relocation, but this doesn't apply to us
 
   ~   As with the file header, we use the label system to keep track of the
   ~ program header's size.
-  current-offset 4 roll - L!' elf-program-header-size ;
+  current-offset 4 roll - L!' elf-program-header-size
+  ~ : deindent
+  ;
 
 ~ ~~~~~~~~~~~~~~~~
 ~ ~~ That's it! ~~
diff --git a/transform.e b/transform.e
index 77671cd..12c5483 100644
--- a/transform.e
+++ b/transform.e
@@ -2720,10 +2720,11 @@ allocate-transformation-state s" transformation-state" variable
 : hex-output-metadata-label-loop-buffer-start ;
 : hex-output-metadata-label-loop-buffer-length 8 + ;
 : hex-output-metadata-latest-output-point 2 8 * + ;
-: hex-output-metadata-is-fresh-line 3 8 * + ;
-: hex-output-metadata-indentation-depth 4 8 * + ;
-: hex-output-metadata-current-column 5 8 * + ;
-: hex-output-metadata-first-entry 6 8 * + ;
+: hex-output-metadata-suppression-count 3 8 * + ;
+: hex-output-metadata-is-fresh-line 4 8 * + ;
+: hex-output-metadata-indentation-depth 5 8 * + ;
+: hex-output-metadata-current-column 6 8 * + ;
+: hex-output-metadata-first-entry 7 8 * + ;
 : hex-output-metadata-entry-data-start ;
 : hex-output-metadata-entry-data-length 8 + ;
 : hex-output-metadata-entry-type 2 8 * + ;
@@ -2735,7 +2736,8 @@ allocate-transformation-state s" transformation-state" variable
 : hex-output-metadata-entry-type-blank-line 3 ;
 : hex-output-metadata-entry-type-indent 4 ;
 : hex-output-metadata-entry-type-string-literal 5 ;
-: hex-output-metadata-entry-type-alignment 6 ;
+: hex-output-metadata-entry-type-raw-string-literal 6 ;
+: hex-output-metadata-entry-type-alignment 7 ;
 
 ~   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
@@ -2748,6 +2750,7 @@ allocate-transformation-state s" transformation-state" variable
   dup hex-output-metadata-label-loop-buffer-start 0 swap !
   dup hex-output-metadata-label-loop-buffer-length 0 swap !
   dup hex-output-metadata-latest-output-point 0 swap !
+  dup hex-output-metadata-suppression-count 0 swap !
   dup hex-output-metadata-is-fresh-line 1 swap !
   dup hex-output-metadata-indentation-depth 0 swap !
   dup hex-output-metadata-current-column 0 swap !
@@ -2781,6 +2784,16 @@ allocate-transformation-state s" transformation-state" variable
 
 ~ (data start, data length, entry type, string pointer --)
 : add-hex-output-metadata-entry
+  ~ If the suppression count is greater than zero, decrement it.
+  transformation-state transformation-state-output-metadata @
+  hex-output-metadata-suppression-count @
+  dup 0 < {
+    1-
+    transformation-state transformation-state-output-metadata @
+    hex-output-metadata-suppression-count !
+    4 ndrop exit
+  } { drop } if-else
+
   3 pick is-in-label-loop-buffer {
     transformation-state transformation-state-output-metadata @
     hex-output-metadata-first-entry
@@ -2810,6 +2823,11 @@ allocate-transformation-state s" transformation-state" variable
     crash
   } if-else ;
 
+~ (count adjustment --)
+: adjust-hex-output-suppression-count
+  transformation-state transformation-state-output-metadata @
+  hex-output-metadata-suppression-count dup @ 3roll + swap ! ;
+
 ~   This is the followup to zero-hex-output-metadata, above. Once we do have
 ~ the label-loop buffer, we need to create some default entries. This is
 ~ called in the first label-loop iteration by hex-allocate-replacement, and
@@ -3024,23 +3042,33 @@ allocate-transformation-state s" transformation-state" variable
       memmove
       ~ (entry pointer)
 
+      ~   We have a feature which lets a suffix comment be created with a
+      ~ negative length, which means it covers bytes before the current output
+      ~ point rather than after it. This logic here is the implementation of
+      ~ that feature.
+      dup hex-output-metadata-entry-data-start @ dup
+      2 pick hex-output-metadata-entry-data-length @ +
+      2dup min 3unroll max
+      ~ (entry pointer, low end of data, high end of data)
+
       ~   Now we have the original entry at the original location, and a copy
       ~ of it at the next location. We modify the original one in-place to
-      ~ turn it into a fresh-line entry...
-      dup hex-output-metadata-entry-type
+      ~ turn it into a fresh-line entry at the low end of the data...
+      2 pick hex-output-metadata-entry-type
       hex-output-metadata-entry-type-fresh-line swap !
 
-      dup hex-output-metadata-entry-data-length 0 swap !
+      2 pick hex-output-metadata-entry-data-start 3roll swap !
+      2 pick hex-output-metadata-entry-data-length 0 swap !
+      ~ (entry pointer, high end of data)
 
       ~   ... then we modify the next entry in-place to set its location to
       ~ the end of the data instead of the beginning, and its length to zero.
-      dup hex-output-metadata-next-entry
-      ~ (entry pointer, next entry pointer)
+      over hex-output-metadata-next-entry
+      ~ (entry pointer, high end of data, next entry pointer)
 
-      dup hex-output-metadata-entry-data-length @
-      over hex-output-metadata-entry-data-start @ +
-      over hex-output-metadata-entry-data-start !
+      dup hex-output-metadata-entry-data-start 3roll swap !
       hex-output-metadata-entry-data-length 0 swap !
+      ~ (entry pointer)
 
       ~   This rule won't fire again on the fresh-line entry because it's of a
       ~ different type, and it won't fire on the modified suffix-comment entry
@@ -3122,7 +3150,22 @@ allocate-transformation-state s" transformation-state" variable
           fresh-line
           indentation-depth@ dup indent advance-current-column
 
-          ." ~ Null-terminated string literal: "
+          ." ~ String literal with null terminator: "
+          0x22 value@ emitstring drop
+          dup hex-output-metadata-entry-string @ emitstring
+          0x22 value@ emitstring drop
+
+          newline
+          1 is-fresh-line!
+          0 current-column!
+        } if
+
+        dup hex-output-metadata-entry-type @
+        hex-output-metadata-entry-type-raw-string-literal = {
+          fresh-line
+          indentation-depth@ dup indent advance-current-column
+
+          ." ~ String literal with no terminator: "
           0x22 value@ emitstring drop
           dup hex-output-metadata-entry-string @ emitstring
           0x22 value@ emitstring drop
@@ -3385,6 +3428,47 @@ allocate-transformation-state s" transformation-state" variable
     exit
   } if
 
+  ~ This is highly similar to packstring.
+  dup s" pack-raw-string" stringcmp 0 = {
+    create dropstring
+    s" docol" find entry-to-execution-token execute ,
+    make-hidden
+
+    ~ (output point, string pointer)
+    s" 2dup" find entry-to-execution-token ,
+    s" dup" find entry-to-execution-token ,
+    s" stringlen" find entry-to-execution-token ,
+    ~ (output point, string pointer, string length NOT including terminator)
+
+    ~   Before we add the metadata entry, we also want to call hex-pack-trace
+    ~ to make sure latest-output-point gets adjusted for the string.
+    ~ Otherwise, we'd see magic comments in the wrong place.
+    s" 3roll" find entry-to-execution-token ,
+    s" dup" find entry-to-execution-token ,
+    s" lit" find entry-to-execution-token ,
+    4 ,
+    s" unroll" find entry-to-execution-token ,
+    s" swap" find entry-to-execution-token ,
+    s" dup" find entry-to-execution-token ,
+    s" 3unroll" find entry-to-execution-token ,
+    ~ (output point, string pointer, string length NOT including terminator,
+    ~  output point, string length NOT including terminator)
+    ' hex-pack-trace entry-to-execution-token ,
+
+    ~ (output point, string pointer, string length including terminator)
+    s" swap" find entry-to-execution-token ,
+    ' hex-output-metadata-entry-type-raw-string-literal
+    entry-to-execution-token ,
+    s" swap" find entry-to-execution-token ,
+    ' add-hex-output-metadata-entry entry-to-execution-token ,
+    ~ (output point, string pointer)
+    ~ Fall through to the inner implementation.
+
+    ' ] entry-to-execution-token execute
+    exit
+  } if
+
+
   dup s" pack8" stringcmp 0 = {
     create dropstring
     s" docol" find entry-to-execution-token execute ,
@@ -3888,6 +3972,13 @@ allocate-transformation-state s" transformation-state" variable
     exit
   } if
 
+  dup s" suppress" stringcmp 0 = {
+    ~   Suppress the next N entries, or adjust the remaining count of entries
+    ~ to suppress.
+    drop swap drop adjust-hex-output-suppression-count
+    exit
+  } if
+
   dup s" fresh-line" stringcmp 0 = {
     ~ Create a new fresh-line entry.
     drop hex-output-metadata-entry-type-fresh-line 0