From: Peter Johnson Date: Wed, 21 Nov 2001 08:25:09 +0000 (-0000) Subject: Massive cleanup of debugging output (via _print() functions). All now take X-Git-Tag: v0.1.0~173 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=825eaa582324bcdb40b3515d22d1b96eb3b39051;p=yasm Massive cleanup of debugging output (via _print() functions). All now take 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 --- diff --git a/frontends/yasm/yasm.c b/frontends/yasm/yasm.c index bdc31999..18a8f550 100644 --- a/frontends/yasm/yasm.c +++ b/frontends/yasm/yasm.c @@ -22,6 +22,10 @@ #include "util.h" /*@unused@*/ RCSID("$IdPath$"); +#ifdef STDC_HEADERS +# include +#endif + #ifdef gettext_noop #define N_(String) gettext_noop(String) #else @@ -49,11 +53,13 @@ #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", "" }, + { 'o', "objfile", 1, opt_objfile_handler, 0, "name of object-file output", "" }, /* 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(""); } @@ -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; } diff --git a/libyasm/arch.h b/libyasm/arch.h index b614aca4..9dd71fb8 100644 --- a/libyasm/arch.h +++ b/libyasm/arch.h @@ -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; }; diff --git a/libyasm/bytecode.c b/libyasm/bytecode.c index bfc19cbf..eaf05dc7 100644 --- a/libyasm/bytecode.c +++ b/libyasm/bytecode.c @@ -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 : "", 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 : "", 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; } } diff --git a/libyasm/bytecode.h b/libyasm/bytecode.h index da6f7e8b..60156416 100644 --- a/libyasm/bytecode.h +++ b/libyasm/bytecode.h @@ -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 diff --git a/libyasm/expr.c b/libyasm/expr.c index 230bc186..211dceab 100644 --- a/libyasm/expr.c +++ b/libyasm/expr.c @@ -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; inumterms; 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); } } diff --git a/libyasm/expr.h b/libyasm/expr.h index 73fa151b..be7ec1a4 100644 --- a/libyasm/expr.h +++ b/libyasm/expr.h @@ -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 diff --git a/libyasm/floatnum.c b/libyasm/floatnum.c index e0c739e7..0f8e870b 100644 --- a/libyasm/floatnum.c +++ b/libyasm/floatnum.c @@ -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"); } diff --git a/libyasm/floatnum.h b/libyasm/floatnum.h index 49bce9ec..b5ab637c 100644 --- a/libyasm/floatnum.h +++ b/libyasm/floatnum.h @@ -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 diff --git a/libyasm/intnum.c b/libyasm/intnum.c index fec1bb4d..75c74703 100644 --- a/libyasm/intnum.c +++ b/libyasm/intnum.c @@ -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; } diff --git a/libyasm/intnum.h b/libyasm/intnum.h index 1ec5104e..4c00e454 100644 --- a/libyasm/intnum.h +++ b/libyasm/intnum.h @@ -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 diff --git a/libyasm/linemgr.c b/libyasm/linemgr.c index 895ff64f..dd618c6b 100644 --- a/libyasm/linemgr.c +++ b/libyasm/linemgr.c @@ -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 diff --git a/libyasm/linemgr.h b/libyasm/linemgr.h index 9349d12b..4ae8532c 100644 --- a/libyasm/linemgr.h +++ b/libyasm/linemgr.h @@ -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); diff --git a/libyasm/objfmt.h b/libyasm/objfmt.h index 7b36c157..a3938ab0 100644 --- a/libyasm/objfmt.h +++ b/libyasm/objfmt.h @@ -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 diff --git a/libyasm/section.c b/libyasm/section.c index df38d1dd..ef897913 100644 --- a/libyasm/section.c +++ b/libyasm/section.c @@ -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(§->bc); + fprintf(f, "%*sBytecodes:\n", indent_level, ""); + indent_level++; + bcs_print(f, §->bc); + indent_level--; } } diff --git a/libyasm/section.h b/libyasm/section.h index ddfaaddd..dd28cade 100644 --- a/libyasm/section.h +++ b/libyasm/section.h @@ -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 diff --git a/libyasm/symrec.c b/libyasm/symrec.c index 70a611d5..c265fa88 100644 --- a/libyasm/symrec.c +++ b/libyasm/symrec.c @@ -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); } diff --git a/libyasm/symrec.h b/libyasm/symrec.h index 2d2c1497..105d48c4 100644 --- a/libyasm/symrec.h +++ b/libyasm/symrec.h @@ -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 diff --git a/libyasm/valparam.c b/libyasm/valparam.c index 434b0b00..05ab9644 100644 --- a/libyasm/valparam.c +++ b/libyasm/valparam.c @@ -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, ","); + } +} diff --git a/libyasm/valparam.h b/libyasm/valparam.h index 32fc171d..98bce3b1 100644 --- a/libyasm/valparam.h +++ b/libyasm/valparam.h @@ -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 diff --git a/modules/arch/x86/bytecode.c b/modules/arch/x86/bytecode.c index d5176935..8b0070e7 100644 --- a/modules/arch/x86/bytecode.c +++ b/modules/arch/x86/bytecode.c @@ -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; } } diff --git a/modules/arch/x86/x86-int.h b/modules/arch/x86/x86-int.h index 7d1f5f13..50d3bcce 100644 --- a/modules/arch/x86/x86-int.h +++ b/modules/arch/x86/x86-int.h @@ -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, diff --git a/modules/arch/x86/x86bc.c b/modules/arch/x86/x86bc.c index d5176935..8b0070e7 100644 --- a/modules/arch/x86/x86bc.c +++ b/modules/arch/x86/x86bc.c @@ -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; } } diff --git a/modules/objfmts/dbg/dbg-objfmt.c b/modules/objfmts/dbg/dbg-objfmt.c index ab6a3349..7a606ca1 100644 --- a/modules/objfmts/dbg/dbg-objfmt.c +++ b/modules/objfmts/dbg/dbg-objfmt.c @@ -22,6 +22,7 @@ #include "util.h" /*@unused@*/ RCSID("$IdPath$"); +#include "globals.h" #include "expr.h" #include "symrec.h" @@ -29,6 +30,21 @@ #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 }; diff --git a/modules/objfmts/dbg/objfmt.c b/modules/objfmts/dbg/objfmt.c index ab6a3349..7a606ca1 100644 --- a/modules/objfmts/dbg/objfmt.c +++ b/modules/objfmts/dbg/objfmt.c @@ -22,6 +22,7 @@ #include "util.h" /*@unused@*/ RCSID("$IdPath$"); +#include "globals.h" #include "expr.h" #include "symrec.h" @@ -29,6 +30,21 @@ #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 }; diff --git a/src/arch.h b/src/arch.h index b614aca4..9dd71fb8 100644 --- a/src/arch.h +++ b/src/arch.h @@ -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; }; diff --git a/src/arch/x86/bytecode.c b/src/arch/x86/bytecode.c index d5176935..8b0070e7 100644 --- a/src/arch/x86/bytecode.c +++ b/src/arch/x86/bytecode.c @@ -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; } } diff --git a/src/arch/x86/x86-int.h b/src/arch/x86/x86-int.h index 7d1f5f13..50d3bcce 100644 --- a/src/arch/x86/x86-int.h +++ b/src/arch/x86/x86-int.h @@ -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, diff --git a/src/arch/x86/x86bc.c b/src/arch/x86/x86bc.c index d5176935..8b0070e7 100644 --- a/src/arch/x86/x86bc.c +++ b/src/arch/x86/x86bc.c @@ -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; } } diff --git a/src/bytecode.c b/src/bytecode.c index bfc19cbf..eaf05dc7 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -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 : "", 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 : "", 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; } } diff --git a/src/bytecode.h b/src/bytecode.h index da6f7e8b..60156416 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -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 diff --git a/src/expr.c b/src/expr.c index 230bc186..211dceab 100644 --- a/src/expr.c +++ b/src/expr.c @@ -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; inumterms; 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); } } diff --git a/src/expr.h b/src/expr.h index 73fa151b..be7ec1a4 100644 --- a/src/expr.h +++ b/src/expr.h @@ -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 diff --git a/src/floatnum.c b/src/floatnum.c index e0c739e7..0f8e870b 100644 --- a/src/floatnum.c +++ b/src/floatnum.c @@ -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"); } diff --git a/src/floatnum.h b/src/floatnum.h index 49bce9ec..b5ab637c 100644 --- a/src/floatnum.h +++ b/src/floatnum.h @@ -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 diff --git a/src/globals.c b/src/globals.c index 895ff64f..dd618c6b 100644 --- a/src/globals.c +++ b/src/globals.c @@ -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 diff --git a/src/globals.h b/src/globals.h index 9349d12b..4ae8532c 100644 --- a/src/globals.h +++ b/src/globals.h @@ -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); diff --git a/src/intnum.c b/src/intnum.c index fec1bb4d..75c74703 100644 --- a/src/intnum.c +++ b/src/intnum.c @@ -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; } diff --git a/src/intnum.h b/src/intnum.h index 1ec5104e..4c00e454 100644 --- a/src/intnum.h +++ b/src/intnum.h @@ -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 diff --git a/src/linemgr.c b/src/linemgr.c index 895ff64f..dd618c6b 100644 --- a/src/linemgr.c +++ b/src/linemgr.c @@ -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 diff --git a/src/linemgr.h b/src/linemgr.h index 9349d12b..4ae8532c 100644 --- a/src/linemgr.h +++ b/src/linemgr.h @@ -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); diff --git a/src/main.c b/src/main.c index bdc31999..18a8f550 100644 --- a/src/main.c +++ b/src/main.c @@ -22,6 +22,10 @@ #include "util.h" /*@unused@*/ RCSID("$IdPath$"); +#ifdef STDC_HEADERS +# include +#endif + #ifdef gettext_noop #define N_(String) gettext_noop(String) #else @@ -49,11 +53,13 @@ #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", "" }, + { 'o', "objfile", 1, opt_objfile_handler, 0, "name of object-file output", "" }, /* 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(""); } @@ -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; } diff --git a/src/objfmt.h b/src/objfmt.h index 7b36c157..a3938ab0 100644 --- a/src/objfmt.h +++ b/src/objfmt.h @@ -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 diff --git a/src/objfmts/dbg/dbg-objfmt.c b/src/objfmts/dbg/dbg-objfmt.c index ab6a3349..7a606ca1 100644 --- a/src/objfmts/dbg/dbg-objfmt.c +++ b/src/objfmts/dbg/dbg-objfmt.c @@ -22,6 +22,7 @@ #include "util.h" /*@unused@*/ RCSID("$IdPath$"); +#include "globals.h" #include "expr.h" #include "symrec.h" @@ -29,6 +30,21 @@ #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 }; diff --git a/src/objfmts/dbg/objfmt.c b/src/objfmts/dbg/objfmt.c index ab6a3349..7a606ca1 100644 --- a/src/objfmts/dbg/objfmt.c +++ b/src/objfmts/dbg/objfmt.c @@ -22,6 +22,7 @@ #include "util.h" /*@unused@*/ RCSID("$IdPath$"); +#include "globals.h" #include "expr.h" #include "symrec.h" @@ -29,6 +30,21 @@ #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 }; diff --git a/src/section.c b/src/section.c index df38d1dd..ef897913 100644 --- a/src/section.c +++ b/src/section.c @@ -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(§->bc); + fprintf(f, "%*sBytecodes:\n", indent_level, ""); + indent_level++; + bcs_print(f, §->bc); + indent_level--; } } diff --git a/src/section.h b/src/section.h index ddfaaddd..dd28cade 100644 --- a/src/section.h +++ b/src/section.h @@ -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 diff --git a/src/symrec.c b/src/symrec.c index 70a611d5..c265fa88 100644 --- a/src/symrec.c +++ b/src/symrec.c @@ -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); } diff --git a/src/symrec.h b/src/symrec.h index 2d2c1497..105d48c4 100644 --- a/src/symrec.h +++ b/src/symrec.h @@ -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 diff --git a/src/ternary.c b/src/ternary.c index a83bdfb8..07ba7b4d 100644 --- a/src/ternary.c +++ b/src/ternary.c @@ -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); } diff --git a/src/ternary.h b/src/ternary.h index ffa7bd26..dd5fb37d 100644 --- a/src/ternary.h +++ b/src/ternary.h @@ -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 diff --git a/src/valparam.c b/src/valparam.c index 434b0b00..05ab9644 100644 --- a/src/valparam.c +++ b/src/valparam.c @@ -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, ","); + } +} diff --git a/src/valparam.h b/src/valparam.h index 32fc171d..98bce3b1 100644 --- a/src/valparam.h +++ b/src/valparam.h @@ -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