mescc: Produce object files in hex2 format, remove hex3.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sun, 25 Jun 2017 07:33:55 +0000 (09:33 +0200)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sun, 25 Jun 2017 07:33:55 +0000 (09:33 +0200)
* GNUmakefile (HEX2_FLAGS): New variable.
* make/mescc-guile.make ($(OUT)/$(TARGET)): Use HEX2 for linking.
* make/mescc-mes.make ($(OUT)/$(TARGET)): Likewise.
* guile/mescc.scm (main): Remove hex3 support.
* scripts/mescc.mes (main): Likewise.
* stage0/elf32-0header.hex2: New file, merging of elf32.hex and elf32-header.hex2.
* stage0/elf-0footer.hex2: New file.
* stage0/elf32-header.hex2: Rename from elf32-header-exit-42.hex2,
  repurpose as generic debug heder.
* stage0/elf32-footer-single-main.hex2: Rename from elf32-footer-exit-42.hex2,
  repurpose as generic debug footer for single-main source.
* stage0/exit-42.c: New file.
* stage0/stage0.make ($(OUT)/0exit-42): Test 0header, 0footer.
  ($(OUT)/exit-42.guile): Test generic debug header, footer.
* stage0/elf32.hex2: Remove.

18 files changed:
GNUmakefile
guile/mescc.scm
make/mescc-guile.make
make/mescc-mes.make
module/language/c99/compiler.mes
module/mes/as-i386.mes
module/mes/hex2.mes
module/mes/hex2.scm
scripts/mescc.mes
stage0/elf-0footer.hex2 [new file with mode: 0644]
stage0/elf32-0header.hex2 [new file with mode: 0644]
stage0/elf32-footer-exit-42.hex2 [deleted file]
stage0/elf32-footer-single-main.hex2 [new file with mode: 0644]
stage0/elf32-header-exit-42.hex2 [deleted file]
stage0/elf32-header.hex2 [new file with mode: 0644]
stage0/elf32.hex2 [deleted file]
stage0/exit-42.c [new file with mode: 0644]
stage0/stage0.make

index ddd4b3520c1a282a30a33941149f841104c6f1be..f595e8488b565badaaa45e3dfcfbb82931c178f8 100644 (file)
@@ -7,6 +7,7 @@ default: all
 
 MES_DEBUG:=1
 CFLAGS:=--std=gnu99 -O0 -g --include libc-gcc.c
+HEX2_FLAGS:=--LittleEndian --Architecture 1 --BaseAddress 0x1000000
 OUT:=out
 
 SUBDIRS:=\
index a00f349d4f0a4f47e57608ff231b086b07bb9c05..7e53951e635d87e524c0cbdb1dad6ffa2fa6f665 100755 (executable)
@@ -79,7 +79,7 @@ Usage: mescc.scm [OPTION]... FILE...
   -c                 compile and assemble, but do not link
   -D DEFINE          define DEFINE
   -E                 preprocess only; do not compile, assemble or link
-  -g                 add debug info [GDB, objdump] using hex3 format
+  -g                 add debug info [GDB, objdump] TODO: hex2 footer
   -h, --help         display this help and exit
   -I DIR             append DIR to include path
   -o FILE            write output to FILE
