From 1de0f33020cd3541a0efd5a44fcf44b1de522746 Mon Sep 17 00:00:00 2001 From: Jan Nieuwenhuizen Date: Sun, 25 Jun 2017 09:33:55 +0200 Subject: [PATCH] mescc: Produce object files in hex2 format, remove hex3. * 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. --- GNUmakefile | 1 + guile/mescc.scm | 11 +- make/mescc-guile.make | 12 +- make/mescc-mes.make | 8 +- module/language/c99/compiler.mes | 112 +++++----- module/mes/as-i386.mes | 34 ++-- module/mes/hex2.mes | 191 ++++++------------ module/mes/hex2.scm | 9 +- scripts/mescc.mes | 11 +- stage0/elf-0footer.hex2 | 26 +++ stage0/elf32-0header.hex2 | 78 +++++++ ...-42.hex2 => elf32-footer-single-main.hex2} | 2 +- ...-header-exit-42.hex2 => elf32-header.hex2} | 3 +- stage0/elf32.hex2 | 75 ------- stage0/exit-42.c | 25 +++ stage0/stage0.make | 35 +++- 16 files changed, 330 insertions(+), 303 deletions(-) create mode 100644 stage0/elf-0footer.hex2 create mode 100644 stage0/elf32-0header.hex2 rename stage0/{elf32-footer-exit-42.hex2 => elf32-footer-single-main.hex2} (96%) rename stage0/{elf32-header-exit-42.hex2 => elf32-header.hex2} (99%) delete mode 100644 stage0/elf32.hex2 create mode 100644 stage0/exit-42.c diff --git a/GNUmakefile b/GNUmakefile index ddd4b352..f595e848 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -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:=\ diff --git a/guile/mescc.scm b/guile/mescc.scm index a00f349d..7e53951e 100755 --- a/guile/mescc.scm +++ b/guile/mescc.scm @@ -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?)) diff --git a/make/mescc-guile.make b/make/mescc-guile.make index 74e393f3..1f462065 100644 --- a/make/mescc-guile.make +++ b/make/mescc-guile.make @@ -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) diff --git a/make/mescc-mes.make b/make/mescc-mes.make index c55bd842..bb542725 100644 --- a/make/mescc-mes.make +++ b/make/mescc-mes.make @@ -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) diff --git a/module/language/c99/compiler.mes b/module/language/c99/compiler.mes index c0fa4b09..95273785 100644 --- a/module/language/c99/compiler.mes +++ b/module/language/c99/compiler.mes @@ -652,7 +652,7 @@ (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) @@ -738,11 +738,11 @@ ((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)))) @@ -750,11 +750,11 @@ 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)))) @@ -773,7 +773,8 @@ (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)) @@ -852,6 +853,13 @@ (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 @@ -1012,11 +1020,11 @@ (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) @@ -1029,8 +1037,8 @@ (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)))) @@ -1055,7 +1063,7 @@ (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 @@ -1065,8 +1073,8 @@ (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) @@ -1096,7 +1104,7 @@ (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))))) @@ -1278,11 +1286,11 @@ ((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) @@ -1291,37 +1299,34 @@ ((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))))) @@ -1330,23 +1335,21 @@ ;; 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")) @@ -1362,8 +1365,7 @@ #: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")) @@ -1373,14 +1375,14 @@ (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 @@ -1388,21 +1390,20 @@ #: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 @@ -1410,8 +1411,7 @@ #: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")) @@ -1423,7 +1423,7 @@ (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 @@ -1431,11 +1431,11 @@ #: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))) @@ -1825,7 +1825,8 @@ ;; ;; 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))) @@ -1863,7 +1864,8 @@ ;;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)) @@ -2104,7 +2106,7 @@ (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 @@ -2144,4 +2146,4 @@ ((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)))) diff --git a/module/mes/as-i386.mes b/module/mes/as-i386.mes index b845deeb..c5b224f2 100644 --- a/module/mes/as-i386.mes +++ b/module/mes/as-i386.mes @@ -41,10 +41,10 @@ '(#x83 #xec #x40)) ; sub $0x10,%esp -- 16 local vars (define (i386:push-label label) - `(#x68 ,label #f #f #F)) ; push $0x + `(#x68 (#:address ,label))) ; push $0x (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) @@ -117,7 +117,7 @@ `(#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 @@ -214,19 +214,19 @@ #x83 #xc2 ,(- 0 (* 4 n)))) ; add $0x,%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 $,%edx + `(#xba (#:address ,label))) ; mov $,%edx (define (i386:label-mem->accu label) - `(#xa1 ,label #f #f #f)) ; mov 0x,%eax + `(#xa1 (#:address ,label))) ; mov 0x,%eax (define (i386:label-mem->base label) - `(#x8b #x15 ,label #f #f #f)) ; mov 0x,%edx + `(#x8b #x15 (#:address ,label))) ; mov 0x,%edx (define (i386:label-mem-add label v) - `(#x83 #x05 ,label #f #f #f ,v)) ; addl $,0x + `(#x83 #x05 (#:address ,label) ,v)) ; addl $,0x (define (i386:byte-base-mem->accu) '(#x01 #xd0 ; add %edx,%eax @@ -297,7 +297,7 @@ (define (i386:value->label label v) (or v (error "invalid value: value->label: " v)) - `(#xc7 #x05 ,label #f #f #f ; movl $,() + `(#xc7 #x05 (#:address ,label) ; movl $,() ,@(int->bv32 v))) (define (i386:value->local n v) @@ -310,7 +310,7 @@ `(#x83 #x7d ,(- 0 (* 4 n)) ,v)) ; cmpl $,0x(%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) @@ -339,28 +339,28 @@ '(#x85 #xc0)) ; test %eax,%eax (define (i386:jump label) - `(#xe9 ,label #f #f #f)) ; jmp . + + `(#xe9 (#:offset ,label))) ; jmp . + (define (i386:jump-z label) - `(#x0f #x84 ,label #f #f #f)) ; jz . + + `(#x0f #x84 (#:offset ,label))) ; jz . + (define (i386:jump-byte-z label) `(#x84 #xc0 ; test %al,%al - #x74 ,label)) ; jne + #x74 (#:offset1 ,label))) ; jne ;; signed (define (i386:jump-g label) - `(#x0f #x8f ,label #f #f #f)) ; jg/jnle + `(#x0f #x8f (#:offset ,label))) ; jg/jnle ;; signed (define (i386:jump-ge label) - `(#x0f #x8d ,label #f #f #f)) ; jge/jnl + `(#x0f #x8d (#:offset ,label))) ; jge/jnl (define (i386:jump-nz label) - `(#x0f #x85 ,label #f #f #f)) ; jnz . + + `(#x0f #x85 (#:offset ,label))) ; jnz . + (define (i386:jump-z label) - `(#x0f #x84 ,label #f #f #f)) ; jz . + + `(#x0f #x84 (#:offset ,label))) ; jz . + (define (i386:byte-test-base) `(#x38 #xc2)) ; cmp %al,%dl diff --git a/module/mes/hex2.mes b/module/mes/hex2.mes index e311ff2f..759e5fcb 100644 --- a/module/mes/hex2.mes +++ b/module/mes/hex2.mes @@ -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)) @@ -40,60 +41,11 @@ (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))) @@ -108,78 +60,68 @@ (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 @@ -196,17 +138,10 @@ (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 "### !