]> granicus.if.org Git - yasm/commitdiff
Massive cleanup of debugging output (via _print() functions). All now take
authorPeter Johnson <peter@tortall.net>
Wed, 21 Nov 2001 08:25:09 +0000 (08:25 -0000)
committerPeter Johnson <peter@tortall.net>
Wed, 21 Nov 2001 08:25:09 +0000 (08:25 -0000)
FILE *'s to print to somewhere other than stdout, and the formatting is
improved through the use of a global indent_level.

Changes to main() include the ability to specify an output file.

svn path=/trunk/yasm/; revision=357

52 files changed:
frontends/yasm/yasm.c
libyasm/arch.h
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/expr.c
libyasm/expr.h
libyasm/floatnum.c
libyasm/floatnum.h
libyasm/intnum.c
libyasm/intnum.h
libyasm/linemgr.c
libyasm/linemgr.h
libyasm/objfmt.h
libyasm/section.c
libyasm/section.h
libyasm/symrec.c
libyasm/symrec.h
libyasm/valparam.c
libyasm/valparam.h
modules/arch/x86/bytecode.c
modules/arch/x86/x86-int.h
modules/arch/x86/x86bc.c
modules/objfmts/dbg/dbg-objfmt.c
modules/objfmts/dbg/objfmt.c
src/arch.h
src/arch/x86/bytecode.c
src/arch/x86/x86-int.h
src/arch/x86/x86bc.c
src/bytecode.c
src/bytecode.h
src/expr.c
src/expr.h
src/floatnum.c
src/floatnum.h
src/globals.c
src/globals.h
src/intnum.c
src/intnum.h
src/linemgr.c
src/linemgr.h
src/main.c
src/objfmt.h
src/objfmts/dbg/dbg-objfmt.c
src/objfmts/dbg/objfmt.c
src/section.c
src/section.h
src/symrec.c
src/symrec.h
src/ternary.c
src/ternary.h
src/valparam.c
src/valparam.h

index bdc319994508e252c5800054c725580781da5486..18a8f55079235ae6b598f4f15b8f5753cdbb157e 100644 (file)
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#ifdef STDC_HEADERS
+# include <assert.h>
+#endif
+
 #ifdef gettext_noop
 #define N_(String)     gettext_noop(String)
 #else
 #endif
 
 static int files_open = 0;
-/*@null@*/ static FILE *in;
+/*@null@*/ /*@only@*/ static char *obj_filename = NULL;
+/*@null@*/ static FILE *in = NULL, *obj = NULL;
 
 /* Forward declarations: cmd line parser handlers */
 static int opt_option_handler(char *cmd, /*@null@*/ char *param, int extra);
 static int opt_format_handler(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_objfile_handler(char *cmd, /*@null@*/ char *param, int extra);
 /* Fake handlers: remove them */
 static int boo_boo_handler(char *cmd, /*@null@*/ char *param, int extra);
 static int b_handler(char *cmd, /*@null@*/ char *param, int extra);
@@ -66,6 +72,7 @@ static opt_option options[] =
 {
     { 'h', "help",    0, opt_option_handler, OPT_SHOW_HELP, "show help text", NULL },
     { 'f', "oformat", 1, opt_format_handler, 0, "select output format", "<format>" },
+    { 'o', "objfile", 1, opt_objfile_handler, 0, "name of object-file output", "<filename>" },
     /* Fake handlers: remove them */
     { 'b', NULL,      0, b_handler, 0, "says boom!", NULL },
     {  0,  "boo-boo", 0, boo_boo_handler, 0, "says boo-boo!", NULL },
@@ -88,6 +95,7 @@ static const char *help_tail =
     "\n";
 
 /* main function */
+/*@-globstate@*/
 int
 main(int argc, char *argv[])
 {
@@ -108,8 +116,7 @@ main(int argc, char *argv[])
     }
 
     /* if no files were specified, fallback to reading stdin */
-    if (!in)
-    {
+    if (!in) {
        in = stdin;
        switch_filename("<STDIN>");
     }
@@ -124,6 +131,28 @@ main(int argc, char *argv[])
        return EXIT_FAILURE;
     }
 
+    /* open the object file if not specified */
+    if (!obj) {
+       /* build the object filename */
+       /* TODO: replace the existing extension; this just appends. */
+       if (obj_filename)
+           xfree(obj_filename);
+       assert(in_filename != NULL);
+       obj_filename = xmalloc(strlen(in_filename)+
+                              strlen(cur_objfmt->extension)+2);
+       sprintf(obj_filename, "%s.%s", in_filename, cur_objfmt->extension);
+
+       /* open the built filename */
+       obj = fopen(obj_filename, "wb");
+       if (!obj) {
+           ErrorNow(_("could not open file `%s'"), obj_filename);
+           return EXIT_FAILURE;
+       }
+    }
+
+    /* Initialize the object format */
+    cur_objfmt->initialize(obj);
+
     /* Set NASM as the parser */
     cur_parser = find_parser("nasm");
     if (!cur_parser) {
@@ -136,6 +165,8 @@ main(int argc, char *argv[])
 
     sections = cur_parser->do_parse(cur_parser, in);
 
+    fclose(in);
+
     if (OutputAllErrorWarning() > 0) {
        sections_delete(sections);
        symrec_delete_all();
@@ -144,22 +175,40 @@ main(int argc, char *argv[])
        return EXIT_FAILURE;
     }
 
-    sections_print(sections);
-    printf("\n***Symbol Table***\n");
-    symrec_foreach((int (*) (symrec *))symrec_print);
+    /* XXX  Only for temporary debugging! */
+    fprintf(obj, "\nSections after parsing:\n");
+    indent_level++;
+    sections_print(obj, sections);
+    indent_level--;
+
+    fprintf(obj, "\nSymbol Table:\n");
+    indent_level++;
+    symrec_print_all(obj);
+    indent_level--;
 
     symrec_parser_finalize();
     sections_parser_finalize(sections);
 
-    printf("Post-parser-finalization:\n");
-    sections_print(sections);
+    fprintf(obj, "\nSections after post-parser-finalization:\n");
+    indent_level++;
+    sections_print(obj, sections);
+    indent_level--;
+
+    /* Finalize the object output */
+    cur_objfmt->finalize();
+
+    fclose(obj);
+    if (obj_filename)
+       xfree(obj_filename);
 
     sections_delete(sections);
     symrec_delete_all();
     filename_delete_all();
+
     BitVector_Shutdown();
     return EXIT_SUCCESS;
 }
+/*@=globstate@*/
 
 /*
  *  Command line options handlers
@@ -194,7 +243,38 @@ opt_option_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
 static int
 opt_format_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
 {
-    printf("selected format: %s\n", param?param:"(NULL)");
+    assert(param != NULL);
+    printf("selected format: %s\n", param);
+    return 0;
+}
+
+static int
+opt_objfile_handler(/*@unused@*/ char *cmd, char *param,
+                   /*@unused@*/ int extra)
+{
+    assert(param != NULL);
+    if (strcasecmp(param, "stdout") == 0)
+       obj = stdout;
+    else if (strcasecmp(param, "stderr") == 0)
+       obj = stderr;
+    else {
+       if (obj) {
+           WarningNow("can open only one output file, last specified used");
+           if (obj != stdout && obj != stderr && fclose(obj))
+               ErrorNow("could not close old output file");
+       }
+    }
+
+    obj = fopen(param, "wb");
+    if (!obj) {
+       ErrorNow(_("could not open file `%s'"), param);
+       return 1;
+    }
+
+    if (obj_filename)
+       xfree(obj_filename);
+    obj_filename = xstrdup(param);
+
     return 0;
 }
 
index b614aca446123e92698d90587ea288e5de5fd908..9dd71fb8ca7e60b6fd7934bf939f3feba56065ab 100644 (file)
@@ -37,7 +37,7 @@ struct arch {
        const int type_max;
 
        void (*bc_delete) (bytecode *bc);
-       void (*bc_print) (const bytecode *bc);
+       void (*bc_print) (FILE *f, const bytecode *bc);
        void (*bc_parser_finalize) (bytecode *bc);
     } bc;
 };
index bfc19cbf4ac1e6c547bd82b8e0ae653b9d7c2ff3..eaf05dc70ce9aebe49a3551cbdced008565a1458 100644 (file)
@@ -212,48 +212,50 @@ bc_get_offset(/*@unused@*/ section *sect, /*@unused@*/ bytecode *bc,
 }
 
 void
-bc_print(const bytecode *bc)
+bc_print(FILE *f, const bytecode *bc)
 {
     const bytecode_data *data;
     const bytecode_reserve *reserve;
 
     switch (bc->type) {
        case BC_EMPTY:
-           printf("_Empty_\n");
+           fprintf(f, "%*s_Empty_\n", indent_level, "");
            break;
        case BC_DATA:
            data = bc_get_const_data(bc);
-           printf("_Data_\n");
-           printf("Final Element Size=%u\n",
-                  (unsigned int)data->size);
-           printf("Elements:\n");
-           dvs_print(&data->datahead);
+           fprintf(f, "%*s_Data_\n", indent_level, "");
+           indent_level++;
+           fprintf(f, "%*sFinal Element Size=%u\n", indent_level, "",
+                   (unsigned int)data->size);
+           fprintf(f, "%*sElements:\n", indent_level, "");
+           indent_level++;
+           dvs_print(f, &data->datahead);
+           indent_level-=2;
            break;
        case BC_RESERVE:
            reserve = bc_get_const_data(bc);
-           printf("_Reserve_\n");
-           printf("Num Items=");
-           expr_print(reserve->numitems);
-           printf("\nItem Size=%u\n",
-                  (unsigned int)reserve->itemsize);
+           fprintf(f, "%*s_Reserve_\n", indent_level, "");
+           fprintf(f, "%*sNum Items=", indent_level, "");
+           expr_print(f, reserve->numitems);
+           fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
+                   (unsigned int)reserve->itemsize);
            break;
        default:
            if (bc->type < cur_arch->bc.type_max)
-               cur_arch->bc.bc_print(bc);
+               cur_arch->bc.bc_print(f, bc);
            else
-               printf("_Unknown_\n");
+               fprintf(f, "%*s_Unknown_\n", indent_level, "");
            break;
     }
-    printf("Multiple=");
+    fprintf(f, "%*sMultiple=", indent_level, "");
     if (!bc->multiple)
-       printf("nil (1)");
+       fprintf(f, "nil (1)");
     else
-       expr_print(bc->multiple);
-    printf("\n");
-    printf("Length=%lu\n", bc->len);
-    printf("Filename=\"%s\" Line Number=%u\n",
-          bc->filename ? bc->filename : "<UNKNOWN>", bc->lineno);
-    printf("Offset=%lx\n", bc->offset);
+       expr_print(f, bc->multiple);
+    fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
+    fprintf(f, "%*sFilename=\"%s\" Line Number=%u\n", indent_level, "",
+           bc->filename ? bc->filename : "<UNKNOWN>", bc->lineno);
+    fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
 }
 
 void
@@ -301,13 +303,15 @@ bcs_append(bytecodehead *headp, bytecode *bc)
 }
 
 void
-bcs_print(const bytecodehead *headp)
+bcs_print(FILE *f, const bytecodehead *headp)
 {
     bytecode *cur;
 
     STAILQ_FOREACH(cur, headp, link) {
-       printf("---Next Bytecode---\n");
-       bc_print(cur);
+       fprintf(f, "%*sNext Bytecode:\n", indent_level, "");
+       indent_level++;
+       bc_print(f, cur);
+       indent_level--;
     }
 }
 
@@ -377,22 +381,23 @@ dvs_append(datavalhead *headp, dataval *dv)
 }
 
 void
-dvs_print(const datavalhead *head)
+dvs_print(FILE *f, const datavalhead *head)
 {
     dataval *cur;
 
     STAILQ_FOREACH(cur, head, link) {
        switch (cur->type) {
            case DV_EMPTY:
-               printf(" Empty\n");
+               fprintf(f, "%*sEmpty\n", indent_level, "");
                break;
            case DV_EXPR:
-               printf(" Expr=");
-               expr_print(cur->data.expn);
-               printf("\n");
+               fprintf(f, "%*sExpr=", indent_level, "");
+               expr_print(f, cur->data.expn);
+               fprintf(f, "\n");
                break;
            case DV_STRING:
-               printf(" String=%s\n", cur->data.str_val);
+               fprintf(f, "%*sString=%s\n", indent_level, "",
+                       cur->data.str_val);
                break;
        }
     }
index da6f7e8b294e4ca6e0cd665031975905c6978ead..601564162898946aa1654bf8726b0dcfc8c5092e 100644 (file)
@@ -58,7 +58,7 @@ void bc_delete(/*@only@*/ /*@null@*/ bytecode *bc);
 int bc_get_offset(section *sect, bytecode *bc,
                  /*@out@*/ unsigned long *ret_val);
 
-void bc_print(const bytecode *bc);
+void bc_print(FILE *f, const bytecode *bc);
 
 void bc_parser_finalize(bytecode *bc);
 
@@ -77,7 +77,7 @@ void bcs_delete(bytecodehead *headp);
                                           /*@returned@*/ /*@only@*/ /*@null@*/
                                           bytecode *bc);
 
-void bcs_print(const bytecodehead *headp);
+void bcs_print(FILE *f, const bytecodehead *headp);
 
 void bcs_parser_finalize(bytecodehead *headp);
 
@@ -99,6 +99,6 @@ void dvs_delete(datavalhead *headp);
 /*@null@*/ dataval *dvs_append(datavalhead *headp,
                               /*@returned@*/ /*@null@*/ dataval *dv);
 
-void dvs_print(const datavalhead *head);
+void dvs_print(FILE *f, const datavalhead *head);
 
 #endif
index 230bc1863eb38f847e87ca34e00068992f20b5e3..211dceab30c1629093b1d6826d5ff901c3a6f5e8 100644 (file)
@@ -830,12 +830,17 @@ expr_get_symrec(expr **ep, int simplify)
 /*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
 
 void
-expr_print(expr *e)
+expr_print(FILE *f, expr *e)
 {
     static const char *regs[] = {"ax","cx","dx","bx","sp","bp","si","di"};
     char opstr[3];
     int i;
 
+    if (!e) {
+       fprintf(f, "(nil)");
+       return;
+    }
+
     switch (e->op) {
        case EXPR_ADD:
            strcpy(opstr, "+");
@@ -859,10 +864,12 @@ expr_print(expr *e)
            strcpy(opstr, "%%");
            break;
        case EXPR_NEG:
-           strcpy(opstr, "-");
+           fprintf(f, "-");
+           opstr[0] = 0;
            break;
        case EXPR_NOT:
-           strcpy(opstr, "~");
+           fprintf(f, "~");
+           opstr[0] = 0;
            break;
        case EXPR_OR:
            strcpy(opstr, "|");
@@ -913,28 +920,28 @@ expr_print(expr *e)
     for (i=0; i<e->numterms; i++) {
        switch (e->terms[i].type) {
            case EXPR_SYM:
-               printf("%s", symrec_get_name(e->terms[i].data.sym));
+               fprintf(f, "%s", symrec_get_name(e->terms[i].data.sym));
                break;
            case EXPR_EXPR:
-               printf("(");
-               expr_print(e->terms[i].data.expn);
-               printf(")");
+               fprintf(f, "(");
+               expr_print(f, e->terms[i].data.expn);
+               fprintf(f, ")");
                break;
            case EXPR_INT:
-               intnum_print(e->terms[i].data.intn);
+               intnum_print(f, e->terms[i].data.intn);
                break;
            case EXPR_FLOAT:
-               floatnum_print(e->terms[i].data.flt);
+               floatnum_print(f, e->terms[i].data.flt);
                break;
            case EXPR_REG:
                if (e->terms[i].data.reg.size == 32)
-                   printf("e");
-               printf("%s", regs[e->terms[i].data.reg.num&7]);
+                   fprintf(f, "e");
+               fprintf(f, "%s", regs[e->terms[i].data.reg.num&7]);
                break;
            case EXPR_NONE:
                break;
        }
        if (i < e->numterms-1)
-           printf("%s", opstr);
+           fprintf(f, "%s", opstr);
     }
 }
index 73fa151bd32f791f659ddfd9474817652c647e4b..be7ec1a41e28527ff0a31cfde1da6792410cfc3a 100644 (file)
@@ -69,6 +69,6 @@ void expr_expand_equ(expr *e);
 /*@dependent@*/ /*@null@*/ const symrec *expr_get_symrec(expr **ep,
                                                         int simplify);
 
-void expr_print(expr *);
+void expr_print(FILE *f, /*@null@*/ expr *);
 
 #endif
index e0c739e78714093555ff34b14e34a66f38f73ca5..0f8e870be5fb14e2981e25363fc321cdafa4f88a 100644 (file)
@@ -660,7 +660,7 @@ floatnum_check_size(/*@unused@*/ const floatnum *flt, size_t size)
 }
 
 void
-floatnum_print(const floatnum *flt)
+floatnum_print(FILE *f, const floatnum *flt)
 {
     unsigned char out[10];
     unsigned char *str;
@@ -668,24 +668,25 @@ floatnum_print(const floatnum *flt)
 
     /* Internal format */
     str = BitVector_to_Hex(flt->mantissa);
-    printf("%c %s *2^%04x\n", flt->sign?'-':'+', (char *)str, flt->exponent);
+    fprintf(f, "%c %s *2^%04x\n", flt->sign?'-':'+', (char *)str,
+           flt->exponent);
     xfree(str);
 
     /* 32-bit (single precision) format */
-    printf("32-bit: %d: ", floatnum_get_sized(flt, out, 4));
+    fprintf(f, "32-bit: %d: ", floatnum_get_sized(flt, out, 4));
     for (i=0; i<4; i++)
-       printf("%02x ", out[i]);
-    printf("\n");
+       fprintf(f, "%02x ", out[i]);
+    fprintf(f, "\n");
 
     /* 64-bit (double precision) format */
-    printf("64-bit: %d: ", floatnum_get_sized(flt, out, 8));
+    fprintf(f, "64-bit: %d: ", floatnum_get_sized(flt, out, 8));
     for (i=0; i<8; i++)
-       printf("%02x ", out[i]);
-    printf("\n");
+       fprintf(f, "%02x ", out[i]);
+    fprintf(f, "\n");
 
     /* 80-bit (extended precision) format */
-    printf("80-bit: %d: ", floatnum_get_sized(flt, out, 10));
+    fprintf(f, "80-bit: %d: ", floatnum_get_sized(flt, out, 10));
     for (i=0; i<10; i++)
-       printf("%02x ", out[i]);
-    printf("\n");
+       fprintf(f, "%02x ", out[i]);
+    fprintf(f, "\n");
 }
