#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#ifdef STDC_HEADERS
+# include <assert.h>
+#endif
+
#ifdef gettext_noop
#define N_(String) gettext_noop(String)
#else
#endif
static int files_open = 0;
-/*@null@*/ static FILE *in;
+/*@null@*/ /*@only@*/ static char *obj_filename = NULL;
+/*@null@*/ static FILE *in = NULL, *obj = NULL;
/* Forward declarations: cmd line parser handlers */
static int opt_option_handler(char *cmd, /*@null@*/ char *param, int extra);
static int opt_format_handler(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_objfile_handler(char *cmd, /*@null@*/ char *param, int extra);
/* Fake handlers: remove them */
static int boo_boo_handler(char *cmd, /*@null@*/ char *param, int extra);
static int b_handler(char *cmd, /*@null@*/ char *param, int extra);
{
{ 'h', "help", 0, opt_option_handler, OPT_SHOW_HELP, "show help text", NULL },
{ 'f', "oformat", 1, opt_format_handler, 0, "select output format", "<format>" },
+ { 'o', "objfile", 1, opt_objfile_handler, 0, "name of object-file output", "<filename>" },
/* Fake handlers: remove them */
{ 'b', NULL, 0, b_handler, 0, "says boom!", NULL },
{ 0, "boo-boo", 0, boo_boo_handler, 0, "says boo-boo!", NULL },
"\n";
/* main function */
+/*@-globstate@*/
int
main(int argc, char *argv[])
{
}
/* if no files were specified, fallback to reading stdin */
- if (!in)
- {
+ if (!in) {
in = stdin;
switch_filename("<STDIN>");
}
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) {
sections = cur_parser->do_parse(cur_parser, in);
+ fclose(in);
+
if (OutputAllErrorWarning() > 0) {
sections_delete(sections);
symrec_delete_all();
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
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;
}
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;
};
}
void
-bc_print(const bytecode *bc)
+bc_print(FILE *f, const bytecode *bc)
{
const bytecode_data *data;
const bytecode_reserve *reserve;
switch (bc->type) {
case BC_EMPTY:
- printf("_Empty_\n");
+ fprintf(f, "%*s_Empty_\n", indent_level, "");
break;
case BC_DATA:
data = bc_get_const_data(bc);
- printf("_Data_\n");
- printf("Final Element Size=%u\n",
- (unsigned int)data->size);
- printf("Elements:\n");
- dvs_print(&data->datahead);
+ fprintf(f, "%*s_Data_\n", indent_level, "");
+ indent_level++;
+ fprintf(f, "%*sFinal Element Size=%u\n", indent_level, "",
+ (unsigned int)data->size);
+ fprintf(f, "%*sElements:\n", indent_level, "");
+ indent_level++;
+ dvs_print(f, &data->datahead);
+ indent_level-=2;
break;
case BC_RESERVE:
reserve = bc_get_const_data(bc);
- printf("_Reserve_\n");
- printf("Num Items=");
- expr_print(reserve->numitems);
- printf("\nItem Size=%u\n",
- (unsigned int)reserve->itemsize);
+ fprintf(f, "%*s_Reserve_\n", indent_level, "");
+ fprintf(f, "%*sNum Items=", indent_level, "");
+ expr_print(f, reserve->numitems);
+ fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
+ (unsigned int)reserve->itemsize);
break;
default:
if (bc->type < cur_arch->bc.type_max)
- cur_arch->bc.bc_print(bc);
+ cur_arch->bc.bc_print(f, bc);
else
- printf("_Unknown_\n");
+ fprintf(f, "%*s_Unknown_\n", indent_level, "");
break;
}
- printf("Multiple=");
+ fprintf(f, "%*sMultiple=", indent_level, "");
if (!bc->multiple)
- printf("nil (1)");
+ fprintf(f, "nil (1)");
else
- expr_print(bc->multiple);
- printf("\n");
- printf("Length=%lu\n", bc->len);
- printf("Filename=\"%s\" Line Number=%u\n",
- bc->filename ? bc->filename : "<UNKNOWN>", bc->lineno);
- printf("Offset=%lx\n", bc->offset);
+ expr_print(f, bc->multiple);
+ fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
+ fprintf(f, "%*sFilename=\"%s\" Line Number=%u\n", indent_level, "",
+ bc->filename ? bc->filename : "<UNKNOWN>", bc->lineno);
+ fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
}
void
}
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--;
}
}
}
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;
}
}
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);
/*@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);
/*@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
/*@=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, "+");
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, "|");
for (i=0; i<e->numterms; i++) {
switch (e->terms[i].type) {
case EXPR_SYM:
- printf("%s", symrec_get_name(e->terms[i].data.sym));
+ fprintf(f, "%s", symrec_get_name(e->terms[i].data.sym));
break;
case EXPR_EXPR:
- printf("(");
- expr_print(e->terms[i].data.expn);
- printf(")");
+ fprintf(f, "(");
+ expr_print(f, e->terms[i].data.expn);
+ fprintf(f, ")");
break;
case EXPR_INT:
- intnum_print(e->terms[i].data.intn);
+ intnum_print(f, e->terms[i].data.intn);
break;
case EXPR_FLOAT:
- floatnum_print(e->terms[i].data.flt);
+ floatnum_print(f, e->terms[i].data.flt);
break;
case EXPR_REG:
if (e->terms[i].data.reg.size == 32)
- printf("e");
- printf("%s", regs[e->terms[i].data.reg.num&7]);
+ fprintf(f, "e");
+ fprintf(f, "%s", regs[e->terms[i].data.reg.num&7]);
break;
case EXPR_NONE:
break;
}
if (i < e->numterms-1)
- printf("%s", opstr);
+ fprintf(f, "%s", opstr);
}
}
/*@dependent@*/ /*@null@*/ const symrec *expr_get_symrec(expr **ep,
int simplify);
-void expr_print(expr *);
+void expr_print(FILE *f, /*@null@*/ expr *);
#endif
}
void
-floatnum_print(const floatnum *flt)
+floatnum_print(FILE *f, const floatnum *flt)
{
unsigned char out[10];
unsigned char *str;
/* 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");
}
*/
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
}
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;
}
*/
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
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
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);
/* 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;
*/
/* 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);
/*@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
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 *
}
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--;
}
}
}
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--;
}
}
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);
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
/* 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 *
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)) {
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.)"));
/*@=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);
}
/*@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);
*/
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
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#include "globals.h"
#include "expr.h"
}
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, ",");
+ }
+}
#define vps_foreach(iter, headp) STAILQ_FOREACH(iter, headp, link)
+void vps_print(FILE *f, /*@null@*/ valparamhead *headp);
+
#endif
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "expr.h"
}
void
-x86_bc_print(const bytecode *bc)
+x86_bc_print(FILE *f, const bytecode *bc)
{
const x86_insn *insn;
const x86_jmprel *jmprel;
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;
}
}
*/
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;
} 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,
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "expr.h"
}
void
-x86_bc_print(const bytecode *bc)
+x86_bc_print(FILE *f, const bytecode *bc)
{
const x86_insn *insn;
const x86_jmprel *jmprel;
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;
}
}
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#include "globals.h"
#include "expr.h"
#include "symrec.h"
#include "objfmt.h"
+/*@dependent@*/ FILE *dbg_f;
+
+static void
+dbg_objfmt_initialize(/*@dependent@*/ FILE *f)
+{
+ dbg_f = f;
+ fprintf(dbg_f, "%*sinitialize(f)\n", indent_level, "");
+}
+
+static void
+dbg_objfmt_finalize(void)
+{
+ fprintf(dbg_f, "%*sfinalize()\n", indent_level, "");
+}
+
static /*@dependent@*/ /*@null@*/ section *
dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
/*@unused@*/ /*@null@*/
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;
}
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;
}
/*@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 */
}
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,
dbg_objfmt_global_data_new,
dbg_objfmt_common_data_new,
dbg_objfmt_declare_data_delete,
+ dbg_objfmt_declare_data_print,
dbg_objfmt_directive
};
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#include "globals.h"
#include "expr.h"
#include "symrec.h"
#include "objfmt.h"
+/*@dependent@*/ FILE *dbg_f;
+
+static void
+dbg_objfmt_initialize(/*@dependent@*/ FILE *f)
+{
+ dbg_f = f;
+ fprintf(dbg_f, "%*sinitialize(f)\n", indent_level, "");
+}
+
+static void
+dbg_objfmt_finalize(void)
+{
+ fprintf(dbg_f, "%*sfinalize()\n", indent_level, "");
+}
+
static /*@dependent@*/ /*@null@*/ section *
dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
/*@unused@*/ /*@null@*/
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;
}
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;
}
/*@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 */
}
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,
dbg_objfmt_global_data_new,
dbg_objfmt_common_data_new,
dbg_objfmt_declare_data_delete,
+ dbg_objfmt_declare_data_print,
dbg_objfmt_directive
};
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;
};
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "expr.h"
}
void
-x86_bc_print(const bytecode *bc)
+x86_bc_print(FILE *f, const bytecode *bc)
{
const x86_insn *insn;
const x86_jmprel *jmprel;
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;
}
}
*/
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;
} 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,
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#include "globals.h"
#include "errwarn.h"
#include "intnum.h"
#include "expr.h"
}
void
-x86_bc_print(const bytecode *bc)
+x86_bc_print(FILE *f, const bytecode *bc)
{
const x86_insn *insn;
const x86_jmprel *jmprel;
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;
}
}
}
void
-bc_print(const bytecode *bc)
+bc_print(FILE *f, const bytecode *bc)
{
const bytecode_data *data;
const bytecode_reserve *reserve;
switch (bc->type) {
case BC_EMPTY:
- printf("_Empty_\n");
+ fprintf(f, "%*s_Empty_\n", indent_level, "");
break;
case BC_DATA:
data = bc_get_const_data(bc);
- printf("_Data_\n");
- printf("Final Element Size=%u\n",
- (unsigned int)data->size);
- printf("Elements:\n");
- dvs_print(&data->datahead);
+ fprintf(f, "%*s_Data_\n", indent_level, "");
+ indent_level++;
+ fprintf(f, "%*sFinal Element Size=%u\n", indent_level, "",
+ (unsigned int)data->size);
+ fprintf(f, "%*sElements:\n", indent_level, "");
+ indent_level++;
+ dvs_print(f, &data->datahead);
+ indent_level-=2;
break;
case BC_RESERVE:
reserve = bc_get_const_data(bc);
- printf("_Reserve_\n");
- printf("Num Items=");
- expr_print(reserve->numitems);
- printf("\nItem Size=%u\n",
- (unsigned int)reserve->itemsize);
+ fprintf(f, "%*s_Reserve_\n", indent_level, "");
+ fprintf(f, "%*sNum Items=", indent_level, "");
+ expr_print(f, reserve->numitems);
+ fprintf(f, "\n%*sItem Size=%u\n", indent_level, "",
+ (unsigned int)reserve->itemsize);
break;
default:
if (bc->type < cur_arch->bc.type_max)
- cur_arch->bc.bc_print(bc);
+ cur_arch->bc.bc_print(f, bc);
else
- printf("_Unknown_\n");
+ fprintf(f, "%*s_Unknown_\n", indent_level, "");
break;
}
- printf("Multiple=");
+ fprintf(f, "%*sMultiple=", indent_level, "");
if (!bc->multiple)
- printf("nil (1)");
+ fprintf(f, "nil (1)");
else
- expr_print(bc->multiple);
- printf("\n");
- printf("Length=%lu\n", bc->len);
- printf("Filename=\"%s\" Line Number=%u\n",
- bc->filename ? bc->filename : "<UNKNOWN>", bc->lineno);
- printf("Offset=%lx\n", bc->offset);
+ expr_print(f, bc->multiple);
+ fprintf(f, "\n%*sLength=%lu\n", indent_level, "", bc->len);
+ fprintf(f, "%*sFilename=\"%s\" Line Number=%u\n", indent_level, "",
+ bc->filename ? bc->filename : "<UNKNOWN>", bc->lineno);
+ fprintf(f, "%*sOffset=%lx\n", indent_level, "", bc->offset);
}
void
}
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--;
}
}
}
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;
}
}
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);
/*@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);
/*@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
/*@=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, "+");
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, "|");
for (i=0; i<e->numterms; i++) {
switch (e->terms[i].type) {
case EXPR_SYM:
- printf("%s", symrec_get_name(e->terms[i].data.sym));
+ fprintf(f, "%s", symrec_get_name(e->terms[i].data.sym));
break;
case EXPR_EXPR:
- printf("(");
- expr_print(e->terms[i].data.expn);
- printf(")");
+ fprintf(f, "(");
+ expr_print(f, e->terms[i].data.expn);
+ fprintf(f, ")");
break;
case EXPR_INT:
- intnum_print(e->terms[i].data.intn);
+ intnum_print(f, e->terms[i].data.intn);
break;
case EXPR_FLOAT:
- floatnum_print(e->terms[i].data.flt);
+ floatnum_print(f, e->terms[i].data.flt);
break;
case EXPR_REG:
if (e->terms[i].data.reg.size == 32)
- printf("e");
- printf("%s", regs[e->terms[i].data.reg.num&7]);
+ fprintf(f, "e");
+ fprintf(f, "%s", regs[e->terms[i].data.reg.num&7]);
break;
case EXPR_NONE:
break;
}
if (i < e->numterms-1)
- printf("%s", opstr);
+ fprintf(f, "%s", opstr);
}
}
/*@dependent@*/ /*@null@*/ const symrec *expr_get_symrec(expr **ep,
int simplify);
-void expr_print(expr *);
+void expr_print(FILE *f, /*@null@*/ expr *);
#endif
}
void
-floatnum_print(const floatnum *flt)
+floatnum_print(FILE *f, const floatnum *flt)
{
unsigned char out[10];
unsigned char *str;
/* 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");
}
*/
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
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
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);
}
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;
}
*/
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
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
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);
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#ifdef STDC_HEADERS
+# include <assert.h>
+#endif
+
#ifdef gettext_noop
#define N_(String) gettext_noop(String)
#else
#endif
static int files_open = 0;
-/*@null@*/ static FILE *in;
+/*@null@*/ /*@only@*/ static char *obj_filename = NULL;
+/*@null@*/ static FILE *in = NULL, *obj = NULL;
/* Forward declarations: cmd line parser handlers */
static int opt_option_handler(char *cmd, /*@null@*/ char *param, int extra);
static int opt_format_handler(char *cmd, /*@null@*/ char *param, int extra);
+static int opt_objfile_handler(char *cmd, /*@null@*/ char *param, int extra);
/* Fake handlers: remove them */
static int boo_boo_handler(char *cmd, /*@null@*/ char *param, int extra);
static int b_handler(char *cmd, /*@null@*/ char *param, int extra);
{
{ 'h', "help", 0, opt_option_handler, OPT_SHOW_HELP, "show help text", NULL },
{ 'f', "oformat", 1, opt_format_handler, 0, "select output format", "<format>" },
+ { 'o', "objfile", 1, opt_objfile_handler, 0, "name of object-file output", "<filename>" },
/* Fake handlers: remove them */
{ 'b', NULL, 0, b_handler, 0, "says boom!", NULL },
{ 0, "boo-boo", 0, boo_boo_handler, 0, "says boo-boo!", NULL },
"\n";
/* main function */
+/*@-globstate@*/
int
main(int argc, char *argv[])
{
}
/* if no files were specified, fallback to reading stdin */
- if (!in)
- {
+ if (!in) {
in = stdin;
switch_filename("<STDIN>");
}
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) {
sections = cur_parser->do_parse(cur_parser, in);
+ fclose(in);
+
if (OutputAllErrorWarning() > 0) {
sections_delete(sections);
symrec_delete_all();
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
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;
}
/* 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;
*/
/* 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);
/*@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
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#include "globals.h"
#include "expr.h"
#include "symrec.h"
#include "objfmt.h"
+/*@dependent@*/ FILE *dbg_f;
+
+static void
+dbg_objfmt_initialize(/*@dependent@*/ FILE *f)
+{
+ dbg_f = f;
+ fprintf(dbg_f, "%*sinitialize(f)\n", indent_level, "");
+}
+
+static void
+dbg_objfmt_finalize(void)
+{
+ fprintf(dbg_f, "%*sfinalize()\n", indent_level, "");
+}
+
static /*@dependent@*/ /*@null@*/ section *
dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
/*@unused@*/ /*@null@*/
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;
}
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;
}
/*@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 */
}
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,
dbg_objfmt_global_data_new,
dbg_objfmt_common_data_new,
dbg_objfmt_declare_data_delete,
+ dbg_objfmt_declare_data_print,
dbg_objfmt_directive
};
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#include "globals.h"
#include "expr.h"
#include "symrec.h"
#include "objfmt.h"
+/*@dependent@*/ FILE *dbg_f;
+
+static void
+dbg_objfmt_initialize(/*@dependent@*/ FILE *f)
+{
+ dbg_f = f;
+ fprintf(dbg_f, "%*sinitialize(f)\n", indent_level, "");
+}
+
+static void
+dbg_objfmt_finalize(void)
+{
+ fprintf(dbg_f, "%*sfinalize()\n", indent_level, "");
+}
+
static /*@dependent@*/ /*@null@*/ section *
dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
/*@unused@*/ /*@null@*/
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;
}
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;
}
/*@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 */
}
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,
dbg_objfmt_global_data_new,
dbg_objfmt_common_data_new,
dbg_objfmt_declare_data_delete,
+ dbg_objfmt_declare_data_print,
dbg_objfmt_directive
};
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 *
}
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--;
}
}
}
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--;
}
}
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);
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
/* 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 *
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)) {
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.)"));
/*@=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);
}
/*@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);
*/
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
/* 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);
}
/* 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
#include "util.h"
/*@unused@*/ RCSID("$IdPath$");
+#include "globals.h"
#include "expr.h"
}
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, ",");
+ }
+}
#define vps_foreach(iter, headp) STAILQ_FOREACH(iter, headp, link)
+void vps_print(FILE *f, /*@null@*/ valparamhead *headp);
+
#endif