@@ -136,8 +136,7 @@ Usage: mescc.scm [OPTION]... FILE...
                                            (else "a.out"))))
          (multi-opt (lambda (option) (lambda (o) (and (eq? (car o) option) (cdr o)))))
          (defines (reverse (filter-map (multi-opt 'D) options)))
-         (includes (reverse (filter-map (multi-opt 'I) options)))
-         (objects->hex (if debug-info? objects->hex3 objects->hex2)))
+         (includes (reverse (filter-map (multi-opt 'I) options))))
     (when (getenv "MES_DEBUG") (format (current-error-port) "options=~s\n" options)
           (format (current-error-port) "output: ~a\n" out))
     (if (and (pair? sources) (pair? objects)) (error "cannot mix source and object files:" files))
@@ -146,16 +145,16 @@ Usage: mescc.scm [OPTION]... FILE...
         (if (and (not compile?)
                  (not preprocess?)) (set-port-encoding! (current-output-port) "ISO-8859-1"))
         (cond ((pair? objects) (let ((objects (map read-object objects)))
-                                 (if compile? (objects->hex objects)
+                                 (if compile? (objects->hex2 objects)
                                      (objects->elf objects))))
               ((pair? asts) (let* ((infos (map main:ast->info asts))
                                    (objects (map info->object infos)))
-                              (if compile? (objects->hex objects)
+                              (if compile? (objects->hex2 objects)
                                   (objects->elf objects))))
               ((pair? sources) (if preprocess? (map (source->ast defines includes) sources)
                                    (let* ((infos (map (source->info defines includes) sources))
                                           (objects (map info->object infos)))
-                                     (if compile? (objects->hex objects)
+                                     (if compile? (objects->hex2 objects)
                                          (objects->elf objects))))))))
     (if (and (not compile?)
              (not preprocess?))
index 74e393f3800a83d942b2a7ee83957257782a059b..1f462065c7a59b5788a86847edead5671e5ca86a 100644 (file)
@@ -16,9 +16,14 @@ CLEAN+=$(OUT)/$(TARGET)
 
 INCLUDES+=mlibc/include mlibc $(OUT)/$(DIR)
 MESCC.scm:=guile/mescc.scm -g
-MESLD.scm:=guile/mescc.scm -g
+LINK.hex2:=$(HEX2)
+#ELF_HEADER:=stage0/elf32-0header.hex2
+#ELF_FOOTER:=stage0/elf-0footer.hex2
+ELF_HEADER:=stage0/elf32-header.hex2
+ELF_FOOTER:=stage0/elf32-footer-single-main.hex2
 
-$(OUT)/$(TARGET): ld:=MESLD.scm
+
+$(OUT)/$(TARGET): ld:=$(LINK.hex2)
 $(OUT)/$(TARGET): LD:=$(MESLD.scm)
 $(OUT)/$(TARGET): CC:=$(MESCC.scm)
 $(OUT)/$(TARGET): CFLAGS:=
@@ -26,7 +31,8 @@ $(OUT)/$(TARGET): LDFLAGS:=
 $(OUT)/$(TARGET): O_FILES:=$(O_FILES)
 $(OUT)/$(TARGET): $(O_FILES)
        @echo "  $(ld)  $(notdir $(O_FILES)) -> $(notdir $@)"
-       $(QUIET)$(LINK.c) $(O_FILES) $(LOADLIBES) $(LDLIBS) -o $@
+       $(QUIET)$(LINK.hex2) $(HEX2_FLAGS) -f $(ELF_HEADER) $(O_FILES:%=-f %) $(LOADLIBES:%=-f %) $(LDLIBS:%=-f %) -f $(ELF_FOOTER) > $@ || { rm -f $@; exit 1;}
+       @chmod +x $@
 
 define mescc.scm-c-compile
 $(OUT)/$(1:.c=.$(CROSS)o): CROSS:=$(CROSS)
index c55bd842a01609dcf8732cac0cf76914ff186328..bb542725904c06937c686155ddeb7ae4b2626e74 100644 (file)
@@ -16,6 +16,11 @@ CLEAN+=$(OUT)/$(TARGET)
 INCLUDES+=mlibc/include mlibc $(OUT)/$(DIR)
 MESCC.mes:=scripts/mescc.mes -g
 MESLD.mes:=scripts/mescc.mes -g
+LINK.hex2:=$(HEX2)
+#ELF_HEADER:=stage0/elf32-0header.hex2
+#ELF_FOOTER:=stage0/elf-0footer.hex2
+ELF_HEADER:=stage0/elf32-header.hex2
+ELF_FOOTER:=stage0/elf32-footer-single-main.hex2
 
 $(OUT)/$(TARGET): ld:=MESLD.mes
 $(OUT)/$(TARGET): LD:=$(MESLD.mes)
@@ -27,7 +32,8 @@ $(OUT)/$(TARGET): scripts/mes
 $(OUT)/$(TARGET): O_FILES:=$(O_FILES)
 $(OUT)/$(TARGET): $(O_FILES)
        @echo "  $(ld)  $(notdir $(O_FILES)) -> $(notdir $@)"
-       $(QUIET)$(LINK.c) $(O_FILES) $(LOADLIBES) $(LDLIBS) -o $@
+       $(QUIET)$(LINK.hex2) $(HEX2_FLAGS) -f $(ELF_HEADER) $(O_FILES:%=-f %) $(LOADLIBES:%=-f %) $(LDLIBS:%=-f %) -f $(ELF_FOOTER) > $@ || { rm -f $@; exit 1;}
+       @chmod +x $@
 
 define mescc.mes-c-compile
 $(OUT)/$(1:.c=.$(CROSS)o): CROSS:=$(CROSS)
index c0fa4b0947c8b126da8b14e5869083c3c6618c98..95273785280983a8ea8b86257c35b0c95d1c7db3 100644 (file)
                      (if (and (not (assoc name (.functions info)))
                               (not (assoc name globals)))
                          (stderr "warning: undeclared function: ~a\n" name))
-                     (append-text args-info (list (i386:call-label `(#:relative ,name) n))))
+                     (append-text args-info (list (i386:call-label name n))))
                    (let* ((empty (clone info #:text '()))
                           (accu ((expr->accu empty) `(p-expr (ident ,name)))))
                      (append-text args-info (append (.text accu)
         ((lt ,a ,b) ((binop->accu info) b a (i386:base-sub)))
 
         ((or ,a ,b)
-         (let* ((here (number->string (length (.text info))))
-                (skip-b-label (string-append (.function info) "_skip_b_" here))
-                (info ((expr->accu info) a))
+         (let* ((info ((expr->accu info) a))
+                (here (number->string (length (.text info))))
+                (skip-b-label (string-append (.function info) "_" here "_or_skip_b"))
                 (info (append-text info (wrap-as (i386:accu-test))))
-                (info (append-text info (wrap-as (i386:jump-nz `(#:local ,skip-b-label)))))
+                (info (append-text info (wrap-as (i386:jump-nz skip-b-label))))
                 (info (append-text info (wrap-as (i386:accu-test))))
                 (info ((expr->accu info) b))
                 (info (append-text info (wrap-as (i386:accu-test))))
            info))
 
         ((and ,a ,b)
-         (let* ((here (number->string (length (.text info))))
-                (skip-b-label (string-append (.function info) "_skip_b_" here))
-                (info ((expr->accu info) a))
+         (let* ((info ((expr->accu info) a))
+                (here (number->string (length (.text info))))
+                (skip-b-label (string-append (.function info) "_" here "_and_skip_b"))
                 (info (append-text info (wrap-as (i386:accu-test))))
-                (info (append-text info (wrap-as (i386:jump-z `(#:local ,skip-b-label)))))
+                (info (append-text info (wrap-as (i386:jump-z skip-b-label))))
                 (info (append-text info (wrap-as (i386:accu-test))))
                 (info ((expr->accu info) b))
                 (info (append-text info (wrap-as (i386:accu-test))))
            (append-text info ((ident-add info) name -1)))) ;; FIXME: size
 
         ((assn-expr ,a (op ,op) ,b)
-         (let* ((info ((expr->accu info) b))
+         (let* ((info (append-text info (ast->comment o)))
+                (info ((expr->accu info) b))
                 (info (if (equal? op "=") info
                           (let* ((info (append-text info (wrap-as (i386:push-accu))))
                                  (info ((expr->accu info) a))
 (define (wrap-as o . annotation)
   `(,@annotation ,o))
 
+(define (make-comment o)
+  (wrap-as `(#:comment ,o)))
+
+(define (ast->comment o)
+  (let ((source (with-output-to-string (lambda () (pretty-print-c99 o)))))
+    (make-comment (string-join (string-split source #\newline) " "))))
+
 (define (expr->accu* info)
   (lambda (o)
     (pmatch o
   (define body-label
     (string-append label "body" (number->string i)))
   (define (jump label)
-    (wrap-as (i386:jump `(#:local ,label))))
+    (wrap-as (i386:jump label)))
   (define (jump-nz label)
-    (wrap-as (i386:jump-nz `(#:local ,label))))
+    (wrap-as (i386:jump-nz label)))
   (define (jump-z label)
-    (wrap-as (i386:jump-z `(#:local ,label))))
+    (wrap-as (i386:jump-z label)))
   (define (test->text test)
     (let ((value (pmatch test
                    (0 0)
               (jump-z body-label))))
   (define (cases+jump info cases)
     (let* ((info (append-text info (wrap-as `(#:label ,clause-label))))
-           (next-clause-label (string-append label "clause"
-                                             (number->string (1+ i))))
+           (next-clause-label (if last? (string-append label "break")
+                                  (string-append label "clause" (number->string (1+ i)))))
            (info (append-text info (apply append cases)))
            (info (if (null? cases) info
                      (append-text info (jump next-clause-label))))
            (if last? clause
                (let ((next-body-label (string-append label "body"
                                                      (number->string (1+ i)))))
-                 (append-text clause (wrap-as (i386:jump `(#:local ,next-body-label))))))))
+                 (append-text clause (wrap-as (i386:jump next-body-label)))))))
         (_
          (let ((clause (or clause (cases+jump info cases))))
            (loop '() cases
   (define (jump type . test)
     (lambda (o)
       (let* ((info ((ast->info info) o))
-             (info (append-text info (wrap-as `(#:comment "jmp test LABEL"))))
-             (jump-text (wrap-as (type `(#:local ,label)))))
+             (info (append-text info (make-comment "jmp test LABEL")))
+             (jump-text (wrap-as (type label))))
         (append-text info (append (if (null? test) '() (car test))
                                   jump-text)))))
   (lambda (o)
               (skip-b-label (string-append label "_skip_b_" here))
               (b-label (string-append label "_b_" here))
               (info ((test-jump-label->info info b-label) a))
-              (info (append-text info (wrap-as (i386:jump `(#:local ,skip-b-label)))))
+              (info (append-text info (wrap-as (i386:jump skip-b-label))))
               (info (append-text info (wrap-as `(#:label ,b-label))))
               (info ((test-jump-label->info info label) b))
               (info (append-text info (wrap-as `(#:label ,skip-b-label)))))
 
         ((break)
          (let ((label (car (.break info))))
-           (append-text info (wrap-as (i386:jump `(#:local ,label))))))
+           (append-text info (wrap-as (i386:jump label)))))
 
         ((continue)
          (let ((label (car (.continue info))))
-           (append-text info (wrap-as (i386:jump `(#:local ,label))))))
+           (append-text info (wrap-as (i386:jump label)))))
 
         ;; FIXME: expr-stmt wrapper?
         (trans-unit info)
         ((compd-stmt (block-item-list . ,statements)) ((ast-list->info info) statements))
         
         ((expr-stmt (fctn-call (p-expr (ident ,name)) (expr-list . ,expr-list)))
-         (let* ((source (with-output-to-string (lambda () (pretty-print-c99 o))))
-                (info (append-text info (wrap-as `(#:comment ,source)))))
-           (if (equal? name "asm") (let ((arg0 (cadr (cadar expr-list))))
-                                     (append-text info (wrap-as (asm->hex arg0))))
-              (let ((info ((expr->accu info) `(fctn-call (p-expr (ident ,name)) (expr-list . ,expr-list)))))
-                (append-text info (wrap-as (i386:accu-zero?)))))))
+         (if (equal? name "asm") (let ((arg0 (cadr (cadar expr-list))))
+                                   (append-text info (wrap-as (asm->hex arg0))))
+             (let* ((info (append-text info (ast->comment o)))
+                    (info ((expr->accu info) `(fctn-call (p-expr (ident ,name)) (expr-list . ,expr-list)))))
+               (append-text info (wrap-as (i386:accu-zero?))))))
 
         ((if ,test ,then)
-         (let* ((source (with-output-to-string (lambda () (pretty-print-c99 `(if ,test (ellipsis))))))
-                (info (append-text info (wrap-as `(#:comment ,source))))
+         (let* ((info (append-text info (ast->comment `(if ,test (ellipsis)))))
                 (here (number->string (length text)))
                 (label (string-append (.function info) "_" here "_"))
                 (break-label (string-append label "break"))
                 (else-label (string-append label "else"))
                 (info ((test-jump-label->info info break-label) test))
                 (info ((ast->info info) then))
-                (info (append-text info (wrap-as (i386:jump `(#:local ,break-label)))))
+                (info (append-text info (wrap-as (i386:jump break-label))))
                 (info (append-text info (wrap-as `(#:label ,break-label)))))
            (clone info
                   #:locals locals)))
 
         ((if ,test ,then ,else)
-         (let* ((source (with-output-to-string (lambda () (pretty-print-c99 `(if ,test (ellipsis) (ellipsis))))))
-                (info (append-text info (wrap-as `(#:comment ,source))))
+         (let* ((info (append-text info (ast->comment `(if ,test (ellipsis) (ellipsis)))))
                 (here (number->string (length text)))
                 (label (string-append (.function info) "_" here "_"))
                 (break-label (string-append label "break"))
                 (else-label (string-append label "else"))
                 (info ((test-jump-label->info info else-label) test))
                 (info ((ast->info info) then))
-                (info (append-text info (wrap-as (i386:jump `(#:local ,break-label)))))
+                (info (append-text info (wrap-as (i386:jump break-label))))
                 (info (append-text info (wrap-as `(#:label ,else-label))))
                 (info ((ast->info info) else))
                 (info (append-text info (wrap-as `(#:label ,break-label)))))
 
         ;; Hmm?
         ((expr-stmt (cond-expr ,test ,then ,else))
-         (let* ((source (with-output-to-string (lambda () (pretty-print-c99 `(cond-expr ,test (ellipsis) (ellipsis))))))
-                (info (append-text info (wrap-as `(#:comment ,source))))
+         (let* ((info (append-text info (ast->comment `(cond-expr ,test (ellipsis) (ellipsis)))))
                 (here (number->string (length text)))
                 (label (string-append (.function info) "_" here "_"))
                 (else-label (string-append label "else"))
                 (break-label (string-append label "break"))
                 (info ((test-jump-label->info info else-label) test))
                 (info ((ast->info info) then))
-                (info (append-text info (wrap-as (i386:jump `(#:local ,break-label)))))
+                (info (append-text info (wrap-as (i386:jump break-label))))
                 (info (append-text info (wrap-as `(#:label ,else-label))))
                 (info ((ast->info info) else))
                 (info (append-text info (wrap-as `(#:label ,break-label)))))
            info))
 
         ((switch ,expr (compd-stmt (block-item-list . ,statements)))
-         (let* ((source (with-output-to-string (lambda () (pretty-print-c99 `(switch ,expr (compd-stmt (block-item-list (ellipsis))))))))
-                (info (append-text info (wrap-as `(#:comment ,source))))
+         (let* ((info (append-text info (ast->comment `(switch ,expr (compd-stmt (block-item-list (ellipsis)))))))
                 (here (number->string (length text)))
                 (label (string-append (.function info) "_" here "_"))
                 (break-label (string-append label "break"))
                   #:break (cdr (.break info)))))
 
         ((for ,init ,test ,step ,body)
-         (let* ((source (with-output-to-string (lambda () (pretty-print-c99 `(for ,init ,test ,step (ellipsis))))))
-                (info (append-text info (wrap-as `(#:comment ,source))))
+         (let* ((info (append-text info (ast->comment `(for ,init ,test ,step (ellipsis)))))
                 (here (number->string (length text)))
                 (label (string-append (.function info) "_" here "_"))
                 (break-label (string-append label "break"))
                 (info ((ast->info info) init))
                 (info (clone info #:break (cons break-label (.break info))))
                 (info (clone info #:continue (cons continue-label (.continue info))))
-                (info (append-text info (wrap-as (i386:jump `(#:local ,initial-skip-label)))))
+                (info (append-text info (wrap-as (i386:jump initial-skip-label))))
                 (info (append-text info (wrap-as `(#:label ,loop-label))))
                 (info ((ast->info info) body))
                 (info (append-text info (wrap-as `(#:label ,continue-label))))
                 (info ((expr->accu info) step))
                 (info (append-text info (wrap-as `(#:label ,initial-skip-label))))
                 (info ((test-jump-label->info info break-label) test))
-                (info (append-text info (wrap-as (i386:jump `(#:local ,loop-label)))))
+                (info (append-text info (wrap-as (i386:jump loop-label))))
                 (info (append-text info (wrap-as `(#:label ,break-label)))))
            (clone info
                   #:locals locals
                   #:continue (cdr (.continue info)))))
 
         ((while ,test ,body)
-         (let* ((source (with-output-to-string (lambda () (pretty-print-c99 `(while ,test (ellipsis))))))
-                (info (append-text info (wrap-as `(#:comment ,source))))
+         (let* ((info (append-text info (ast->comment `(while ,test (ellipsis)))))
                 (here (number->string (length text)))
                 (label (string-append (.function info) "_" here "_"))
                 (break-label (string-append label "break"))
                 (loop-label (string-append label "loop"))
                 (continue-label (string-append label "continue"))
-                (info (append-text info (wrap-as (i386:jump `(#:local ,continue-label)))))
+                (info (append-text info (wrap-as (i386:jump continue-label))))
                 (info (clone info #:break (cons break-label (.break info))))
                 (info (clone info #:continue (cons continue-label (.continue info))))
                 (info (append-text info (wrap-as `(#:label ,loop-label))))
                 (info ((ast->info info) body))
                 (info (append-text info (wrap-as `(#:label ,continue-label))))
                 (info ((test-jump-label->info info break-label) test))
-                (info (append-text info (wrap-as (i386:jump `(#:local ,loop-label)))))
+                (info (append-text info (wrap-as (i386:jump loop-label))))
                 (info (append-text info (wrap-as `(#:label ,break-label)))))
            (clone info
                   #:locals locals
                   #:continue (cdr (.continue info)))))
 
         ((do-while ,body ,test)
-         (let* ((source (with-output-to-string (lambda () (pretty-print-c99 `(do-while ,test (ellipsis))))))
-                (info (append-text info (wrap-as `(#:comment ,source))))
+         (let* ((info (append-text info (ast->comment `(do-while ,test (ellipsis)))))
                 (here (number->string (length text)))
                 (label (string-append (.function info) "_" here "_"))
                 (break-label (string-append label "break"))
                 (info ((ast->info info) body))
                 (info (append-text info (wrap-as `(#:label ,continue-label))))
                 (info ((test-jump-label->info info break-label) test))
-                (info (append-text info (wrap-as (i386:jump `(#:local ,loop-label)))))
+                (info (append-text info (wrap-as (i386:jump loop-label))))
                 (info (append-text info (wrap-as `(#:label ,break-label)))))
            (clone info
                   #:locals locals
                   #:continue (cdr (.continue info)))))
 
         ((labeled-stmt (ident ,label) ,statement)
-         (let ((info (append-text info `((#:label ,label)))))
+         (let ((info (append-text info `((#:label ,(string-append (.function info) "_label_" label))))))
            ((ast->info info) statement)))
 
         ((goto (ident ,label))
-         (append-text info (wrap-as (i386:jump `(#:local ,label)))))
+         (append-text info (wrap-as (i386:jump (string-append (.function info) "_label_" label)))))
 
         ((return ,expr)
          (let ((info ((expr->accu info) expr)))
         ;;
         ;; struct f = {...};
         ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (ident ,name) (initzer (initzer-list . ,initzers)))))
-         (let* ((type (decl->type type))
+         (let* ((info (append-text info (ast->comment o)))
+                (type (decl->type type))
                 (fields (type->description info type))
                 (size (type->size info type))
                 (initzers (map (initzer->non-const info) initzers)))
         ;;char cc = g_cells[c].cdr;  ==> generic?
         ((decl (decl-spec-list (type-spec ,type)) (init-declr-list (init-declr (ident ,name) (initzer ,initzer))))
          (let ((type (decl->type type))
-               (initzer ((initzer->non-const info) initzer)))
+               (initzer ((initzer->non-const info) initzer))
+               (info (append-text info (ast->comment o))))
            (if (.function info)
                (let* ((locals (add-local locals name type 0))
                       (info (clone info #:locals locals))
            (formals (.formals o))
            (text (formals->text formals))
            (locals (formals->locals formals)))
-      (format (current-error-port) "compiling: ~a\n" name)
+      (format (current-error-port) "    :~a\n" name)
       (let loop ((statements (.statements o))
                  (info (clone info #:locals locals #:function (.name o) #:text text)))
         (if (null? statements) (clone info
   ((compose object->elf info->object (c99-input->info #:defines defines #:includes includes))))
 
 (define* (c99-input->object #:key (defines '()) (includes '()))
-  ((compose write-hex3 info->object (c99-input->info #:defines defines #:includes includes))))
+  ((compose object->hex2 info->object (c99-input->info #:defines defines #:includes includes))))
index b845deebdbe0a405c86a8329453314750c8e3064..c5b224f26a81d867c9c4d6bb74add0780f99aac2 100644 (file)
   '(#x83 #xec #x40))              ; sub    $0x10,%esp -- 16 local vars
 
 (define (i386:push-label label)
-  `(#x68 ,label #f #f #F))              ; push  $0x<o>
+  `(#x68 (#:address ,label)))        ; push  $0x<o>
 
 (define (i386:push-label-mem label)
-  `(#xa1 ,label #f #f #f                ; mov    0x804a000,%eax
+  `(#xa1 (#:address ,label)                ; mov    0x804a000,%eax
          #x50))                         ; push  %eax
 
 (define (i386:push-local n)
   `(#x89 #x55 ,(- 0 (* 4 n))))          ; mov    %edx,-<0xn>(%ebp)
 
 (define (i386:accu->label label)
-  `(#xa3 ,label #f #f #f))
+  `(#xa3 (#:address ,label)))
 
 (define (i386:accu-zero?)
   '(#x85 #xc0))                         ; cmpl   %eax,%eax
          #x83 #xc2 ,(- 0 (* 4 n))))     ; add    $0x<n>,%edx
 
 (define (i386:label->accu label)
-  `(#xb8 ,label #f #f #f))              ; mov    $<>,%eax
+  `(#xb8 (#:address ,label)))              ; mov    $<>,%eax
 
 (define (i386:label->base label)
-  `(#xba ,label #f #f #f))              ; mov   $<n>,%edx
+  `(#xba (#:address ,label)))              ; mov   $<n>,%edx
 
 (define (i386:label-mem->accu label)
-  `(#xa1 ,label #f #f #f))              ; mov    0x<n>,%eax
+  `(#xa1 (#:address ,label)))              ; mov    0x<n>,%eax
 
 (define (i386:label-mem->base label)
-  `(#x8b #x15 ,label #f #f #f))         ; mov    0x<n>,%edx
+  `(#x8b #x15 (#:address ,label)))         ; mov    0x<n>,%edx
 
 (define (i386:label-mem-add label v)
-  `(#x83 #x05 ,label #f #f #f ,v))      ; addl   $<v>,0x<n>
+  `(#x83 #x05 (#:address ,label) ,v))      ; addl   $<v>,0x<n>
 
 (define (i386:byte-base-mem->accu)
   '(#x01 #xd0                           ; add    %edx,%eax
 
 (define (i386:value->label label v)
   (or v (error "invalid value: value->label: " v))
-  `(#xc7 #x05 ,label #f #f #f           ; movl   $<v>,(<n>)
+  `(#xc7 #x05 (#:address ,label)     ; movl   $<v>,(<n>)
          ,@(int->bv32 v)))
 
 (define (i386:value->local n v)
   `(#x83 #x7d ,(- 0 (* 4 n)) ,v))       ; cmpl   $<v>,0x<n>(%ebp)
 
 (define (i386:call-label label n)
-  `(#xe8 ,label #f #f #f                ; call   relative $00
+  `(#xe8 (#:offset ,label)           ; call   offset $00
          #x83 #xc4 ,(* n 4)))           ; add    $00,%esp
 
 (define (i386:call-accu n)
   '(#x85 #xc0))                         ; test   %eax,%eax
 
 (define (i386:jump label)
-  `(#xe9 ,label #f #f #f))              ; jmp . + <n>
+  `(#xe9 (#:offset ,label)))         ; jmp . + <n>
 
 (define (i386:jump-z label)
-  `(#x0f #x84 ,label #f #f #f))         ; jz . + <n>
+  `(#x0f #x84 (#:offset ,label)))    ; jz . + <n>
 
 (define (i386:jump-byte-z label)
   `(#x84 #xc0                           ; test   %al,%al
-    #x74 ,label))                       ; jne <n>
+    #x74 (#:offset1 ,label)))           ; jne <n>
 
 ;; signed
 (define (i386:jump-g label)
-  `(#x0f #x8f ,label #f #f #f))         ; jg/jnle <n>
+  `(#x0f #x8f (#:offset ,label)))    ; jg/jnle <n>
 
 ;; signed
 (define (i386:jump-ge label)
-  `(#x0f #x8d ,label #f #f #f))         ; jge/jnl <n>
+  `(#x0f #x8d (#:offset ,label)))    ; jge/jnl <n>
 
 (define (i386:jump-nz label)
-  `(#x0f #x85 ,label #f #f #f))         ; jnz . + <n>
+  `(#x0f #x85 (#:offset ,label)))    ; jnz . + <n>
 
 (define (i386:jump-z label)
-  `(#x0f #x84 ,label #f #f #f))         ; jz . + <n>
+  `(#x0f #x84 (#:offset ,label)))    ; jz . + <n>
 
 (define (i386:byte-test-base)
   `(#x38 #xc2))                         ; cmp    %al,%dl
index e311ff2f7d1b1bd36a34a636ec9d374f0d68b73b..759e5fcbf9f285a74b11fc53075b00f514bafc2f 100644 (file)
@@ -30,7 +30,8 @@
   (mes-use-module (srfi srfi-1))
   (mes-use-module (mes elf-util))
   (mes-use-module (mes elf))
-  (mes-use-module (mes optargs))))
+  (mes-use-module (mes optargs))
+  (mes-use-module (mes pmatch))))
 
 (define (logf port string . rest)
   (apply format (cons* port string rest))
 (define (stderr string . rest)
   (apply logf (cons* (current-error-port) string rest)))
 
-(define (dec->xhex o)
-  (if (number? o) (string-append "#x" (dec->hex o))
-      (format #f "~s" o)))
-
-(define (write-hex3 o)
-  (define (write-line o)
-    (cond ((null? o))
-          ((not (pair? o))
-           (display (dec->xhex o)))
-          ((string? (car o))
-           (format #t ";; ~a\n" (car o))
-           (display (string-join (map dec->xhex (cdr o)) " ")))
-          ((number? (car o))
-           (display (string-join (map dec->xhex o) " ")))
-          ((member (car o) '(#:comment #:label))
-           (write o))
-          ((and (pair? (car o)) (member (caar o) '(#:comment #:label)))
-           (write (car o)))
-          (else (error "write-line LINE:" o))))
-  (define (write-function o)
-    (stderr "function: ~s\n" (car o))
-    (format #t "\n(~s " (car o))
-    (if (pair? (cadr o)) (for-each
-                          (lambda (x) (display "\n  (") (write-line x) (display ")"))
-                          (filter pair? (cdr o)))
-        (write-line o))
-    (display ")"))
-  (define (write-global o)
-    (stderr "global: ~s\n" (car o))
-    (format #t "\n(~s "(car o))
-    (display (string-join (map dec->xhex (cdr o)) " "))
-    (display ")"))
-  (define (write-init o)
-    (stderr "init: ~s\n" o)
-    (format #t "\n  (~s "(car o))
-    (display (string-join (map dec->xhex (global:value (cdr o))) " "))
-    (display ")"))
-  (stderr "object:\n")
-  (display ";;; hex3: hex2 in sexps with annotated labels\n")
-  (display "((functions ")
-  (for-each write-function (filter cdr (assoc-ref o 'functions)))
-  (display ")\n")
-  (display "(globals ")
-  (for-each write-global (assoc-ref o 'globals))
-  (display "))\n"))
-
 (define (objects->hex2 objects)
-  ((compose write-hex2 merge-objects) objects))
-
-(define (objects->hex3 objects)
-  ((compose write-hex3 merge-objects) objects))
+  ((compose object->hex2 merge-objects) objects))
 
 (define (objects->elf objects)
-  ((compose object->elf merge-objects) objects))
+  (error "->ELF support dropped, use hex2"))
 
 (define (merge-objects objects)
   (let loop ((objects (cdr objects)) (object (car objects)))
          (a-keys (map car a)))
     (append a (filter (lambda (e) (not (member (car e) a-keys))) b))))
 
-(define (write-hex2 o)
+(define (hex2:address o)
+  (string-append "&" o))
+
+(define (hex2:offset o)
+  (string-append "%" o))
+
+(define (hex2:offset1 o)
+  (string-append "!" o))
+
+(define (object->hex2 o)
   (let* ((functions (assoc-ref o 'functions))
          (function-names (map car functions))
          (globals (assoc-ref o 'globals))
          (global-names (map car globals))
          (strings (filter (lambda (g) (and (pair? g) (eq? (car g) #:string))) global-names)))
     (define (string->label o)
-      (format #f "string_~a" (list-index (lambda (s) (equal? s o)) strings)))
-    (define (dec->hex o)
-      (cond ((number? o) (string-append (if (and (>= o 0) (< o 16)) "0" "")
-                                        (number->string
-                                         (if (>= o 0) o (+ o #x100))
-                                         16)))
-            ((char? o) (dec->hex (char->integer o)))
-            ((and (pair? o) (eq? (car o) #:string))
-             (format #f "&~a" (string->label o)))
-            ((string? o) (format #f "~a" o))
-            (else (format #f "~a" o))))
-    (define (write-line function)
-      (lambda (o)
-        (newline)
-        (cond ((not (pair? o))
-               (display (dec->hex o)))
-              ((number? (car o))
-               ;;(display (string-join (map dec->hex (filter identity o)) " "))
-               ;; FIXME: c&p from elf-util: function->text
-               (let ((text (let loop ((text o))
-                             (if (null? text) '()
-                                 (let ((label (car text)))
-                                   (if (number? label) (cons label (loop (cdr text)))
-                                       (if (and (pair? label) (member (car label) '(#:comment #:label))) (loop (cdr text))
-                                           (let* ((prefix (cond ((and (pair? (cdr text))
-                                                                      (pair? (cddr text))
-                                                                      (boolean? (caddr text))) 4)
-                                                                ((and (pair? (cdr text))
-                                                                      (boolean? (cadr text))) 2)
-                                                                (else 1)))
-                                                  (address? (and (pair? label) (eq? (car label) #:address)))
-                                                  (local? (and (pair? label) (eq? (car label) #:local)))
-                                                  (relative? (and (pair? label) (eq? (car label) #:relative)))
-                                                  (label (if (or address? local? relative?) (cadr label) label))
-                                                  (function? (member label function-names))
-                                                  (string-label (string->label label))
-                                                  (string? (not (equal? string-label "string_#f")))
-                                                  (global? (member label global-names))
-                                                  (label (if local? (string-append "local_" function "_" label) label)))
-                                             (cons (cond
-                                                    ((eq? prefix 1) (format #f "!~a" label))
-                                                    ((eq? prefix 2) (format #f "@~a" label))
-                                                    (local? (format #f "%~a" label))
-                                                    (function? (if address? (format #f "&~a" label)
-                                                                   (format #f "%~a" label)))
-                                                    (string? (format #f "&~a" string-label))
-                                                    (global? (format #f "&~a" label))
-                                                    (else (format #f "%~a" label)))
-                                                   (loop (list-tail text prefix)))))))))))
-                 (display (string-join (map dec->hex text) " "))))
-              ((member (car o) '(#:comment))
-               (format #t "# ~s" (cadr o)))
-              ((eq? (car o) #:label)
-               (format #t ":local_~a_~a\n" function (cadr o)))
-              ((and (pair? (car o)) (eq? (caar o) #:label))
-               (format #t ":local_~a\n" (cadar o)))
-              ((and (pair? (car o)) (member (caar o) '(#:comment)))
-               (format #t "# ~s" (cadar o)))
-              ((and (pair? (car o)) (member (caar o) '(#:comment #:label)))
-               (write (car o)))
-              (else (error "write-line LINE:" o)))))
+      (let ((index (list-index (lambda (s) (equal? s o)) strings)))
+        ;;;(if (not index) (error "no such string:" o))
+       (format #f "string_~a" index)))
+    (define (text->hex2 o)
+      (pmatch o
+        ;; FIXME
+        ((#:address (#:string ,string)) (hex2:address (string->label `(#:string ,string))))
+        ((#:string (#:address ,address)) (hex2:address address))
+        ((#:address (#:address ,address)) (hex2:address address))
+
+        ((#:string ,string) (hex2:address (string->label o)))
+        ((#:address ,address) (hex2:address address))
+        ((#:offset ,offset) (hex2:offset offset))
+        ((#:offset1 ,offset1) (hex2:offset1 offset1))
+        (_ (cond ((char? o) (text->hex2 (char->integer o)))
+                 ((string? o) (format #f "~a" o))
+                 ((number? o) (string-append (if (and (>= o 0) (< o 16)) "0" "")
+                                             (number->string
+                                              (if (>= o 0) o (+ o #x100))
+                                              16)))
+                 (else (format #f "~a" o))))))
     (define (write-function o)
-      (format #t "\n\n:~a" (car o))
-      (if (pair? (cadr o)) (for-each (write-line (car o)) (cdr o))
-          ((write-line (car o)) (cdr o))))
+      (let ((name (car o))
+            (text (cdr o)))
+        (define (line->hex2 o)
+          (cond ((null? o))
+                ((not (pair? o))
+                 (display (text->hex2 o)))
+                ((string? (car o))
+                 (format #t ";; ~a" (car o))
+                 (display (string-join (map text->hex2 (cdr o)) " ")))
+                ((number? (car o))
+                 (display (string-join (map text->hex2 o) " ")))
+                ((eq? (car o) #:label)
+                 ;;FIXME: more support for local labels?
+                 ;;(format #t ":local_~a_~a" name (cadr o))
+                 ;;(format #t ":~a_~a" name (cadr o))
+                 (format #t ":~a" (cadr o)))
+                ((eq? (car o) #:comment)
+                 (format #t "  # ~a" (cadr o)))
+                ;; ((and (pair? (car o)) (eq? (caar o) #:label))
+                ;;  (write (car o)))
+                (else (error "line->hex2 invalid line:" o)))
+          (newline))
+        (format #t "\n\n:~a\n" name)
+        (for-each line->hex2 text)))
     (define (write-global o)
       (define (labelize o)
         (if (not (string? o)) o
              (data (cdr o))
              (data (filter-map labelize data)))
         (format #t "\n:~a\n" label)
-        (display (string-join (map dec->hex data) " "))
+        (display (string-join (map text->hex2 data) " "))
         (newline)))
-    (display "### stage0's hex2 format for x86\n")
-    (display "###    !<label>          1 byte relative\n")
-    (display "###    $<label>          2 byte address\n")
-    (display "###    @<label>          2 byte relative\n")
-    (display "###    &<label>          4 byte address\n")
-    (display "###    %<label>          4 byte relative\n")
-    (display "###    local_<label>     function-local\n")
-    (display "###    string_<index>    string #<index>\n")
-    (display "\n##.text")
+    (display "\n:HEX2_text")
     (for-each write-function (filter cdr functions))
-    (display "\n\n##.data\n")
+    (display "\n\n:ELF_data\n") ;; FIXME
+    (display "\n\n:HEX2_data\n")
     (for-each write-global globals)))
index f16ee436739ae427a15ac4dd5041d2d9bed7f4fb..6db4d60d29510b5173c74ab30fb681a7a3d2aa53 100644 (file)
 
 (define-module (mes hex2)
   #:use-module (srfi srfi-1)
+  #:use-module (system base pmatch)
   #:use-module (mes elf-util)
   #:use-module (mes elf)
-  #:export (objects->hex2
-            objects->hex3
-            objects->elf
-            write-hex2
-            write-hex3))
+  #:export (object->hex2
+            objects->hex2
+            objects->elf))
 
 (cond-expand
  (guile-2)
index 275ac17fcc771283f7053b6a0894c3d110bb5d6d..b6569b48cf8fedb41ffde012283633aaef5b4146 100755 (executable)
@@ -78,7 +78,7 @@ Usage: mescc.mes [OPTION]... FILE...
   -c                 compile and assemble, but do not link
   -D DEFINE          define DEFINE
   -E                 preprocess only; do not compile, assemble or link
-  -g                 add debug info [GDB, objdump] using hex3 format
+  -g                 add debug info [GDB, objdump] TODO: hex2 footer
   -h, --help         display this help and exit
   -I DIR             append DIR to include path
   -o FILE            write output to FILE
@@ -136,8 +136,7 @@ Usage: mescc.mes [OPTION]... FILE...
                                            (else "a.out"))))
          (multi-opt (lambda (option) (lambda (o) (and (eq? (car o) option) (cdr o)))))
          (defines (reverse (filter-map (multi-opt 'D) options)))
-         (includes (reverse (filter-map (multi-opt 'I) options)))
-         (objects->hex (if debug-info? objects->hex3 objects->hex2)))
+         (includes (reverse (filter-map (multi-opt 'I) options))))
     (when (getenv "MES_DEBUG") (format (current-error-port) "options=~s\n" options)
           (format (current-error-port) "output: ~a\n" out))
     (if (and (pair? sources) (pair? objects)) (error "cannot mix source and object files:" files))
@@ -145,16 +144,16 @@ Usage: mescc.mes [OPTION]... FILE...
                                                         (not preprocess?)) S_IRWXU))
       (lambda ()
         (cond ((pair? objects) (let ((objects (map read-object objects)))
-                                 (if compile? (objects->hex objects)
+                                 (if compile? (objects->hex2 objects)
                                      (objects->elf objects))))
               ((pair? asts) (let* ((infos (map main:ast->info asts))
                                    (objects (map info->object infos)))
-                              (if compile? (objects->hex objects)
+                              (if compile? (objects->hex2 objects)
                                   (objects->elf objects))))
               ((pair? sources) (if preprocess? (map (source->ast defines includes) sources)
                                    (let* ((infos (map (source->info defines includes) sources))
                                           (objects (map info->object infos)))
-                                     (if compile? (objects->hex objects)
+                                     (if compile? (objects->hex2 objects)
                                          (objects->elf objects))))))))))
 
 (main (command-line))
diff --git a/stage0/elf-0footer.hex2 b/stage0/elf-0footer.hex2
new file mode 100644 (file)
index 0000000..3db17ed
--- /dev/null
@@ -0,0 +1,26 @@
+### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
+### This file is part of stage0.
+###
+### stage0 is free software: you an redistribute it and/or modify
+### it under the terms of the GNU General Public License as published by
+### the Free Software Foundation, either version 3 of the License, or
+### (at your option) any later version.
+###
+### stage0 is distributed in the hope that it will be useful,
+### but WITHOUT ANY WARRANTY; without even the implied warranty of
+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+### GNU General Public License for more details.
+###
+### You should have received a copy of the GNU General Public License
+### along with stage0.  If not, see <http://www.gnu.org/licenses/>.
+
+### stage0's hex2 format for x86
+###    !<label>          1 byte relative
+###    $<label>          2 byte address
+###    @<label>          2 byte relative
+###    &<label>          4 byte address
+###    %<label>          4 byte relative
+###    local_<label>     function-local
+###    string_<index>    string #<index>
+
+:ELF_end
diff --git a/stage0/elf32-0header.hex2 b/stage0/elf32-0header.hex2
new file mode 100644 (file)
index 0000000..69d9245
--- /dev/null
@@ -0,0 +1,78 @@
+### Copyright (C) 2016 Jeremiah Orians
+### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
+### This file is part of stage0.
+###
+### stage0 is free software: you an redistribute it and/or modify
+### it under the terms of the GNU General Public License as published by
+### the Free Software Foundation, either version 3 of the License, or
+### (at your option) any later version.
+###
+### stage0 is distributed in the hope that it will be useful,
+### but WITHOUT ANY WARRANTY; without even the implied warranty of
+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+### GNU General Public License for more details.
+###
+### You should have received a copy of the GNU General Public License
+### along with stage0.  If not, see <http://www.gnu.org/licenses/>.
+
+### stage0's hex2 format for x86
+###    !<label>          1 byte relative
+###    $<label>          2 byte address
+###    @<label>          2 byte relative
+###    &<label>          4 byte address
+###    %<label>          4 byte relative
+###    local_<label>     function-local
+###    string_<index>    string #<index>
+
+### elf32-header-exit-42.hex2: 32 bit elf header in hex2 for `exit 42'
+
+:ELF_base
+7F 45 4C 46                    # e_ident[EI_MAG0-3] ELF's magic number
+
+01                             # e_ident[EI_CLASS] Indicating 32 bit
+01                             # e_ident[EI_DATA] Indicating little endianness
+01                             # e_ident[EI_VERSION] Indicating original elf
+
+00                             # e_ident[EI_OSABI] Set at 0 because none cares
+00                             # e_ident[EI_ABIVERSION] See above
+
+00 00 00 00 00 00 00           # e_ident[EI_PAD]
+
+02 00                          # e_type Indicating Executable
+03 00                          # e_machine Indicating AMD64
+01 00 00 00                    # e_version Indicating original elf
+
+&ELF_text                      # e_entry Address of the entry point
+%ELF_program_headers>ELF_base  # e_phoff Address of program header table
+00 00 00 00                    # e_shoff Address of section header table
+
+00 00 00 00                    # e_flags
+
+34 00                          # e_ehsize Indicating our 52 Byte header
+
+20 00                          # e_phentsize size of a program header table
+01 00                          # e_phnum number of entries in program table
+
+00 00                          # e_shentsize size of a section header table
+00 00                          # e_shnum number of entries in section table
+
+00 00                          # e_shstrndx index of the section names
+
+# @34
+00 00 00 00
+00 00 00 00
+00 00 00 00
+
+# @40
+:ELF_program_headers
+:ELF_program_header__text
+01 00 00 00                    # ph_type: PT-LOAD = 1
+00 00 00 00                    # ph_offset
+&ELF_base                      # ph_vaddr
+&ELF_base                      # ph_physaddr
+%ELF_end>ELF_base              # ph_filesz
+%ELF_end>ELF_base              # ph_memsz
+07 00 00 00                    # ph_flags: PF-X|PF-W|PF-R = 7
+01 00 00 00                    # ph_align
+
+:ELF_text
diff --git a/stage0/elf32-footer-exit-42.hex2 b/stage0/elf32-footer-exit-42.hex2
deleted file mode 100644 (file)
index 74b76c5..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
-### This file is part of stage0.
-###
-### stage0 is free software: you an redistribute it and/or modify
-### it under the terms of the GNU General Public License as published by
-### the Free Software Foundation, either version 3 of the License, or
-### (at your option) any later version.
-###
-### stage0 is distributed in the hope that it will be useful,
-### but WITHOUT ANY WARRANTY; without even the implied warranty of
-### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-### GNU General Public License for more details.
-###
-### You should have received a copy of the GNU General Public License
-### along with stage0.  If not, see <http://www.gnu.org/licenses/>.
-
-### stage0's hex2 format for x86
-###    !<label>          1 byte relative
-###    $<label>          2 byte address
-###    @<label>          2 byte relative
-###    &<label>          4 byte address
-###    %<label>          4 byte relative
-###    local_<label>     function-local
-###    string_<index>    string #<index>
-
-### elf32-footer-exit-42.hex2: 32 bit elf footer in hex2 for `exit 42'
-
-# @230
-
-:ELF_str
-00                             # 0
-:ELF_str__start
-5f 73 74 61 72 74 00           # _start
-:ELF_str__main
-6d 61 69 6e 00                 # main
-
-00 00 00
-
-# @240
-:ELF_sym
-00 00 00 00                    # st-name
-00 00 00 00                    # st-offset: &_start - BaseAddress
-00 00 00 00                    # st-len   : &main - _start
-00                             # st-info = stt-func= 2
-00                             # st-other
-01 00                          # st-shndx: 1
-
-# _start
-%ELF_str__start>ELF_str        # st-name
-&_start
-10 00 00 00                    # st-len   : &main - _start
-02                             # st-info = stt-func= 2
-00                             # st-other
-01 00                          # st-shndx: 1
-
-# main
-%ELF_str__main>ELF_str         # st-name
-&main
-10 00 00 00                    # st-len   : &ELF_data - main
-02                             # st-info = stt-func= 2
-00                             # st-other
-01 00                          # st-shndx: 1
-
-:ELF_end
diff --git a/stage0/elf32-footer-single-main.hex2 b/stage0/elf32-footer-single-main.hex2
new file mode 100644 (file)
index 0000000..6137228
--- /dev/null
@@ -0,0 +1,64 @@
+### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
+### This file is part of stage0.
+###
+### stage0 is free software: you an redistribute it and/or modify
+### it under the terms of the GNU General Public License as published by
+### the Free Software Foundation, either version 3 of the License, or
+### (at your option) any later version.
+###
+### stage0 is distributed in the hope that it will be useful,
+### but WITHOUT ANY WARRANTY; without even the implied warranty of
+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+### GNU General Public License for more details.
+###
+### You should have received a copy of the GNU General Public License
+### along with stage0.  If not, see <http://www.gnu.org/licenses/>.
+
+### stage0's hex2 format for x86
+###    !<label>          1 byte relative
+###    $<label>          2 byte address
+###    @<label>          2 byte relative
+###    &<label>          4 byte address
+###    %<label>          4 byte relative
+###    local_<label>     function-local
+###    string_<index>    string #<index>
+
+### elf32-footer-single-main.hex2: 32 bit elf footer in hex2 for single main
+
+# @230
+
+:ELF_str
+00                             # 0
+:ELF_str__start
+5f 73 74 61 72 74 00           # _start
+:ELF_str__main
+6d 61 69 6e 00                 # main
+
+00 00 00
+
+# @240
+:ELF_sym
+00 00 00 00                    # st-name
+00 00 00 00                    # st-offset: &_start - BaseAddress
+00 00 00 00                    # st-len   : &main - _start
+00                             # st-info = stt-func= 2
+00                             # st-other
+01 00                          # st-shndx: 1
+
+# _start
+%ELF_str__start>ELF_str        # st-name
+&_start
+10 00 00 00                    # st-len   : &main - _start
+02                             # st-info = stt-func= 2
+00                             # st-other
+01 00                          # st-shndx: 1
+
+# main
+%ELF_str__main>ELF_str         # st-name
+&main
+10 00 00 00                    # st-len   : &ELF_data - main
+02                             # st-info = stt-func= 2
+00                             # st-other
+01 00                          # st-shndx: 1
+
+:ELF_end
diff --git a/stage0/elf32-header-exit-42.hex2 b/stage0/elf32-header-exit-42.hex2
deleted file mode 100644 (file)
index d224d79..0000000
+++ /dev/null
@@ -1,217 +0,0 @@
-### Copyright (C) 2016 Jeremiah Orians
-### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
-### This file is part of stage0.
-###
-### stage0 is free software: you an redistribute it and/or modify
-### it under the terms of the GNU General Public License as published by
-### the Free Software Foundation, either version 3 of the License, or
-### (at your option) any later version.
-###
-### stage0 is distributed in the hope that it will be useful,
-### but WITHOUT ANY WARRANTY; without even the implied warranty of
-### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-### GNU General Public License for more details.
-###
-### You should have received a copy of the GNU General Public License
-### along with stage0.  If not, see <http://www.gnu.org/licenses/>.
-
-### stage0's hex2 format for x86
-###    !<label>          1 byte relative
-###    $<label>          2 byte address
-###    @<label>          2 byte relative
-###    &<label>          4 byte address
-###    %<label>          4 byte relative
-###    local_<label>     function-local
-###    string_<index>    string #<index>
-
-### elf32-header-exit-42.hex2: 32 bit elf header in hex2 for `exit 42'
-
-:ELF_base
-7F 45 4C 46                    # e_ident[EI_MAG0-3] ELF's magic number
-
-01                             # e_ident[EI_CLASS] Indicating 32 bit
-01                             # e_ident[EI_DATA] Indicating little endianness
-01                             # e_ident[EI_VERSION] Indicating original elf
-
-00                             # e_ident[EI_OSABI] Set at 0 because none cares
-00                             # e_ident[EI_ABIVERSION] See above
-
-00 00 00 00 00 00 00           # e_ident[EI_PAD]
-
-02 00                          # e_type Indicating Executable
-03 00                          # e_machine Indicating AMD64
-01 00 00 00                    # e_version Indicating original elf
-
-&ELF_text                      # e_entry Address of the entry point
-%ELF_program_headers>ELF_base  # e_phoff Address of program header table
-%ELF_section_headers>ELF_base  # e_shoff Address of section header table
-
-#d0 00 00 00                   # e_shoff Address of section header table
-
-00 00 00 00                    # e_flags
-
-34 00                          # e_ehsize Indicating our 52 Byte header
-
-20 00                          # e_phentsize size of a program header table
-02 00                          # e_phnum number of entries in program table
-
-28 00                          # e_shentsize size of a section header table
-07 00                          # e_shnum number of entries in section table
-
-04 00                          # e_shstrndx index of the section names
-
-# @34
-00 00 00 00
-00 00 00 00
-00 00 00 00
-
-# @40
-:ELF_program_headers
-:ELF_program_header__text
-01 00 00 00                    # ph_type: PT-LOAD = 1
-00 00 00 00                    # ph_offset
-&ELF_base                      # ph_vaddr
-&ELF_base                      # ph_physaddr
-%ELF_end>ELF_base              # ph_filesz
-%ELF_end>ELF_base              # ph_memsz
-07 00 00 00                    # ph_flags: PF-X|PF-W|PF-R = 7
-01 00 00 00                    # ph_align
-
-# @60
-:ELF_program_header__data
-01 00 00 00                     # ph_type: PT-LOAD = 1
-00 00 00 00                     # ph_offset
-&ELF_base                       # ph_vaddr
-&ELF_base                       # ph_physaddr
-%ELF_end>ELF_base               # ph_filesz
-%ELF_end>ELF_base               # ph_memsz
-07 00 00 00                     # ph_flags: PF-X|PF-W|PF-R = 7
-01 00 00 00                     # ph_align
-
-# @80
-:ELF_comment
-4d 45 53 00                     # MES
-00 00 00 00                     # align
-00 00 00 00
-00 00 00 00
-
-4d 45 53 00                     # MES
-00 00 00 00                     # align
-00 00 00 00
-00 00 00 00
-
-# @a0
-:ELF_shstr
-00
-:ELF_shstr__text
-2e 74 65 78 74 00               # .text
-:ELF_shstr__data
-2e 64 61 74 61 00               # .data
-:ELF_shstr__comment
-2e 63 6f 6d 6d 65 6e 74 00      # .comment
-:ELF_shstr__shstr
-2e 73 68 73 74 72 74 61 62 00   # .shstrtab
-:ELF_shstr__sym
-2e 73 79 6d 74 61 62 00         # .symtab
-:ELF_shstr__str
-2e 73 74 72 74 61 62 00         # .strtab
-
-# @d0
-
-:ELF_section_headers
-00 00 00 00                     # sh_name
-00 00 00 00                     # sh_type
-00 00 00 00                     # sh_flags
-00 00 00 00                     # sh_addr
-00 00 00 00                     # sh_offset
-00 00 00 00                     # sh_length
-00 00 00 00                     # sh_link
-00 00 00 00                     # sh_info
-01 00 00 00                     # sh_1?
-00 00 00 00                     # sh_entsize
-
-## FIXME: M0 for calculations?
-:ELF_section_header_text
-%ELF_shstr__text>ELF_shstr      # sh_name
-01 00 00 00                     # sh_type = SHT_PROGBITS = 1
-06 00 00 00                     # sh_flags = SHF-ALLOC|SHF-EXEC =2 | 4 = 6
-&ELF_text                       # sh_addr
-%ELF_text>ELF_base              # sh_offset
-%ELF_data>ELF_text              # sh_length
-00 00 00 00                     # sh_link
-00 00 00 00                     # sh_info
-01 00 00 00                     # sh_1?
-00 00 00 00                     # sh_entsize
-
-:ELF_section_header_data
-%ELF_shstr__data>ELF_shstr     # sh_name
-01 00 00 00                    # sh_type = SHT_PROGBITS = 1
-03 00 00 00                    # sh_flags = SHF-WRITE|SHF-ALLOC = 1 | 2 = 3
-&ELF_data                      # sh_addr
-%ELF_data>ELF_base             # sh_offset
-%ELF_sym>ELF_data              # sh_length
-00 00 00 00                    # sh_link
-00 00 00 00                    # sh_info
-01 00 00 00                    # sh_1?
-00 00 00 00                    # sh_entsize
-
-:ELF_section_header_comment
-%ELF_shstr__comment>ELF_shstr  # sh_name
-01 00 00 00                    # sh_type = SHT_PROGBITS = 1
-00 00 00 00                    # sh_flags
-&ELF_comment                   # sh_addr
-%ELF_comment>ELF_base          # sh_offset
-%ELF_shstr>ELF_comment         # sh_length
-00 00 00 00                    # sh_link
-00 00 00 00                    # sh_info
-01 00 00 00                    # sh_1?
-00 00 00 00                    # sh_entsize
-
-:ELF_section_header_shstr
-%ELF_shstr__shstr>ELF_shstr    # sh_name
-03 00 00 00                    # sh_type: str-sht-strtab
-00 00 00 00                    # sh_flags
-&ELF_shstr                     # sh_addr
-%ELF_shstr>ELF_base            # sh_offset
-%ELF_section_headers>ELF_shstr # sh_length
-00 00 00 00                    # sh_link
-00 00 00 00                    # sh_info
-01 00 00 00                    # sh_1?
-00 00 00 00                    # sh_entsize
-
-:ELF_section_header_sym
-%ELF_shstr__sym>ELF_shstr      # sh_name
-02 00 00 00                    # sh_type: str-sht-symtab
-00 00 00 00                    # sh_flags
-&ELF_sym                       # sh_addr
-%ELF_sym>ELF_base              # sh_offset
-%ELF_end>ELF_sym               # sh_length
-06 00 00 00                    # sh_link:6
-00 00 00 00                    # sh_info
-01 00 00 00                    # sh_1?
-10 00 00 00                    # sh_entsize
-
-:ELF_section_header_str
-%ELF_shstr__str>ELF_shstr      # sh_name
-03 00 00 00                    # sh_type: str-sht-strtab
-00 00 00 00                    # sh_flags
-&ELF_str                       # sh_addr
-%ELF_str>ELF_base              # sh_offset
-%ELF_sym>ELF_str               # sh_length
-00 00 00 00                    # sh_link
-00 00 00 00                    # sh_info
-01 00 00 00                    # sh_1?
-00 00 00 00                    # sh_entsize
-
-# @1e8
-00 00 00 00  # align
-00 00 00 00
-
-# @1f0
-
-00 00 00 00  # align
-00 00 00 00
-00 00 00 00
-00 00 00 00
-
-# @200
diff --git a/stage0/elf32-header.hex2 b/stage0/elf32-header.hex2
new file mode 100644 (file)
index 0000000..6149932
--- /dev/null
@@ -0,0 +1,216 @@
+### Copyright (C) 2016 Jeremiah Orians
+### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
+### This file is part of stage0.
+###
+### stage0 is free software: you an redistribute it and/or modify
+### it under the terms of the GNU General Public License as published by
+### the Free Software Foundation, either version 3 of the License, or
+### (at your option) any later version.
+###
+### stage0 is distributed in the hope that it will be useful,
+### but WITHOUT ANY WARRANTY; without even the implied warranty of
+### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+### GNU General Public License for more details.
+###
+### You should have received a copy of the GNU General Public License
+### along with stage0.  If not, see <http://www.gnu.org/licenses/>.
+
+### stage0's hex2 format for x86
+###    !<label>          1 byte relative
+###    $<label>          2 byte address
+###    @<label>          2 byte relative
+###    &<label>          4 byte address
+###    %<label>          4 byte relative
+###    local_<label>     function-local
+###    string_<index>    string #<index>
+
+### elf32-header-exit-42.hex2: 32 bit elf header in hex2 for `exit 42'
+
+:ELF_base
+7F 45 4C 46                    # e_ident[EI_MAG0-3] ELF's magic number
+
+01                             # e_ident[EI_CLASS] Indicating 32 bit
+01                             # e_ident[EI_DATA] Indicating little endianness
+01                             # e_ident[EI_VERSION] Indicating original elf
+
+00                             # e_ident[EI_OSABI] Set at 0 because none cares
+00                             # e_ident[EI_ABIVERSION] See above
+
+00 00 00 00 00 00 00           # e_ident[EI_PAD]
+
+02 00                          # e_type Indicating Executable
+03 00                          # e_machine Indicating AMD64
+01 00 00 00                    # e_version Indicating original elf
+
+&ELF_text                      # e_entry Address of the entry point
+%ELF_program_headers>ELF_base  # e_phoff Address of program header table
+%ELF_section_headers>ELF_base  # e_shoff Address of section header table
+
+00 00 00 00                    # e_flags
+
+34 00                          # e_ehsize Indicating our 52 Byte header
+
+20 00                          # e_phentsize size of a program header table
+02 00                          # e_phnum number of entries in program table
+
+28 00                          # e_shentsize size of a section header table
+07 00                          # e_shnum number of entries in section table
+
+04 00                          # e_shstrndx index of the section names
+
+# @34
+00 00 00 00
+00 00 00 00
+00 00 00 00
+
+# @40
+:ELF_program_headers
+:ELF_program_header__text
+01 00 00 00                    # ph_type: PT-LOAD = 1
+00 00 00 00                    # ph_offset
+&ELF_base                      # ph_vaddr
+&ELF_base                      # ph_physaddr
+%ELF_end>ELF_base              # ph_filesz
+%ELF_end>ELF_base              # ph_memsz
+07 00 00 00                    # ph_flags: PF-X|PF-W|PF-R = 7
+01 00 00 00                    # ph_align
+
+# @60
+:ELF_program_header__data
+01 00 00 00                     # ph_type: PT-LOAD = 1
+00 00 00 00                     # ph_offset
+&ELF_base                       # ph_vaddr
+&ELF_base                       # ph_physaddr
+%ELF_end>ELF_base               # ph_filesz
+%ELF_end>ELF_base               # ph_memsz
+07 00 00 00                     # ph_flags: PF-X|PF-W|PF-R = 7
+01 00 00 00                     # ph_align
+
+# @80
+:ELF_comment
+4d 45 53 00                     # MES
+00 00 00 00                     # align
+00 00 00 00
+00 00 00 00
+
+4d 45 53 00                     # MES
+00 00 00 00                     # align
+00 00 00 00
+00 00 00 00
+
+# @a0
+:ELF_shstr
+00
+:ELF_shstr__text
+2e 74 65 78 74 00               # .text
+:ELF_shstr__data
+2e 64 61 74 61 00               # .data
+:ELF_shstr__comment
+2e 63 6f 6d 6d 65 6e 74 00      # .comment
+:ELF_shstr__shstr
+2e 73 68 73 74 72 74 61 62 00   # .shstrtab
+:ELF_shstr__sym
+2e 73 79 6d 74 61 62 00         # .symtab
+:ELF_shstr__str
+2e 73 74 72 74 61 62 00         # .strtab
+
+# @d0
+
+:ELF_section_headers
+00 00 00 00                     # sh_name
+00 00 00 00                     # sh_type
+00 00 00 00                     # sh_flags
+00 00 00 00                     # sh_addr
+00 00 00 00                     # sh_offset
+00 00 00 00                     # sh_length
+00 00 00 00                     # sh_link
+00 00 00 00                     # sh_info
+01 00 00 00                     # sh_1?
+00 00 00 00                     # sh_entsize
+
+## FIXME: M0 for calculations?
+:ELF_section_header_text
+%ELF_shstr__text>ELF_shstr      # sh_name
+01 00 00 00                     # sh_type = SHT_PROGBITS = 1
+06 00 00 00                     # sh_flags = SHF-ALLOC|SHF-EXEC =2 | 4 = 6
+&ELF_text                       # sh_addr
+%ELF_text>ELF_base              # sh_offset
+%ELF_data>ELF_text              # sh_length
+00 00 00 00                     # sh_link
+00 00 00 00                     # sh_info
+01 00 00 00                     # sh_1?
+00 00 00 00                     # sh_entsize
+
+:ELF_section_header_data
+%ELF_shstr__data>ELF_shstr     # sh_name
+01 00 00 00                    # sh_type = SHT_PROGBITS = 1
+03 00 00 00                    # sh_flags = SHF-WRITE|SHF-ALLOC = 1 | 2 = 3
+&ELF_data                      # sh_addr
+%ELF_data>ELF_base             # sh_offset
+%ELF_sym>ELF_data              # sh_length
+00 00 00 00                    # sh_link
+00 00 00 00                    # sh_info
+01 00 00 00                    # sh_1?
+00 00 00 00                    # sh_entsize
+
+:ELF_section_header_comment
+%ELF_shstr__comment>ELF_shstr  # sh_name
+01 00 00 00                    # sh_type = SHT_PROGBITS = 1
+00 00 00 00                    # sh_flags
+&ELF_comment                   # sh_addr
+%ELF_comment>ELF_base          # sh_offset
+%ELF_shstr>ELF_comment         # sh_length
+00 00 00 00                    # sh_link
+00 00 00 00                    # sh_info
+01 00 00 00                    # sh_1?
+00 00 00 00                    # sh_entsize
+
+:ELF_section_header_shstr
+%ELF_shstr__shstr>ELF_shstr    # sh_name
+03 00 00 00                    # sh_type: str-sht-strtab
+00 00 00 00                    # sh_flags
+&ELF_shstr                     # sh_addr
+%ELF_shstr>ELF_base            # sh_offset
+%ELF_section_headers>ELF_shstr # sh_length
+00 00 00 00                    # sh_link
+00 00 00 00                    # sh_info
+01 00 00 00                    # sh_1?
+00 00 00 00                    # sh_entsize
+
+:ELF_section_header_sym
+%ELF_shstr__sym>ELF_shstr      # sh_name
+02 00 00 00                    # sh_type: str-sht-symtab
+00 00 00 00                    # sh_flags
+&ELF_sym                       # sh_addr
+%ELF_sym>ELF_base              # sh_offset
+%ELF_end>ELF_sym               # sh_length
+06 00 00 00                    # sh_link:6
+00 00 00 00                    # sh_info
+01 00 00 00                    # sh_1?
+10 00 00 00                    # sh_entsize
+
+:ELF_section_header_str
+%ELF_shstr__str>ELF_shstr      # sh_name
+03 00 00 00                    # sh_type: str-sht-strtab
+00 00 00 00                    # sh_flags
+&ELF_str                       # sh_addr
+%ELF_str>ELF_base              # sh_offset
+%ELF_sym>ELF_str               # sh_length
+00 00 00 00                    # sh_link
+00 00 00 00                    # sh_info
+01 00 00 00                    # sh_1?
+00 00 00 00                    # sh_entsize
+
+# @1e8
+00 00 00 00  # align
+00 00 00 00
+
+# @1f0
+
+00 00 00 00  # align
+00 00 00 00
+00 00 00 00
+00 00 00 00
+
+# @200
+:ELF_text
diff --git a/stage0/elf32.hex2 b/stage0/elf32.hex2
deleted file mode 100644 (file)
index 11c8dd2..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-### Copyright (C) 2016 Jeremiah Orians
-### Copyright (C) 2017 Jan Nieuwenhuizen <janneke@gnu.org>
-### This file is part of stage0.
-###
-### stage0 is free software: you an redistribute it and/or modify
-### it under the terms of the GNU General Public License as published by
-### the Free Software Foundation, either version 3 of the License, or
-### (at your option) any later version.
-###
-### stage0 is distributed in the hope that it will be useful,
-### but WITHOUT ANY WARRANTY; without even the implied warranty of
-### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-### GNU General Public License for more details.
-###
-### You should have received a copy of the GNU General Public License
-### along with stage0.  If not, see <http://www.gnu.org/licenses/>.
-
-### elf32.hex2: 32 bit elf header in hex2
-
-## ELF Header
-7F 45 4C 46           # e_ident[EI_MAG0-3] ELF's magic number
-
-01                    # e_ident[EI_CLASS] Indicating 32 bit
-01                    # e_ident[EI_DATA] Indicating little endianness
-01                    # e_ident[EI_VERSION] Indicating original elf
-
-00                    # e_ident[EI_OSABI] Set at 0 because none cares
-00                    # e_ident[EI_ABIVERSION] See above
-
-00 00 00 00 00 00 00  # e_ident[EI_PAD]
-02 00                 # e_type Indicating Executable
-03 00                 # e_machine Indicating AMD64
-01 00 00 00           # e_version Indicating original elf
-
-54 80 04 08           # e_entry Address of the entry point
-34 00 00 00           # e_phoff Address of program header table
-00 00 00 00           # e_shoff Address of section header table
-
-00 00 00 00           # e_flags
-34 00                 # e_ehsize Indicating our 52 Byte header
-
-20 00                 # e_phentsize size of a program header table
-01 00                 # e_phnum number of entries in program table
-
-00 00                 # e_shentsize size of a section header table
-00 00                 # e_shnum number of entries in section table
-
-00 00                 # e_shstrndx index of the section names
-
-## Program Header
-01 00 00 00           # p_type
-00 00 00 00           # p_offset
-
-00 80 04 08           # p_vaddr
-00 80 04 08           # p_physaddr
-
-## FIXME!
-##60 00 00 00           # p_filesz
-##60 00 00 00           # p_memsz
-
-#65 01 00 00           # p_filesz
-#65 01 00 00           # p_memsz
-
-ff ff 00 00           # p_filesz
-ff ff 00 00           # p_memsz
-
-
-07 00 00 00           # p_flags
-01 00 00 00           # alignment
-
-## _start
-# exit (42) -- works!
-#bb 2a 00 00 00      # mov    $42,%ebx
-#b8 01 00 00 00      # mov    $0x1,%eax
-#cd 80               # int    $0x80
diff --git a/stage0/exit-42.c b/stage0/exit-42.c
new file mode 100644 (file)
index 0000000..8bc9125
--- /dev/null
@@ -0,0 +1,25 @@
+/* -*-comment-start: "//";comment-end:""-*-
+ * Mes --- Maxwell Equations of Software
+ * Copyright © 2017 Jan Nieuwenhuizen <janneke@gnu.org>
+ *
+ * This file is part of Mes.
+ *
+ * Mes is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * Mes is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+int
+main (int argc, char *argv[])
+{
+  return 42;
+}
index fc9d62aa0bc3579cd40ea4a63e500149415948e4..e69854c2b47298376445cbcb93bfd57b1b4cc177 100644 (file)
@@ -1,10 +1,37 @@
 ifneq ($(HEX2),)
-CLEAN+=$(OUT)/exit42
-$(OUT)/exit42: stage0/elf32-header-exit-42.hex2 stage0/elf32-body-exit-42.hex2 stage0/elf32-footer-exit-42.hex2
+
+CLEAN+=$(OUT)/0exit-42
+$(OUT)/0exit-42: stage0/elf32-0header.hex2 stage0/elf32-body-exit-42.hex2 stage0/elf-0footer.hex2 | $(OUT)
        @echo "  HEX2   $(notdir $^) -> $(notdir $@)"
-       $(QUIET)$(HEX2) -f stage0/elf32-header-exit-42.hex2 -f stage0/elf32-body-exit-42.hex2 -f stage0/elf32-footer-exit-42.hex2 --LittleEndian --Architecture 1 --BaseAddress 0x1000000 > $@
+       $(QUIET)$(HEX2) $(HEX2_FLAGS) $(^:%=-f %) > $@ || rm -f $@
        chmod +x $@
-TARGET:=exit42
+TARGET:=0exit-42
 EXPECT:=42
 include make/check.make
+
+CLEAN+=$(OUT)/exit-42
+$(OUT)/exit-42: stage0/elf32-header.hex2 stage0/elf32-body-exit-42.hex2 stage0/elf32-footer-single-main.hex2 | $(OUT)
+       @echo "  HEX2   $(notdir $^) -> $(notdir $@)"
+       $(QUIET)$(HEX2) $(HEX2_FLAGS) $(^:%=-f %) > $@ || rm -f $@
+       chmod +x $@
+TARGET:=exit-42
+EXPECT:=42
+include make/check.make
+
+CLEAN+=$(OUT)/exit-42.guile
+$(OUT)/exit-42.guile: stage0/elf32-header.hex2 $(OUT)/mlibc/mini-libc-mes.hex2 $(OUT)/stage0/exit-42.hex2 stage0/elf32-footer-single-main.hex2 | $(OUT)
+       @echo "  HEX2   $(notdir $^) -> $(notdir $@)"
+       $(QUIET)$(HEX2) $(HEX2_FLAGS) $(^:%=-f %) > $@ || rm -f $@
+       chmod +x $@
+
+MESCC.scm:=guile/mescc.scm
+$(OUT)/%.hex2: %.c | all-go
+       @echo "  MESCC.scm      $(notdir $<) -> $(notdir $@)"
+       @mkdir -p $(dir $@)
+       $(QUIET) $(MESCC.scm) -c -o $@ $^
+
+TARGET:=exit-42.guile
+EXPECT:=42
+include make/check.make
+
 endif