index 49bce9ecb3f6c1dd94eb138565b85e8cbeaa2a2b..b5ab637cee783d6c909ab30d344c127b09ec35ae 100644 (file)
@@ -52,6 +52,6 @@ int floatnum_get_sized(const floatnum *flt, /*@out@*/ unsigned char *ptr,
  */
 int floatnum_check_size(const floatnum *flt, size_t size);
 
-void floatnum_print(const floatnum *flt);
+void floatnum_print(FILE *f, const floatnum *flt);
 
 #endif
index fec1bb4d0a41bc30807a193c2f52c94760fa391f..75c747035844d606b871d4edffeefc0cdab90f14 100644 (file)
@@ -606,17 +606,17 @@ intnum_check_size(const intnum *intn, size_t size, int is_signed)
 }
 
 void
-intnum_print(const intnum *intn)
+intnum_print(FILE *f, const intnum *intn)
 {
     unsigned char *s;
 
     switch (intn->type) {
        case INTNUM_UL:
-           printf("0x%lx/%u", intn->val.ul, (unsigned int)intn->origsize);
+           fprintf(f, "0x%lx/%u", intn->val.ul, (unsigned int)intn->origsize);
            break;
        case INTNUM_BV:
            s = BitVector_to_Hex(intn->val.bv);
-           printf("0x%s/%u", (char *)s, (unsigned int)intn->origsize);
+           fprintf(f, "0x%s/%u", (char *)s, (unsigned int)intn->origsize);
            xfree(s);
            break;
     }
index 1ec5104e81cb0cf2b4fbf9d376d10b0b628972b5..4c00e4543247a378309dfbae827b52953a469044 100644 (file)
@@ -62,6 +62,6 @@ void intnum_get_sized(const intnum *intn, unsigned char *ptr, size_t size);
  */
 int intnum_check_size(const intnum *intn, size_t size, int is_signed);
 
-void intnum_print(const intnum *intn);
+void intnum_print(FILE *f, const intnum *intn);
 
 #endif
index 895ff64fcbd6d92121311f7b1aa3e1a08a5a294f..dd618c6bd566722f9dd72409d1f8b271b11fab14 100644 (file)
@@ -37,6 +37,8 @@
 unsigned int line_number = 1;
 unsigned int asm_options = 0;
 
+int indent_level = 0;
+
 static /*@only@*/ /*@null@*/ ternary_tree filename_table = (ternary_tree)NULL;
 
 void
index 9349d12b70e69c4f7bc28f6169f75768b8c932e1..4ae8532c5f77375acd459d8ce1a8185d9b03a7e5 100644 (file)
@@ -32,6 +32,8 @@ extern /*@null@*/ objfmt *cur_objfmt;
 extern unsigned int line_number;
 extern unsigned int asm_options;
 
+extern int indent_level;
+
 void switch_filename(const char *filename);
 void filename_delete_all(void);
 
index 7b36c157eddde1547f054291df3b4081a76491f6..a3938ab0cb35e9ae38bb53c423a6aec6cda7e302 100644 (file)
@@ -30,6 +30,9 @@ struct objfmt {
     /* keyword used to select format on the command line */
     const char *keyword;
 
+    /* default output file extension (without the '.') */
+    const char *extension;
+
     /* default (starting) section name */
     const char *default_section_name;
 
@@ -46,15 +49,24 @@ struct objfmt {
      */
 /*    debugfmt *default_df;*/
 
+    /* Initializes object output.  Must be called before any other object
+     * format functions.
+     */
+    void (*initialize) (/*@dependent@*/ FILE *f);
+
+    /* Finishes object output, and cleans up anything created by initialize. */
+    void (*finalize) (void);
+
     /* Switch object file sections.  The first val of the valparams should
-     * be the section name.
+     * be the section name.  Returns NULL if something's wrong, otherwise
+     * returns the new section.
      */
     /*@dependent@*/ /*@null@*/ section *
        (*sections_switch)(sectionhead *headp, valparamhead *valparams,
                           /*@null@*/ valparamhead *objext_valparams);
 
     void (*section_data_delete)(/*@only@*/ void *data);
-    void (*section_data_print)(void *data);
+    void (*section_data_print)(FILE *f, /*@null@*/ void *data);
 
     /*@null@*/ void *(*extern_data_new)(const char *name, /*@null@*/
                                        valparamhead *objext_valparams);
@@ -64,10 +76,12 @@ struct objfmt {
                                        /*@only@*/ expr *size, /*@null@*/
                                        valparamhead *objext_valparams);
 
-    /* It's only valid to pass this *one* SymVisibility (eg, vis is an enum not
-     * a bitmask).
+    /* It's only valid to pass these two functions *one* SymVisibility (eg, vis
+     * is an enum not a bitmask).
      */
     void (*declare_data_delete)(SymVisibility vis, /*@only@*/ void *data);
+    void (*declare_data_print)(FILE *f, SymVisibility vis,
+                              /*@null@*/ void *data);
 
     /* Object format-specific directive support.  Returns 1 if directive was
      * not recognized.  Returns 0 if directive was recognized, even if it
index df38d1dd40506b1287d755ce65745acec5d55c7e..ef897913ac6303c49d7fd932aa1f487d13c5f16f 100644 (file)
@@ -59,29 +59,28 @@ struct section {
     bytecodehead bc;           /* the bytecodes for the section's contents */
 };
 
+/*@-compdestroy@*/
 section *
 sections_initialize(sectionhead *headp)
 {
     section *s;
+    valparamhead vps;
+    valparam *vp;
 
     /* Initialize linked list */
     STAILQ_INIT(headp);
 
-    /* Add an initial "default" section to the list */
-    s = xcalloc(1, sizeof(section));
-    STAILQ_INSERT_TAIL(headp, s, link);
-
-    /* Initialize default section */
-    s->type = SECTION_GENERAL;
+    /* Add an initial "default" section */
     assert(cur_objfmt != NULL);
-    s->data.general.name = xstrdup(cur_objfmt->default_section_name);
-    s->data.general.of_data = NULL;
-    bytecodes_initialize(&s->bc);
-
-    s->res_only = 0;
+    vp_new(vp, xstrdup(cur_objfmt->default_section_name), NULL);
+    vps_initialize(&vps);
+    vps_append(&vps, vp);
+    s = cur_objfmt->sections_switch(headp, &vps, NULL);
+    vps_delete(&vps);
 
     return s;
 }
+/*@=compdestroy@*/
 
 /*@-onlytrans@*/
 section *
@@ -164,13 +163,15 @@ sections_delete(sectionhead *headp)
 }
 
 void
-sections_print(const sectionhead *headp)
+sections_print(FILE *f, const sectionhead *headp)
 {
     section *cur;
     
     STAILQ_FOREACH(cur, headp, link) {
-       printf("***SECTION***\n");
-       section_print(cur, 1);
+       fprintf(f, "%*sSection:\n", indent_level, "");
+       indent_level++;
+       section_print(f, cur, 1);
+       indent_level--;
     }
 }
 
@@ -227,28 +228,37 @@ section_delete(section *sect)
 }
 
 void
-section_print(const section *sect, int print_bcs)
+section_print(FILE *f, const section *sect, int print_bcs)
 {
-    printf(" type=");
+    if (!sect) {
+       fprintf(f, "%*s(none)\n", indent_level, "");
+       return;
+    }
+
+    fprintf(f, "%*stype=", indent_level, "");
     switch (sect->type) {
        case SECTION_GENERAL:
-           printf("general\n name=%s\n objfmt data:\n",
-                  sect->data.general.name);
+           fprintf(f, "general\n%*sname=%s\n%*sobjfmt data:\n", indent_level,
+                   "", sect->data.general.name, indent_level, "");
            assert(cur_objfmt != NULL);
+           indent_level++;
            if (sect->data.general.of_data)
-               cur_objfmt->section_data_print(sect->data.general.of_data);
+               cur_objfmt->section_data_print(f, sect->data.general.of_data);
            else
-               printf("  (none)\n");
+               fprintf(f, "%*s(none)\n", indent_level, "");
+           indent_level--;
            break;
        case SECTION_ABSOLUTE:
-           printf("absolute\n start=");
-           expr_print(sect->data.start);
-           printf("\n");
+           fprintf(f, "absolute\n%*sstart=", indent_level, "");
+           expr_print(f, sect->data.start);
+           fprintf(f, "\n");
            break;
     }
 
     if (print_bcs) {
-       printf(" Bytecodes:\n");
-       bcs_print(&sect->bc);
+       fprintf(f, "%*sBytecodes:\n", indent_level, "");
+       indent_level++;
+       bcs_print(f, &sect->bc);
+       indent_level--;
     }
 }
index ddfaaddd5fe8772d2c21a8d9c9ce9cadf677565f..dd28cade85ae0d6da6ce7a874c0a54294c877107 100644 (file)
@@ -39,7 +39,7 @@ int section_is_absolute(section *sect);
 
 void sections_delete(sectionhead *headp);
 
-void sections_print(const sectionhead *headp);
+void sections_print(FILE *f, const sectionhead *headp);
 
 void sections_parser_finalize(sectionhead *headp);
 
@@ -50,5 +50,5 @@ void sections_parser_finalize(sectionhead *headp);
 
 void section_delete(/*@only@*/ section *sect);
 
-void section_print(const section *sect, int print_bcs);
+void section_print(FILE *f, /*@null@*/ const section *sect, int print_bcs);
 #endif
index 70a611d5446384001bcd89ea5842bd23b788b87c..c265fa88819f77e470054869d0df694e2237ed79 100644 (file)
@@ -114,9 +114,9 @@ symrec_get_or_new(const char *name, int in_table)
 /* Call a function with each symrec.  Stops early if 0 returned by func.
    Returns 0 if stopped early. */
 int
-symrec_foreach(int (*func) (symrec *sym))
+symrec_traverse(void *d, int (*func) (symrec *sym, void *d))
 {
-    return ternary_traverse(sym_table, (int (*) (void *))func);
+    return ternary_traverse(sym_table, d, (int (*) (void *, void *))func);
 }
 
 symrec *
@@ -264,7 +264,7 @@ symrec_get_equ(const symrec *sym)
 static unsigned long firstundef_line;
 static /*@dependent@*/ /*@null@*/ const char *firstundef_filename;
 static int
-symrec_parser_finalize_checksym(symrec *sym)
+symrec_parser_finalize_checksym(symrec *sym, /*@unused@*/ /*@null@*/ void *d)
 {
     /* error if a symbol is used but never defined */
     if ((sym->status & SYM_USED) && !(sym->status & SYM_DEFINED)) {
@@ -283,7 +283,7 @@ void
 symrec_parser_finalize(void)
 {
     firstundef_line = ULONG_MAX;
-    symrec_foreach(symrec_parser_finalize_checksym);
+    symrec_traverse(NULL, symrec_parser_finalize_checksym);
     if (firstundef_line < ULONG_MAX)
        ErrorAt(firstundef_filename, firstundef_line,
                _(" (Each undefined symbol is reported only once.)"));
@@ -324,64 +324,101 @@ symrec_delete(symrec *sym)
     /*@=branchstate@*/
 }
 
+/*@+voidabstract@*/
+static int
+symrec_print_wrapper(symrec *sym, /*@null@*/ void *d)
+{
+    FILE *f;
+    assert(d != NULL);
+    f = (FILE *)d;
+    fprintf(f, "%*sSymbol `%s'\n", indent_level, "", sym->name);
+    indent_level++;
+    symrec_print(f, sym);
+    indent_level--;
+    return 1;
+}
+
 void
-symrec_print(const symrec *sym)
+symrec_print_all(FILE *f)
 {
-    printf("---Symbol `%s'---\n", sym->name);
+    symrec_traverse(f, symrec_print_wrapper);
+}
+/*@=voidabstract@*/
 
+void
+symrec_print(FILE *f, const symrec *sym)
+{
     switch (sym->type) {
        case SYM_UNKNOWN:
-           printf("-Unknown (Common/Extern)-\n");
+           fprintf(f, "%*s-Unknown (Common/Extern)-\n", indent_level, "");
            break;
        case SYM_EQU:
-           printf("_EQU_\n");
-           printf("Expn=");
-           expr_print(sym->value.expn);
-           printf("\n");
+           fprintf(f, "%*s_EQU_\n", indent_level, "");
+           fprintf(f, "%*sExpn=", indent_level, "");
+           expr_print(f, sym->value.expn);
+           fprintf(f, "\n");
            break;
        case SYM_LABEL:
-           printf("_Label_\nSection:");
-           if (sym->value.label.sect)
-               section_print(sym->value.label.sect, 0);
-           else
-               printf(" (none)\n");
+           fprintf(f, "%*s_Label_\n%*sSection:\n", indent_level, "",
+                   indent_level, "");
+           indent_level++;
+           section_print(f, sym->value.label.sect, 0);
+           indent_level--;
            if (!sym->value.label.bc)
-               printf("[First bytecode]\n");
+               fprintf(f, "%*sFirst bytecode\n", indent_level, "");
            else {
-               printf("[Preceding bytecode]\n");
-               bc_print(sym->value.label.bc);
+               fprintf(f, "%*sPreceding bytecode:\n", indent_level, "");
+               indent_level++;
+               bc_print(f, sym->value.label.bc);
+               indent_level--;
            }
            break;
     }
 
-    printf("Status=");
+    fprintf(f, "%*sStatus=", indent_level, "");
     if (sym->status == SYM_NOSTATUS)
-       printf("None\n");
+       fprintf(f, "None\n");
     else {
        if (sym->status & SYM_USED)
-           printf("Used,");
+           fprintf(f, "Used,");
        if (sym->status & SYM_DEFINED)
-           printf("Defined,");
+           fprintf(f, "Defined,");
        if (sym->status & SYM_VALUED)
-           printf("Valued,");
+           fprintf(f, "Valued,");
        if (sym->status & SYM_NOTINTABLE)
-           printf("Not in Table,");
-       printf("\n");
+           fprintf(f, "Not in Table,");
+       fprintf(f, "\n");
     }
 
-    printf("Visibility=");
+    fprintf(f, "%*sVisibility=", indent_level, "");
     if (sym->visibility == SYM_LOCAL)
-       printf("Local\n");
+       fprintf(f, "Local\n");
     else {
        if (sym->visibility & SYM_GLOBAL)
-           printf("Global,");
+           fprintf(f, "Global,");
        if (sym->visibility & SYM_COMMON)
-           printf("Common,");
+           fprintf(f, "Common,");
        if (sym->visibility & SYM_EXTERN)
-           printf("Extern,");
-       printf("\n");
+           fprintf(f, "Extern,");
+       fprintf(f, "\n");
+    }
+
+    assert(cur_objfmt != NULL);
+    if (sym->visibility & SYM_GLOBAL) {
+       fprintf(f, "%*sGlobal object format-specific data:\n", indent_level,
+               "");
+       indent_level++;
+       cur_objfmt->declare_data_print(f, SYM_GLOBAL, sym->of_data_vis_g);
+       indent_level--;
+    }
+    if (sym->visibility & SYM_COMMON) {
+       fprintf(f, "%*sCommon/Extern object format-specific data:\n",
+               indent_level, "");
+       indent_level++;
+       cur_objfmt->declare_data_print(f, SYM_COMMON, sym->of_data_vis_ce);
+       indent_level--;
     }
 
-    printf("Filename=\"%s\" Line Number=%lu\n",
+    fprintf(f, "%*sFilename=\"%s\" Line Number=%lu\n", indent_level, "",
           sym->filename?sym->filename:"(NULL)", sym->line);
 }
index 2d2c149732820eae86a8a34f9a6f01573c6d8723..105d48c44a03557b08faccd6e5ec39d05c70550d 100644 (file)
@@ -47,7 +47,9 @@ SymVisibility symrec_get_visibility(const symrec *sym);
 
 /*@observer@*/ /*@null@*/ const expr *symrec_get_equ(const symrec *sym);
 
-int /*@alt void@*/ symrec_foreach(int (*func) (symrec *sym));
+int /*@alt void@*/ symrec_traverse(/*@null@*/ void *d,
+                                  int (*func) (symrec *sym,
+                                               /*@null@*/ void *d));
 
 void symrec_parser_finalize(void);
 
@@ -58,5 +60,7 @@ void symrec_delete_all(void);
  */
 void symrec_delete(/*@only@*/ symrec *sym);
 
-void symrec_print(const symrec *sym);
+void symrec_print_all(FILE *f);
+
+void symrec_print(FILE *f, const symrec *sym);
 #endif
index 434b0b00a33b914f8a89fdfa9cf8c97a2ba3649d..05ab9644e3079495d7896e6123152eccecbd7e0c 100644 (file)
@@ -22,6 +22,7 @@
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#include "globals.h"
 #include "expr.h"
 
 
@@ -42,3 +43,28 @@ vps_delete(valparamhead *headp)
     }
     STAILQ_INIT(headp);
 }
+
+void
+vps_print(FILE *f, valparamhead *headp)
+{
+    valparam *vp;
+
+    if(!headp) {
+       fprintf(f, "(none)");
+       return;
+    }
+
+    vps_foreach(vp, headp) {
+       if (vp->val)
+           fprintf(f, "(\"%s\",", vp->val);
+       else
+           fprintf(f, "((nil),");
+       if (vp->param)
+           expr_print(f, vp->param);
+       else
+           fprintf(f, "(nil)");
+       fprintf(f, ")");
+       if (vps_next(vp))
+           fprintf(f, ",");
+    }
+}
index 32fc171d717aab255b1e0ad75bc2aa1657acfd71..98bce3b1eab5f503476eee1ff90221ae037ce386 100644 (file)
@@ -54,4 +54,6 @@ void vps_append(valparamhead *headp, /*@keep@*/ valparam *vp);
 
 #define vps_foreach(iter, headp)    STAILQ_FOREACH(iter, headp, link)
 
+void vps_print(FILE *f, /*@null@*/ valparamhead *headp);
+
 #endif
index d5176935a3035ad81f277fd90f2baffcce9213ed..8b0070e7d8fbcdd3c1f4abe4ce58e4ef425c1a94 100644 (file)
@@ -22,6 +22,7 @@
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#include "globals.h"
 #include "errwarn.h"
 #include "intnum.h"
 #include "expr.h"
@@ -331,7 +332,7 @@ x86_bc_delete(bytecode *bc)
 }
 
 void
-x86_bc_print(const bytecode *bc)
+x86_bc_print(FILE *f, const bytecode *bc)
 {
     const x86_insn *insn;
     const x86_jmprel *jmprel;
@@ -340,108 +341,121 @@ x86_bc_print(const bytecode *bc)
     switch ((x86_bytecode_type)bc->type) {
        case X86_BC_INSN:
            insn = bc_get_const_data(bc);
-           printf("_Instruction_\n");
-           printf("Effective Address:");
+           fprintf(f, "%*s_Instruction_\n", indent_level, "");
+           fprintf(f, "%*sEffective Address:", indent_level, "");
            if (!insn->ea)
-               printf(" (nil)\n");
+               fprintf(f, " (nil)\n");
            else {
-               printf("\n Disp=");
-               if (insn->ea->disp)
-                   expr_print(insn->ea->disp);
-               else
-                   printf("(nil)");
-               printf("\n");
+               indent_level++;
+               fprintf(f, "\n%*sDisp=", indent_level, "");
+               expr_print(f, insn->ea->disp);
+               fprintf(f, "\n");
                ead = ea_get_data(insn->ea);
-               printf(" Len=%u SegmentOv=%02x NoSplit=%u\n",
-                      (unsigned int)insn->ea->len,
-                      (unsigned int)ead->segment,
-                      (unsigned int)insn->ea->nosplit);
-               printf(" ModRM=%03o ValidRM=%u NeedRM=%u\n",
-                      (unsigned int)ead->modrm,
-                      (unsigned int)ead->valid_modrm,
-                      (unsigned int)ead->need_modrm);
-               printf(" SIB=%03o ValidSIB=%u NeedSIB=%u\n",
-                      (unsigned int)ead->sib,
-                      (unsigned int)ead->valid_sib,
-                      (unsigned int)ead->need_sib);
+               fprintf(f, "%*sLen=%u SegmentOv=%02x NoSplit=%u\n",
+                       indent_level, "", (unsigned int)insn->ea->len,
+                       (unsigned int)ead->segment,
+                       (unsigned int)insn->ea->nosplit);
+               fprintf(f, "%*sModRM=%03o ValidRM=%u NeedRM=%u\n",
+                       indent_level, "", (unsigned int)ead->modrm,
+                       (unsigned int)ead->valid_modrm,
+                       (unsigned int)ead->need_modrm);
+               fprintf(f, "%*sSIB=%03o ValidSIB=%u NeedSIB=%u\n",
+                       indent_level, "", (unsigned int)ead->sib,
+                       (unsigned int)ead->valid_sib,
+                       (unsigned int)ead->need_sib);
+               indent_level--;
            }
-           printf("Immediate Value:");
+           fprintf(f, "%*sImmediate Value:", indent_level, "");
            if (!insn->imm)
-               printf(" (nil)\n");
+               fprintf(f, " (nil)\n");
            else {
-               printf("\n Val=");
+               indent_level++;
+               fprintf(f, "\n%*sVal=", indent_level, "");
                if (insn->imm->val)
-                   expr_print(insn->imm->val);
+                   expr_print(f, insn->imm->val);
                else
-                   printf("(nil-SHOULDN'T HAPPEN)");
-               printf("\n");
-               printf(" Len=%u, IsNeg=%u\n",
-                      (unsigned int)insn->imm->len,
-                      (unsigned int)insn->imm->isneg);
-               printf(" FLen=%u, FSign=%u\n",
-                      (unsigned int)insn->imm->f_len,
-                      (unsigned int)insn->imm->f_sign);
+                   fprintf(f, "(nil-SHOULDN'T HAPPEN)");
+               fprintf(f, "\n");
+               fprintf(f, "%*sLen=%u, IsNeg=%u\n", indent_level, "",
+                       (unsigned int)insn->imm->len,
+                       (unsigned int)insn->imm->isneg);
+               fprintf(f, "%*sFLen=%u, FSign=%u\n", indent_level, "",
+                       (unsigned int)insn->imm->f_len,
+                       (unsigned int)insn->imm->f_sign);
+               indent_level--;
            }
-           printf("Opcode: %02x %02x %02x OpLen=%u\n",
-                  (unsigned int)insn->opcode[0],
-                  (unsigned int)insn->opcode[1],
-                  (unsigned int)insn->opcode[2],
-                  (unsigned int)insn->opcode_len);
-           printf("AddrSize=%u OperSize=%u LockRepPre=%02x ShiftOp=%u\n",
-                  (unsigned int)insn->addrsize,
-                  (unsigned int)insn->opersize,
-                  (unsigned int)insn->lockrep_pre,
-                  (unsigned int)insn->shift_op);
-           printf("BITS=%u\n", (unsigned int)insn->mode_bits);
+           fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level,
+                   "", (unsigned int)insn->opcode[0],
+                   (unsigned int)insn->opcode[1],
+                   (unsigned int)insn->opcode[2],
+                   (unsigned int)insn->opcode_len);
+           fprintf(f,
+                   "%*sAddrSize=%u OperSize=%u LockRepPre=%02x ShiftOp=%u\n",
+                   indent_level, "",
+                   (unsigned int)insn->addrsize,
+                   (unsigned int)insn->opersize,
+                   (unsigned int)insn->lockrep_pre,
+                   (unsigned int)insn->shift_op);
+           fprintf(f, "%*sBITS=%u\n", indent_level, "",
+                   (unsigned int)insn->mode_bits);
            break;
        case X86_BC_JMPREL:
            jmprel = bc_get_const_data(bc);
-           printf("_Relative Jump_\n");
-           printf("Target=");
-           expr_print(jmprel->target);
-           printf("\nShort Form:\n");
+           fprintf(f, "%*s_Relative Jump_\n", indent_level, "");
+           fprintf(f, "%*sTarget=", indent_level, "");
+           expr_print(f, jmprel->target);
+           fprintf(f, "\n%*sShort Form:\n", indent_level, "");
+           indent_level++;
            if (jmprel->shortop.opcode_len == 0)
-               printf(" None\n");
+               fprintf(f, "%*sNone\n", indent_level, "");
            else
-               printf(" Opcode: %02x %02x %02x OpLen=%u\n",
-                      (unsigned int)jmprel->shortop.opcode[0],
-                      (unsigned int)jmprel->shortop.opcode[1],
-                      (unsigned int)jmprel->shortop.opcode[2],
-                      (unsigned int)jmprel->shortop.opcode_len);
+               fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+                       indent_level, "",
+                       (unsigned int)jmprel->shortop.opcode[0],
+                       (unsigned int)jmprel->shortop.opcode[1],
+                       (unsigned int)jmprel->shortop.opcode[2],
+                       (unsigned int)jmprel->shortop.opcode_len);
+           indent_level--;
+           fprintf(f, "%*sNear Form:\n", indent_level, "");
+           indent_level++;
            if (jmprel->nearop.opcode_len == 0)
-               printf(" None\n");
+               fprintf(f, "%*sNone\n", indent_level, "");
            else
-               printf(" Opcode: %02x %02x %02x OpLen=%u\n",
-                      (unsigned int)jmprel->nearop.opcode[0],
-                      (unsigned int)jmprel->nearop.opcode[1],
-                      (unsigned int)jmprel->nearop.opcode[2],
-                      (unsigned int)jmprel->nearop.opcode_len);
-           printf("OpSel=");
+               fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+                       indent_level, "",
+                       (unsigned int)jmprel->nearop.opcode[0],
+                       (unsigned int)jmprel->nearop.opcode[1],
+                       (unsigned int)jmprel->nearop.opcode[2],
+                       (unsigned int)jmprel->nearop.opcode_len);
+           indent_level--;
+           fprintf(f, "%*sOpSel=", indent_level, "");
            switch (jmprel->op_sel) {
                case JR_NONE:
-                   printf("None");
+                   fprintf(f, "None");
                    break;
                case JR_SHORT:
-                   printf("Short");
+                   fprintf(f, "Short");
                    break;
                case JR_NEAR:
-                   printf("Near");
+                   fprintf(f, "Near");
                    break;
                case JR_SHORT_FORCED:
-                   printf("Forced Short");
+                   fprintf(f, "Forced Short");
                    break;
                case JR_NEAR_FORCED:
-                   printf("Forced Near");
+                   fprintf(f, "Forced Near");
                    break;
                default:
-                   printf("UNKNOWN!!");
+                   fprintf(f, "UNKNOWN!!");
                    break;
            }
-           printf(" BITS=%u\nAddrSize=%u OperSize=%u LockRepPre=%02x\n",
-                  (unsigned int)jmprel->mode_bits,
-                  (unsigned int)jmprel->addrsize,
-                  (unsigned int)jmprel->opersize,
-                  (unsigned int)jmprel->lockrep_pre);
+           fprintf(f, "\n%*sAddrSize=%u OperSize=%u LockRepPre=%02x\n",
+                   indent_level, "",
+                   (unsigned int)jmprel->addrsize,
+                   (unsigned int)jmprel->opersize,
+                   (unsigned int)jmprel->lockrep_pre);
+           fprintf(f, "%*sBITS=%u\n", indent_level, "",
+                   (unsigned int)jmprel->mode_bits);
            break;
     }
 }
index 7d1f5f13c25e803b3cee7a1c3c6a4c41a7b154f8..50d3bcce3f49521464fdf2c9c9b2727f39dff1bc 100644 (file)
@@ -66,6 +66,12 @@ typedef struct x86_insn {
      */
     unsigned char shift_op;
 
+    /* HACK, similar to that for shift_op above, for optimizing instructions
+     * that take a sign-extended imm8 as well as imm values (eg, the arith
+     * instructions and a subset of the imul instructions).
+     */
+    unsigned char signext_imm8_op;
+
     unsigned char mode_bits;
 } x86_insn;
 
@@ -89,7 +95,7 @@ typedef struct x86_jmprel {
 } x86_jmprel;
 
 void x86_bc_delete(bytecode *bc);
-void x86_bc_print(const bytecode *bc);
+void x86_bc_print(FILE *f, const bytecode *bc);
 void x86_bc_parser_finalize(bytecode *bc);
 
 int x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
index d5176935a3035ad81f277fd90f2baffcce9213ed..8b0070e7d8fbcdd3c1f4abe4ce58e4ef425c1a94 100644 (file)
@@ -22,6 +22,7 @@
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#include "globals.h"
 #include "errwarn.h"
 #include "intnum.h"
 #include "expr.h"
@@ -331,7 +332,7 @@ x86_bc_delete(bytecode *bc)
 }
 
 void
-x86_bc_print(const bytecode *bc)
+x86_bc_print(FILE *f, const bytecode *bc)
 {
     const x86_insn *insn;
     const x86_jmprel *jmprel;
@@ -340,108 +341,121 @@ x86_bc_print(const bytecode *bc)
     switch ((x86_bytecode_type)bc->type) {
        case X86_BC_INSN:
            insn = bc_get_const_data(bc);
-           printf("_Instruction_\n");
-           printf("Effective Address:");
+           fprintf(f, "%*s_Instruction_\n", indent_level, "");
+           fprintf(f, "%*sEffective Address:", indent_level, "");
            if (!insn->ea)
-               printf(" (nil)\n");
+               fprintf(f, " (nil)\n");
            else {
-               printf("\n Disp=");
-               if (insn->ea->disp)
-                   expr_print(insn->ea->disp);
-               else
-                   printf("(nil)");
-               printf("\n");
+               indent_level++;
+               fprintf(f, "\n%*sDisp=", indent_level, "");
+               expr_print(f, insn->ea->disp);
+               fprintf(f, "\n");
                ead = ea_get_data(insn->ea);
-               printf(" Len=%u SegmentOv=%02x NoSplit=%u\n",
-                      (unsigned int)insn->ea->len,
-                      (unsigned int)ead->segment,
-                      (unsigned int)insn->ea->nosplit);
-               printf(" ModRM=%03o ValidRM=%u NeedRM=%u\n",
-                      (unsigned int)ead->modrm,
-                      (unsigned int)ead->valid_modrm,
-                      (unsigned int)ead->need_modrm);
-               printf(" SIB=%03o ValidSIB=%u NeedSIB=%u\n",
-                      (unsigned int)ead->sib,
-                      (unsigned int)ead->valid_sib,
-                      (unsigned int)ead->need_sib);
+               fprintf(f, "%*sLen=%u SegmentOv=%02x NoSplit=%u\n",
+                       indent_level, "", (unsigned int)insn->ea->len,
+                       (unsigned int)ead->segment,
+                       (unsigned int)insn->ea->nosplit);
+               fprintf(f, "%*sModRM=%03o ValidRM=%u NeedRM=%u\n",
+                       indent_level, "", (unsigned int)ead->modrm,
+                       (unsigned int)ead->valid_modrm,
+                       (unsigned int)ead->need_modrm);
+               fprintf(f, "%*sSIB=%03o ValidSIB=%u NeedSIB=%u\n",
+                       indent_level, "", (unsigned int)ead->sib,
+                       (unsigned int)ead->valid_sib,
+                       (unsigned int)ead->need_sib);
+               indent_level--;
            }
-           printf("Immediate Value:");
+           fprintf(f, "%*sImmediate Value:", indent_level, "");
            if (!insn->imm)
-               printf(" (nil)\n");
+               fprintf(f, " (nil)\n");
            else {
-               printf("\n Val=");
+               indent_level++;
+               fprintf(f, "\n%*sVal=", indent_level, "");
                if (insn->imm->val)
-                   expr_print(insn->imm->val);
+                   expr_print(f, insn->imm->val);
                else
-                   printf("(nil-SHOULDN'T HAPPEN)");
-               printf("\n");
-               printf(" Len=%u, IsNeg=%u\n",
-                      (unsigned int)insn->imm->len,
-                      (unsigned int)insn->imm->isneg);
-               printf(" FLen=%u, FSign=%u\n",
-                      (unsigned int)insn->imm->f_len,
-                      (unsigned int)insn->imm->f_sign);
+                   fprintf(f, "(nil-SHOULDN'T HAPPEN)");
+               fprintf(f, "\n");
+               fprintf(f, "%*sLen=%u, IsNeg=%u\n", indent_level, "",
+                       (unsigned int)insn->imm->len,
+                       (unsigned int)insn->imm->isneg);
+               fprintf(f, "%*sFLen=%u, FSign=%u\n", indent_level, "",
+                       (unsigned int)insn->imm->f_len,
+                       (unsigned int)insn->imm->f_sign);
+               indent_level--;
            }
-           printf("Opcode: %02x %02x %02x OpLen=%u\n",
-                  (unsigned int)insn->opcode[0],
-                  (unsigned int)insn->opcode[1],
-                  (unsigned int)insn->opcode[2],
-                  (unsigned int)insn->opcode_len);
-           printf("AddrSize=%u OperSize=%u LockRepPre=%02x ShiftOp=%u\n",
-                  (unsigned int)insn->addrsize,
-                  (unsigned int)insn->opersize,
-                  (unsigned int)insn->lockrep_pre,
-                  (unsigned int)insn->shift_op);
-           printf("BITS=%u\n", (unsigned int)insn->mode_bits);
+           fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level,
+                   "", (unsigned int)insn->opcode[0],
+                   (unsigned int)insn->opcode[1],
+                   (unsigned int)insn->opcode[2],
+                   (unsigned int)insn->opcode_len);
+           fprintf(f,
+                   "%*sAddrSize=%u OperSize=%u LockRepPre=%02x ShiftOp=%u\n",
+                   indent_level, "",
+                   (unsigned int)insn->addrsize,
+                   (unsigned int)insn->opersize,
+                   (unsigned int)insn->lockrep_pre,
+                   (unsigned int)insn->shift_op);
+           fprintf(f, "%*sBITS=%u\n", indent_level, "",
+                   (unsigned int)insn->mode_bits);
            break;
        case X86_BC_JMPREL:
            jmprel = bc_get_const_data(bc);
-           printf("_Relative Jump_\n");
-           printf("Target=");
-           expr_print(jmprel->target);
-           printf("\nShort Form:\n");
+           fprintf(f, "%*s_Relative Jump_\n", indent_level, "");
+           fprintf(f, "%*sTarget=", indent_level, "");
+           expr_print(f, jmprel->target);
+           fprintf(f, "\n%*sShort Form:\n", indent_level, "");
+           indent_level++;
            if (jmprel->shortop.opcode_len == 0)
-               printf(" None\n");
+               fprintf(f, "%*sNone\n", indent_level, "");
            else
-               printf(" Opcode: %02x %02x %02x OpLen=%u\n",
-                      (unsigned int)jmprel->shortop.opcode[0],
-                      (unsigned int)jmprel->shortop.opcode[1],
-                      (unsigned int)jmprel->shortop.opcode[2],
-                      (unsigned int)jmprel->shortop.opcode_len);
+               fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+                       indent_level, "",
+                       (unsigned int)jmprel->shortop.opcode[0],
+                       (unsigned int)jmprel->shortop.opcode[1],
+                       (unsigned int)jmprel->shortop.opcode[2],
+                       (unsigned int)jmprel->shortop.opcode_len);
+           indent_level--;
+           fprintf(f, "%*sNear Form:\n", indent_level, "");
+           indent_level++;
            if (jmprel->nearop.opcode_len == 0)
-               printf(" None\n");
+               fprintf(f, "%*sNone\n", indent_level, "");
            else
-               printf(" Opcode: %02x %02x %02x OpLen=%u\n",
-                      (unsigned int)jmprel->nearop.opcode[0],
-                      (unsigned int)jmprel->nearop.opcode[1],
-                      (unsigned int)jmprel->nearop.opcode[2],
-                      (unsigned int)jmprel->nearop.opcode_len);
-           printf("OpSel=");
+               fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+                       indent_level, "",
+                       (unsigned int)jmprel->nearop.opcode[0],
+                       (unsigned int)jmprel->nearop.opcode[1],
+                       (unsigned int)jmprel->nearop.opcode[2],
+                       (unsigned int)jmprel->nearop.opcode_len);
+           indent_level--;
+           fprintf(f, "%*sOpSel=", indent_level, "");
            switch (jmprel->op_sel) {
                case JR_NONE:
-                   printf("None");
+                   fprintf(f, "None");
                    break;
                case JR_SHORT:
-                   printf("Short");
+                   fprintf(f, "Short");
                    break;
                case JR_NEAR:
-                   printf("Near");
+                   fprintf(f, "Near");
                    break;
                case JR_SHORT_FORCED:
-                   printf("Forced Short");
+                   fprintf(f, "Forced Short");
                    break;
                case JR_NEAR_FORCED:
-                   printf("Forced Near");
+                   fprintf(f, "Forced Near");
                    break;
                default:
-                   printf("UNKNOWN!!");
+                   fprintf(f, "UNKNOWN!!");
                    break;
            }
-           printf(" BITS=%u\nAddrSize=%u OperSize=%u LockRepPre=%02x\n",
-                  (unsigned int)jmprel->mode_bits,
-                  (unsigned int)jmprel->addrsize,
-                  (unsigned int)jmprel->opersize,
-                  (unsigned int)jmprel->lockrep_pre);
+           fprintf(f, "\n%*sAddrSize=%u OperSize=%u LockRepPre=%02x\n",
+                   indent_level, "",
+                   (unsigned int)jmprel->addrsize,
+                   (unsigned int)jmprel->opersize,
+                   (unsigned int)jmprel->lockrep_pre);
+           fprintf(f, "%*sBITS=%u\n", indent_level, "",
+                   (unsigned int)jmprel->mode_bits);
            break;
     }
 }
index ab6a3349ec71b643c55b5d8b91dd4a0bfa4d57c6..7a606ca1f618738e1faa8c927fca77f69ec8b8b4 100644 (file)
@@ -22,6 +22,7 @@
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#include "globals.h"
 #include "expr.h"
 #include "symrec.h"
 
 #include "objfmt.h"
 
 
+/*@dependent@*/ FILE *dbg_f;
+
+static void
+dbg_objfmt_initialize(/*@dependent@*/ FILE *f)
+{
+    dbg_f = f;
+    fprintf(dbg_f, "%*sinitialize(f)\n", indent_level, "");
+}
+
+static void
+dbg_objfmt_finalize(void)
+{
+    fprintf(dbg_f, "%*sfinalize()\n", indent_level, "");
+}
+
 static /*@dependent@*/ /*@null@*/ section *
 dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
                           /*@unused@*/ /*@null@*/
@@ -38,55 +54,49 @@ dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
     section *retval;
     int isnew;
 
-#if 0
-    fprintf(stderr, "-dbg_objfmt_sections_switch():\n");
-    printf(" Val/Params:\n");
-    vps_foreach(vp, valparams) {
-       printf("  (%s,", vp->val?vp->val:"(nil)");
-       if (vp->param)
-           expr_print(vp->param);
-       else
-           printf("(nil)");
-       printf(")\n");
-    }
-    printf(" Obj Ext Val/Params:\n");
-    if (!objext_valparams)
-       printf("  (none)\n");
-    else
-       vps_foreach(vp, objext_valparams) {
-           printf("  (%s,", vp->val?vp->val:"(nil)");
-           if (vp->param)
-               expr_print(vp->param);
-           else
-               printf("(nil)");
-           printf(")\n");
-       }
-#endif
+    fprintf(dbg_f, "%*ssections_switch(headp, ", indent_level, "");
+    vps_print(dbg_f, valparams);
+    fprintf(dbg_f, ", ");
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning ");
+
     if ((vp = vps_first(valparams)) && !vp->param && vp->val != NULL) {
        retval = sections_switch_general(headp, vp->val, NULL, 0, &isnew);
-       if (isnew)
+       if (isnew) {
+           fprintf(dbg_f, "(new) ");
            symrec_define_label(vp->val, retval, (bytecode *)NULL, 1);
+       }
+       fprintf(dbg_f, "\"%s\" section\n", vp->val);
        return retval;
-    } else
+    } else {
+       fprintf(dbg_f, "NULL\n");
        return NULL;
+    }
 }
 
 static void
 dbg_objfmt_section_data_delete(/*@only@*/ void *data)
 {
+    fprintf(dbg_f, "%*ssection_data_delete(%p)\n", indent_level, "", data);
     xfree(data);
 }
 
 static void
-dbg_objfmt_section_data_print(/*@unused@*/ void *data)
+dbg_objfmt_section_data_print(FILE *f, /*@null@*/ void *data)
 {
+    if (data)
+       fprintf(f, "%*s%p\n", indent_level, "", data);
+    else
+       fprintf(f, "%*s(none)\n", indent_level, "");
 }
 
 static /*@null@*/ void *
 dbg_objfmt_extern_data_new(const char *name, /*@unused@*/ /*@null@*/
                           valparamhead *objext_valparams)
 {
-    printf("extern_data_new(\"%s\")\n", name);
+    fprintf(dbg_f, "%*sextern_data_new(\"%s\", ", indent_level, "", name);
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning NULL\n");
     return NULL;
 }
 
@@ -94,7 +104,9 @@ static /*@null@*/ void *
 dbg_objfmt_global_data_new(const char *name, /*@unused@*/ /*@null@*/
                           valparamhead *objext_valparams)
 {
-    printf("global_data_new(\"%s\")\n", name);
+    fprintf(dbg_f, "%*sglobal_data_new(\"%s\", ", indent_level, "", name);
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning NULL\n");
     return NULL;
 }
 
@@ -103,51 +115,66 @@ dbg_objfmt_common_data_new(const char *name, /*@only@*/ expr *size,
                           /*@unused@*/ /*@null@*/
                           valparamhead *objext_valparams)
 {
-    printf("common_data_new(\"%s\",", name);
-    expr_print(size);
-    printf(")\n");
+    fprintf(dbg_f, "%*scommon_data_new(\"%s\", ", indent_level, "", name);
+    expr_print(dbg_f, size);
+    fprintf(dbg_f, ", ");
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning ");
+    expr_print(dbg_f, size);
+    fprintf(dbg_f, "\n");
     return size;
 }
 
 static void
-dbg_objfmt_declare_data_delete(/*@unused@*/ SymVisibility vis,
-                              /*@unused@*/ /*@only@*/ void *data)
+dbg_objfmt_declare_data_delete(SymVisibility vis, /*@only@*/ void *data)
 {
-    printf("declare_data_delete()\n");
-    if (vis == SYM_COMMON)
+    fprintf(dbg_f, "%*sdeclare_data_delete(", indent_level, "");
+    switch (vis) {
+       case SYM_LOCAL:
+           fprintf(dbg_f, "Local, ");
+           break;
+       case SYM_GLOBAL:
+           fprintf(dbg_f, "Global, ");
+           break;
+       case SYM_COMMON:
+           fprintf(dbg_f, "Common, ");
+           break;
+       case SYM_EXTERN:
+           fprintf(dbg_f, "Extern, ");
+           break;
+    }
+    if (vis == SYM_COMMON) {
+       expr_print(dbg_f, data);
        expr_delete(data);
-    else
+    } else {
+       fprintf(dbg_f, "%p", data);
        xfree(data);
+    }
+    fprintf(dbg_f, ")\n");
+}
+
+static void
+dbg_objfmt_declare_data_print(FILE *f, SymVisibility vis,
+                             /*@null@*/ void *data)
+{
+    if (vis == SYM_COMMON) {
+       fprintf(f, "%*sSize=", indent_level, "");
+       expr_print(f, data);
+       fprintf(f, "\n");
+    } else {
+       fprintf(f, "%*s(none)\n", indent_level, "");
+    }
 }
 
 static int
 dbg_objfmt_directive(const char *name, valparamhead *valparams,
                     /*@null@*/ valparamhead *objext_valparams)
 {
-    valparam *vp;
-
-    printf("directive(\"%s\", valparams:\n", name);
-    vps_foreach(vp, valparams) {
-       printf("  (%s,", vp->val?vp->val:"(nil)");
-       if (vp->param)
-           expr_print(vp->param);
-       else
-           printf("(nil)");
-       printf(")\n");
-    }
-    printf(" objext_valparams:\n");
-    if (!objext_valparams)
-       printf("  (none)\n");
-    else
-       vps_foreach(vp, objext_valparams) {
-           printf("  (%s,", vp->val?vp->val:"(nil)");
-           if (vp->param)
-               expr_print(vp->param);
-           else
-               printf("(nil)");
-           printf(")\n");
-       }
-
+    fprintf(dbg_f, "%*sdirective(\"%s\", ", indent_level, "", name);
+    vps_print(dbg_f, valparams);
+    fprintf(dbg_f, ", ");
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning 0 (recognized)\n");
     return 0;      /* dbg format "recognizes" all directives */
 }
 
@@ -155,8 +182,11 @@ dbg_objfmt_directive(const char *name, valparamhead *valparams,
 objfmt dbg_objfmt = {
     "Trace of all info passed to object format module",
     "dbg",
+    "dbg",
     ".text",
     32,
+    dbg_objfmt_initialize,
+    dbg_objfmt_finalize,
     dbg_objfmt_sections_switch,
     dbg_objfmt_section_data_delete,
     dbg_objfmt_section_data_print,
@@ -164,5 +194,6 @@ objfmt dbg_objfmt = {
     dbg_objfmt_global_data_new,
     dbg_objfmt_common_data_new,
     dbg_objfmt_declare_data_delete,
+    dbg_objfmt_declare_data_print,
     dbg_objfmt_directive
 };
index ab6a3349ec71b643c55b5d8b91dd4a0bfa4d57c6..7a606ca1f618738e1faa8c927fca77f69ec8b8b4 100644 (file)
@@ -22,6 +22,7 @@
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#include "globals.h"
 #include "expr.h"
 #include "symrec.h"
 
 #include "objfmt.h"
 
 
+/*@dependent@*/ FILE *dbg_f;
+
+static void
+dbg_objfmt_initialize(/*@dependent@*/ FILE *f)
+{
+    dbg_f = f;
+    fprintf(dbg_f, "%*sinitialize(f)\n", indent_level, "");
+}
+
+static void
+dbg_objfmt_finalize(void)
+{
+    fprintf(dbg_f, "%*sfinalize()\n", indent_level, "");
+}
+
 static /*@dependent@*/ /*@null@*/ section *
 dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
                           /*@unused@*/ /*@null@*/
@@ -38,55 +54,49 @@ dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
     section *retval;
     int isnew;
 
-#if 0
-    fprintf(stderr, "-dbg_objfmt_sections_switch():\n");
-    printf(" Val/Params:\n");
-    vps_foreach(vp, valparams) {
-       printf("  (%s,", vp->val?vp->val:"(nil)");
-       if (vp->param)
-           expr_print(vp->param);
-       else
-           printf("(nil)");
-       printf(")\n");
-    }
-    printf(" Obj Ext Val/Params:\n");
-    if (!objext_valparams)
-       printf("  (none)\n");
-    else
-       vps_foreach(vp, objext_valparams) {
-           printf("  (%s,", vp->val?vp->val:"(nil)");
-           if (vp->param)
-               expr_print(vp->param);
-           else
-               printf("(nil)");
-           printf(")\n");
-       }
-#endif
+    fprintf(dbg_f, "%*ssections_switch(headp, ", indent_level, "");
+    vps_print(dbg_f, valparams);
+    fprintf(dbg_f, ", ");
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning ");
+
     if ((vp = vps_first(valparams)) && !vp->param && vp->val != NULL) {
        retval = sections_switch_general(headp, vp->val, NULL, 0, &isnew);
-       if (isnew)
+       if (isnew) {
+           fprintf(dbg_f, "(new) ");
            symrec_define_label(vp->val, retval, (bytecode *)NULL, 1);
+       }
+       fprintf(dbg_f, "\"%s\" section\n", vp->val);
        return retval;
-    } else
+    } else {
+       fprintf(dbg_f, "NULL\n");
        return NULL;
+    }
 }
 
 static void
 dbg_objfmt_section_data_delete(/*@only@*/ void *data)
 {
+    fprintf(dbg_f, "%*ssection_data_delete(%p)\n", indent_level, "", data);
     xfree(data);
 }
 
 static void
-dbg_objfmt_section_data_print(/*@unused@*/ void *data)
+dbg_objfmt_section_data_print(FILE *f, /*@null@*/ void *data)
 {
+    if (data)
+       fprintf(f, "%*s%p\n", indent_level, "", data);
+    else
+       fprintf(f, "%*s(none)\n", indent_level, "");
 }
 
 static /*@null@*/ void *
 dbg_objfmt_extern_data_new(const char *name, /*@unused@*/ /*@null@*/
                           valparamhead *objext_valparams)
 {
-    printf("extern_data_new(\"%s\")\n", name);
+    fprintf(dbg_f, "%*sextern_data_new(\"%s\", ", indent_level, "", name);
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning NULL\n");
     return NULL;
 }
 
@@ -94,7 +104,9 @@ static /*@null@*/ void *
 dbg_objfmt_global_data_new(const char *name, /*@unused@*/ /*@null@*/
                           valparamhead *objext_valparams)
 {
-    printf("global_data_new(\"%s\")\n", name);
+    fprintf(dbg_f, "%*sglobal_data_new(\"%s\", ", indent_level, "", name);
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning NULL\n");
     return NULL;
 }
 
@@ -103,51 +115,66 @@ dbg_objfmt_common_data_new(const char *name, /*@only@*/ expr *size,
                           /*@unused@*/ /*@null@*/
                           valparamhead *objext_valparams)
 {
-    printf("common_data_new(\"%s\",", name);
-    expr_print(size);
-    printf(")\n");
+    fprintf(dbg_f, "%*scommon_data_new(\"%s\", ", indent_level, "", name);
+    expr_print(dbg_f, size);
+    fprintf(dbg_f, ", ");
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning ");
+    expr_print(dbg_f, size);
+    fprintf(dbg_f, "\n");
     return size;
 }
 
 static void
-dbg_objfmt_declare_data_delete(/*@unused@*/ SymVisibility vis,
-                              /*@unused@*/ /*@only@*/ void *data)
+dbg_objfmt_declare_data_delete(SymVisibility vis, /*@only@*/ void *data)
 {
-    printf("declare_data_delete()\n");
-    if (vis == SYM_COMMON)
+    fprintf(dbg_f, "%*sdeclare_data_delete(", indent_level, "");
+    switch (vis) {
+       case SYM_LOCAL:
+           fprintf(dbg_f, "Local, ");
+           break;
+       case SYM_GLOBAL:
+           fprintf(dbg_f, "Global, ");
+           break;
+       case SYM_COMMON:
+           fprintf(dbg_f, "Common, ");
+           break;
+       case SYM_EXTERN:
+           fprintf(dbg_f, "Extern, ");
+           break;
+    }
+    if (vis == SYM_COMMON) {
+       expr_print(dbg_f, data);
        expr_delete(data);
-    else
+    } else {
+       fprintf(dbg_f, "%p", data);
        xfree(data);
+    }
+    fprintf(dbg_f, ")\n");
+}
+
+static void
+dbg_objfmt_declare_data_print(FILE *f, SymVisibility vis,
+                             /*@null@*/ void *data)
+{
+    if (vis == SYM_COMMON) {
+       fprintf(f, "%*sSize=", indent_level, "");
+       expr_print(f, data);
+       fprintf(f, "\n");
+    } else {
+       fprintf(f, "%*s(none)\n", indent_level, "");
+    }
 }
 
 static int
 dbg_objfmt_directive(const char *name, valparamhead *valparams,
                     /*@null@*/ valparamhead *objext_valparams)
 {
-    valparam *vp;
-
-    printf("directive(\"%s\", valparams:\n", name);
-    vps_foreach(vp, valparams) {
-       printf("  (%s,", vp->val?vp->val:"(nil)");
-       if (vp->param)
-           expr_print(vp->param);
-       else
-           printf("(nil)");
-       printf(")\n");
-    }
-    printf(" objext_valparams:\n");
-    if (!objext_valparams)
-       printf("  (none)\n");
-    else
-       vps_foreach(vp, objext_valparams) {
-           printf("  (%s,", vp->val?vp->val:"(nil)");
-           if (vp->param)
-               expr_print(vp->param);
-           else
-               printf("(nil)");
-           printf(")\n");
-       }
-
+    fprintf(dbg_f, "%*sdirective(\"%s\", ", indent_level, "", name);
+    vps_print(dbg_f, valparams);
+    fprintf(dbg_f, ", ");
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning 0 (recognized)\n");
     return 0;      /* dbg format "recognizes" all directives */
 }
 
@@ -155,8 +182,11 @@ dbg_objfmt_directive(const char *name, valparamhead *valparams,
 objfmt dbg_objfmt = {
     "Trace of all info passed to object format module",
     "dbg",
+    "dbg",
     ".text",
     32,
+    dbg_objfmt_initialize,
+    dbg_objfmt_finalize,
     dbg_objfmt_sections_switch,
     dbg_objfmt_section_data_delete,
     dbg_objfmt_section_data_print,
@@ -164,5 +194,6 @@ objfmt dbg_objfmt = {
     dbg_objfmt_global_data_new,
     dbg_objfmt_common_data_new,
     dbg_objfmt_declare_data_delete,
+    dbg_objfmt_declare_data_print,
     dbg_objfmt_directive
 };
index b614aca446123e92698d90587ea288e5de5fd908..9dd71fb8ca7e60b6fd7934bf939f3feba56065ab 100644 (file)
@@ -37,7 +37,7 @@ struct arch {
        const int type_max;
 
        void (*bc_delete) (bytecode *bc);
-       void (*bc_print) (const bytecode *bc);
+       void (*bc_print) (FILE *f, const bytecode *bc);
        void (*bc_parser_finalize) (bytecode *bc);
     } bc;
 };
index d5176935a3035ad81f277fd90f2baffcce9213ed..8b0070e7d8fbcdd3c1f4abe4ce58e4ef425c1a94 100644 (file)
@@ -22,6 +22,7 @@
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#include "globals.h"
 #include "errwarn.h"
 #include "intnum.h"
 #include "expr.h"
@@ -331,7 +332,7 @@ x86_bc_delete(bytecode *bc)
 }
 
 void
-x86_bc_print(const bytecode *bc)
+x86_bc_print(FILE *f, const bytecode *bc)
 {
     const x86_insn *insn;
     const x86_jmprel *jmprel;
@@ -340,108 +341,121 @@ x86_bc_print(const bytecode *bc)
     switch ((x86_bytecode_type)bc->type) {
        case X86_BC_INSN:
            insn = bc_get_const_data(bc);
-           printf("_Instruction_\n");
-           printf("Effective Address:");
+           fprintf(f, "%*s_Instruction_\n", indent_level, "");
+           fprintf(f, "%*sEffective Address:", indent_level, "");
            if (!insn->ea)
-               printf(" (nil)\n");
+               fprintf(f, " (nil)\n");
            else {
-               printf("\n Disp=");
-               if (insn->ea->disp)
-                   expr_print(insn->ea->disp);
-               else
-                   printf("(nil)");
-               printf("\n");
+               indent_level++;
+               fprintf(f, "\n%*sDisp=", indent_level, "");
+               expr_print(f, insn->ea->disp);
+               fprintf(f, "\n");
                ead = ea_get_data(insn->ea);
-               printf(" Len=%u SegmentOv=%02x NoSplit=%u\n",
-                      (unsigned int)insn->ea->len,
-                      (unsigned int)ead->segment,
-                      (unsigned int)insn->ea->nosplit);
-               printf(" ModRM=%03o ValidRM=%u NeedRM=%u\n",
-                      (unsigned int)ead->modrm,
-                      (unsigned int)ead->valid_modrm,
-                      (unsigned int)ead->need_modrm);
-               printf(" SIB=%03o ValidSIB=%u NeedSIB=%u\n",
-                      (unsigned int)ead->sib,
-                      (unsigned int)ead->valid_sib,
-                      (unsigned int)ead->need_sib);
+               fprintf(f, "%*sLen=%u SegmentOv=%02x NoSplit=%u\n",
+                       indent_level, "", (unsigned int)insn->ea->len,
+                       (unsigned int)ead->segment,
+                       (unsigned int)insn->ea->nosplit);
+               fprintf(f, "%*sModRM=%03o ValidRM=%u NeedRM=%u\n",
+                       indent_level, "", (unsigned int)ead->modrm,
+                       (unsigned int)ead->valid_modrm,
+                       (unsigned int)ead->need_modrm);
+               fprintf(f, "%*sSIB=%03o ValidSIB=%u NeedSIB=%u\n",
+                       indent_level, "", (unsigned int)ead->sib,
+                       (unsigned int)ead->valid_sib,
+                       (unsigned int)ead->need_sib);
+               indent_level--;
            }
-           printf("Immediate Value:");
+           fprintf(f, "%*sImmediate Value:", indent_level, "");
            if (!insn->imm)
-               printf(" (nil)\n");
+               fprintf(f, " (nil)\n");
            else {
-               printf("\n Val=");
+               indent_level++;
+               fprintf(f, "\n%*sVal=", indent_level, "");
                if (insn->imm->val)
-                   expr_print(insn->imm->val);
+                   expr_print(f, insn->imm->val);
                else
-                   printf("(nil-SHOULDN'T HAPPEN)");
-               printf("\n");
-               printf(" Len=%u, IsNeg=%u\n",
-                      (unsigned int)insn->imm->len,
-                      (unsigned int)insn->imm->isneg);
-               printf(" FLen=%u, FSign=%u\n",
-                      (unsigned int)insn->imm->f_len,
-                      (unsigned int)insn->imm->f_sign);
+                   fprintf(f, "(nil-SHOULDN'T HAPPEN)");
+               fprintf(f, "\n");
+               fprintf(f, "%*sLen=%u, IsNeg=%u\n", indent_level, "",
+                       (unsigned int)insn->imm->len,
+                       (unsigned int)insn->imm->isneg);
+               fprintf(f, "%*sFLen=%u, FSign=%u\n", indent_level, "",
+                       (unsigned int)insn->imm->f_len,
+                       (unsigned int)insn->imm->f_sign);
+               indent_level--;
            }
-           printf("Opcode: %02x %02x %02x OpLen=%u\n",
-                  (unsigned int)insn->opcode[0],
-                  (unsigned int)insn->opcode[1],
-                  (unsigned int)insn->opcode[2],
-                  (unsigned int)insn->opcode_len);
-           printf("AddrSize=%u OperSize=%u LockRepPre=%02x ShiftOp=%u\n",
-                  (unsigned int)insn->addrsize,
-                  (unsigned int)insn->opersize,
-                  (unsigned int)insn->lockrep_pre,
-                  (unsigned int)insn->shift_op);
-           printf("BITS=%u\n", (unsigned int)insn->mode_bits);
+           fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level,
+                   "", (unsigned int)insn->opcode[0],
+                   (unsigned int)insn->opcode[1],
+                   (unsigned int)insn->opcode[2],
+                   (unsigned int)insn->opcode_len);
+           fprintf(f,
+                   "%*sAddrSize=%u OperSize=%u LockRepPre=%02x ShiftOp=%u\n",
+                   indent_level, "",
+                   (unsigned int)insn->addrsize,
+                   (unsigned int)insn->opersize,
+                   (unsigned int)insn->lockrep_pre,
+                   (unsigned int)insn->shift_op);
+           fprintf(f, "%*sBITS=%u\n", indent_level, "",
+                   (unsigned int)insn->mode_bits);
            break;
        case X86_BC_JMPREL:
            jmprel = bc_get_const_data(bc);
-           printf("_Relative Jump_\n");
-           printf("Target=");
-           expr_print(jmprel->target);
-           printf("\nShort Form:\n");
+           fprintf(f, "%*s_Relative Jump_\n", indent_level, "");
+           fprintf(f, "%*sTarget=", indent_level, "");
+           expr_print(f, jmprel->target);
+           fprintf(f, "\n%*sShort Form:\n", indent_level, "");
+           indent_level++;
            if (jmprel->shortop.opcode_len == 0)
-               printf(" None\n");
+               fprintf(f, "%*sNone\n", indent_level, "");
            else
-               printf(" Opcode: %02x %02x %02x OpLen=%u\n",
-                      (unsigned int)jmprel->shortop.opcode[0],
-                      (unsigned int)jmprel->shortop.opcode[1],
-                      (unsigned int)jmprel->shortop.opcode[2],
-                      (unsigned int)jmprel->shortop.opcode_len);
+               fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+                       indent_level, "",
+                       (unsigned int)jmprel->shortop.opcode[0],
+                       (unsigned int)jmprel->shortop.opcode[1],
+                       (unsigned int)jmprel->shortop.opcode[2],
+                       (unsigned int)jmprel->shortop.opcode_len);
+           indent_level--;
+           fprintf(f, "%*sNear Form:\n", indent_level, "");
+           indent_level++;
            if (jmprel->nearop.opcode_len == 0)
-               printf(" None\n");
+               fprintf(f, "%*sNone\n", indent_level, "");
            else
-               printf(" Opcode: %02x %02x %02x OpLen=%u\n",
-                      (unsigned int)jmprel->nearop.opcode[0],
-                      (unsigned int)jmprel->nearop.opcode[1],
-                      (unsigned int)jmprel->nearop.opcode[2],
-                      (unsigned int)jmprel->nearop.opcode_len);
-           printf("OpSel=");
+               fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+                       indent_level, "",
+                       (unsigned int)jmprel->nearop.opcode[0],
+                       (unsigned int)jmprel->nearop.opcode[1],
+                       (unsigned int)jmprel->nearop.opcode[2],
+                       (unsigned int)jmprel->nearop.opcode_len);
+           indent_level--;
+           fprintf(f, "%*sOpSel=", indent_level, "");
            switch (jmprel->op_sel) {
                case JR_NONE:
-                   printf("None");
+                   fprintf(f, "None");
                    break;
                case JR_SHORT:
-                   printf("Short");
+                   fprintf(f, "Short");
                    break;
                case JR_NEAR:
-                   printf("Near");
+                   fprintf(f, "Near");
                    break;
                case JR_SHORT_FORCED:
-                   printf("Forced Short");
+                   fprintf(f, "Forced Short");
                    break;
                case JR_NEAR_FORCED:
-                   printf("Forced Near");
+                   fprintf(f, "Forced Near");
                    break;
                default:
-                   printf("UNKNOWN!!");
+                   fprintf(f, "UNKNOWN!!");
                    break;
            }
-           printf(" BITS=%u\nAddrSize=%u OperSize=%u LockRepPre=%02x\n",
-                  (unsigned int)jmprel->mode_bits,
-                  (unsigned int)jmprel->addrsize,
-                  (unsigned int)jmprel->opersize,
-                  (unsigned int)jmprel->lockrep_pre);
+           fprintf(f, "\n%*sAddrSize=%u OperSize=%u LockRepPre=%02x\n",
+                   indent_level, "",
+                   (unsigned int)jmprel->addrsize,
+                   (unsigned int)jmprel->opersize,
+                   (unsigned int)jmprel->lockrep_pre);
+           fprintf(f, "%*sBITS=%u\n", indent_level, "",
+                   (unsigned int)jmprel->mode_bits);
            break;
     }
 }
index 7d1f5f13c25e803b3cee7a1c3c6a4c41a7b154f8..50d3bcce3f49521464fdf2c9c9b2727f39dff1bc 100644 (file)
@@ -66,6 +66,12 @@ typedef struct x86_insn {
      */
     unsigned char shift_op;
 
+    /* HACK, similar to that for shift_op above, for optimizing instructions
+     * that take a sign-extended imm8 as well as imm values (eg, the arith
+     * instructions and a subset of the imul instructions).
+     */
+    unsigned char signext_imm8_op;
+
     unsigned char mode_bits;
 } x86_insn;
 
@@ -89,7 +95,7 @@ typedef struct x86_jmprel {
 } x86_jmprel;
 
 void x86_bc_delete(bytecode *bc);
-void x86_bc_print(const bytecode *bc);
+void x86_bc_print(FILE *f, const bytecode *bc);
 void x86_bc_parser_finalize(bytecode *bc);
 
 int x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits,
index d5176935a3035ad81f277fd90f2baffcce9213ed..8b0070e7d8fbcdd3c1f4abe4ce58e4ef425c1a94 100644 (file)
@@ -22,6 +22,7 @@
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#include "globals.h"
 #include "errwarn.h"
 #include "intnum.h"
 #include "expr.h"
@@ -331,7 +332,7 @@ x86_bc_delete(bytecode *bc)
 }
 
 void
-x86_bc_print(const bytecode *bc)
+x86_bc_print(FILE *f, const bytecode *bc)
 {
     const x86_insn *insn;
     const x86_jmprel *jmprel;
@@ -340,108 +341,121 @@ x86_bc_print(const bytecode *bc)
     switch ((x86_bytecode_type)bc->type) {
        case X86_BC_INSN:
            insn = bc_get_const_data(bc);
-           printf("_Instruction_\n");
-           printf("Effective Address:");
+           fprintf(f, "%*s_Instruction_\n", indent_level, "");
+           fprintf(f, "%*sEffective Address:", indent_level, "");
            if (!insn->ea)
-               printf(" (nil)\n");
+               fprintf(f, " (nil)\n");
            else {
-               printf("\n Disp=");
-               if (insn->ea->disp)
-                   expr_print(insn->ea->disp);
-               else
-                   printf("(nil)");
-               printf("\n");
+               indent_level++;
+               fprintf(f, "\n%*sDisp=", indent_level, "");
+               expr_print(f, insn->ea->disp);
+               fprintf(f, "\n");
                ead = ea_get_data(insn->ea);
-               printf(" Len=%u SegmentOv=%02x NoSplit=%u\n",
-                      (unsigned int)insn->ea->len,
-                      (unsigned int)ead->segment,
-                      (unsigned int)insn->ea->nosplit);
-               printf(" ModRM=%03o ValidRM=%u NeedRM=%u\n",
-                      (unsigned int)ead->modrm,
-                      (unsigned int)ead->valid_modrm,
-                      (unsigned int)ead->need_modrm);
-               printf(" SIB=%03o ValidSIB=%u NeedSIB=%u\n",
-                      (unsigned int)ead->sib,
-                      (unsigned int)ead->valid_sib,
-                      (unsigned int)ead->need_sib);
+               fprintf(f, "%*sLen=%u SegmentOv=%02x NoSplit=%u\n",
+                       indent_level, "", (unsigned int)insn->ea->len,
+                       (unsigned int)ead->segment,
+                       (unsigned int)insn->ea->nosplit);
+               fprintf(f, "%*sModRM=%03o ValidRM=%u NeedRM=%u\n",
+                       indent_level, "", (unsigned int)ead->modrm,
+                       (unsigned int)ead->valid_modrm,
+                       (unsigned int)ead->need_modrm);
+               fprintf(f, "%*sSIB=%03o ValidSIB=%u NeedSIB=%u\n",
+                       indent_level, "", (unsigned int)ead->sib,
+                       (unsigned int)ead->valid_sib,
+                       (unsigned int)ead->need_sib);
+               indent_level--;
            }
-           printf("Immediate Value:");
+           fprintf(f, "%*sImmediate Value:", indent_level, "");
            if (!insn->imm)
-               printf(" (nil)\n");
+               fprintf(f, " (nil)\n");
            else {
-               printf("\n Val=");
+               indent_level++;
+               fprintf(f, "\n%*sVal=", indent_level, "");
                if (insn->imm->val)
-                   expr_print(insn->imm->val);
+                   expr_print(f, insn->imm->val);
                else
-                   printf("(nil-SHOULDN'T HAPPEN)");
-               printf("\n");
-               printf(" Len=%u, IsNeg=%u\n",
-                      (unsigned int)insn->imm->len,
-                      (unsigned int)insn->imm->isneg);
-               printf(" FLen=%u, FSign=%u\n",
-                      (unsigned int)insn->imm->f_len,
-                      (unsigned int)insn->imm->f_sign);
+                   fprintf(f, "(nil-SHOULDN'T HAPPEN)");
+               fprintf(f, "\n");
+               fprintf(f, "%*sLen=%u, IsNeg=%u\n", indent_level, "",
+                       (unsigned int)insn->imm->len,
+                       (unsigned int)insn->imm->isneg);
+               fprintf(f, "%*sFLen=%u, FSign=%u\n", indent_level, "",
+                       (unsigned int)insn->imm->f_len,
+                       (unsigned int)insn->imm->f_sign);
+               indent_level--;
            }
-           printf("Opcode: %02x %02x %02x OpLen=%u\n",
-                  (unsigned int)insn->opcode[0],
-                  (unsigned int)insn->opcode[1],
-                  (unsigned int)insn->opcode[2],
-                  (unsigned int)insn->opcode_len);
-           printf("AddrSize=%u OperSize=%u LockRepPre=%02x ShiftOp=%u\n",
-                  (unsigned int)insn->addrsize,
-                  (unsigned int)insn->opersize,
-                  (unsigned int)insn->lockrep_pre,
-                  (unsigned int)insn->shift_op);
-           printf("BITS=%u\n", (unsigned int)insn->mode_bits);
+           fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n", indent_level,
+                   "", (unsigned int)insn->opcode[0],
+                   (unsigned int)insn->opcode[1],
+                   (unsigned int)insn->opcode[2],
+                   (unsigned int)insn->opcode_len);
+           fprintf(f,
+                   "%*sAddrSize=%u OperSize=%u LockRepPre=%02x ShiftOp=%u\n",
+                   indent_level, "",
+                   (unsigned int)insn->addrsize,
+                   (unsigned int)insn->opersize,
+                   (unsigned int)insn->lockrep_pre,
+                   (unsigned int)insn->shift_op);
+           fprintf(f, "%*sBITS=%u\n", indent_level, "",
+                   (unsigned int)insn->mode_bits);
            break;
        case X86_BC_JMPREL:
            jmprel = bc_get_const_data(bc);
-           printf("_Relative Jump_\n");
-           printf("Target=");
-           expr_print(jmprel->target);
-           printf("\nShort Form:\n");
+           fprintf(f, "%*s_Relative Jump_\n", indent_level, "");
+           fprintf(f, "%*sTarget=", indent_level, "");
+           expr_print(f, jmprel->target);
+           fprintf(f, "\n%*sShort Form:\n", indent_level, "");
+           indent_level++;
            if (jmprel->shortop.opcode_len == 0)
-               printf(" None\n");
+               fprintf(f, "%*sNone\n", indent_level, "");
            else
-               printf(" Opcode: %02x %02x %02x OpLen=%u\n",
-                      (unsigned int)jmprel->shortop.opcode[0],
-                      (unsigned int)jmprel->shortop.opcode[1],
-                      (unsigned int)jmprel->shortop.opcode[2],
-                      (unsigned int)jmprel->shortop.opcode_len);
+               fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+                       indent_level, "",
+                       (unsigned int)jmprel->shortop.opcode[0],
+                       (unsigned int)jmprel->shortop.opcode[1],
+                       (unsigned int)jmprel->shortop.opcode[2],
+                       (unsigned int)jmprel->shortop.opcode_len);
+           indent_level--;
+           fprintf(f, "%*sNear Form:\n", indent_level, "");
+           indent_level++;
            if (jmprel->nearop.opcode_len == 0)
-               printf(" None\n");
+               fprintf(f, "%*sNone\n", indent_level, "");
            else
-               printf(" Opcode: %02x %02x %02x OpLen=%u\n",
-                      (unsigned int)jmprel->nearop.opcode[0],
-                      (unsigned int)jmprel->nearop.opcode[1],
-                      (unsigned int)jmprel->nearop.opcode[2],
-                      (unsigned int)jmprel->nearop.opcode_len);
-           printf("OpSel=");
+               fprintf(f, "%*sOpcode: %02x %02x %02x OpLen=%u\n",
+                       indent_level, "",
+                       (unsigned int)jmprel->nearop.opcode[0],
+                       (unsigned int)jmprel->nearop.opcode[1],
+                       (unsigned int)jmprel->nearop.opcode[2],
+                       (unsigned int)jmprel->nearop.opcode_len);
+           indent_level--;
+           fprintf(f, "%*sOpSel=", indent_level, "");
            switch (jmprel->op_sel) {
                case JR_NONE:
-                   printf("None");
+                   fprintf(f, "None");
                    break;
                case JR_SHORT:
-                   printf("Short");
+                   fprintf(f, "Short");
                    break;
                case JR_NEAR:
-                   printf("Near");
+                   fprintf(f, "Near");
                    break;
                case JR_SHORT_FORCED:
-                   printf("Forced Short");
+                   fprintf(f, "Forced Short");
                    break;
                case JR_NEAR_FORCED:
-                   printf("Forced Near");
+                   fprintf(f, "Forced Near");
                    break;
                default:
-                   printf("UNKNOWN!!");
+                   fprintf(f, "UNKNOWN!!");
                    break;
            }
-           printf(" BITS=%u\nAddrSize=%u OperSize=%u LockRepPre=%02x\n",
-                  (unsigned int)jmprel->mode_bits,
-                  (unsigned int)jmprel->addrsize,
-                  (unsigned int)jmprel->opersize,
-                  (unsigned int)jmprel->lockrep_pre);
+           fprintf(f, "\n%*sAddrSize=%u OperSize=%u LockRepPre=%02x\n",
+                   indent_level, "",
+                   (unsigned int)jmprel->addrsize,
+                   (unsigned int)jmprel->opersize,
+                   (unsigned int)jmprel->lockrep_pre);
+           fprintf(f, "%*sBITS=%u\n", indent_level, "",
+                   (unsigned int)jmprel->mode_bits);
            break;
     }
 }
index bfc19cbf4ac1e6c547bd82b8e0ae653b9d7c2ff3..eaf05dc70ce9aebe49a3551cbdced008565a1458 100644 (file)
@@ -212,48 +212,50 @@ bc_get_offset(/*@unused@*/ section *sect, /*@unused@*/ bytecode *bc,
 }
 
 void
-bc_print(const bytecode *bc)
+bc_print(FILE *f, const bytecode *bc)
 {
     const bytecode_data *data;
     const bytecode_reserve *reserve;
 
     switch (bc->type) {
        case BC_EMPTY:
-           printf("_Empty_\n");
+           fprintf(f, "%*s_Empty_\n", indent_level, "");
            break;
        case BC_DATA:
            data = bc_get_const_data(bc);
-           printf("_Data_\n");
-           printf("Final Element Size=%u\n",
-                  (unsigned int)data->size);
-           printf("Elements:\n");
-           dvs_print(&data->datahead);
+           fprintf(f, "%*s_Data_\n", indent_level, "");
+           indent_level++;
+           fprintf(f, "%*sFinal Element Size=%u\n", indent_level, "",
+                   (unsigned int)data->size);
+           fprintf(f, "%*sElements:\n", indent_level, "");
+           indent_level++;
+           dvs_print(f, &data->datahead);
+           indent_level-=2;
            break;
        case BC_RESERVE:
            reserve = bc_get_const_data(bc);
-           printf("_Reserve_\n");
-           printf("Num Items=");
-           expr_print(reserve->numitems);
-           printf("\nItem Size=%u\n",
-                  (unsigned int)reserve->itemsize);
+           fprintf(f, "%*s_Reserve_\n", indent_level, "");
+           fprintf(f, "%*sNum Items=", indent_level, "");
+           expr_print(f, reserve->numitems);
+           fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
+                   (unsigned int)reserve->itemsize);
            break;
        default:
            if (bc->type < cur_arch->bc.type_max)
-               cur_arch->bc.bc_print(bc);
+               cur_arch->bc.bc_print(f, bc);
            else
-               printf("_Unknown_\n");
+               fprintf(f, "%*s_Unknown_\n", indent_level, "");
            break;
     }
-    printf("Multiple=");
+    fprintf(f, "%*sMultiple=", indent_level, "");
     if (!bc->multiple)
-       printf("nil (1)");
+       fprintf(f, "nil (1)");
     else
-       expr_print(bc->multiple);
-    printf("\n");
-    printf("Length=%lu\n", bc->len);
-    printf("Filename=\"%s\" Line Number=%u\n",
-          bc->filename ? bc->filename : "<UNKNOWN>", bc->lineno);
-    printf("Offset=%lx\n", bc->offset);
+       expr_print(f, bc->multiple);
+    fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
+    fprintf(f, "%*sFilename=\"%s\" Line Number=%u\n", indent_level, "",
+           bc->filename ? bc->filename : "<UNKNOWN>", bc->lineno);
+    fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
 }
 
 void
@@ -301,13 +303,15 @@ bcs_append(bytecodehead *headp, bytecode *bc)
 }
 
 void
-bcs_print(const bytecodehead *headp)
+bcs_print(FILE *f, const bytecodehead *headp)
 {
     bytecode *cur;
 
     STAILQ_FOREACH(cur, headp, link) {
-       printf("---Next Bytecode---\n");
-       bc_print(cur);
+       fprintf(f, "%*sNext Bytecode:\n", indent_level, "");
+       indent_level++;
+       bc_print(f, cur);
+       indent_level--;
     }
 }
 
@@ -377,22 +381,23 @@ dvs_append(datavalhead *headp, dataval *dv)
 }
 
 void
-dvs_print(const datavalhead *head)
+dvs_print(FILE *f, const datavalhead *head)
 {
     dataval *cur;
 
     STAILQ_FOREACH(cur, head, link) {
        switch (cur->type) {
            case DV_EMPTY:
-               printf(" Empty\n");
+               fprintf(f, "%*sEmpty\n", indent_level, "");
                break;
            case DV_EXPR:
-               printf(" Expr=");
-               expr_print(cur->data.expn);
-               printf("\n");
+               fprintf(f, "%*sExpr=", indent_level, "");
+               expr_print(f, cur->data.expn);
+               fprintf(f, "\n");
                break;
            case DV_STRING:
-               printf(" String=%s\n", cur->data.str_val);
+               fprintf(f, "%*sString=%s\n", indent_level, "",
+                       cur->data.str_val);
                break;
        }
     }
index da6f7e8b294e4ca6e0cd665031975905c6978ead..601564162898946aa1654bf8726b0dcfc8c5092e 100644 (file)
@@ -58,7 +58,7 @@ void bc_delete(/*@only@*/ /*@null@*/ bytecode *bc);
 int bc_get_offset(section *sect, bytecode *bc,
                  /*@out@*/ unsigned long *ret_val);
 
-void bc_print(const bytecode *bc);
+void bc_print(FILE *f, const bytecode *bc);
 
 void bc_parser_finalize(bytecode *bc);
 
@@ -77,7 +77,7 @@ void bcs_delete(bytecodehead *headp);
                                           /*@returned@*/ /*@only@*/ /*@null@*/
                                           bytecode *bc);
 
-void bcs_print(const bytecodehead *headp);
+void bcs_print(FILE *f, const bytecodehead *headp);
 
 void bcs_parser_finalize(bytecodehead *headp);
 
@@ -99,6 +99,6 @@ void dvs_delete(datavalhead *headp);
 /*@null@*/ dataval *dvs_append(datavalhead *headp,
                               /*@returned@*/ /*@null@*/ dataval *dv);
 
-void dvs_print(const datavalhead *head);
+void dvs_print(FILE *f, const datavalhead *head);
 
 #endif
index 230bc1863eb38f847e87ca34e00068992f20b5e3..211dceab30c1629093b1d6826d5ff901c3a6f5e8 100644 (file)
@@ -830,12 +830,17 @@ expr_get_symrec(expr **ep, int simplify)
 /*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/
 
 void
-expr_print(expr *e)
+expr_print(FILE *f, expr *e)
 {
     static const char *regs[] = {"ax","cx","dx","bx","sp","bp","si","di"};
     char opstr[3];
     int i;
 
+    if (!e) {
+       fprintf(f, "(nil)");
+       return;
+    }
+
     switch (e->op) {
        case EXPR_ADD:
            strcpy(opstr, "+");
@@ -859,10 +864,12 @@ expr_print(expr *e)
            strcpy(opstr, "%%");
            break;
        case EXPR_NEG:
-           strcpy(opstr, "-");
+           fprintf(f, "-");
+           opstr[0] = 0;
            break;
        case EXPR_NOT:
-           strcpy(opstr, "~");
+           fprintf(f, "~");
+           opstr[0] = 0;
            break;
        case EXPR_OR:
            strcpy(opstr, "|");
@@ -913,28 +920,28 @@ expr_print(expr *e)
     for (i=0; i<e->numterms; i++) {
        switch (e->terms[i].type) {
            case EXPR_SYM:
-               printf("%s", symrec_get_name(e->terms[i].data.sym));
+               fprintf(f, "%s", symrec_get_name(e->terms[i].data.sym));
                break;
            case EXPR_EXPR:
-               printf("(");
-               expr_print(e->terms[i].data.expn);
-               printf(")");
+               fprintf(f, "(");
+               expr_print(f, e->terms[i].data.expn);
+               fprintf(f, ")");
                break;
            case EXPR_INT:
-               intnum_print(e->terms[i].data.intn);
+               intnum_print(f, e->terms[i].data.intn);
                break;
            case EXPR_FLOAT:
-               floatnum_print(e->terms[i].data.flt);
+               floatnum_print(f, e->terms[i].data.flt);
                break;
            case EXPR_REG:
                if (e->terms[i].data.reg.size == 32)
-                   printf("e");
-               printf("%s", regs[e->terms[i].data.reg.num&7]);
+                   fprintf(f, "e");
+               fprintf(f, "%s", regs[e->terms[i].data.reg.num&7]);
                break;
            case EXPR_NONE:
                break;
        }
        if (i < e->numterms-1)
-           printf("%s", opstr);
+           fprintf(f, "%s", opstr);
     }
 }
index 73fa151bd32f791f659ddfd9474817652c647e4b..be7ec1a41e28527ff0a31cfde1da6792410cfc3a 100644 (file)
@@ -69,6 +69,6 @@ void expr_expand_equ(expr *e);
 /*@dependent@*/ /*@null@*/ const symrec *expr_get_symrec(expr **ep,
                                                         int simplify);
 
-void expr_print(expr *);
+void expr_print(FILE *f, /*@null@*/ expr *);
 
 #endif
index e0c739e78714093555ff34b14e34a66f38f73ca5..0f8e870be5fb14e2981e25363fc321cdafa4f88a 100644 (file)
@@ -660,7 +660,7 @@ floatnum_check_size(/*@unused@*/ const floatnum *flt, size_t size)
 }
 
 void
-floatnum_print(const floatnum *flt)
+floatnum_print(FILE *f, const floatnum *flt)
 {
     unsigned char out[10];
     unsigned char *str;
@@ -668,24 +668,25 @@ floatnum_print(const floatnum *flt)
 
     /* Internal format */
     str = BitVector_to_Hex(flt->mantissa);
-    printf("%c %s *2^%04x\n", flt->sign?'-':'+', (char *)str, flt->exponent);
+    fprintf(f, "%c %s *2^%04x\n", flt->sign?'-':'+', (char *)str,
+           flt->exponent);
     xfree(str);
 
     /* 32-bit (single precision) format */
-    printf("32-bit: %d: ", floatnum_get_sized(flt, out, 4));
+    fprintf(f, "32-bit: %d: ", floatnum_get_sized(flt, out, 4));
     for (i=0; i<4; i++)
-       printf("%02x ", out[i]);
-    printf("\n");
+       fprintf(f, "%02x ", out[i]);
+    fprintf(f, "\n");
 
     /* 64-bit (double precision) format */
-    printf("64-bit: %d: ", floatnum_get_sized(flt, out, 8));
+    fprintf(f, "64-bit: %d: ", floatnum_get_sized(flt, out, 8));
     for (i=0; i<8; i++)
-       printf("%02x ", out[i]);
-    printf("\n");
+       fprintf(f, "%02x ", out[i]);
+    fprintf(f, "\n");
 
     /* 80-bit (extended precision) format */
-    printf("80-bit: %d: ", floatnum_get_sized(flt, out, 10));
+    fprintf(f, "80-bit: %d: ", floatnum_get_sized(flt, out, 10));
     for (i=0; i<10; i++)
-       printf("%02x ", out[i]);
-    printf("\n");
+       fprintf(f, "%02x ", out[i]);
+    fprintf(f, "\n");
 }
index 49bce9ecb3f6c1dd94eb138565b85e8cbeaa2a2b..b5ab637cee783d6c909ab30d344c127b09ec35ae 100644 (file)
@@ -52,6 +52,6 @@ int floatnum_get_sized(const floatnum *flt, /*@out@*/ unsigned char *ptr,
  */
 int floatnum_check_size(const floatnum *flt, size_t size);
 
-void floatnum_print(const floatnum *flt);
+void floatnum_print(FILE *f, const floatnum *flt);
 
 #endif
index 895ff64fcbd6d92121311f7b1aa3e1a08a5a294f..dd618c6bd566722f9dd72409d1f8b271b11fab14 100644 (file)
@@ -37,6 +37,8 @@
 unsigned int line_number = 1;
 unsigned int asm_options = 0;
 
+int indent_level = 0;
+
 static /*@only@*/ /*@null@*/ ternary_tree filename_table = (ternary_tree)NULL;
 
 void
index 9349d12b70e69c4f7bc28f6169f75768b8c932e1..4ae8532c5f77375acd459d8ce1a8185d9b03a7e5 100644 (file)
@@ -32,6 +32,8 @@ extern /*@null@*/ objfmt *cur_objfmt;
 extern unsigned int line_number;
 extern unsigned int asm_options;
 
+extern int indent_level;
+
 void switch_filename(const char *filename);
 void filename_delete_all(void);
 
index fec1bb4d0a41bc30807a193c2f52c94760fa391f..75c747035844d606b871d4edffeefc0cdab90f14 100644 (file)
@@ -606,17 +606,17 @@ intnum_check_size(const intnum *intn, size_t size, int is_signed)
 }
 
 void
-intnum_print(const intnum *intn)
+intnum_print(FILE *f, const intnum *intn)
 {
     unsigned char *s;
 
     switch (intn->type) {
        case INTNUM_UL:
-           printf("0x%lx/%u", intn->val.ul, (unsigned int)intn->origsize);
+           fprintf(f, "0x%lx/%u", intn->val.ul, (unsigned int)intn->origsize);
            break;
        case INTNUM_BV:
            s = BitVector_to_Hex(intn->val.bv);
-           printf("0x%s/%u", (char *)s, (unsigned int)intn->origsize);
+           fprintf(f, "0x%s/%u", (char *)s, (unsigned int)intn->origsize);
            xfree(s);
            break;
     }
index 1ec5104e81cb0cf2b4fbf9d376d10b0b628972b5..4c00e4543247a378309dfbae827b52953a469044 100644 (file)
@@ -62,6 +62,6 @@ void intnum_get_sized(const intnum *intn, unsigned char *ptr, size_t size);
  */
 int intnum_check_size(const intnum *intn, size_t size, int is_signed);
 
-void intnum_print(const intnum *intn);
+void intnum_print(FILE *f, const intnum *intn);
 
 #endif
index 895ff64fcbd6d92121311f7b1aa3e1a08a5a294f..dd618c6bd566722f9dd72409d1f8b271b11fab14 100644 (file)
@@ -37,6 +37,8 @@
 unsigned int line_number = 1;
 unsigned int asm_options = 0;
 
+int indent_level = 0;
+
 static /*@only@*/ /*@null@*/ ternary_tree filename_table = (ternary_tree)NULL;
 
 void
index 9349d12b70e69c4f7bc28f6169f75768b8c932e1..4ae8532c5f77375acd459d8ce1a8185d9b03a7e5 100644 (file)
@@ -32,6 +32,8 @@ extern /*@null@*/ objfmt *cur_objfmt;
 extern unsigned int line_number;
 extern unsigned int asm_options;
 
+extern int indent_level;
+
 void switch_filename(const char *filename);
 void filename_delete_all(void);
 
index bdc319994508e252c5800054c725580781da5486..18a8f55079235ae6b598f4f15b8f5753cdbb157e 100644 (file)
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#ifdef STDC_HEADERS
+# include <assert.h>
+#endif
+
 #ifdef gettext_noop
 #define N_(String)     gettext_noop(String)
 #else
 #endif
 
 static int files_open = 0;
-/*@null@*/ static FILE *in;
+/*@null@*/ /*@only@*/ static char *obj_filename = NULL;
+/*@null@*/ static FILE *in = NULL, *obj = NULL;
 
 /* Forward declarations: cmd line parser handlers */
 static int opt_option_handler(char *cmd, /*@null@*/ char *param, int extra);
 static int opt_format_handler(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_objfile_handler(char *cmd, /*@null@*/ char *param, int extra);
 /* Fake handlers: remove them */
 static int boo_boo_handler(char *cmd, /*@null@*/ char *param, int extra);
 static int b_handler(char *cmd, /*@null@*/ char *param, int extra);
@@ -66,6 +72,7 @@ static opt_option options[] =
 {
     { 'h', "help",    0, opt_option_handler, OPT_SHOW_HELP, "show help text", NULL },
     { 'f', "oformat", 1, opt_format_handler, 0, "select output format", "<format>" },
+    { 'o', "objfile", 1, opt_objfile_handler, 0, "name of object-file output", "<filename>" },
     /* Fake handlers: remove them */
     { 'b', NULL,      0, b_handler, 0, "says boom!", NULL },
     {  0,  "boo-boo", 0, boo_boo_handler, 0, "says boo-boo!", NULL },
@@ -88,6 +95,7 @@ static const char *help_tail =
     "\n";
 
 /* main function */
+/*@-globstate@*/
 int
 main(int argc, char *argv[])
 {
@@ -108,8 +116,7 @@ main(int argc, char *argv[])
     }
 
     /* if no files were specified, fallback to reading stdin */
-    if (!in)
-    {
+    if (!in) {
        in = stdin;
        switch_filename("<STDIN>");
     }
@@ -124,6 +131,28 @@ main(int argc, char *argv[])
        return EXIT_FAILURE;
     }
 
+    /* open the object file if not specified */
+    if (!obj) {
+       /* build the object filename */
+       /* TODO: replace the existing extension; this just appends. */
+       if (obj_filename)
+           xfree(obj_filename);
+       assert(in_filename != NULL);
+       obj_filename = xmalloc(strlen(in_filename)+
+                              strlen(cur_objfmt->extension)+2);
+       sprintf(obj_filename, "%s.%s", in_filename, cur_objfmt->extension);
+
+       /* open the built filename */
+       obj = fopen(obj_filename, "wb");
+       if (!obj) {
+           ErrorNow(_("could not open file `%s'"), obj_filename);
+           return EXIT_FAILURE;
+       }
+    }
+
+    /* Initialize the object format */
+    cur_objfmt->initialize(obj);
+
     /* Set NASM as the parser */
     cur_parser = find_parser("nasm");
     if (!cur_parser) {
@@ -136,6 +165,8 @@ main(int argc, char *argv[])
 
     sections = cur_parser->do_parse(cur_parser, in);
 
+    fclose(in);
+
     if (OutputAllErrorWarning() > 0) {
        sections_delete(sections);
        symrec_delete_all();
@@ -144,22 +175,40 @@ main(int argc, char *argv[])
        return EXIT_FAILURE;
     }
 
-    sections_print(sections);
-    printf("\n***Symbol Table***\n");
-    symrec_foreach((int (*) (symrec *))symrec_print);
+    /* XXX  Only for temporary debugging! */
+    fprintf(obj, "\nSections after parsing:\n");
+    indent_level++;
+    sections_print(obj, sections);
+    indent_level--;
+
+    fprintf(obj, "\nSymbol Table:\n");
+    indent_level++;
+    symrec_print_all(obj);
+    indent_level--;
 
     symrec_parser_finalize();
     sections_parser_finalize(sections);
 
-    printf("Post-parser-finalization:\n");
-    sections_print(sections);
+    fprintf(obj, "\nSections after post-parser-finalization:\n");
+    indent_level++;
+    sections_print(obj, sections);
+    indent_level--;
+
+    /* Finalize the object output */
+    cur_objfmt->finalize();
+
+    fclose(obj);
+    if (obj_filename)
+       xfree(obj_filename);
 
     sections_delete(sections);
     symrec_delete_all();
     filename_delete_all();
+
     BitVector_Shutdown();
     return EXIT_SUCCESS;
 }
+/*@=globstate@*/
 
 /*
  *  Command line options handlers
@@ -194,7 +243,38 @@ opt_option_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, int extra)
 static int
 opt_format_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
 {
-    printf("selected format: %s\n", param?param:"(NULL)");
+    assert(param != NULL);
+    printf("selected format: %s\n", param);
+    return 0;
+}
+
+static int
+opt_objfile_handler(/*@unused@*/ char *cmd, char *param,
+                   /*@unused@*/ int extra)
+{
+    assert(param != NULL);
+    if (strcasecmp(param, "stdout") == 0)
+       obj = stdout;
+    else if (strcasecmp(param, "stderr") == 0)
+       obj = stderr;
+    else {
+       if (obj) {
+           WarningNow("can open only one output file, last specified used");
+           if (obj != stdout && obj != stderr && fclose(obj))
+               ErrorNow("could not close old output file");
+       }
+    }
+
+    obj = fopen(param, "wb");
+    if (!obj) {
+       ErrorNow(_("could not open file `%s'"), param);
+       return 1;
+    }
+
+    if (obj_filename)
+       xfree(obj_filename);
+    obj_filename = xstrdup(param);
+
     return 0;
 }
 
index 7b36c157eddde1547f054291df3b4081a76491f6..a3938ab0cb35e9ae38bb53c423a6aec6cda7e302 100644 (file)
@@ -30,6 +30,9 @@ struct objfmt {
     /* keyword used to select format on the command line */
     const char *keyword;
 
+    /* default output file extension (without the '.') */
+    const char *extension;
+
     /* default (starting) section name */
     const char *default_section_name;
 
@@ -46,15 +49,24 @@ struct objfmt {
      */
 /*    debugfmt *default_df;*/
 
+    /* Initializes object output.  Must be called before any other object
+     * format functions.
+     */
+    void (*initialize) (/*@dependent@*/ FILE *f);
+
+    /* Finishes object output, and cleans up anything created by initialize. */
+    void (*finalize) (void);
+
     /* Switch object file sections.  The first val of the valparams should
-     * be the section name.
+     * be the section name.  Returns NULL if something's wrong, otherwise
+     * returns the new section.
      */
     /*@dependent@*/ /*@null@*/ section *
        (*sections_switch)(sectionhead *headp, valparamhead *valparams,
                           /*@null@*/ valparamhead *objext_valparams);
 
     void (*section_data_delete)(/*@only@*/ void *data);
-    void (*section_data_print)(void *data);
+    void (*section_data_print)(FILE *f, /*@null@*/ void *data);
 
     /*@null@*/ void *(*extern_data_new)(const char *name, /*@null@*/
                                        valparamhead *objext_valparams);
@@ -64,10 +76,12 @@ struct objfmt {
                                        /*@only@*/ expr *size, /*@null@*/
                                        valparamhead *objext_valparams);
 
-    /* It's only valid to pass this *one* SymVisibility (eg, vis is an enum not
-     * a bitmask).
+    /* It's only valid to pass these two functions *one* SymVisibility (eg, vis
+     * is an enum not a bitmask).
      */
     void (*declare_data_delete)(SymVisibility vis, /*@only@*/ void *data);
+    void (*declare_data_print)(FILE *f, SymVisibility vis,
+                              /*@null@*/ void *data);
 
     /* Object format-specific directive support.  Returns 1 if directive was
      * not recognized.  Returns 0 if directive was recognized, even if it
index ab6a3349ec71b643c55b5d8b91dd4a0bfa4d57c6..7a606ca1f618738e1faa8c927fca77f69ec8b8b4 100644 (file)
@@ -22,6 +22,7 @@
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#include "globals.h"
 #include "expr.h"
 #include "symrec.h"
 
 #include "objfmt.h"
 
 
+/*@dependent@*/ FILE *dbg_f;
+
+static void
+dbg_objfmt_initialize(/*@dependent@*/ FILE *f)
+{
+    dbg_f = f;
+    fprintf(dbg_f, "%*sinitialize(f)\n", indent_level, "");
+}
+
+static void
+dbg_objfmt_finalize(void)
+{
+    fprintf(dbg_f, "%*sfinalize()\n", indent_level, "");
+}
+
 static /*@dependent@*/ /*@null@*/ section *
 dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
                           /*@unused@*/ /*@null@*/
@@ -38,55 +54,49 @@ dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
     section *retval;
     int isnew;
 
-#if 0
-    fprintf(stderr, "-dbg_objfmt_sections_switch():\n");
-    printf(" Val/Params:\n");
-    vps_foreach(vp, valparams) {
-       printf("  (%s,", vp->val?vp->val:"(nil)");
-       if (vp->param)
-           expr_print(vp->param);
-       else
-           printf("(nil)");
-       printf(")\n");
-    }
-    printf(" Obj Ext Val/Params:\n");
-    if (!objext_valparams)
-       printf("  (none)\n");
-    else
-       vps_foreach(vp, objext_valparams) {
-           printf("  (%s,", vp->val?vp->val:"(nil)");
-           if (vp->param)
-               expr_print(vp->param);
-           else
-               printf("(nil)");
-           printf(")\n");
-       }
-#endif
+    fprintf(dbg_f, "%*ssections_switch(headp, ", indent_level, "");
+    vps_print(dbg_f, valparams);
+    fprintf(dbg_f, ", ");
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning ");
+
     if ((vp = vps_first(valparams)) && !vp->param && vp->val != NULL) {
        retval = sections_switch_general(headp, vp->val, NULL, 0, &isnew);
-       if (isnew)
+       if (isnew) {
+           fprintf(dbg_f, "(new) ");
            symrec_define_label(vp->val, retval, (bytecode *)NULL, 1);
+       }
+       fprintf(dbg_f, "\"%s\" section\n", vp->val);
        return retval;
-    } else
+    } else {
+       fprintf(dbg_f, "NULL\n");
        return NULL;
+    }
 }
 
 static void
 dbg_objfmt_section_data_delete(/*@only@*/ void *data)
 {
+    fprintf(dbg_f, "%*ssection_data_delete(%p)\n", indent_level, "", data);
     xfree(data);
 }
 
 static void
-dbg_objfmt_section_data_print(/*@unused@*/ void *data)
+dbg_objfmt_section_data_print(FILE *f, /*@null@*/ void *data)
 {
+    if (data)
+       fprintf(f, "%*s%p\n", indent_level, "", data);
+    else
+       fprintf(f, "%*s(none)\n", indent_level, "");
 }
 
 static /*@null@*/ void *
 dbg_objfmt_extern_data_new(const char *name, /*@unused@*/ /*@null@*/
                           valparamhead *objext_valparams)
 {
-    printf("extern_data_new(\"%s\")\n", name);
+    fprintf(dbg_f, "%*sextern_data_new(\"%s\", ", indent_level, "", name);
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning NULL\n");
     return NULL;
 }
 
@@ -94,7 +104,9 @@ static /*@null@*/ void *
 dbg_objfmt_global_data_new(const char *name, /*@unused@*/ /*@null@*/
                           valparamhead *objext_valparams)
 {
-    printf("global_data_new(\"%s\")\n", name);
+    fprintf(dbg_f, "%*sglobal_data_new(\"%s\", ", indent_level, "", name);
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning NULL\n");
     return NULL;
 }
 
@@ -103,51 +115,66 @@ dbg_objfmt_common_data_new(const char *name, /*@only@*/ expr *size,
                           /*@unused@*/ /*@null@*/
                           valparamhead *objext_valparams)
 {
-    printf("common_data_new(\"%s\",", name);
-    expr_print(size);
-    printf(")\n");
+    fprintf(dbg_f, "%*scommon_data_new(\"%s\", ", indent_level, "", name);
+    expr_print(dbg_f, size);
+    fprintf(dbg_f, ", ");
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning ");
+    expr_print(dbg_f, size);
+    fprintf(dbg_f, "\n");
     return size;
 }
 
 static void
-dbg_objfmt_declare_data_delete(/*@unused@*/ SymVisibility vis,
-                              /*@unused@*/ /*@only@*/ void *data)
+dbg_objfmt_declare_data_delete(SymVisibility vis, /*@only@*/ void *data)
 {
-    printf("declare_data_delete()\n");
-    if (vis == SYM_COMMON)
+    fprintf(dbg_f, "%*sdeclare_data_delete(", indent_level, "");
+    switch (vis) {
+       case SYM_LOCAL:
+           fprintf(dbg_f, "Local, ");
+           break;
+       case SYM_GLOBAL:
+           fprintf(dbg_f, "Global, ");
+           break;
+       case SYM_COMMON:
+           fprintf(dbg_f, "Common, ");
+           break;
+       case SYM_EXTERN:
+           fprintf(dbg_f, "Extern, ");
+           break;
+    }
+    if (vis == SYM_COMMON) {
+       expr_print(dbg_f, data);
        expr_delete(data);
-    else
+    } else {
+       fprintf(dbg_f, "%p", data);
        xfree(data);
+    }
+    fprintf(dbg_f, ")\n");
+}
+
+static void
+dbg_objfmt_declare_data_print(FILE *f, SymVisibility vis,
+                             /*@null@*/ void *data)
+{
+    if (vis == SYM_COMMON) {
+       fprintf(f, "%*sSize=", indent_level, "");
+       expr_print(f, data);
+       fprintf(f, "\n");
+    } else {
+       fprintf(f, "%*s(none)\n", indent_level, "");
+    }
 }
 
 static int
 dbg_objfmt_directive(const char *name, valparamhead *valparams,
                     /*@null@*/ valparamhead *objext_valparams)
 {
-    valparam *vp;
-
-    printf("directive(\"%s\", valparams:\n", name);
-    vps_foreach(vp, valparams) {
-       printf("  (%s,", vp->val?vp->val:"(nil)");
-       if (vp->param)
-           expr_print(vp->param);
-       else
-           printf("(nil)");
-       printf(")\n");
-    }
-    printf(" objext_valparams:\n");
-    if (!objext_valparams)
-       printf("  (none)\n");
-    else
-       vps_foreach(vp, objext_valparams) {
-           printf("  (%s,", vp->val?vp->val:"(nil)");
-           if (vp->param)
-               expr_print(vp->param);
-           else
-               printf("(nil)");
-           printf(")\n");
-       }
-
+    fprintf(dbg_f, "%*sdirective(\"%s\", ", indent_level, "", name);
+    vps_print(dbg_f, valparams);
+    fprintf(dbg_f, ", ");
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning 0 (recognized)\n");
     return 0;      /* dbg format "recognizes" all directives */
 }
 
@@ -155,8 +182,11 @@ dbg_objfmt_directive(const char *name, valparamhead *valparams,
 objfmt dbg_objfmt = {
     "Trace of all info passed to object format module",
     "dbg",
+    "dbg",
     ".text",
     32,
+    dbg_objfmt_initialize,
+    dbg_objfmt_finalize,
     dbg_objfmt_sections_switch,
     dbg_objfmt_section_data_delete,
     dbg_objfmt_section_data_print,
@@ -164,5 +194,6 @@ objfmt dbg_objfmt = {
     dbg_objfmt_global_data_new,
     dbg_objfmt_common_data_new,
     dbg_objfmt_declare_data_delete,
+    dbg_objfmt_declare_data_print,
     dbg_objfmt_directive
 };
index ab6a3349ec71b643c55b5d8b91dd4a0bfa4d57c6..7a606ca1f618738e1faa8c927fca77f69ec8b8b4 100644 (file)
@@ -22,6 +22,7 @@
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#include "globals.h"
 #include "expr.h"
 #include "symrec.h"
 
 #include "objfmt.h"
 
 
+/*@dependent@*/ FILE *dbg_f;
+
+static void
+dbg_objfmt_initialize(/*@dependent@*/ FILE *f)
+{
+    dbg_f = f;
+    fprintf(dbg_f, "%*sinitialize(f)\n", indent_level, "");
+}
+
+static void
+dbg_objfmt_finalize(void)
+{
+    fprintf(dbg_f, "%*sfinalize()\n", indent_level, "");
+}
+
 static /*@dependent@*/ /*@null@*/ section *
 dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
                           /*@unused@*/ /*@null@*/
@@ -38,55 +54,49 @@ dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
     section *retval;
     int isnew;
 
-#if 0
-    fprintf(stderr, "-dbg_objfmt_sections_switch():\n");
-    printf(" Val/Params:\n");
-    vps_foreach(vp, valparams) {
-       printf("  (%s,", vp->val?vp->val:"(nil)");
-       if (vp->param)
-           expr_print(vp->param);
-       else
-           printf("(nil)");
-       printf(")\n");
-    }
-    printf(" Obj Ext Val/Params:\n");
-    if (!objext_valparams)
-       printf("  (none)\n");
-    else
-       vps_foreach(vp, objext_valparams) {
-           printf("  (%s,", vp->val?vp->val:"(nil)");
-           if (vp->param)
-               expr_print(vp->param);
-           else
-               printf("(nil)");
-           printf(")\n");
-       }
-#endif
+    fprintf(dbg_f, "%*ssections_switch(headp, ", indent_level, "");
+    vps_print(dbg_f, valparams);
+    fprintf(dbg_f, ", ");
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning ");
+
     if ((vp = vps_first(valparams)) && !vp->param && vp->val != NULL) {
        retval = sections_switch_general(headp, vp->val, NULL, 0, &isnew);
-       if (isnew)
+       if (isnew) {
+           fprintf(dbg_f, "(new) ");
            symrec_define_label(vp->val, retval, (bytecode *)NULL, 1);
+       }
+       fprintf(dbg_f, "\"%s\" section\n", vp->val);
        return retval;
-    } else
+    } else {
+       fprintf(dbg_f, "NULL\n");
        return NULL;
+    }
 }
 
 static void
 dbg_objfmt_section_data_delete(/*@only@*/ void *data)
 {
+    fprintf(dbg_f, "%*ssection_data_delete(%p)\n", indent_level, "", data);
     xfree(data);
 }
 
 static void
-dbg_objfmt_section_data_print(/*@unused@*/ void *data)
+dbg_objfmt_section_data_print(FILE *f, /*@null@*/ void *data)
 {
+    if (data)
+       fprintf(f, "%*s%p\n", indent_level, "", data);
+    else
+       fprintf(f, "%*s(none)\n", indent_level, "");
 }
 
 static /*@null@*/ void *
 dbg_objfmt_extern_data_new(const char *name, /*@unused@*/ /*@null@*/
                           valparamhead *objext_valparams)
 {
-    printf("extern_data_new(\"%s\")\n", name);
+    fprintf(dbg_f, "%*sextern_data_new(\"%s\", ", indent_level, "", name);
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning NULL\n");
     return NULL;
 }
 
@@ -94,7 +104,9 @@ static /*@null@*/ void *
 dbg_objfmt_global_data_new(const char *name, /*@unused@*/ /*@null@*/
                           valparamhead *objext_valparams)
 {
-    printf("global_data_new(\"%s\")\n", name);
+    fprintf(dbg_f, "%*sglobal_data_new(\"%s\", ", indent_level, "", name);
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning NULL\n");
     return NULL;
 }
 
@@ -103,51 +115,66 @@ dbg_objfmt_common_data_new(const char *name, /*@only@*/ expr *size,
                           /*@unused@*/ /*@null@*/
                           valparamhead *objext_valparams)
 {
-    printf("common_data_new(\"%s\",", name);
-    expr_print(size);
-    printf(")\n");
+    fprintf(dbg_f, "%*scommon_data_new(\"%s\", ", indent_level, "", name);
+    expr_print(dbg_f, size);
+    fprintf(dbg_f, ", ");
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning ");
+    expr_print(dbg_f, size);
+    fprintf(dbg_f, "\n");
     return size;
 }
 
 static void
-dbg_objfmt_declare_data_delete(/*@unused@*/ SymVisibility vis,
-                              /*@unused@*/ /*@only@*/ void *data)
+dbg_objfmt_declare_data_delete(SymVisibility vis, /*@only@*/ void *data)
 {
-    printf("declare_data_delete()\n");
-    if (vis == SYM_COMMON)
+    fprintf(dbg_f, "%*sdeclare_data_delete(", indent_level, "");
+    switch (vis) {
+       case SYM_LOCAL:
+           fprintf(dbg_f, "Local, ");
+           break;
+       case SYM_GLOBAL:
+           fprintf(dbg_f, "Global, ");
+           break;
+       case SYM_COMMON:
+           fprintf(dbg_f, "Common, ");
+           break;
+       case SYM_EXTERN:
+           fprintf(dbg_f, "Extern, ");
+           break;
+    }
+    if (vis == SYM_COMMON) {
+       expr_print(dbg_f, data);
        expr_delete(data);
-    else
+    } else {
+       fprintf(dbg_f, "%p", data);
        xfree(data);
+    }
+    fprintf(dbg_f, ")\n");
+}
+
+static void
+dbg_objfmt_declare_data_print(FILE *f, SymVisibility vis,
+                             /*@null@*/ void *data)
+{
+    if (vis == SYM_COMMON) {
+       fprintf(f, "%*sSize=", indent_level, "");
+       expr_print(f, data);
+       fprintf(f, "\n");
+    } else {
+       fprintf(f, "%*s(none)\n", indent_level, "");
+    }
 }
 
 static int
 dbg_objfmt_directive(const char *name, valparamhead *valparams,
                     /*@null@*/ valparamhead *objext_valparams)
 {
-    valparam *vp;
-
-    printf("directive(\"%s\", valparams:\n", name);
-    vps_foreach(vp, valparams) {
-       printf("  (%s,", vp->val?vp->val:"(nil)");
-       if (vp->param)
-           expr_print(vp->param);
-       else
-           printf("(nil)");
-       printf(")\n");
-    }
-    printf(" objext_valparams:\n");
-    if (!objext_valparams)
-       printf("  (none)\n");
-    else
-       vps_foreach(vp, objext_valparams) {
-           printf("  (%s,", vp->val?vp->val:"(nil)");
-           if (vp->param)
-               expr_print(vp->param);
-           else
-               printf("(nil)");
-           printf(")\n");
-       }
-
+    fprintf(dbg_f, "%*sdirective(\"%s\", ", indent_level, "", name);
+    vps_print(dbg_f, valparams);
+    fprintf(dbg_f, ", ");
+    vps_print(dbg_f, objext_valparams);
+    fprintf(dbg_f, "), returning 0 (recognized)\n");
     return 0;      /* dbg format "recognizes" all directives */
 }
 
@@ -155,8 +182,11 @@ dbg_objfmt_directive(const char *name, valparamhead *valparams,
 objfmt dbg_objfmt = {
     "Trace of all info passed to object format module",
     "dbg",
+    "dbg",
     ".text",
     32,
+    dbg_objfmt_initialize,
+    dbg_objfmt_finalize,
     dbg_objfmt_sections_switch,
     dbg_objfmt_section_data_delete,
     dbg_objfmt_section_data_print,
@@ -164,5 +194,6 @@ objfmt dbg_objfmt = {
     dbg_objfmt_global_data_new,
     dbg_objfmt_common_data_new,
     dbg_objfmt_declare_data_delete,
+    dbg_objfmt_declare_data_print,
     dbg_objfmt_directive
 };
index df38d1dd40506b1287d755ce65745acec5d55c7e..ef897913ac6303c49d7fd932aa1f487d13c5f16f 100644 (file)
@@ -59,29 +59,28 @@ struct section {
     bytecodehead bc;           /* the bytecodes for the section's contents */
 };
 
+/*@-compdestroy@*/
 section *
 sections_initialize(sectionhead *headp)
 {
     section *s;
+    valparamhead vps;
+    valparam *vp;
 
     /* Initialize linked list */
     STAILQ_INIT(headp);
 
-    /* Add an initial "default" section to the list */
-    s = xcalloc(1, sizeof(section));
-    STAILQ_INSERT_TAIL(headp, s, link);
-
-    /* Initialize default section */
-    s->type = SECTION_GENERAL;
+    /* Add an initial "default" section */
     assert(cur_objfmt != NULL);
-    s->data.general.name = xstrdup(cur_objfmt->default_section_name);
-    s->data.general.of_data = NULL;
-    bytecodes_initialize(&s->bc);
-
-    s->res_only = 0;
+    vp_new(vp, xstrdup(cur_objfmt->default_section_name), NULL);
+    vps_initialize(&vps);
+    vps_append(&vps, vp);
+    s = cur_objfmt->sections_switch(headp, &vps, NULL);
+    vps_delete(&vps);
 
     return s;
 }
+/*@=compdestroy@*/
 
 /*@-onlytrans@*/
 section *
@@ -164,13 +163,15 @@ sections_delete(sectionhead *headp)
 }
 
 void
-sections_print(const sectionhead *headp)
+sections_print(FILE *f, const sectionhead *headp)
 {
     section *cur;
     
     STAILQ_FOREACH(cur, headp, link) {
-       printf("***SECTION***\n");
-       section_print(cur, 1);
+       fprintf(f, "%*sSection:\n", indent_level, "");
+       indent_level++;
+       section_print(f, cur, 1);
+       indent_level--;
     }
 }
 
@@ -227,28 +228,37 @@ section_delete(section *sect)
 }
 
 void
-section_print(const section *sect, int print_bcs)
+section_print(FILE *f, const section *sect, int print_bcs)
 {
-    printf(" type=");
+    if (!sect) {
+       fprintf(f, "%*s(none)\n", indent_level, "");
+       return;
+    }
+
+    fprintf(f, "%*stype=", indent_level, "");
     switch (sect->type) {
        case SECTION_GENERAL:
-           printf("general\n name=%s\n objfmt data:\n",
-                  sect->data.general.name);
+           fprintf(f, "general\n%*sname=%s\n%*sobjfmt data:\n", indent_level,
+                   "", sect->data.general.name, indent_level, "");
            assert(cur_objfmt != NULL);
+           indent_level++;
            if (sect->data.general.of_data)
-               cur_objfmt->section_data_print(sect->data.general.of_data);
+               cur_objfmt->section_data_print(f, sect->data.general.of_data);
            else
-               printf("  (none)\n");
+               fprintf(f, "%*s(none)\n", indent_level, "");
+           indent_level--;
            break;
        case SECTION_ABSOLUTE:
-           printf("absolute\n start=");
-           expr_print(sect->data.start);
-           printf("\n");
+           fprintf(f, "absolute\n%*sstart=", indent_level, "");
+           expr_print(f, sect->data.start);
+           fprintf(f, "\n");
            break;
     }
 
     if (print_bcs) {
-       printf(" Bytecodes:\n");
-       bcs_print(&sect->bc);
+       fprintf(f, "%*sBytecodes:\n", indent_level, "");
+       indent_level++;
+       bcs_print(f, &sect->bc);
+       indent_level--;
     }
 }
index ddfaaddd5fe8772d2c21a8d9c9ce9cadf677565f..dd28cade85ae0d6da6ce7a874c0a54294c877107 100644 (file)
@@ -39,7 +39,7 @@ int section_is_absolute(section *sect);
 
 void sections_delete(sectionhead *headp);
 
-void sections_print(const sectionhead *headp);
+void sections_print(FILE *f, const sectionhead *headp);
 
 void sections_parser_finalize(sectionhead *headp);
 
@@ -50,5 +50,5 @@ void sections_parser_finalize(sectionhead *headp);
 
 void section_delete(/*@only@*/ section *sect);
 
-void section_print(const section *sect, int print_bcs);
+void section_print(FILE *f, /*@null@*/ const section *sect, int print_bcs);
 #endif
index 70a611d5446384001bcd89ea5842bd23b788b87c..c265fa88819f77e470054869d0df694e2237ed79 100644 (file)
@@ -114,9 +114,9 @@ symrec_get_or_new(const char *name, int in_table)
 /* Call a function with each symrec.  Stops early if 0 returned by func.
    Returns 0 if stopped early. */
 int
-symrec_foreach(int (*func) (symrec *sym))
+symrec_traverse(void *d, int (*func) (symrec *sym, void *d))
 {
-    return ternary_traverse(sym_table, (int (*) (void *))func);
+    return ternary_traverse(sym_table, d, (int (*) (void *, void *))func);
 }
 
 symrec *
@@ -264,7 +264,7 @@ symrec_get_equ(const symrec *sym)
 static unsigned long firstundef_line;
 static /*@dependent@*/ /*@null@*/ const char *firstundef_filename;
 static int
-symrec_parser_finalize_checksym(symrec *sym)
+symrec_parser_finalize_checksym(symrec *sym, /*@unused@*/ /*@null@*/ void *d)
 {
     /* error if a symbol is used but never defined */
     if ((sym->status & SYM_USED) && !(sym->status & SYM_DEFINED)) {
@@ -283,7 +283,7 @@ void
 symrec_parser_finalize(void)
 {
     firstundef_line = ULONG_MAX;
-    symrec_foreach(symrec_parser_finalize_checksym);
+    symrec_traverse(NULL, symrec_parser_finalize_checksym);
     if (firstundef_line < ULONG_MAX)
        ErrorAt(firstundef_filename, firstundef_line,
                _(" (Each undefined symbol is reported only once.)"));
@@ -324,64 +324,101 @@ symrec_delete(symrec *sym)
     /*@=branchstate@*/
 }
 
+/*@+voidabstract@*/
+static int
+symrec_print_wrapper(symrec *sym, /*@null@*/ void *d)
+{
+    FILE *f;
+    assert(d != NULL);
+    f = (FILE *)d;
+    fprintf(f, "%*sSymbol `%s'\n", indent_level, "", sym->name);
+    indent_level++;
+    symrec_print(f, sym);
+    indent_level--;
+    return 1;
+}
+
 void
-symrec_print(const symrec *sym)
+symrec_print_all(FILE *f)
 {
-    printf("---Symbol `%s'---\n", sym->name);
+    symrec_traverse(f, symrec_print_wrapper);
+}
+/*@=voidabstract@*/
 
+void
+symrec_print(FILE *f, const symrec *sym)
+{
     switch (sym->type) {
        case SYM_UNKNOWN:
-           printf("-Unknown (Common/Extern)-\n");
+           fprintf(f, "%*s-Unknown (Common/Extern)-\n", indent_level, "");
            break;
        case SYM_EQU:
-           printf("_EQU_\n");
-           printf("Expn=");
-           expr_print(sym->value.expn);
-           printf("\n");
+           fprintf(f, "%*s_EQU_\n", indent_level, "");
+           fprintf(f, "%*sExpn=", indent_level, "");
+           expr_print(f, sym->value.expn);
+           fprintf(f, "\n");
            break;
        case SYM_LABEL:
-           printf("_Label_\nSection:");
-           if (sym->value.label.sect)
-               section_print(sym->value.label.sect, 0);
-           else
-               printf(" (none)\n");
+           fprintf(f, "%*s_Label_\n%*sSection:\n", indent_level, "",
+                   indent_level, "");
+           indent_level++;
+           section_print(f, sym->value.label.sect, 0);
+           indent_level--;
            if (!sym->value.label.bc)
-               printf("[First bytecode]\n");
+               fprintf(f, "%*sFirst bytecode\n", indent_level, "");
            else {
-               printf("[Preceding bytecode]\n");
-               bc_print(sym->value.label.bc);
+               fprintf(f, "%*sPreceding bytecode:\n", indent_level, "");
+               indent_level++;
+               bc_print(f, sym->value.label.bc);
+               indent_level--;
            }
            break;
     }
 
-    printf("Status=");
+    fprintf(f, "%*sStatus=", indent_level, "");
     if (sym->status == SYM_NOSTATUS)
-       printf("None\n");
+       fprintf(f, "None\n");
     else {
        if (sym->status & SYM_USED)
-           printf("Used,");
+           fprintf(f, "Used,");
        if (sym->status & SYM_DEFINED)
-           printf("Defined,");
+           fprintf(f, "Defined,");
        if (sym->status & SYM_VALUED)
-           printf("Valued,");
+           fprintf(f, "Valued,");
        if (sym->status & SYM_NOTINTABLE)
-           printf("Not in Table,");
-       printf("\n");
+           fprintf(f, "Not in Table,");
+       fprintf(f, "\n");
     }
 
-    printf("Visibility=");
+    fprintf(f, "%*sVisibility=", indent_level, "");
     if (sym->visibility == SYM_LOCAL)
-       printf("Local\n");
+       fprintf(f, "Local\n");
     else {
        if (sym->visibility & SYM_GLOBAL)
-           printf("Global,");
+           fprintf(f, "Global,");
        if (sym->visibility & SYM_COMMON)
-           printf("Common,");
+           fprintf(f, "Common,");
        if (sym->visibility & SYM_EXTERN)
-           printf("Extern,");
-       printf("\n");
+           fprintf(f, "Extern,");
+       fprintf(f, "\n");
+    }
+
+    assert(cur_objfmt != NULL);
+    if (sym->visibility & SYM_GLOBAL) {
+       fprintf(f, "%*sGlobal object format-specific data:\n", indent_level,
+               "");
+       indent_level++;
+       cur_objfmt->declare_data_print(f, SYM_GLOBAL, sym->of_data_vis_g);
+       indent_level--;
+    }
+    if (sym->visibility & SYM_COMMON) {
+       fprintf(f, "%*sCommon/Extern object format-specific data:\n",
+               indent_level, "");
+       indent_level++;
+       cur_objfmt->declare_data_print(f, SYM_COMMON, sym->of_data_vis_ce);
+       indent_level--;
     }
 
-    printf("Filename=\"%s\" Line Number=%lu\n",
+    fprintf(f, "%*sFilename=\"%s\" Line Number=%lu\n", indent_level, "",
           sym->filename?sym->filename:"(NULL)", sym->line);
 }
index 2d2c149732820eae86a8a34f9a6f01573c6d8723..105d48c44a03557b08faccd6e5ec39d05c70550d 100644 (file)
@@ -47,7 +47,9 @@ SymVisibility symrec_get_visibility(const symrec *sym);
 
 /*@observer@*/ /*@null@*/ const expr *symrec_get_equ(const symrec *sym);
 
-int /*@alt void@*/ symrec_foreach(int (*func) (symrec *sym));
+int /*@alt void@*/ symrec_traverse(/*@null@*/ void *d,
+                                  int (*func) (symrec *sym,
+                                               /*@null@*/ void *d));
 
 void symrec_parser_finalize(void);
 
@@ -58,5 +60,7 @@ void symrec_delete_all(void);
  */
 void symrec_delete(/*@only@*/ symrec *sym);
 
-void symrec_print(const symrec *sym);
+void symrec_print_all(FILE *f);
+
+void symrec_print(FILE *f, const symrec *sym);
 #endif
index a83bdfb8e8d7da145ea0840f892bd5baa646cc86..07ba7b4dcec94968a409a051ee6bff49f805b682 100644 (file)
@@ -171,20 +171,21 @@ ternary_recursivesearch (ternary_tree p, const char *s)
 /* Traverse over tree, calling callback function for each leaf. 
    Stops early if func returns 0. */
 int
-ternary_traverse (ternary_tree p, int (*func) (/*@dependent@*/ /*@null@*/
-                                              void *d))
+ternary_traverse (ternary_tree p, void *d,
+                 int (*func) (/*@dependent@*/ /*@null@*/ void *node,
+                              /*@null@*/ void *d))
 {
   if (!p)
     return 1;
-  if (ternary_traverse (p->lokid, func) == 0)
+  if (ternary_traverse (p->lokid, d, func) == 0)
     return 0;
   if (p->splitchar)
     {
-      if (ternary_traverse (p->eqkid, func) == 0)
+      if (ternary_traverse (p->eqkid, d, func) == 0)
        return 0;
     }
   else
-    if (func (p->eqkid) == 0)
+    if (func (p->eqkid, d) == 0)
       return 0;
-  return ternary_traverse (p->hikid, func);
+  return ternary_traverse (p->hikid, d, func);
 }
index ffa7bd2688e88ac988790ac19b5551aa1bcc6255..dd5fb37dcd455288ed61ed99c2604e681cbe0c48 100644 (file)
@@ -54,6 +54,7 @@ void ternary_cleanup (/*@only@*/ ternary_tree p,
 
 /* Traverse over tree, calling callback function for each leaf. 
    Stops early if func returns 0. */
-int ternary_traverse (ternary_tree p, int (*func) (/*@dependent@*/ /*@null@*/
-                                                  void *d));
+int ternary_traverse (ternary_tree p, /*@null@*/ void *d,
+                     int (*func) (/*@dependent@*/ /*@null@*/ void *node,
+                                  /*@null@*/ void *d));
 #endif
index 434b0b00a33b914f8a89fdfa9cf8c97a2ba3649d..05ab9644e3079495d7896e6123152eccecbd7e0c 100644 (file)
@@ -22,6 +22,7 @@
 #include "util.h"
 /*@unused@*/ RCSID("$IdPath$");
 
+#include "globals.h"
 #include "expr.h"
 
 
@@ -42,3 +43,28 @@ vps_delete(valparamhead *headp)
     }
     STAILQ_INIT(headp);
 }
+
+void
+vps_print(FILE *f, valparamhead *headp)
+{
+    valparam *vp;
+
+    if(!headp) {
+       fprintf(f, "(none)");
+       return;
+    }
+
+    vps_foreach(vp, headp) {
+       if (vp->val)
+           fprintf(f, "(\"%s\",", vp->val);
+       else
+           fprintf(f, "((nil),");
+       if (vp->param)
+           expr_print(f, vp->param);
+       else
+           fprintf(f, "(nil)");
+       fprintf(f, ")");
+       if (vps_next(vp))
+           fprintf(f, ",");
+    }
+}
index 32fc171d717aab255b1e0ad75bc2aa1657acfd71..98bce3b1eab5f503476eee1ff90221ae037ce386 100644 (file)
@@ -54,4 +54,6 @@ void vps_append(valparamhead *headp, /*@keep@*/ valparam *vp);
 
 #define vps_foreach(iter, headp)    STAILQ_FOREACH(iter, headp, link)
 
+void vps_print(FILE *f, /*@null@*/ valparamhead *headp);
+
 #endif