From 9f6cb6783f30ff19413e8e0800ac55bbff42818f Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Fri, 1 Nov 2002 10:05:03 +0000 Subject: [PATCH] Modularize errwarn. gettext()-ize in errwarn, not in every module, eliminating libintl dependency in modules. Also standardize initialize() and cleanup() functions. Move replace_extension() from file.c to main.c. Clean up some extern variable declarations in various places (particularly nasm-compatible parser). svn path=/trunk/yasm/; revision=792 --- frontends/yasm/Makefile.inc | 2 +- frontends/yasm/yasm-options.c | 15 +- frontends/yasm/yasm.c | 187 ++++++++++++---- libyasm/Makefile.inc | 2 +- libyasm/arch.h | 3 + libyasm/bytecode.c | 72 ++++--- libyasm/bytecode.h | 2 +- libyasm/coretype.h | 1 + libyasm/errwarn.c | 239 +++++++++++---------- libyasm/errwarn.h | 90 ++++---- libyasm/expr.c | 9 +- libyasm/expr.h | 2 +- libyasm/file.c | 49 ----- libyasm/file.h | 9 - libyasm/floatnum.c | 32 ++- libyasm/floatnum.h | 3 +- libyasm/hamt.c | 22 +- libyasm/hamt.h | 8 +- libyasm/intnum.c | 64 +++--- libyasm/intnum.h | 3 +- libyasm/linemgr.c | 7 +- libyasm/linemgr.h | 5 +- libyasm/objfmt.h | 2 +- libyasm/optimizer.h | 2 +- libyasm/parser.h | 2 +- libyasm/preproc.h | 8 +- libyasm/section.c | 26 ++- libyasm/section.h | 13 +- libyasm/symrec.c | 77 ++++--- libyasm/symrec.h | 4 +- libyasm/tests/floatnum_test.c | 1 + libyasm/util.h | 2 + libyasm/xmalloc.c | 17 +- modules/Makefile.inc | 2 +- modules/arch/x86/x86arch.c | 21 +- modules/arch/x86/x86arch.h | 2 + modules/arch/x86/x86bc.c | 63 +++--- modules/arch/x86/x86expr.c | 38 ++-- modules/arch/x86/x86id.re | 53 +++-- modules/objfmts/bin/bin-objfmt.c | 56 +++-- modules/objfmts/coff/coff-objfmt.c | 54 +++-- modules/objfmts/dbg/dbg-objfmt.c | 9 +- modules/optimizers/basic/basic-optimizer.c | 12 +- modules/parsers/nasm/Makefile.inc | 1 + modules/parsers/nasm/nasm-bison.y | 118 +++++----- modules/parsers/nasm/nasm-parser.c | 21 +- modules/parsers/nasm/nasm-parser.h | 53 +++++ modules/parsers/nasm/nasm-token.re | 72 +++---- modules/preprocs/raw/raw-preproc.c | 21 +- modules/preprocs/yapp/yapp-preproc.c | 86 ++++---- modules/preprocs/yapp/yapp-preproc.h | 6 + modules/preprocs/yapp/yapp-token.h | 2 - modules/preprocs/yapp/yapp-token.l | 28 ++- src/Makefile.inc | 2 +- src/arch.h | 3 + src/arch/x86/x86arch.c | 21 +- src/arch/x86/x86arch.h | 2 + src/arch/x86/x86bc.c | 63 +++--- src/arch/x86/x86expr.c | 38 ++-- src/arch/x86/x86id.re | 53 +++-- src/bytecode.c | 72 ++++--- src/bytecode.h | 2 +- src/coretype.h | 1 + src/errwarn.c | 239 +++++++++++---------- src/errwarn.h | 90 ++++---- src/expr.c | 9 +- src/expr.h | 2 +- src/file.c | 49 ----- src/file.h | 9 - src/floatnum.c | 32 ++- src/floatnum.h | 3 +- src/hamt.c | 22 +- src/hamt.h | 8 +- src/intnum.c | 64 +++--- src/intnum.h | 3 +- src/linemgr.c | 7 +- src/linemgr.h | 5 +- src/main.c | 187 ++++++++++++---- src/objfmt.h | 2 +- src/objfmts/bin/bin-objfmt.c | 56 +++-- src/objfmts/coff/coff-objfmt.c | 54 +++-- src/objfmts/dbg/dbg-objfmt.c | 9 +- src/optimizer.h | 2 +- src/optimizers/basic/basic-optimizer.c | 12 +- src/options.c | 15 +- src/parser.h | 2 +- src/parsers/nasm/Makefile.inc | 1 + src/parsers/nasm/nasm-bison.y | 118 +++++----- src/parsers/nasm/nasm-parser.c | 21 +- src/parsers/nasm/nasm-parser.h | 53 +++++ src/parsers/nasm/nasm-token.re | 72 +++---- src/preproc.h | 8 +- src/preprocs/raw/raw-preproc.c | 21 +- src/preprocs/yapp/yapp-preproc.c | 86 ++++---- src/preprocs/yapp/yapp-preproc.h | 6 + src/preprocs/yapp/yapp-token.h | 2 - src/preprocs/yapp/yapp-token.l | 28 ++- src/section.c | 26 ++- src/section.h | 13 +- src/symrec.c | 77 ++++--- src/symrec.h | 4 +- src/tests/floatnum_test.c | 1 + src/util.h | 2 + src/xmalloc.c | 17 +- util.h | 2 + 105 files changed, 1926 insertions(+), 1468 deletions(-) create mode 100644 modules/parsers/nasm/nasm-parser.h create mode 100644 src/parsers/nasm/nasm-parser.h diff --git a/frontends/yasm/Makefile.inc b/frontends/yasm/Makefile.inc index 1926b5ae..27ce2791 100644 --- a/frontends/yasm/Makefile.inc +++ b/frontends/yasm/Makefile.inc @@ -4,7 +4,6 @@ libyasm_la_SOURCES = \ src/bytecode.c \ src/bytecode.h \ src/bc-int.h \ - src/errwarn.c \ src/errwarn.h \ src/expr.c \ src/expr.h \ @@ -47,6 +46,7 @@ yasm_SOURCES += \ src/parser.c \ src/module.h \ src/module.c \ + src/errwarn.c \ src/linemgr.c diff --git a/frontends/yasm/yasm-options.c b/frontends/yasm/yasm-options.c index 9b4c7faa..f48dfb4e 100644 --- a/frontends/yasm/yasm-options.c +++ b/frontends/yasm/yasm-options.c @@ -67,9 +67,9 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts) if (options[i].takes_param) { param = strchr(&argv[0][2], '='); if (!param) { - ErrorNow(_ - ("option '--%s' needs an argument!"), - options[i].lopt); + fprintf(stderr, + _("option '--%s' needs an argument!"), + options[i].lopt); errors++; goto fail; } else { @@ -86,7 +86,7 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts) } } if (!got_it) { - ErrorNow(_("unrecognized option '%s'"), argv[0]); + fprintf(stderr, _("unrecognized option '%s'"), argv[0]); errors++; } } else { /* sopt */ @@ -101,8 +101,9 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts) if (argv[0][2] != '\0') param = &argv[0][2]; else if (param == NULL || *param == '-') { - ErrorNow(_("option '-%c' needs an argument!"), - options[i].sopt); + fprintf(stderr, + _("option '-%c' needs an argument!"), + options[i].sopt); errors++; goto fail; } else { @@ -118,7 +119,7 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts) } } if (!got_it) { - ErrorNow(_("unrecognized option '%s'"), argv[0]); + fprintf(stderr, _("unrecognized option '%s'"), argv[0]); errors++; } } diff --git a/frontends/yasm/yasm.c b/frontends/yasm/yasm.c index a63bc53f..b8689b13 100644 --- a/frontends/yasm/yasm.c +++ b/frontends/yasm/yasm.c @@ -50,6 +50,9 @@ /* YASM's line manager (for parse stage). */ extern linemgr yasm_linemgr; +/* YASM's errwarn handlers. */ +extern errwarn yasm_errwarn; + /* Extra path to search for our modules. */ #ifndef YASM_MODULE_PATH_ENV # define YASM_MODULE_PATH_ENV "YASM_MODULE_PATH" @@ -67,6 +70,7 @@ static int special_options = 0; /*@null@*/ /*@dependent@*/ static optimizer *cur_optimizer = NULL; /*@null@*/ /*@dependent@*/ static dbgfmt *cur_dbgfmt = NULL; static int preproc_only = 0; +static int warning_error = 0; /* warnings being treated as errors */ /*@null@*/ /*@dependent@*/ static FILE *open_obj(const char *mode); static void cleanup(/*@null@*/ sectionhead *sections); @@ -81,6 +85,9 @@ static int opt_objfile_handler(char *cmd, /*@null@*/ char *param, int extra); static int opt_warning_handler(char *cmd, /*@null@*/ char *param, int extra); static int preproc_only_handler(char *cmd, /*@null@*/ char *param, int extra); +static /*@only@*/ char *replace_extension(const char *orig, /*@null@*/ + const char *ext, const char *def); + /* values for special_options */ #define SPECIAL_SHOW_HELP 0x01 #define SPECIAL_SHOW_VERSION 0x02 @@ -102,15 +109,16 @@ static opt_option options[] = /* version message */ /*@observer@*/ static const char *version_msg[] = { - N_("yasm " VERSION "\n"), - N_("Copyright (c) 2001-2002 Peter Johnson and other " PACKAGE " developers\n"), + PACKAGE " " VERSION "\n", + N_("Copyright (c) 2001-2002 Peter Johnson and other"), " " PACKAGE " ", + N_("developers.\n"), N_("This program is free software; you may redistribute it under the\n"), N_("terms of the GNU General Public License. Portions of this program\n"), N_("are licensed under the GNU Lesser General Public License or the\n"), N_("3-clause BSD license; see individual file comments for details.\n"), N_("This program has absolutely no warranty; not even for\n"), N_("merchantibility or fitness for a particular purpose.\n"), - N_("Compiled on " __DATE__ ".\n"), + N_("Compiled on"), " " __DATE__ ".\n", }; /* help messages */ @@ -144,6 +152,12 @@ main(int argc, char *argv[]) #endif textdomain(PACKAGE); + /* Initialize errwarn handling */ + yasm_errwarn.initialize(); + + /* Initialize memory allocation */ + xalloc_initialize((void (*) (int))yasm_errwarn.fatal, FATAL_NOMEM); + /* Set libltdl malloc/free functions. */ #ifdef WITH_DMALLOC lt_dlmalloc = malloc; @@ -166,7 +180,7 @@ main(int argc, char *argv[]) errors = lt_dladdsearchdir(path); } if (errors != 0) { - ErrorNow(_("Module loader initialization failed")); + fprintf(stderr, _("Module loader initialization failed")); return EXIT_FAILURE; } @@ -186,7 +200,7 @@ main(int argc, char *argv[]) /* Initialize BitVector (needed for floating point). */ if (BitVector_Boot() != ErrCode_Ok) { - ErrorNow(_("Could not initialize BitVector")); + fprintf(stderr, _("Could not initialize BitVector")); return EXIT_FAILURE; } @@ -194,7 +208,7 @@ main(int argc, char *argv[]) /* Open the input file (if not standard input) */ in = fopen(in_filename, "rt"); if (!in) { - ErrorNow(_("could not open file `%s'"), in_filename); + fprintf(stderr, _("could not open file `%s'"), in_filename); xfree(in_filename); if (obj_filename) xfree(obj_filename); @@ -208,9 +222,16 @@ main(int argc, char *argv[]) } /* Initialize line manager */ - yasm_linemgr.initialize(); + yasm_linemgr.initialize(yasm_errwarn.internal_error_); yasm_linemgr.set(in_filename, 1, 1); + /* Initialize intnum and floatnum */ + intnum_initialize(&yasm_errwarn); + floatnum_initialize(&yasm_errwarn); + + /* Initialize symbol table */ + symrec_initialize(&yasm_errwarn); + /* handle preproc-only case here */ if (preproc_only) { char *preproc_buf = xmalloc(PREPROC_BUF_SIZE); @@ -233,15 +254,14 @@ main(int argc, char *argv[]) cur_preproc = load_preproc("yapp"); if (!cur_preproc) { - ErrorNow(_("Could not load default preprocessor")); + fprintf(stderr, _("Could not load default preprocessor")); cleanup(NULL); return EXIT_FAILURE; } /* Pre-process until done */ - cur_preproc->initialize(in, in_filename); - while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE, - &yasm_linemgr)) != 0) + cur_preproc->initialize(in, in_filename, &yasm_linemgr, &yasm_errwarn); + while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE)) != 0) fwrite(preproc_buf, got, 1, obj); if (in != stdin) @@ -250,8 +270,8 @@ main(int argc, char *argv[]) if (obj != stdout) fclose(obj); - if (GetNumErrors() > 0) { - OutputAllErrorWarning(&yasm_linemgr); + if (yasm_errwarn.get_num_errors(warning_error) > 0) { + yasm_errwarn.output_all(&yasm_linemgr, warning_error); if (obj != stdout) remove(obj_filename); xfree(preproc_buf); @@ -267,28 +287,30 @@ main(int argc, char *argv[]) cur_arch = load_arch("x86"); if (!cur_arch) { - ErrorNow(_("Could not load default architecture")); + fprintf(stderr, _("Could not load default architecture")); return EXIT_FAILURE; } + cur_arch->initialize(&yasm_errwarn); + /* Set basic as the optimizer (TODO: user choice) */ cur_optimizer = load_optimizer("basic"); if (!cur_optimizer) { - ErrorNow(_("Could not load default optimizer")); + fprintf(stderr, _("Could not load default optimizer")); return EXIT_FAILURE; } arch_common_initialize(cur_arch); - expr_initialize(cur_arch); - bc_initialize(cur_arch); + expr_initialize(cur_arch, &yasm_errwarn); + bc_initialize(cur_arch, &yasm_errwarn); /* If not already specified, default to bin as the object format. */ if (!cur_objfmt) cur_objfmt = load_objfmt("bin"); if (!cur_objfmt) { - ErrorNow(_("Could not load default object format")); + fprintf(stderr, _("Could not load default object format")); return EXIT_FAILURE; } @@ -305,8 +327,9 @@ main(int argc, char *argv[]) cur_dbgfmt->keyword) == 0) matched_dbgfmt = 1; if (!matched_dbgfmt) { - ErrorNow(_("`%s' is not a valid debug format for object format `%s'"), - cur_dbgfmt->keyword, cur_objfmt->keyword); + fprintf(stderr, + _("`%s' is not a valid debug format for object format `%s'"), + cur_dbgfmt->keyword, cur_objfmt->keyword); if (in != stdin) fclose(in); cleanup(NULL); @@ -315,7 +338,7 @@ main(int argc, char *argv[]) } if (!cur_dbgfmt) { - ErrorNow(_("Could not load default debug format")); + fprintf(stderr, _("Could not load default debug format")); return EXIT_FAILURE; } @@ -334,12 +357,12 @@ main(int argc, char *argv[]) /* Initialize the object format */ if (cur_objfmt->initialize) cur_objfmt->initialize(in_filename, obj_filename, cur_dbgfmt, - cur_arch); + cur_arch, &yasm_errwarn); /* Set NASM as the parser */ cur_parser = load_parser("nasm"); if (!cur_parser) { - ErrorNow(_("unrecognized parser `%s'"), "nasm"); + fprintf(stderr, _("unrecognized parser `%s'"), "nasm"); cleanup(NULL); return EXIT_FAILURE; } @@ -357,8 +380,9 @@ main(int argc, char *argv[]) cur_preproc->keyword) == 0) matched_preproc = 1; if (!matched_preproc) { - ErrorNow(_("`%s' is not a valid preprocessor for parser `%s'"), - cur_preproc->keyword, cur_parser->keyword); + fprintf(stderr, + _("`%s' is not a valid preprocessor for parser `%s'"), + cur_preproc->keyword, cur_parser->keyword); if (in != stdin) fclose(in); cleanup(NULL); @@ -376,23 +400,24 @@ main(int argc, char *argv[]) /* Parse! */ sections = cur_parser->do_parse(cur_preproc, cur_arch, cur_objfmt, - &yasm_linemgr, in, in_filename); + &yasm_linemgr, &yasm_errwarn, in, + in_filename); /* Close input file */ if (in != stdin) fclose(in); - if (GetNumErrors() > 0) { - OutputAllErrorWarning(&yasm_linemgr); + if (yasm_errwarn.get_num_errors(warning_error) > 0) { + yasm_errwarn.output_all(&yasm_linemgr, warning_error); cleanup(sections); return EXIT_FAILURE; } symrec_parser_finalize(); - cur_optimizer->optimize(sections); + cur_optimizer->optimize(sections, &yasm_errwarn); - if (GetNumErrors() > 0) { - OutputAllErrorWarning(&yasm_linemgr); + if (yasm_errwarn.get_num_errors(warning_error) > 0) { + yasm_errwarn.output_all(&yasm_linemgr, warning_error); cleanup(sections); return EXIT_FAILURE; } @@ -416,14 +441,14 @@ main(int argc, char *argv[]) /* If we had an error at this point, we also need to delete the output * object file (to make sure it's not left newer than the source). */ - if (GetNumErrors() > 0) { - OutputAllErrorWarning(&yasm_linemgr); + if (yasm_errwarn.get_num_errors(warning_error) > 0) { + yasm_errwarn.output_all(&yasm_linemgr, warning_error); remove(obj_filename); cleanup(sections); return EXIT_FAILURE; } - OutputAllErrorWarning(&yasm_linemgr); + yasm_errwarn.output_all(&yasm_linemgr, warning_error); cleanup(sections); return EXIT_SUCCESS; @@ -440,7 +465,7 @@ open_obj(const char *mode) obj = fopen(obj_filename, mode); if (!obj) - ErrorNow(_("could not open file `%s'"), obj_filename); + fprintf(stderr, _("could not open file `%s'"), obj_filename); return obj; } @@ -450,13 +475,21 @@ cleanup(sectionhead *sections) { if (cur_objfmt && cur_objfmt->cleanup) cur_objfmt->cleanup(); + if (cur_dbgfmt && cur_dbgfmt->cleanup) + cur_dbgfmt->cleanup(); + if (cur_preproc) + cur_preproc->cleanup(); if (sections) sections_delete(sections); - symrec_delete_all(); - yasm_linemgr.cleanup(); + symrec_cleanup(); + if (cur_arch) + cur_arch->cleanup(); - floatnum_shutdown(); - intnum_shutdown(); + floatnum_cleanup(); + intnum_cleanup(); + + yasm_errwarn.cleanup(); + yasm_linemgr.cleanup(); BitVector_Shutdown(); @@ -478,7 +511,8 @@ int not_an_option_handler(char *param) { if (in_filename) { - WarningNow(_("can open only one input file, only the last file will be processed")); + fprintf(stderr, + _("warning: can open only one input file, only the last file will be processed")); xfree(in_filename); } @@ -501,7 +535,7 @@ opt_parser_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) assert(param != NULL); cur_parser = load_parser(param); if (!cur_parser) { - ErrorNow(_("unrecognized parser `%s'"), param); + fprintf(stderr, _("unrecognized parser `%s'"), param); return 1; } return 0; @@ -513,7 +547,7 @@ opt_preproc_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) assert(param != NULL); cur_preproc = load_preproc(param); if (!cur_preproc) { - ErrorNow(_("unrecognized preprocessor `%s'"), param); + fprintf(stderr, _("unrecognized preprocessor `%s'"), param); return 1; } return 0; @@ -525,7 +559,7 @@ opt_objfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) assert(param != NULL); cur_objfmt = load_objfmt(param); if (!cur_objfmt) { - ErrorNow(_("unrecognized object format `%s'"), param); + fprintf(stderr, _("unrecognized object format `%s'"), param); return 1; } return 0; @@ -537,7 +571,7 @@ opt_dbgfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) assert(param != NULL); cur_dbgfmt = load_objfmt(param); if (!cur_dbgfmt) { - ErrorNow(_("unrecognized debugging format `%s'"), param); + fprintf(stderr, _("unrecognized debugging format `%s'"), param); return 1; } return 0; @@ -548,7 +582,8 @@ opt_objfile_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) { if (obj_filename) { - WarningNow(_("can output to only one object file, last specified used")); + fprintf(stderr, + _("warning: can output to only one object file, last specified used")); xfree(obj_filename); } @@ -565,7 +600,7 @@ opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra) if (extra == 1) { /* -w, disable warnings */ - warnings_disabled = 1; + yasm_errwarn.warn_disable_all(); return 0; } @@ -584,7 +619,10 @@ opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra) else if (strcmp(cmd, "error") == 0) { warning_error = enable; } else if (strcmp(cmd, "unrecognized-char") == 0) { - WARN_ENABLE(WARN_UNRECOGNIZED_CHAR, enable); + if (enable) + yasm_errwarn.warn_enable(WARN_UNREC_CHAR); + else + yasm_errwarn.warn_disable(WARN_UNREC_CHAR); } else return 1; @@ -598,3 +636,58 @@ preproc_only_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, preproc_only = 1; return 0; } + +/* Replace extension on a filename (or append one if none is present). + * If output filename would be identical to input (same extension out as in), + * returns (copy of) def. + * A NULL ext means the trailing '.' should NOT be included, whereas a "" ext + * means the trailing '.' should be included. + */ +static char * +replace_extension(const char *orig, /*@null@*/ const char *ext, + const char *def) +{ + char *out, *outext; + + /* allocate enough space for full existing name + extension */ + out = xmalloc(strlen(orig)+(ext ? (strlen(ext)+2) : 1)); + strcpy(out, orig); + outext = strrchr(out, '.'); + if (outext) { + /* Existing extension: make sure it's not the same as the replacement + * (as we don't want to overwrite the source file). + */ + outext++; /* advance past '.' */ + if (ext && strcmp(outext, ext) == 0) { + outext = NULL; /* indicate default should be used */ + fprintf(stderr, + _("file name already ends in `.%s': output will be in `%s'"), + ext, def); + } + } else { + /* No extension: make sure the output extension is not empty + * (again, we don't want to overwrite the source file). + */ + if (!ext) + fprintf(stderr, + _("file name already has no extension: output will be in `%s'"), + def); + else { + outext = strrchr(out, '\0'); /* point to end of the string */ + *outext++ = '.'; /* append '.' */ + } + } + + /* replace extension or use default name */ + if (outext) { + if (!ext) { + /* Back up and replace '.' with string terminator */ + outext--; + *outext = '\0'; + } else + strcpy(outext, ext); + } else + strcpy(out, def); + + return out; +} diff --git a/libyasm/Makefile.inc b/libyasm/Makefile.inc index 1926b5ae..27ce2791 100644 --- a/libyasm/Makefile.inc +++ b/libyasm/Makefile.inc @@ -4,7 +4,6 @@ libyasm_la_SOURCES = \ src/bytecode.c \ src/bytecode.h \ src/bc-int.h \ - src/errwarn.c \ src/errwarn.h \ src/expr.c \ src/expr.h \ @@ -47,6 +46,7 @@ yasm_SOURCES += \ src/parser.c \ src/module.h \ src/module.c \ + src/errwarn.c \ src/linemgr.c diff --git a/libyasm/arch.h b/libyasm/arch.h index 3d23ea8c..fb26d312 100644 --- a/libyasm/arch.h +++ b/libyasm/arch.h @@ -58,6 +58,9 @@ struct arch { /* keyword used to select architecture */ const char *keyword; + void (*initialize) (errwarn *we); + void (*cleanup) (void); + struct { /* All "data" below starts the parse initialized to 0. Thus, it is * okay for a funtion to use/check previously stored data to see if diff --git a/libyasm/bytecode.c b/libyasm/bytecode.c index 3a1132d3..2f84a64e 100644 --- a/libyasm/bytecode.c +++ b/libyasm/bytecode.c @@ -96,12 +96,14 @@ typedef struct bytecode_objfmt_data { unsigned char bytes_static[16]; /*@dependent@*/ static arch *cur_arch; +/*@dependent@*/ static errwarn *cur_we; void -bc_initialize(arch *a) +bc_initialize(arch *a, errwarn *we) { cur_arch = a; + cur_we = we; } immval * @@ -328,13 +330,14 @@ bc_delete(bytecode *bc) objfmt_data->of->bc_objfmt_data_delete(objfmt_data->type, objfmt_data->data); else - InternalError(_("objfmt can't handle its own objfmt data bytecode")); + cur_we->internal_error( + N_("objfmt can't handle its own objfmt data bytecode")); break; default: if (bc->type < cur_arch->bc.type_max) cur_arch->bc.bc_delete(bc); else - InternalError(_("Unknown bytecode type")); + cur_we->internal_error(N_("Unknown bytecode type")); break; } /*@=branchstate@*/ @@ -500,10 +503,11 @@ bc_resolve_reserve(bytecode_reserve *reserve, unsigned long *len, int save, * the circular reference error to filter through. */ if (temp && expr_contains(temp, EXPR_FLOAT)) - Error(line, _("expression must not contain floating point value")); + cur_we->error(line, + N_("expression must not contain floating point value")); else - Error(line, - _("attempt to reserve non-constant quantity of space")); + cur_we->error(line, + N_("attempt to reserve non-constant quantity of space")); retval = BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } else *len += intnum_get_uint(num)*reserve->itemsize; @@ -565,12 +569,13 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save, /* Open file and determine its length */ f = fopen(incbin->filename, "rb"); if (!f) { - Error(line, _("`incbin': unable to open file `%s'"), incbin->filename); + cur_we->error(line, N_("`incbin': unable to open file `%s'"), + incbin->filename); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } if (fseek(f, 0L, SEEK_END) < 0) { - Error(line, _("`incbin': unable to seek on file `%s'"), - incbin->filename); + cur_we->error(line, N_("`incbin': unable to seek on file `%s'"), + incbin->filename); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } flen = (unsigned long)ftell(f); @@ -578,8 +583,9 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save, /* Compute length of incbin from start, maxlen, and len */ if (start > flen) { - Warning(line, _("`incbin': start past end of file `%s'"), - incbin->filename); + cur_we->warning(WARN_GENERAL, line, + N_("`incbin': start past end of file `%s'"), + incbin->filename); start = flen; } flen -= start; @@ -603,7 +609,7 @@ bc_resolve(bytecode *bc, int save, const section *sect, switch (bc->type) { case BC_EMPTY: - InternalError(_("got empty bytecode in bc_calc_len")); + cur_we->internal_error(N_("got empty bytecode in bc_calc_len")); case BC_DATA: retval = bc_resolve_data((bytecode_data *)bc, &bc->len); break; @@ -617,17 +623,18 @@ bc_resolve(bytecode *bc, int save, const section *sect, break; case BC_ALIGN: /* TODO */ - InternalError(_("TODO: align bytecode not implemented!")); + cur_we->internal_error( + N_("TODO: align bytecode not implemented!")); /*break;*/ case BC_OBJFMT_DATA: - InternalError(_("resolving objfmt data bytecode?")); + cur_we->internal_error(N_("resolving objfmt data bytecode?")); /*break;*/ default: if (bc->type < cur_arch->bc.type_max) retval = cur_arch->bc.bc_resolve(bc, save, sect, calc_bc_dist); else - InternalError(_("Unknown bytecode type")); + cur_we->internal_error(N_("Unknown bytecode type")); } /* Multiply len by number of multiples */ @@ -644,8 +651,8 @@ bc_resolve(bytecode *bc, int save, const section *sect, if (!num) { retval = BC_RESOLVE_UNKNOWN_LEN; if (temp && expr_contains(temp, EXPR_FLOAT)) { - Error(bc->line, - _("expression must not contain floating point value")); + cur_we->error(bc->line, + N_("expression must not contain floating point value")); retval |= BC_RESOLVE_ERROR; } } else @@ -711,29 +718,32 @@ bc_tobytes_incbin(bytecode_incbin *incbin, unsigned char **bufp, if (incbin->start) { num = expr_get_intnum(&incbin->start, NULL); if (!num) - InternalError(_("could not determine start in bc_tobytes_incbin")); + cur_we->internal_error( + N_("could not determine start in bc_tobytes_incbin")); start = intnum_get_uint(num); } /* Open file */ f = fopen(incbin->filename, "rb"); if (!f) { - Error(line, _("`incbin': unable to open file `%s'"), incbin->filename); + cur_we->error(line, N_("`incbin': unable to open file `%s'"), + incbin->filename); return 1; } /* Seek to start of data */ if (fseek(f, (long)start, SEEK_SET) < 0) { - Error(line, _("`incbin': unable to seek on file `%s'"), - incbin->filename); + cur_we->error(line, N_("`incbin': unable to seek on file `%s'"), + incbin->filename); fclose(f); return 1; } /* Read len bytes */ if (fread(*bufp, (size_t)len, 1, f) < (size_t)len) { - Error(line, _("`incbin': unable to read %lu bytes from file `%s'"), - len, incbin->filename); + cur_we->error(line, + N_("`incbin': unable to read %lu bytes from file `%s'"), + len, incbin->filename); fclose(f); return 1; } @@ -760,7 +770,8 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize, if (bc->multiple) { num = expr_get_intnum(&bc->multiple, NULL); if (!num) - InternalError(_("could not determine multiple in bc_tobytes")); + cur_we->internal_error( + N_("could not determine multiple in bc_tobytes")); *multiple = intnum_get_uint(num); if (*multiple == 0) { *bufsize = 0; @@ -790,7 +801,7 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize, switch (bc->type) { case BC_EMPTY: - InternalError(_("got empty bytecode in bc_tobytes")); + cur_we->internal_error(N_("got empty bytecode in bc_tobytes")); case BC_DATA: error = bc_tobytes_data((bytecode_data *)bc, &destbuf, sect, bc, d, output_expr); @@ -801,7 +812,8 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize, break; case BC_ALIGN: /* TODO */ - InternalError(_("TODO: align bytecode not implemented!")); + cur_we->internal_error( + N_("TODO: align bytecode not implemented!")); /*break;*/ case BC_OBJFMT_DATA: objfmt_data = (bytecode_objfmt_data *)bc; @@ -809,18 +821,20 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize, error = output_bc_objfmt_data(objfmt_data->type, objfmt_data->data, &destbuf); else - InternalError(_("Have objfmt data bytecode but no way to output it")); + cur_we->internal_error( + N_("Have objfmt data bytecode but no way to output it")); break; default: if (bc->type < cur_arch->bc.type_max) error = cur_arch->bc.bc_tobytes(bc, &destbuf, sect, d, output_expr); else - InternalError(_("Unknown bytecode type")); + cur_we->internal_error(N_("Unknown bytecode type")); } if (!error && ((unsigned long)(destbuf - origbuf) != datasize)) - InternalError(_("written length does not match optimized length")); + cur_we->internal_error( + N_("written length does not match optimized length")); return mybuf; } diff --git a/libyasm/bytecode.h b/libyasm/bytecode.h index f2938ef4..2259400e 100644 --- a/libyasm/bytecode.h +++ b/libyasm/bytecode.h @@ -40,7 +40,7 @@ typedef enum { } bytecode_type; #define BYTECODE_TYPE_BASE BC_OBJFMT_DATA+1 -void bc_initialize(arch *a); +void bc_initialize(arch *a, errwarn *we); /*@only@*/ immval *imm_new_int(unsigned long int_val, unsigned long lindex); /*@only@*/ immval *imm_new_expr(/*@keep@*/ expr *e); diff --git a/libyasm/coretype.h b/libyasm/coretype.h index d1585fa9..0701d56d 100644 --- a/libyasm/coretype.h +++ b/libyasm/coretype.h @@ -43,6 +43,7 @@ typedef struct intnum intnum; typedef struct floatnum floatnum; typedef struct linemgr linemgr; +typedef struct errwarn errwarn; typedef enum { EXPR_ADD, diff --git a/libyasm/errwarn.c b/libyasm/errwarn.c index c74d5337..6278a3e1 100644 --- a/libyasm/errwarn.c +++ b/libyasm/errwarn.c @@ -34,29 +34,18 @@ #define MSG_MAXSIZE 1024 -/* ALL warnings are disabled if this is nonzero. */ -int warnings_disabled = 0; +/* Enabled warnings. See errwarn.h for a list. */ +static unsigned long warn_class_enabled; -/* Warnings are treated as errors if this is nonzero. - * =2 indicates that warnings are treated as errors, and the message to the - * user saying that has been output. - */ -int warning_error = 0; +/* Total error count */ +static unsigned int error_count; -/* Default enabled warnings. See errwarn.h for a list. */ -unsigned long warning_flags = - (1UL<= 0 on finish. */ -static unsigned int error_count = 0; - -/* Total warning count for entire assembler run. - * Should not affect exit value of assembler. */ -static unsigned int warning_count = 0; +/* Total warning count */ +static unsigned int warning_count; /* See errwarn.h for constants that match up to these strings. - * When adding a string here, keep errwarn.h in sync! */ + * When adding a string here, keep errwarn.h in sync! + */ /* Fatal error messages. Match up with fatal_num enum in errwarn.h. */ /*@-observertrans@*/ @@ -66,12 +55,12 @@ static const char *fatal_msgs[] = { }; /*@=observertrans@*/ -typedef /*@reldef@*/ SLIST_HEAD(errwarnhead_s, errwarn_s) errwarnhead; -static /*@only@*/ /*@null@*/ errwarnhead errwarns = - SLIST_HEAD_INITIALIZER(errwarns); +typedef /*@reldef@*/ SLIST_HEAD(errwarndatahead_s, errwarn_data) + errwarndatahead; +static /*@only@*/ /*@null@*/ errwarndatahead errwarns; -typedef struct errwarn_s { - /*@reldef@*/ SLIST_ENTRY(errwarn_s) link; +typedef struct errwarn_data { + /*@reldef@*/ SLIST_ENTRY(errwarn_data) link; enum { WE_UNKNOWN, WE_ERROR, WE_WARNING, WE_PARSERERROR } type; @@ -79,18 +68,47 @@ typedef struct errwarn_s { /* FIXME: This should not be a fixed size. But we don't have vasprintf() * right now. */ char msg[MSG_MAXSIZE]; -} errwarn; +} errwarn_data; /* Last inserted error/warning. Used to speed up insertions. */ -static /*@null@*/ errwarn *previous_we = NULL; +static /*@null@*/ errwarn_data *previous_we; /* Static buffer for use by conv_unprint(). */ static char unprint[5]; + +static void +yasm_errwarn_initialize(void) +{ + /* Default enabled warnings. See errwarn.h for a list. */ + warn_class_enabled = + (1UL<type = WE_UNKNOWN; we->line = lindex; @@ -184,7 +205,8 @@ errwarn_new(unsigned long lindex, int replace_parser_error) assert(ins_we != NULL); SLIST_INSERT_AFTER(ins_we, we, link); } else - InternalError(_("Unexpected errwarn insert action")); + yasm_errwarn_internal_error_(__FILE__, __LINE__, + N_("Unexpected errwarn insert action")); } /* Remember previous err/warn */ @@ -193,40 +215,52 @@ errwarn_new(unsigned long lindex, int replace_parser_error) return we; } -/* Register an error. Does not print the error, only stores it for - * OutputAllErrorWarning() to print. +/* Register an error at line lindex. Does not print the error, only stores it + * for output_all() to print. */ static void -error_common(unsigned long lindex, const char *fmt, va_list ap) +yasm_errwarn_error(unsigned long lindex, const char *fmt, ...) { - errwarn *we = errwarn_new(lindex, 1); + va_list va; + errwarn_data *we = errwarn_data_new(lindex, 1); we->type = WE_ERROR; + va_start(va, fmt); #ifdef HAVE_VSNPRINTF - vsnprintf(we->msg, MSG_MAXSIZE, fmt, ap); + vsnprintf(we->msg, MSG_MAXSIZE, gettext(fmt), va); #else - vsprintf(we->msg, fmt, ap); + vsprintf(we->msg, gettext(fmt), va); #endif + va_end(va); error_count++; } -/* Register an warning. Does not print the warning, only stores it for - * OutputAllErrorWarning() to print. +/* Register an warning at line lindex. Does not print the warning, only stores + * it for output_all() to print. */ static void -warning_common(unsigned long lindex, const char *fmt, va_list va) +yasm_errwarn_warning(warn_class_num num, unsigned long lindex, const char *fmt, + ...) { - errwarn *we = errwarn_new(lindex, 0); + va_list va; + errwarn_data *we; + + if (!(warn_class_enabled & (1UL<type = WE_WARNING; + va_start(va, fmt); #ifdef HAVE_VSNPRINTF - vsnprintf(we->msg, MSG_MAXSIZE, fmt, va); + vsnprintf(we->msg, MSG_MAXSIZE, gettext(fmt), va); #else - vsprintf(we->msg, fmt, va); + vsprintf(we->msg, gettext(fmt), va); #endif + va_end(va); warning_count++; } @@ -234,92 +268,59 @@ warning_common(unsigned long lindex, const char *fmt, va_list va) /* Parser error handler. Moves YACC-style error into our error handling * system. */ -void -ParserError(unsigned long lindex, const char *s) +static void +yasm_errwarn_parser_error(unsigned long lindex, const char *s) { - Error(lindex, "%s %s", _("parser error:"), s); + yasm_errwarn_error(lindex, N_("parser error: %s"), s); previous_we->type = WE_PARSERERROR; } -/* Register an error at line lindex. Does not print the error, only stores it - * for OutputAllErrorWarning() to print. - */ -void -Error(unsigned long lindex, const char *fmt, ...) +static void +yasm_errwarn_warn_enable(warn_class_num num) { - va_list va; - va_start(va, fmt); - error_common(lindex, fmt, va); - va_end(va); + warn_class_enabled |= (1UL<lookup(we->line, &filename, &line); if (we->type == WE_ERROR) @@ -327,9 +328,21 @@ OutputAllErrorWarning(linemgr *lm) else fprintf(stderr, "%s:%lu: %s %s\n", filename, line, _("warning:"), we->msg); - - /* Delete */ - SLIST_REMOVE_HEAD(&errwarns, link); - xfree(we); } } + +errwarn yasm_errwarn = { + yasm_errwarn_initialize, + yasm_errwarn_cleanup, + yasm_errwarn_internal_error_, + yasm_errwarn_fatal, + yasm_errwarn_error, + yasm_errwarn_warning, + yasm_errwarn_parser_error, + yasm_errwarn_warn_enable, + yasm_errwarn_warn_disable, + yasm_errwarn_warn_disable_all, + yasm_errwarn_get_num_errors, + yasm_errwarn_output_all, + yasm_errwarn_conv_unprint +}; diff --git a/libyasm/errwarn.h b/libyasm/errwarn.h index 75ee91a3..e3c3014e 100644 --- a/libyasm/errwarn.h +++ b/libyasm/errwarn.h @@ -22,66 +22,66 @@ #ifndef YASM_ERRWARN_H #define YASM_ERRWARN_H -/* ALL warnings disabled? */ -extern int warnings_disabled; - -/* Warnings treated as errors? */ -extern int warning_error; - -/* Warning flags. Currently a maximum of 32 are allowed. This can be - * increased by making this an array and modifying the WARN_ macros to use the - * proper array index based on the warning number. - * - * If a bit is 1, it means that particular warning is enabled. The bit numbers - * are assigned according to the warn_flag_num enum. - * - * See errwarn.c for what warnings are enabled by default. - */ -extern unsigned long warning_flags; +/* Warning classes (may be enabled/disabled). */ typedef enum { - WARN_UNRECOGNIZED_CHAR = 0 -} warn_flag_num; - -/* Tests the warning flags to see if warning "warn" is enabled */ -#define WARN_ENABLED(warn) (warning_flags & (1<<(warn))) -/* Sets warning "warn" to be enabled or disabled based on "s" (1=en, 0=dis). */ -#define WARN_ENABLE(warn, s) do { \ - warning_flags &= ~(1<<(warn)); \ - warning_flags |= (s)<<(warn); \ - } while(0) + WARN_GENERAL = 0, /* non-specific warnings */ + WARN_UNREC_CHAR, /* unrecognized characters (while tokenizing) */ + WARN_PREPROC /* preprocessor warnings */ +} warn_class_num; /* Fatal error constants. * See fatal_msgs in errwarn.c for strings that match up to these constants. - * When adding a constant here, keep errwarn.c in sync! */ + * When adding a constant here, keep errwarn.c in sync! + */ typedef enum { FATAL_UNKNOWN = 0, FATAL_NOMEM } fatal_num; -/*@shared@*/ char *conv_unprint(char ch); +struct errwarn { + /* Initialize any internal data structures. */ + void (*initialize) (void); -void ParserError(unsigned long lindex, const char *); + /* Cleans up any memory allocated by initialize or other functions. */ + void (*cleanup) (void); -/*@exits@*/ void InternalError_(const char *file, unsigned int line, - const char *message); -#define InternalError(msg) InternalError_(__FILE__, __LINE__, msg) + /* Reporting point of internal errors. These are usually due to sanity + * check failures in the code. + * This function must NOT return to calling code. Either exit or longjmp. + */ + /*@exits@*/ void (*internal_error_) (const char *file, unsigned int line, + const char *message); +#define internal_error(msg) internal_error_(__FILE__, __LINE__, msg) -/*@exits@*/ void Fatal(fatal_num); + /* Reporting point of fatal errors. + * This function must NOT return to calling code. Either exit or longjmp. + */ + /*@exits@*/ void (*fatal) (fatal_num); -void Error(unsigned long lindex, const char *, ...) /*@printflike@*/; -void Warning(unsigned long lindex, const char *, ...) /*@printflike@*/; + void (*error) (unsigned long lindex, const char *, ...) /*@printflike@*/; + void (*warning) (warn_class_num, unsigned long lindex, const char *, ...) + /*@printflike@*/; -/* These two functions immediately output the error or warning, with no file - * or line information. They should be used for errors and warnings outside - * the parser stage (at program startup, for instance). - */ -void ErrorNow(const char *, ...) /*@printflike@*/; -void WarningNow(const char *, ...) /*@printflike@*/; + /* Logs a parser error. These can be overwritten by non-parser errors on + * the same line. + */ + void (*parser_error) (unsigned long lindex, const char *); -/* Returns total number of errors to this point in assembly. */ -unsigned int GetNumErrors(void); + /* Enables/disables a class of warnings. */ + void (*warn_enable) (warn_class_num); + void (*warn_disable) (warn_class_num); + void (*warn_disable_all) (void); -/* Outputs all errors/warnings to standard error. */ -void OutputAllErrorWarning(linemgr *lm); + /* Returns total number of errors logged to this point. + * If warning_as_error is nonzero, warnings are treated as errors. + */ + unsigned int (*get_num_errors) (int warning_as_error); + + /* Outputs all errors/warnings (e.g. to stderr or elsewhere). */ + void (*output_all) (linemgr *lm, int warning_as_error); + + /* Convert a possibly unprintable character into a printable string. */ + char * (*conv_unprint) (char ch); +}; #endif diff --git a/libyasm/expr.c b/libyasm/expr.c index a56762aa..8f76aec0 100644 --- a/libyasm/expr.c +++ b/libyasm/expr.c @@ -43,12 +43,14 @@ static int expr_traverse_nodes_post(/*@null@*/ expr *e, /*@null@*/ void *d, /*@null@*/ void *d)); static /*@dependent@*/ arch *cur_arch; +static /*@dependent@*/ errwarn *cur_we; void -expr_initialize(arch *a) +expr_initialize(arch *a, errwarn *we) { cur_arch = a; + cur_we = we; } /* allocate a new expression node, with children as defined. @@ -81,7 +83,7 @@ expr_new(ExprOp op, ExprItem *left, ExprItem *right, unsigned long lindex) /*@=usereleased@*/ } } else { - InternalError(_("Right side of expression must exist")); + cur_we->internal_error(N_("Right side of expression must exist")); } if (right) { @@ -700,7 +702,8 @@ expr_level_tree(expr *e, int fold_const, int simplify_ident, /* Check for circular reference */ SLIST_FOREACH(np, eh, next) { if (np->e == equ_expr) { - Error(e->line, _("circular reference detected.")); + cur_we->error(e->line, + N_("circular reference detected.")); return e; } } diff --git a/libyasm/expr.h b/libyasm/expr.h index 36e53972..73aee925 100644 --- a/libyasm/expr.h +++ b/libyasm/expr.h @@ -24,7 +24,7 @@ typedef struct ExprItem ExprItem; -void expr_initialize(arch *a); +void expr_initialize(arch *a, errwarn *we); /*@only@*/ expr *expr_new(ExprOp, /*@only@*/ ExprItem *, /*@only@*/ /*@null@*/ ExprItem *, diff --git a/libyasm/file.c b/libyasm/file.c index 77f1aa9e..ae05f513 100644 --- a/libyasm/file.c +++ b/libyasm/file.c @@ -24,55 +24,6 @@ #include "file.h" -#include "errwarn.h" - - -char * -replace_extension(const char *orig, /*@null@*/ const char *ext, - const char *def) -{ - char *out, *outext; - - /* allocate enough space for full existing name + extension */ - out = xmalloc(strlen(orig)+(ext ? (strlen(ext)+2) : 1)); - strcpy(out, orig); - outext = strrchr(out, '.'); - if (outext) { - /* Existing extension: make sure it's not the same as the replacement - * (as we don't want to overwrite the source file). - */ - outext++; /* advance past '.' */ - if (ext && strcmp(outext, ext) == 0) { - outext = NULL; /* indicate default should be used */ - WarningNow(_("file name already ends in `.%s': output will be in `%s'"), - ext, def); - } - } else { - /* No extension: make sure the output extension is not empty - * (again, we don't want to overwrite the source file). - */ - if (!ext) - WarningNow(_("file name already has no extension: output will be in `%s'"), - def); - else { - outext = strrchr(out, '\0'); /* point to end of the string */ - *outext++ = '.'; /* append '.' */ - } - } - - /* replace extension or use default name */ - if (outext) { - if (!ext) { - /* Back up and replace '.' with string terminator */ - outext--; - *outext = '\0'; - } else - strcpy(outext, ext); - } else - strcpy(out, def); - - return out; -} size_t fwrite_16_l(unsigned short val, FILE *f) diff --git a/libyasm/file.h b/libyasm/file.h index 39407478..be83f779 100644 --- a/libyasm/file.h +++ b/libyasm/file.h @@ -22,15 +22,6 @@ #ifndef YASM_FILE_H #define YASM_FILE_H -/* Replace extension on a filename (or append one if none is present). - * If output filename would be identical to input (same extension out as in), - * returns (copy of) def. - * A NULL ext means the trailing '.' should NOT be included, whereas a "" ext - * means the trailing '.' should be included. - */ -/*@only@*/ char *replace_extension(const char *orig, /*@null@*/ - const char *ext, const char *def); - /* These functions only work properly if p is an (unsigned char *) */ #define WRITE_8(ptr, val) \ diff --git a/libyasm/floatnum.c b/libyasm/floatnum.c index f7b4fe60..73da72d9 100644 --- a/libyasm/floatnum.c +++ b/libyasm/floatnum.c @@ -84,9 +84,7 @@ typedef struct POT_Entry_Source_s { * entry[12-n] = 10 ** (-2 ** n) for 0 <= n <= 12. * entry[13] = 1.0 */ -/*@-nullassign@*/ -static /*@only@*/ POT_Entry *POT_TableN = (POT_Entry *)NULL; -/*@=nullassign@*/ +static /*@only@*/ POT_Entry *POT_TableN; static POT_Entry_Source POT_TableN_Source[] = { {{0xe3,0x2d,0xde,0x9f,0xce,0xd2,0xc8,0x04,0xdd,0xa6},0x4ad8}, /* 1e-4096 */ {{0x25,0x49,0xe4,0x2d,0x36,0x34,0x4f,0x53,0xae,0xce},0x656b}, /* 1e-2048 */ @@ -132,6 +130,9 @@ static POT_Entry_Source POT_TableP_Source[] = { {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80},0x7fff}, /* 1e+0 */ }; +static /*@dependent@*/ errwarn *cur_we; + + static void POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp) { @@ -153,14 +154,16 @@ POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp) } /*@-compdef@*/ -static void -POT_Table_Init(void) +void +floatnum_initialize(errwarn *we) /*@globals undef POT_TableN, undef POT_TableP, POT_TableP_Source, POT_TableN_Source @*/ { int dec_exp = 1; int i; + cur_we = we; + /* Allocate space for two POT tables */ POT_TableN = xmalloc(14*sizeof(POT_Entry)); POT_TableP = xmalloc(15*sizeof(POT_Entry)); /* note 1 extra for -1 */ @@ -186,13 +189,10 @@ POT_Table_Init(void) /*@-globstate@*/ void -floatnum_shutdown(void) +floatnum_cleanup(void) { int i; - if (!POT_TableN) - return; - /* Un-offset POT_TableP */ POT_TableP--; @@ -310,10 +310,6 @@ floatnum_new(const char *str) int decimal_pt; boolean carry; - /* Initialize POT tables if necessary */ - if (!POT_TableN) - POT_Table_Init(); - flt = xmalloc(sizeof(floatnum)); flt->mantissa = BitVector_Create(MANT_BITS, TRUE); @@ -515,7 +511,8 @@ floatnum_calc(floatnum *acc, ExprOp op, /*@unused@*/ floatnum *operand, unsigned long lindex) { if (op != EXPR_NEG) - Error(lindex, _("Unsupported floating-point arithmetic operation")); + cur_we->error(lindex, + N_("Unsupported floating-point arithmetic operation")); else acc->sign ^= 1; } @@ -590,7 +587,7 @@ floatnum_get_common(const floatnum *flt, /*@out@*/ unsigned char *ptr, /* underflow and overflow both set!? */ if (underflow && overflow) - InternalError(_("Both underflow and overflow set")); + cur_we->internal_error(N_("Both underflow and overflow set")); /* check for underflow or overflow and set up appropriate output */ if (underflow) { @@ -613,7 +610,8 @@ floatnum_get_common(const floatnum *flt, /*@out@*/ unsigned char *ptr, /* get little-endian bytes */ buf = BitVector_Block_Read(output, &len); if (len < byte_size) - InternalError(_("Byte length of BitVector does not match bit length")); + cur_we->internal_error( + N_("Byte length of BitVector does not match bit length")); /* copy to output */ memcpy(ptr, buf, byte_size*sizeof(unsigned char)); @@ -667,7 +665,7 @@ floatnum_get_sized(const floatnum *flt, unsigned char *ptr, size_t size) case 10: return floatnum_get_common(flt, ptr, 10, 64, 0, 15); default: - InternalError(_("Invalid float conversion size")); + cur_we->internal_error(N_("Invalid float conversion size")); /*@notreached@*/ return 1; /* never reached, but silence GCC warning */ } diff --git a/libyasm/floatnum.h b/libyasm/floatnum.h index a5d05bba..60f20050 100644 --- a/libyasm/floatnum.h +++ b/libyasm/floatnum.h @@ -24,8 +24,9 @@ #ifndef YASM_FLOATNUM_H #define YASM_FLOATNUM_H +void floatnum_initialize(errwarn *we); /* Clean up internal allocations */ -void floatnum_shutdown(void); +void floatnum_cleanup(void); /*@only@*/ floatnum *floatnum_new(const char *str); /*@only@*/ floatnum *floatnum_copy(const floatnum *flt); diff --git a/libyasm/hamt.c b/libyasm/hamt.c index 26606d70..a1fa2c3b 100644 --- a/libyasm/hamt.c +++ b/libyasm/hamt.c @@ -35,7 +35,6 @@ #include "util.h" /*@unused@*/ RCSID("$IdPath$"); -#include "errwarn.h" #include "hamt.h" typedef struct HAMTEntry { @@ -52,6 +51,8 @@ typedef struct HAMTNode { struct HAMT { SLIST_HEAD(HAMTEntryHead, HAMTEntry) entries; HAMTNode *root; + /*@exits@*/ void (*error_func) (const char *file, unsigned int line, + const char *message); }; /* XXX make a portable version of this. This depends on the pointer being @@ -59,9 +60,10 @@ struct HAMT { * the subtrie flag! */ #define IsSubTrie(n) ((unsigned long)((n)->BaseValue) & 1) -#define SetSubTrie(n, v) do { \ +#define SetSubTrie(h, n, v) do { \ if ((unsigned long)(v) & 1) \ - InternalError(_("Subtrie is seen as subtrie before flag is set (misaligned?)")); \ + h->error_func(__FILE__, __LINE__, \ + N_("Subtrie is seen as subtrie before flag is set (misaligned?)")); \ (n)->BaseValue = (void *)((unsigned long)(v) | 1); \ } while (0) #define GetSubTrie(n) (HAMTNode *)((unsigned long)((n)->BaseValue)&~1UL) @@ -85,7 +87,8 @@ ReHashKey(const char *key, int Level) } HAMT * -HAMT_new(void) +HAMT_new(/*@exits@*/ void (*error_func) (const char *file, unsigned int line, + const char *message)) { /*@out@*/ HAMT *hamt = xmalloc(sizeof(HAMT)); int i; @@ -98,6 +101,8 @@ HAMT_new(void) hamt->root[i].BaseValue = NULL; } + hamt->error_func = error_func; + return hamt; } @@ -174,7 +179,8 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace, SLIST_INSERT_HEAD(&hamt->entries, entry, next); node->BaseValue = entry; if (IsSubTrie(node)) - InternalError(_("Data is seen as subtrie (misaligned?)")); + hamt->error_func(__FILE__, __LINE__, + N_("Data is seen as subtrie (misaligned?)")); *replace = 1; return data; } @@ -216,7 +222,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace, newnodes = xmalloc(sizeof(HAMTNode)); newnodes[0] = *node; /* structure copy */ node->BitMapKey = 1<BitMapKey = (1UL<data = data; SLIST_INSERT_HEAD(&hamt->entries, entry, next); newnodes[Map].BaseValue = entry; - SetSubTrie(node, newnodes); + SetSubTrie(hamt, node, newnodes); *replace = 1; return data; diff --git a/libyasm/hamt.h b/libyasm/hamt.h index b3cd7931..c21d5201 100644 --- a/libyasm/hamt.h +++ b/libyasm/hamt.h @@ -32,8 +32,12 @@ typedef struct HAMT HAMT; -/* Creates new, empty, HAMT. */ -HAMT *HAMT_new(void); +/* Creates new, empty, HAMT. error_func() is called when an internal error is + * encountered--it should NOT return to the calling function. + */ +HAMT *HAMT_new(/*@exits@*/ void (*error_func) (const char *file, + unsigned int line, + const char *message)); /* Deletes HAMT and all data associated with it using deletefunc() on each data * item. diff --git a/libyasm/intnum.c b/libyasm/intnum.c index 3ca4775d..5fba7ab7 100644 --- a/libyasm/intnum.c +++ b/libyasm/intnum.c @@ -43,15 +43,23 @@ struct intnum { }; /* static bitvect used for conversions */ -static /*@only@*/ /*@null@*/ wordptr conv_bv = NULL; +static /*@only@*/ wordptr conv_bv; +static /*@dependent@*/ errwarn *cur_we; + void -intnum_shutdown(void) +intnum_initialize(errwarn *we) { - if (conv_bv) { - BitVector_Destroy(conv_bv); - conv_bv = NULL; - } + cur_we = we; + + conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE); + BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE); +} + +void +intnum_cleanup(void) +{ + BitVector_Destroy(conv_bv); BitVector_from_Dec_static_Shutdown(); } @@ -62,13 +70,10 @@ intnum_new_dec(char *str, unsigned long lindex) intn->origsize = 0; /* no reliable way to figure this out */ - if (!conv_bv) { - conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE); - BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE); - } if (BitVector_from_Dec_static(conv_bv, (unsigned char *)str) == ErrCode_Ovfl) - Warning(lindex, _("Numeric constant too large for internal format")); + cur_we->warning(WARN_GENERAL, lindex, + N_("Numeric constant too large for internal format")); if (Set_Max(conv_bv) < 32) { intn->type = INTNUM_UL; intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0); @@ -88,12 +93,9 @@ intnum_new_bin(char *str, unsigned long lindex) intn->origsize = (unsigned char)strlen(str); if(intn->origsize > BITVECT_ALLOC_SIZE) - Warning(lindex, _("Numeric constant too large for internal format")); + cur_we->warning(WARN_GENERAL, lindex, + N_("Numeric constant too large for internal format")); - if (!conv_bv) { - conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE); - BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE); - } BitVector_from_Bin(conv_bv, (unsigned char *)str); if (Set_Max(conv_bv) < 32) { intn->type = INTNUM_UL; @@ -114,12 +116,9 @@ intnum_new_oct(char *str, unsigned long lindex) intn->origsize = strlen(str)*3; if(intn->origsize > BITVECT_ALLOC_SIZE) - Warning(lindex, _("Numeric constant too large for internal format")); + cur_we->warning(WARN_GENERAL, lindex, + N_("Numeric constant too large for internal format")); - if (!conv_bv) { - conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE); - BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE); - } BitVector_from_Oct(conv_bv, (unsigned char *)str); if (Set_Max(conv_bv) < 32) { intn->type = INTNUM_UL; @@ -140,12 +139,9 @@ intnum_new_hex(char *str, unsigned long lindex) intn->origsize = strlen(str)*4; if(intn->origsize > BITVECT_ALLOC_SIZE) - Warning(lindex, _("Numeric constant too large for internal format")); + cur_we->warning(WARN_GENERAL, lindex, + N_("Numeric constant too large for internal format")); - if (!conv_bv) { - conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE); - BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE); - } BitVector_from_Hex(conv_bv, (unsigned char *)str); if (Set_Max(conv_bv) < 32) { intn->type = INTNUM_UL; @@ -166,8 +162,8 @@ intnum_new_charconst_nasm(const char *str, unsigned long lindex) size_t len = strlen(str); if (len > 4) - Warning(lindex, - _("character constant too large, ignoring trailing characters")); + cur_we->warning(WARN_GENERAL, lindex, + N_("character constant too large, ignoring trailing characters")); intn->val.ul = 0; intn->type = INTNUM_UL; @@ -273,7 +269,7 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand) } if (!operand && op != EXPR_NEG && op != EXPR_NOT && op != EXPR_LNOT) - InternalError(_("Operation needs an operand")); + cur_we->internal_error(N_("Operation needs an operand")); /* A operation does a bitvector computation if result is allocated. */ switch (op) { @@ -444,7 +440,8 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand) BitVector_Copy(result, op1); break; default: - InternalError(_("invalid operation in intnum calculation")); + cur_we->internal_error( + N_("invalid operation in intnum calculation")); } /* If we were doing a bitvector computation... */ @@ -507,7 +504,7 @@ intnum_get_uint(const intnum *intn) case INTNUM_BV: return BitVector_Chunk_Read(intn->val.bv, 32, 0); default: - InternalError(_("unknown intnum type")); + cur_we->internal_error(N_("unknown intnum type")); /*@notreached@*/ return 0; } @@ -535,7 +532,7 @@ intnum_get_int(const intnum *intn) } else return (long)BitVector_Chunk_Read(intn->val.bv, 32, 0); default: - InternalError(_("unknown intnum type")); + cur_we->internal_error(N_("unknown intnum type")); /*@notreached@*/ return 0; } @@ -560,7 +557,8 @@ intnum_get_sized(const intnum *intn, unsigned char *ptr, size_t size) case INTNUM_BV: buf = BitVector_Block_Read(intn->val.bv, &len); if (len < (unsigned int)size) - InternalError(_("Invalid size specified (too large)")); + cur_we->internal_error( + N_("Invalid size specified (too large)")); memcpy(ptr, buf, size); xfree(buf); break; diff --git a/libyasm/intnum.h b/libyasm/intnum.h index 99f1a105..cd05c737 100644 --- a/libyasm/intnum.h +++ b/libyasm/intnum.h @@ -22,8 +22,9 @@ #ifndef YASM_INTNUM_H #define YASM_INTNUM_H +void intnum_initialize(errwarn *we); /* Clean up internal allocations */ -void intnum_shutdown(void); +void intnum_cleanup(void); /*@only@*/ intnum *intnum_new_dec(char *str, unsigned long lindex); /*@only@*/ intnum *intnum_new_bin(char *str, unsigned long lindex); diff --git a/libyasm/linemgr.c b/libyasm/linemgr.c index 718b01b9..5bdbc7ae 100644 --- a/libyasm/linemgr.c +++ b/libyasm/linemgr.c @@ -93,9 +93,12 @@ yasm_linemgr_set(const char *filename, unsigned long line, } static void -yasm_linemgr_initialize(void) +yasm_linemgr_initialize(/*@exits@*/ + void (*error_func) (const char *file, + unsigned int line, + const char *message)) { - filename_table = HAMT_new(); + filename_table = HAMT_new(error_func); line_index = 1; diff --git a/libyasm/linemgr.h b/libyasm/linemgr.h index 85d474e0..0412df6f 100644 --- a/libyasm/linemgr.h +++ b/libyasm/linemgr.h @@ -24,7 +24,10 @@ struct linemgr { /* Initialize cur_lindex and any manager internal data structures. */ - void (*initialize) (void); + void (*initialize) (/*@exits@*/ + void (*error_func) (const char *file, + unsigned int line, + const char *message)); /* Cleans up any memory allocated by initialize. */ void (*cleanup) (void); diff --git a/libyasm/objfmt.h b/libyasm/objfmt.h index 55f7b9cc..9735ae4e 100644 --- a/libyasm/objfmt.h +++ b/libyasm/objfmt.h @@ -57,7 +57,7 @@ struct objfmt { * provided solely for informational purposes. */ void (*initialize) (const char *in_filename, const char *obj_filename, - dbgfmt *df, arch *a); + dbgfmt *df, arch *a, errwarn *we); /* Write out (post-optimized) sections to the object file. * This function may call symrec functions as necessary (including diff --git a/libyasm/optimizer.h b/libyasm/optimizer.h index 56c90720..44c6a124 100644 --- a/libyasm/optimizer.h +++ b/libyasm/optimizer.h @@ -37,7 +37,7 @@ struct optimizer { * object file. (A failure is indicated by calling ErrorAt() from within * this function). */ - void (*optimize) (sectionhead *sections); + void (*optimize) (sectionhead *sections, errwarn *we); }; #endif diff --git a/libyasm/parser.h b/libyasm/parser.h index 01b0db32..c2e606ff 100644 --- a/libyasm/parser.h +++ b/libyasm/parser.h @@ -51,7 +51,7 @@ struct parser { * (whatever was in the file). */ sectionhead *(*do_parse) (preproc *pp, arch *a, objfmt *of, linemgr *lm, - FILE *f, const char *in_filename); + errwarn *we, FILE *f, const char *in_filename); }; /* Generic functions for all parsers - implemented in src/parser.c */ diff --git a/libyasm/preproc.h b/libyasm/preproc.h index 9b4874bb..96d07cff 100644 --- a/libyasm/preproc.h +++ b/libyasm/preproc.h @@ -38,11 +38,15 @@ struct preproc { * This function also takes the FILE * to the initial starting file and * the filename. */ - void (*initialize) (FILE *f, const char *in_filename); + void (*initialize) (FILE *f, const char *in_filename, linemgr *lm, + errwarn *we); + + /* Cleans up any allocated memory. */ + void (*cleanup) (void); /* Gets more preprocessed source code (up to max_size bytes) into buf. * Note that more than a single line may be returned in buf. */ - size_t (*input) (/*@out@*/ char *buf, size_t max_size, linemgr *lm); + size_t (*input) (/*@out@*/ char *buf, size_t max_size); }; #endif diff --git a/libyasm/section.c b/libyasm/section.c index 430c73bf..a8581137 100644 --- a/libyasm/section.c +++ b/libyasm/section.c @@ -54,6 +54,9 @@ struct section { int res_only; /* allow only resb family of bytecodes? */ bytecodehead bc; /* the bytecodes for the section's contents */ + + /*@exits@*/ void (*error_func) (const char *file, unsigned int line, + const char *message); }; /*@-compdestroy@*/ @@ -82,7 +85,10 @@ sections_initialize(sectionhead *headp, objfmt *of) section * sections_switch_general(sectionhead *headp, const char *name, unsigned long start, int res_only, int *isnew, - unsigned long lindex) + unsigned long lindex, + /*@exits@*/ void (*error_func) (const char *file, + unsigned int line, + const char *message)) { section *s; @@ -113,6 +119,8 @@ sections_switch_general(sectionhead *headp, const char *name, s->opt_flags = 0; s->res_only = res_only; + s->error_func = error_func; + *isnew = 1; return s; } @@ -120,7 +128,10 @@ sections_switch_general(sectionhead *headp, const char *name, /*@-onlytrans@*/ section * -sections_switch_absolute(sectionhead *headp, expr *start) +sections_switch_absolute(sectionhead *headp, expr *start, + /*@exits@*/ void (*error_func) (const char *file, + unsigned int line, + const char *message)) { section *s; @@ -134,6 +145,8 @@ sections_switch_absolute(sectionhead *headp, expr *start) s->opt_flags = 0; s->res_only = 1; + s->error_func = error_func; + return s; } /*@=onlytrans@*/ @@ -164,7 +177,8 @@ section_set_of_data(section *sect, objfmt *of, void *of_data) if (of->section_data_delete) of->section_data_delete(of_data); else - InternalError(_("don't know how to delete objfmt-specific section data")); + sect->error_func(__FILE__, __LINE__, + N_("don't know how to delete objfmt-specific section data")); return; } @@ -174,7 +188,8 @@ section_set_of_data(section *sect, objfmt *of, void *of_data) if (of2->section_data_delete) of2->section_data_delete(sect->data.general.of_data); else - InternalError(_("don't know how to delete objfmt-specific section data")); + sect->error_func(__FILE__, __LINE__, + N_("don't know how to delete objfmt-specific section data")); } /* Assign new of_data */ @@ -285,7 +300,8 @@ section_delete(section *sect) if (of->section_data_delete) of->section_data_delete(sect->data.general.of_data); else - InternalError(_("don't know how to delete objfmt-specific section data")); + sect->error_func(__FILE__, __LINE__, + N_("don't know how to delete objfmt-specific section data")); } } expr_delete(sect->start); diff --git a/libyasm/section.h b/libyasm/section.h index c7f5e954..82536fd7 100644 --- a/libyasm/section.h +++ b/libyasm/section.h @@ -25,14 +25,15 @@ /*@dependent@*/ section *sections_initialize(sectionhead *headp, objfmt *of); /*@dependent@*/ section *sections_switch_general(sectionhead *headp, - const char *name, - unsigned long start, - int res_only, - /*@out@*/ int *isnew, - unsigned long lindex); + const char *name, unsigned long start, int res_only, /*@out@*/ int *isnew, + unsigned long lindex, + /*@exits@*/ void (*error_func) (const char *file, unsigned int line, + const char *message)); /*@dependent@*/ section *sections_switch_absolute(sectionhead *headp, - /*@keep@*/ expr *start); + /*@keep@*/ expr *start, + /*@exits@*/ void (*error_func) (const char *file, unsigned int line, + const char *message)); int section_is_absolute(section *sect); diff --git a/libyasm/symrec.c b/libyasm/symrec.c index fe32457b..80e6f4d4 100644 --- a/libyasm/symrec.c +++ b/libyasm/symrec.c @@ -76,7 +76,7 @@ struct symrec { }; /* The symbol table: a hash array mapped trie (HAMT). */ -static /*@only@*/ /*@null@*/ HAMT *sym_table = NULL; +static /*@only@*/ HAMT *sym_table; /* Linked list of symbols not in the symbol table. */ typedef struct non_table_symrec_s { @@ -85,8 +85,20 @@ typedef struct non_table_symrec_s { } non_table_symrec; typedef /*@reldef@*/ SLIST_HEAD(nontablesymhead_s, non_table_symrec_s) nontablesymhead; -static /*@only@*/ /*@null@*/ nontablesymhead *non_table_syms = NULL; +static /*@only@*/ nontablesymhead *non_table_syms; +static /*@dependent@*/ errwarn *cur_we; + + +void +symrec_initialize(errwarn *we) +{ + cur_we = we; + + sym_table = HAMT_new(cur_we->internal_error_); + non_table_syms = xmalloc(sizeof(nontablesymhead)); + SLIST_INIT(non_table_syms); +} static void symrec_delete_one(/*@only@*/ void *d) @@ -99,7 +111,8 @@ symrec_delete_one(/*@only@*/ void *d) if (sym->of->symrec_data_delete) sym->of->symrec_data_delete(sym->of_data); else - InternalError(_("don't know how to delete objfmt-specific data")); + cur_we->internal_error( + N_("don't know how to delete objfmt-specific data")); } xfree(sym); } @@ -124,9 +137,6 @@ symrec_get_or_new_in_table(/*@only@*/ char *name) symrec *rec = symrec_new_common(name); int replace = 0; - if (!sym_table) - sym_table = HAMT_new(); - rec->status = SYM_NOSTATUS; return HAMT_insert(sym_table, name, rec, &replace, symrec_delete_one); @@ -138,11 +148,6 @@ symrec_get_or_new_not_in_table(/*@only@*/ char *name) non_table_symrec *sym = xmalloc(sizeof(non_table_symrec)); sym->rec = symrec_new_common(name); - if (!non_table_syms) { - non_table_syms = xmalloc(sizeof(nontablesymhead)); - SLIST_INIT(non_table_syms); - } - sym->rec->status = SYM_NOTINTABLE; SLIST_INSERT_HEAD(non_table_syms, sym, link); @@ -169,10 +174,7 @@ symrec_get_or_new(const char *name, int in_table) int symrec_traverse(void *d, int (*func) (symrec *sym, void *d)) { - if (sym_table) - return HAMT_traverse(sym_table, d, (int (*) (void *, void *))func); - else - return 1; + return HAMT_traverse(sym_table, d, (int (*) (void *, void *))func); } symrec * @@ -194,9 +196,9 @@ symrec_define(const char *name, SymType type, int in_table, /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */ if ((rec->status & SYM_DEFINED) || (rec->visibility & (SYM_COMMON | SYM_EXTERN))) { - Error(lindex, - _("duplicate definition of `%s'; first defined on line %lu"), - name, rec->line); + cur_we->error(lindex, + N_("duplicate definition of `%s'; first defined on line %lu"), + name, rec->line); } else { rec->line = lindex; /* set line number of definition */ rec->type = type; @@ -247,9 +249,9 @@ symrec_declare(const char *name, SymVisibility vis, unsigned long lindex) ((rec->visibility & SYM_EXTERN) && (vis == SYM_EXTERN))))) rec->visibility |= vis; else - Error(lindex, - _("duplicate definition of `%s'; first defined on line %lu"), - name, rec->line); + cur_we->error(lindex, + N_("duplicate definition of `%s'; first defined on line %lu"), + name, rec->line); return rec; } @@ -312,7 +314,8 @@ symrec_set_of_data(symrec *sym, objfmt *of, void *of_data) if (sym->of->symrec_data_delete) sym->of->symrec_data_delete(sym->of_data); else - InternalError(_("don't know how to delete objfmt-specific data")); + cur_we->internal_error( + N_("don't know how to delete objfmt-specific data")); } sym->of = of; sym->of_data = of_data; @@ -325,7 +328,8 @@ symrec_parser_finalize_checksym(symrec *sym, /*@unused@*/ /*@null@*/ void *d) /* error if a symbol is used but never defined or extern/common declared */ if ((sym->status & SYM_USED) && !(sym->status & SYM_DEFINED) && !(sym->visibility & (SYM_EXTERN | SYM_COMMON))) { - Error(sym->line, _("undefined symbol `%s' (first use)"), sym->name); + cur_we->error(sym->line, N_("undefined symbol `%s' (first use)"), + sym->name); if (sym->line < firstundef_line) firstundef_line = sym->line; } @@ -339,27 +343,22 @@ symrec_parser_finalize(void) firstundef_line = ULONG_MAX; symrec_traverse(NULL, symrec_parser_finalize_checksym); if (firstundef_line < ULONG_MAX) - Error(firstundef_line, - _(" (Each undefined symbol is reported only once.)")); + cur_we->error(firstundef_line, + N_(" (Each undefined symbol is reported only once.)")); } void -symrec_delete_all(void) +symrec_cleanup(void) { - if (sym_table) { - HAMT_delete(sym_table, symrec_delete_one); - sym_table = NULL; - } - if (non_table_syms) { - while (!SLIST_EMPTY(non_table_syms)) { - non_table_symrec *sym = SLIST_FIRST(non_table_syms); - SLIST_REMOVE_HEAD(non_table_syms, link); - symrec_delete_one(sym->rec); - xfree(sym); - } - xfree(non_table_syms); - non_table_syms = NULL; + HAMT_delete(sym_table, symrec_delete_one); + + while (!SLIST_EMPTY(non_table_syms)) { + non_table_symrec *sym = SLIST_FIRST(non_table_syms); + SLIST_REMOVE_HEAD(non_table_syms, link); + symrec_delete_one(sym->rec); + xfree(sym); } + xfree(non_table_syms); } typedef struct symrec_print_data { diff --git a/libyasm/symrec.h b/libyasm/symrec.h index 47d148e8..b4c8231a 100644 --- a/libyasm/symrec.h +++ b/libyasm/symrec.h @@ -22,6 +22,8 @@ #ifndef YASM_SYMREC_H #define YASM_SYMREC_H +void symrec_initialize(errwarn *we); + /*@dependent@*/ symrec *symrec_use(const char *name, unsigned long lindex); /*@dependent@*/ symrec *symrec_define_equ(const char *name, /*@keep@*/ expr *e, unsigned long lindex); @@ -64,7 +66,7 @@ int /*@alt void@*/ symrec_traverse(/*@null@*/ void *d, void symrec_parser_finalize(void); -void symrec_delete_all(void); +void symrec_cleanup(void); void symrec_print_all(FILE *f, int indent_level); diff --git a/libyasm/tests/floatnum_test.c b/libyasm/tests/floatnum_test.c index 84a4bdad..6972c937 100644 --- a/libyasm/tests/floatnum_test.c +++ b/libyasm/tests/floatnum_test.c @@ -421,6 +421,7 @@ main(void) Suite *s = floatnum_suite(); SRunner *sr = srunner_create(s); BitVector_Boot(); + floatnum_initialize(NULL); srunner_run_all(sr, CRNORMAL); nf = srunner_ntests_failed(sr); srunner_free(sr); diff --git a/libyasm/util.h b/libyasm/util.h index c9d2e2bd..89fa46c8 100644 --- a/libyasm/util.h +++ b/libyasm/util.h @@ -129,6 +129,8 @@ int strncasecmp(const char *s1, const char *s2, size_t n); /*@only@*/ char *xstrdup(const char *str); /* Error-checking memory allocation routines in xmalloc.c. */ +void xalloc_initialize(/*@exits@*/ void (*fatal_func) (int type), + int nomem_fatal_type); /*@only@*/ /*@out@*/ void *xmalloc(size_t size); /*@only@*/ void *xcalloc(size_t nelem, size_t elsize); /*@only@*/ void *xrealloc(/*@only@*/ /*@out@*/ /*@returned@*/ /*@null@*/ diff --git a/libyasm/xmalloc.c b/libyasm/xmalloc.c index c1a38d45..5691f3bf 100644 --- a/libyasm/xmalloc.c +++ b/libyasm/xmalloc.c @@ -22,8 +22,17 @@ #include "util.h" RCSID("$IdPath$"); -#include "errwarn.h" +static /*@exits@*/ void (*fatal_func) (int type); +static int nomem_fatal_type; + + +void +xalloc_initialize(/*@exits@*/ void (*f) (int type), int t) +{ + fatal_func = f; + nomem_fatal_type = t; +} #ifndef WITH_DMALLOC @@ -36,7 +45,7 @@ xmalloc(size_t size) size = 1; newmem = malloc(size); if (!newmem) - Fatal(FATAL_NOMEM); + fatal_func(nomem_fatal_type); return newmem; } @@ -51,7 +60,7 @@ xcalloc(size_t nelem, size_t elsize) newmem = calloc(nelem, elsize); if (!newmem) - Fatal(FATAL_NOMEM); + fatal_func(nomem_fatal_type); return newmem; } @@ -68,7 +77,7 @@ xrealloc(void *oldmem, size_t size) else newmem = realloc(oldmem, size); if (!newmem) - Fatal(FATAL_NOMEM); + fatal_func(nomem_fatal_type); return newmem; } diff --git a/modules/Makefile.inc b/modules/Makefile.inc index 1926b5ae..27ce2791 100644 --- a/modules/Makefile.inc +++ b/modules/Makefile.inc @@ -4,7 +4,6 @@ libyasm_la_SOURCES = \ src/bytecode.c \ src/bytecode.h \ src/bc-int.h \ - src/errwarn.c \ src/errwarn.h \ src/expr.c \ src/expr.h \ @@ -47,6 +46,7 @@ yasm_SOURCES += \ src/parser.c \ src/module.h \ src/module.c \ + src/errwarn.c \ src/linemgr.c diff --git a/modules/arch/x86/x86arch.c b/modules/arch/x86/x86arch.c index 36d3db9f..906434e6 100644 --- a/modules/arch/x86/x86arch.c +++ b/modules/arch/x86/x86arch.c @@ -37,6 +37,19 @@ unsigned char yasm_x86_LTX_mode_bits = 0; +/*@dependent@*/ errwarn *yasm_x86_errwarn; + + +static void +x86_initialize(errwarn *we) +{ + yasm_x86_errwarn = we; +} + +static void +x86_cleanup(void) +{ +} int x86_directive(const char *name, valparamhead *valparams, @@ -53,7 +66,7 @@ x86_directive(const char *name, valparamhead *valparams, (lval = intnum_get_int(intn)) && (lval == 16 || lval == 32)) yasm_x86_LTX_mode_bits = (unsigned char)lval; else - Error(lindex, _("invalid argument to [%s]"), "BITS"); + cur_we->error(lindex, N_("invalid argument to [%s]"), "BITS"); return 0; } else return 1; @@ -79,7 +92,7 @@ x86_get_reg_size(unsigned long reg) case X86_FPUREG: return 10; default: - InternalError(_("unknown register size")); + cur_we->internal_error(N_("unknown register size")); } return 0; } @@ -119,7 +132,7 @@ x86_reg_print(FILE *f, unsigned long reg) fprintf(f, "st%d", (int)(reg&7)); break; default: - InternalError(_("unknown register size")); + cur_we->internal_error(N_("unknown register size")); } } @@ -165,6 +178,8 @@ x86_handle_seg_override(effaddr *ea, unsigned long segreg, arch yasm_x86_LTX_arch = { "x86 (IA-32, x86-64)", "x86", + x86_initialize, + x86_cleanup, { x86_switch_cpu, x86_check_identifier, diff --git a/modules/arch/x86/x86arch.h b/modules/arch/x86/x86arch.h index 4674070b..724e703b 100644 --- a/modules/arch/x86/x86arch.h +++ b/modules/arch/x86/x86arch.h @@ -114,6 +114,8 @@ typedef struct x86_new_jmprel_data { bytecode *x86_bc_new_jmprel(x86_new_jmprel_data *d); extern unsigned char yasm_x86_LTX_mode_bits; +extern /*@dependent@*/ errwarn *yasm_x86_errwarn; +#define cur_we yasm_x86_errwarn void x86_bc_delete(bytecode *bc); void x86_bc_print(FILE *f, int indent_level, const bytecode *bc); diff --git a/modules/arch/x86/x86bc.c b/modules/arch/x86/x86bc.c index 26d76055..5eae04b6 100644 --- a/modules/arch/x86/x86bc.c +++ b/modules/arch/x86/x86bc.c @@ -170,9 +170,11 @@ x86_bc_new_jmprel(x86_new_jmprel_data *d) jmprel->op_sel = d->op_sel; if ((d->op_sel == JR_SHORT_FORCED) && (d->near_op_len == 0)) - Error(d->lindex, _("no SHORT form of that jump instruction exists")); + cur_we->error(d->lindex, + N_("no SHORT form of that jump instruction exists")); if ((d->op_sel == JR_NEAR_FORCED) && (d->short_op_len == 0)) - Error(d->lindex, _("no NEAR form of that jump instruction exists")); + cur_we->error(d->lindex, + N_("no NEAR form of that jump instruction exists")); jmprel->shortop.opcode[0] = d->short_op[0]; jmprel->shortop.opcode[1] = d->short_op[1]; @@ -203,7 +205,8 @@ x86_ea_set_segment(effaddr *ea, unsigned char segment, unsigned long lindex) return; if (segment != 0 && x86_ea->segment != 0) - Warning(lindex, _("multiple segment overrides, using leftmost")); + cur_we->warning(WARN_GENERAL, lindex, + N_("multiple segment overrides, using leftmost")); x86_ea->segment = segment; } @@ -294,7 +297,7 @@ x86_bc_insn_get_ea(bytecode *bc) return NULL; if ((x86_bytecode_type)bc->type != X86_BC_INSN) - InternalError(_("Trying to get EA of non-instruction")); + cur_we->internal_error(N_("Trying to get EA of non-instruction")); return (effaddr *)(((x86_insn *)bc)->ea); } @@ -318,7 +321,8 @@ x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize) jmprel->opersize = opersize; break; default: - InternalError(_("OperSize override applied to non-instruction")); + cur_we->internal_error( + N_("OperSize override applied to non-instruction")); } } @@ -341,7 +345,8 @@ x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize) jmprel->addrsize = addrsize; break; default: - InternalError(_("AddrSize override applied to non-instruction")); + cur_we->internal_error( + N_("AddrSize override applied to non-instruction")); } } @@ -366,11 +371,13 @@ x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix, lockrep_pre = &jmprel->lockrep_pre; break; default: - InternalError(_("LockRep prefix applied to non-instruction")); + cur_we->internal_error( + N_("LockRep prefix applied to non-instruction")); } if (*lockrep_pre != 0) - Warning(lindex, _("multiple LOCK or REP prefixes, using leftmost")); + cur_we->warning(WARN_GENERAL, lindex, + N_("multiple LOCK or REP prefixes, using leftmost")); *lockrep_pre = prefix; } @@ -654,20 +661,21 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save, temp = expr_copy(jmprel->target); num = expr_get_intnum(&temp, calc_bc_dist); if (!num) { - Error(bc->line, - _("short jump target external or out of segment")); + cur_we->error(bc->line, + N_("short jump target external or out of segment")); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } else { rel = intnum_get_int(num); rel -= jmprel->shortop.opcode_len+1; /* does a short form exist? */ if (jmprel->shortop.opcode_len == 0) { - Error(bc->line, _("short jump does not exist")); + cur_we->error(bc->line, + N_("short jump does not exist")); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } /* short displacement must fit in -128 <= rel <= +127 */ if (rel < -128 || rel > 127) { - Error(bc->line, _("short jump out of range")); + cur_we->error(bc->line, N_("short jump out of range")); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } } @@ -678,7 +686,7 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save, jrshort = 0; if (save) { if (jmprel->nearop.opcode_len == 0) { - Error(bc->line, _("near jump does not exist")); + cur_we->error(bc->line, N_("near jump does not exist")); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } } @@ -713,8 +721,8 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save, * it to actually be within short range). */ if (save) { - Error(bc->line, - _("short jump out of range (near jump does not exist)")); + cur_we->error(bc->line, + N_("short jump out of range (near jump does not exist)")); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } jrshort = 1; @@ -730,8 +738,8 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save, jrshort = 0; } else { if (save) { - Error(bc->line, - _("short jump out of range (near jump does not exist)")); + cur_we->error(bc->line, + N_("short jump out of range (near jump does not exist)")); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } jrshort = 1; @@ -780,7 +788,7 @@ x86_bc_resolve(bytecode *bc, int save, const section *sect, default: break; } - InternalError(_("Didn't handle bytecode type in x86 arch")); + cur_we->internal_error(N_("Didn't handle bytecode type in x86 arch")); /*@notreached@*/ return BC_RESOLVE_UNKNOWN_LEN; } @@ -806,7 +814,8 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect, WRITE_8(*bufp, 0x67); if (insn->rex != 0) { if (insn->mode_bits != 64) - InternalError(_("x86: got a REX prefix in non-64-bit mode")); + cur_we->internal_error( + N_("x86: got a REX prefix in non-64-bit mode")); WRITE_8(*bufp, insn->rex); } @@ -820,13 +829,14 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect, if (ea) { if (x86_ea->need_modrm) { if (!x86_ea->valid_modrm) - InternalError(_("invalid Mod/RM in x86 tobytes_insn")); + cur_we->internal_error( + N_("invalid Mod/RM in x86 tobytes_insn")); WRITE_8(*bufp, x86_ea->modrm); } if (x86_ea->need_sib) { if (!x86_ea->valid_sib) - InternalError(_("invalid SIB in x86 tobytes_insn")); + cur_we->internal_error(N_("invalid SIB in x86 tobytes_insn")); WRITE_8(*bufp, x86_ea->sib); } @@ -846,7 +856,7 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect, &eat.valid_modrm, &eat.need_modrm, &eat.sib, &eat.valid_sib, &eat.need_sib, common_calc_bc_dist)) - InternalError(_("checkea failed")); + cur_we->internal_error(N_("checkea failed")); if (ea->disp) { if (output_expr(&ea->disp, bufp, ea->len, *bufp-bufp_orig, @@ -901,7 +911,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp, case JR_SHORT: /* 1 byte relative displacement */ if (jmprel->shortop.opcode_len == 0) - InternalError(_("short jump does not exist")); + cur_we->internal_error(N_("short jump does not exist")); /* Opcode */ for (i=0; ishortop.opcode_len; i++) @@ -916,7 +926,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp, case JR_NEAR: /* 2/4 byte relative displacement (depending on operand size) */ if (jmprel->nearop.opcode_len == 0) { - Error(bc->line, _("near jump does not exist")); + cur_we->error(bc->line, N_("near jump does not exist")); return 1; } @@ -931,7 +941,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp, return 1; break; default: - InternalError(_("unrecognized relative jump op_sel")); + cur_we->internal_error(N_("unrecognized relative jump op_sel")); } return 0; } @@ -961,7 +971,8 @@ x86_intnum_tobytes(const intnum *intn, unsigned char **bufp, if (rel) { long val; if (valsize != 1 && valsize != 2 && valsize != 4) - InternalError(_("tried to do PC-relative offset from invalid sized value")); + cur_we->internal_error( + N_("tried to do PC-relative offset from invalid sized value")); val = intnum_get_uint(intn); val -= bc->len; switch (valsize) { diff --git a/modules/arch/x86/x86expr.c b/modules/arch/x86/x86expr.c index ea022f6d..c6552531 100644 --- a/modules/arch/x86/x86expr.c +++ b/modules/arch/x86/x86expr.c @@ -183,7 +183,7 @@ x86_expr_checkea_distcheck_reg(expr **ep) /* The reg expn *must* be EXPR_ADD at this point. Sanity check. */ if (e->terms[havereg_expr].type != EXPR_EXPR || e->terms[havereg_expr].data.expn->op != EXPR_ADD) - InternalError(_("Register expression not ADD or EXPN")); + cur_we->internal_error(N_("Register expression not ADD or EXPN")); /* Iterate over each term in reg expn */ for (i=0; iterms[havereg_expr].data.expn->numterms; i++) { @@ -282,9 +282,11 @@ x86_expr_checkea_getregusage(expr **ep, /*@null@*/ int *indexreg, void *data, * Sanity check for EXPR_INT. */ if (e->terms[i].data.expn->terms[0].type != EXPR_REG) - InternalError(_("Register not found in reg expn")); + cur_we->internal_error( + N_("Register not found in reg expn")); if (e->terms[i].data.expn->terms[1].type != EXPR_INT) - InternalError(_("Non-integer value in reg expn")); + cur_we->internal_error( + N_("Non-integer value in reg expn")); reg = get_reg(&e->terms[i].data.expn->terms[0], data); if (!reg) return 0; @@ -378,7 +380,7 @@ x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg, */ if (!intnum_check_size(intn, (size_t)wordsize, 0) && !intnum_check_size(intn, 1, 1)) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } @@ -442,8 +444,8 @@ x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg, case 2: case 4: if (wordsize != *displen) { - Error(e->line, - _("invalid effective address (displacement size)")); + cur_we->error(e->line, + N_("invalid effective address (displacement size)")); return 0; } /* TODO: Add optional warning here about 2/4 not being valid @@ -455,7 +457,7 @@ x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg, break; default: /* we shouldn't ever get any other size! */ - InternalError(_("strange EA displacement size")); + cur_we->internal_error(N_("strange EA displacement size")); } return 1; @@ -535,7 +537,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, calc_bc_dist)) { case 0: e = *ep; - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; case 1: return 1; @@ -557,7 +559,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, */ for (i=0; i<8; i++) { if (reg32mult[i] < 0) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } if (i != indexreg && reg32mult[i] == 1 && basereg == REG32_NONE) @@ -598,7 +600,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, */ for (i=0; i<8; i++) if (i != basereg && i != indexreg && reg32mult[i] != 0) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } @@ -606,7 +608,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, if (indexreg != REG32_NONE && reg32mult[indexreg] != 1 && reg32mult[indexreg] != 2 && reg32mult[indexreg] != 4 && reg32mult[indexreg] != 8) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } @@ -616,7 +618,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, * legal. */ if (reg32mult[REG32_ESP] > 1 || basereg == REG32_ESP) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } /* If mult==1 and basereg is not ESP, swap indexreg w/basereg. */ @@ -720,7 +722,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, calc_bc_dist)) { case 0: e = *ep; - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; case 1: return 1; @@ -732,7 +734,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, /* reg multipliers not 0 or 1 are illegal. */ if (reg16mult.bx & ~1 || reg16mult.si & ~1 || reg16mult.di & ~1 || reg16mult.bp & ~1) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } @@ -748,7 +750,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, /* Check the modrm value for invalid combinations. */ if (modrm16[havereg] & 0070) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } @@ -776,17 +778,17 @@ x86_floatnum_tobytes(const floatnum *flt, unsigned char **bufp, int fltret; if (!floatnum_check_size(flt, (size_t)valsize)) { - Error(e->line, _("invalid floating point constant size")); + cur_we->error(e->line, N_("invalid floating point constant size")); return 1; } fltret = floatnum_get_sized(flt, *bufp, (size_t)valsize); if (fltret < 0) { - Error(e->line, _("underflow in floating point expression")); + cur_we->error(e->line, N_("underflow in floating point expression")); return 1; } if (fltret > 0) { - Error(e->line, _("overflow in floating point expression")); + cur_we->error(e->line, N_("overflow in floating point expression")); return 1; } *bufp += valsize; diff --git a/modules/arch/x86/x86id.re b/modules/arch/x86/x86id.re index 4cee4eed..b57ea32a 100644 --- a/modules/arch/x86/x86id.re +++ b/modules/arch/x86/x86id.re @@ -1322,7 +1322,7 @@ x86_new_jmprel(const unsigned long data[4], int num_operands, /* We know the target is in operand 0, but sanity check for Imm. */ op = ops_first(operands); if (op->type != INSN_OPERAND_IMM) - InternalError(_("invalid operand conversion")); + cur_we->internal_error(N_("invalid operand conversion")); d.target = expr_new(EXPR_SUB, ExprExpr(op->data.val), ExprSym(symrec_define_label("$", cur_section, prev_bc, 0, lindex)), lindex); @@ -1556,7 +1556,7 @@ x86_new_insn(const unsigned long data[4], int num_operands, mismatch = 1; break; default: - InternalError(_("invalid operand type")); + cur_we->internal_error(N_("invalid operand type")); } if (mismatch) @@ -1606,7 +1606,7 @@ x86_new_insn(const unsigned long data[4], int num_operands, mismatch = 1; break; default: - InternalError(_("invalid target modifier type")); + cur_we->internal_error(N_("invalid target modifier type")); } } @@ -1618,7 +1618,8 @@ x86_new_insn(const unsigned long data[4], int num_operands, if (!found) { /* Didn't find a matching one */ - Error(lindex, _("invalid combination of opcode and operands")); + cur_we->error(lindex, + N_("invalid combination of opcode and operands")); return NULL; } @@ -1630,23 +1631,25 @@ x86_new_insn(const unsigned long data[4], int num_operands, case MOD_ExtErr: switch ((info->modifiers & MOD_ExtIndex_MASK)>>MOD_ExtIndex_SHIFT) { case 0: - Error(lindex, _("mismatch in operand sizes")); + cur_we->error(lindex, N_("mismatch in operand sizes")); break; case 1: - Error(lindex, _("operand size not specified")); + cur_we->error(lindex, N_("operand size not specified")); break; default: - InternalError(_("unrecognized x86 ext mod index")); + cur_we->internal_error( + N_("unrecognized x86 ext mod index")); } return NULL; /* It was an error */ case MOD_ExtWarn: switch ((info->modifiers & MOD_ExtIndex_MASK)>>MOD_ExtIndex_SHIFT) { default: - InternalError(_("unrecognized x86 ext mod index")); + cur_we->internal_error( + N_("unrecognized x86 ext mod index")); } break; default: - InternalError(_("unrecognized x86 extended modifier")); + cur_we->internal_error(N_("unrecognized x86 extended modifier")); } /* Shortcut to JmpRel */ @@ -1726,7 +1729,8 @@ x86_new_insn(const unsigned long data[4], int num_operands, d.ea = x86_ea_new_reg((unsigned char)op->data.reg); break; case INSN_OPERAND_SEGREG: - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); case INSN_OPERAND_MEMORY: d.ea = op->data.ea; if ((info->operands[i] & OPT_MASK) == OPT_MemOffs) @@ -1746,7 +1750,8 @@ x86_new_insn(const unsigned long data[4], int num_operands, d.im_len = size_lookup[(info->operands[i] & OPS_MASK)>>OPS_SHIFT]; } else - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); break; case OPA_SImm: if (op->type == INSN_OPERAND_IMM) { @@ -1755,36 +1760,41 @@ x86_new_insn(const unsigned long data[4], int num_operands, OPS_MASK)>>OPS_SHIFT]; d.im_sign = 1; } else - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); break; case OPA_Spare: if (op->type == INSN_OPERAND_REG || op->type == INSN_OPERAND_SEGREG) d.spare = (unsigned char)(op->data.reg&7); else - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); break; case OPA_Op0Add: if (op->type == INSN_OPERAND_REG) d.op[0] += (unsigned char)(op->data.reg&7); else - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); break; case OPA_Op1Add: if (op->type == INSN_OPERAND_REG) d.op[1] += (unsigned char)(op->data.reg&7); else - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); break; case OPA_SpareEA: if (op->type == INSN_OPERAND_REG) { d.spare = (unsigned char)(op->data.reg&7); d.ea = x86_ea_new_reg((unsigned char)op->data.reg); } else - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); break; default: - InternalError(_("unknown operand action")); + cur_we->internal_error(N_("unknown operand action")); } switch (info->operands[i] & OPAP_MASK) { @@ -1797,7 +1807,8 @@ x86_new_insn(const unsigned long data[4], int num_operands, d.signext_imm8_op = 1; break; default: - InternalError(_("unknown operand postponed action")); + cur_we->internal_error( + N_("unknown operand postponed action")); } } } @@ -1953,11 +1964,13 @@ x86_switch_cpu(const char *id, unsigned long lindex) /* catchalls */ [\001-\377]+ { - Warning(lindex, _("unrecognized CPU identifier `%s'"), id); + cur_we->warning(WARN_GENERAL, lindex, + N_("unrecognized CPU identifier `%s'"), id); return; } [\000] { - Warning(lindex, _("unrecognized CPU identifier `%s'"), id); + cur_we->warning(WARN_GENERAL, lindex, + N_("unrecognized CPU identifier `%s'"), id); return; } */ diff --git a/modules/objfmts/bin/bin-objfmt.c b/modules/objfmts/bin/bin-objfmt.c index 1ff0534c..d28bac1c 100644 --- a/modules/objfmts/bin/bin-objfmt.c +++ b/modules/objfmts/bin/bin-objfmt.c @@ -44,14 +44,16 @@ objfmt yasm_bin_LTX_objfmt; static /*@dependent@*/ arch *cur_arch; +static /*@dependent@*/ errwarn *cur_we; static void bin_objfmt_initialize(/*@unused@*/ const char *in_filename, /*@unused@*/ const char *obj_filename, - /*@unused@*/ dbgfmt *df, arch *a) + /*@unused@*/ dbgfmt *df, arch *a, errwarn *we) { cur_arch = a; + cur_we = we; } /* Aligns sect to either its specified alignment (in its objfmt-specific data) @@ -163,13 +165,14 @@ bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize, /* Check for complex float expressions */ if (expr_contains(*ep, EXPR_FLOAT)) { - Error((*ep)->line, _("floating point expression too complex")); + cur_we->error((*ep)->line, + N_("floating point expression too complex")); return 1; } /* Couldn't output, assume it contains an external reference. */ - Error((*ep)->line, - _("binary object format does not support external references")); + cur_we->error((*ep)->line, + N_("binary object format does not support external references")); return 1; } @@ -198,8 +201,8 @@ bin_objfmt_output_bytecode(bytecode *bc, /*@null@*/ void *d) /* Warn that gaps are converted to 0 and write out the 0's. */ if (gap) { unsigned long left; - Warning(bc->line, - _("uninitialized space declared in code/data section: zeroing")); + cur_we->warning(WARN_GENERAL, bc->line, + N_("uninitialized space declared in code/data section: zeroing")); /* Write out in chunks */ memset(info->buf, 0, REGULAR_OUTBUF_SIZE); left = multiple*size; @@ -241,7 +244,7 @@ bin_objfmt_output(FILE *f, sectionhead *sections) bss = sections_find_general(sections, ".bss"); if (!text) - InternalError(_("No `.text' section in bin objfmt output")); + cur_we->internal_error(N_("No `.text' section in bin objfmt output")); /* First determine the actual starting offsets for .data and .bss. * As the order in the file is .text -> .data -> .bss (not present), @@ -255,7 +258,8 @@ bin_objfmt_output(FILE *f, sectionhead *sections) assert(startexpr != NULL); startnum = expr_get_intnum(&startexpr, NULL); if (!startnum) - InternalError(_("Complex expr for start in bin objfmt output")); + cur_we->internal_error( + N_("Complex expr for start in bin objfmt output")); start = intnum_get_uint(startnum); expr_delete(startexpr); textstart = start; @@ -340,7 +344,8 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, resonly = 1; } else { /* other section names not recognized. */ - Error(lindex, _("segment name `%s' not recognized"), sectname); + cur_we->error(lindex, N_("segment name `%s' not recognized"), + sectname); return NULL; } @@ -351,16 +356,17 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, unsigned long bitcnt; if (strcmp(sectname, ".text") == 0) { - Error(lindex, - _("cannot specify an alignment to the `%s' section"), - sectname); + cur_we->error(lindex, + N_("cannot specify an alignment to the `%s' section"), + sectname); return NULL; } align = expr_get_intnum(&vp->param, NULL); if (!align) { - Error(lindex, _("argument to `%s' is not a power of two"), - vp->val); + cur_we->error(lindex, + N_("argument to `%s' is not a power of two"), + vp->val); return NULL; } alignval = intnum_get_uint(align); @@ -370,8 +376,9 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, */ BitCount(bitcnt, alignval); if (bitcnt > 1) { - Error(lindex, _("argument to `%s' is not a power of two"), - vp->val); + cur_we->error(lindex, + N_("argument to `%s' is not a power of two"), + vp->val); return NULL; } @@ -380,7 +387,8 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, } retval = sections_switch_general(headp, sectname, start, resonly, - &isnew, lindex); + &isnew, lindex, + cur_we->internal_error_); if (isnew) { if (have_alignval) { @@ -391,8 +399,8 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, symrec_define_label(sectname, retval, (bytecode *)NULL, 1, lindex); } else if (have_alignval) - Warning(lindex, - _("alignment value ignored on section redeclaration")); + cur_we->warning(WARN_GENERAL, lindex, + N_("alignment value ignored on section redeclaration")); return retval; } else @@ -411,7 +419,8 @@ bin_objfmt_common_declare(/*@unused@*/ symrec *sym, /*@only@*/ expr *size, valparamhead *objext_valparams, unsigned long lindex) { expr_delete(size); - Error(lindex, _("binary object format does not support common variables")); + cur_we->error(lindex, + N_("binary object format does not support common variables")); } static int @@ -428,20 +437,21 @@ bin_objfmt_directive(const char *name, valparamhead *valparams, /* ORG takes just a simple integer as param */ vp = vps_first(valparams); if (vp->val) { - Error(lindex, _("argument to ORG should be numeric")); + cur_we->error(lindex, N_("argument to ORG should be numeric")); return 0; } else if (vp->param) start = expr_get_intnum(&vp->param, NULL); if (!start) { - Error(lindex, _("argument to ORG should be numeric")); + cur_we->error(lindex, N_("argument to ORG should be numeric")); return 0; } /* ORG changes the start of the .text section */ sect = sections_find_general(headp, ".text"); if (!sect) - InternalError(_("bin objfmt: .text section does not exist before ORG is called?")); + cur_we->internal_error( + N_("bin objfmt: .text section does not exist before ORG is called?")); section_set_start(sect, intnum_get_uint(start), lindex); return 0; /* directive recognized */ diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c index db6d3075..c7c28432 100644 --- a/modules/objfmts/coff/coff-objfmt.c +++ b/modules/objfmts/coff/coff-objfmt.c @@ -158,6 +158,7 @@ static coff_symtab_head coff_symtab; /* symbol table of indexed syms */ objfmt yasm_coff_LTX_objfmt; static /*@dependent@*/ arch *cur_arch; +static /*@dependent@*/ errwarn *cur_we; static /*@dependent@*/ coff_symtab_entry * @@ -170,7 +171,7 @@ coff_objfmt_symtab_append(symrec *sym, coff_symrec_sclass sclass, coff_symtab_entry *entry; if (STAILQ_EMPTY(&coff_symtab)) - InternalError(_("empty COFF symbol table")); + cur_we->internal_error(N_("empty COFF symbol table")); entry = STAILQ_LAST(&coff_symtab, coff_symtab_entry, link); sym_data_prev = symrec_get_of_data(entry->sym); assert(sym_data_prev != NULL); @@ -194,13 +195,14 @@ coff_objfmt_symtab_append(symrec *sym, coff_symrec_sclass sclass, static void coff_objfmt_initialize(const char *in_filename, /*@unused@*/ const char *obj_filename, - /*@unused@*/ dbgfmt *df, arch *a) + /*@unused@*/ dbgfmt *df, arch *a, errwarn *we) { symrec *filesym; coff_symrec_data *data; coff_symtab_entry *entry; cur_arch = a; + cur_we = we; coff_objfmt_parse_scnum = 1; /* section numbering starts at 1 */ STAILQ_INIT(&coff_symtab); @@ -273,7 +275,7 @@ coff_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize, SymVisibility vis; if (valsize != 4) { - Error((*ep)->line, _("coff: invalid relocation size")); + cur_we->error((*ep)->line, N_("coff: invalid relocation size")); return 1; } @@ -326,11 +328,12 @@ coff_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize, /* Check for complex float expressions */ if (expr_contains(*ep, EXPR_FLOAT)) { - Error((*ep)->line, _("floating point expression too complex")); + cur_we->error((*ep)->line, + N_("floating point expression too complex")); return 1; } - Error((*ep)->line, _("coff: relocation too complex")); + cur_we->error((*ep)->line, N_("coff: relocation too complex")); return 1; } @@ -361,8 +364,8 @@ coff_objfmt_output_bytecode(bytecode *bc, /*@null@*/ void *d) /* Warn that gaps are converted to 0 and write out the 0's. */ if (gap) { unsigned long left; - Warning(bc->line, - _("uninitialized space declared in code/data section: zeroing")); + cur_we->warning(WARN_GENERAL, bc->line, + N_("uninitialized space declared in code/data section: zeroing")); /* Write out in chunks */ memset(info->buf, 0, REGULAR_OUTBUF_SIZE); left = multiple*size; @@ -414,7 +417,7 @@ coff_objfmt_output_section(section *sect, /*@null@*/ void *d) } else { pos = ftell(info->f); if (pos == -1) { - ErrorNow(_("could not get file position on output file")); + cur_we->error(0, N_("could not get file position on output file")); return 1; } @@ -437,7 +440,7 @@ coff_objfmt_output_section(section *sect, /*@null@*/ void *d) pos = ftell(info->f); if (pos == -1) { - ErrorNow(_("could not get file position on output file")); + cur_we->error(0, N_("could not get file position on output file")); return 1; } csd->relptr = (unsigned long)pos; @@ -448,7 +451,8 @@ coff_objfmt_output_section(section *sect, /*@null@*/ void *d) csymd = symrec_get_of_data(reloc->sym); if (!csymd) - InternalError(_("coff: no symbol data for relocated symbol")); + cur_we->internal_error( + N_("coff: no symbol data for relocated symbol")); WRITE_32_L(localbuf, reloc->addr); /* address of relocation */ WRITE_32_L(localbuf, csymd->index); /* relocated symbol */ @@ -487,8 +491,9 @@ coff_objfmt_output_secthead(section *sect, /*@null@*/ void *d) WRITE_32_L(localbuf, csd->relptr); /* file ptr to relocs */ WRITE_32_L(localbuf, 0); /* file ptr to line nums */ if (csd->nreloc >= 64*1024) { - WarningNow(_("too many relocations in section `%s'"), - section_get_name(sect)); + cur_we->warning(WARN_GENERAL, 0, + N_("too many relocations in section `%s'"), + section_get_name(sect)); WRITE_16_L(localbuf, 0xFFFF); /* max out */ } else WRITE_16_L(localbuf, csd->nreloc); /* number of relocation entries */ @@ -515,7 +520,7 @@ coff_objfmt_output(FILE *f, sectionhead *sections) /* Allocate space for headers by seeking forward */ if (fseek(f, 20+40*(coff_objfmt_parse_scnum-1), SEEK_SET) < 0) { - ErrorNow(_("could not seek on output file")); + cur_we->error(0, N_("could not seek on output file")); return; } @@ -537,7 +542,7 @@ coff_objfmt_output(FILE *f, sectionhead *sections) /* Symbol table */ pos = ftell(f); if (pos == -1) { - ErrorNow(_("could not get file position on output file")); + cur_we->error(0, N_("could not get file position on output file")); return; } symtab_pos = (unsigned long)pos; @@ -556,7 +561,8 @@ coff_objfmt_output(FILE *f, sectionhead *sections) /* Get symrec's of_data (needed for storage class) */ csymd = symrec_get_of_data(entry->sym); if (!csymd) - InternalError(_("coff: expected sym data to be present")); + cur_we->internal_error( + N_("coff: expected sym data to be present")); /* Look at symrec for value/scnum/etc. */ if (symrec_get_label(entry->sym, §, &precbc)) { @@ -580,8 +586,8 @@ coff_objfmt_output(FILE *f, sectionhead *sections) const intnum *intn; intn = expr_get_intnum(&csymd->size, common_calc_bc_dist); if (!intn) - Error(csymd->size->line, - _("COMMON data size not an integer expression")); + cur_we->error(csymd->size->line, + N_("COMMON data size not an integer expression")); else value = intnum_get_uint(intn); scnum = 0; @@ -627,7 +633,8 @@ coff_objfmt_output(FILE *f, sectionhead *sections) strncpy((char *)localbuf, entry->aux[0].fname, 14); break; default: - InternalError(_("coff: unrecognized aux symtab type")); + cur_we->internal_error( + N_("coff: unrecognized aux symtab type")); } fwrite(info.buf, 18, 1, f); symtab_count++; @@ -659,7 +666,7 @@ coff_objfmt_output(FILE *f, sectionhead *sections) /* Write headers */ if (fseek(f, 0, SEEK_SET) < 0) { - ErrorNow(_("could not seek on output file")); + cur_we->error(0, N_("could not seek on output file")); return; } @@ -713,8 +720,8 @@ coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, sectname = vp->val; if (strlen(sectname) > 8) { - Warning(lindex, - _("COFF section names limited to 8 characters: truncating")); + cur_we->warning(WARN_GENERAL, lindex, + N_("COFF section names limited to 8 characters: truncating")); sectname[8] = '\0'; } @@ -742,7 +749,7 @@ coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, } retval = sections_switch_general(headp, sectname, 0, resonly, &isnew, - lindex); + lindex, cur_we->internal_error_); if (isnew) { coff_section_data *data; @@ -765,7 +772,8 @@ coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, COFF_SYMTAB_AUX_SECT); data->sym = sym; } else if (flags_override) - Warning(lindex, _("section flags ignored on section redeclaration")); + cur_we->warning(WARN_GENERAL, lindex, + N_("section flags ignored on section redeclaration")); return retval; } diff --git a/modules/objfmts/dbg/dbg-objfmt.c b/modules/objfmts/dbg/dbg-objfmt.c index 3b10a442..5f2233ab 100644 --- a/modules/objfmts/dbg/dbg-objfmt.c +++ b/modules/objfmts/dbg/dbg-objfmt.c @@ -46,14 +46,17 @@ objfmt yasm_dbg_LTX_objfmt; */ static FILE *dbg_objfmt_file; +static /*@dependent@*/ errwarn *cur_we; static void dbg_objfmt_initialize(const char *in_filename, const char *obj_filename, - dbgfmt *df, arch *a) + dbgfmt *df, arch *a, errwarn *we) { + cur_we = we; + dbg_objfmt_file = fopen(obj_filename, "wt"); if (!dbg_objfmt_file) { - ErrorNow(_("could not open file `%s'"), obj_filename); + fprintf(stderr, N_("could not open file `%s'"), obj_filename); return; } fprintf(dbg_objfmt_file, @@ -95,7 +98,7 @@ dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, if ((vp = vps_first(valparams)) && !vp->param && vp->val != NULL) { retval = sections_switch_general(headp, vp->val, 200, 0, &isnew, - lindex); + lindex, cur_we->internal_error_); if (isnew) { fprintf(dbg_objfmt_file, "(new) "); symrec_define_label(vp->val, retval, (bytecode *)NULL, 1, lindex); diff --git a/modules/optimizers/basic/basic-optimizer.c b/modules/optimizers/basic/basic-optimizer.c index 5c654b7d..1b87423c 100644 --- a/modules/optimizers/basic/basic-optimizer.c +++ b/modules/optimizers/basic/basic-optimizer.c @@ -43,6 +43,8 @@ #define BCFLAG_INPROGRESS (1UL<<0) #define BCFLAG_DONE (1UL<<1) +static /*@dependent@*/ errwarn *cur_we; + static int basic_optimize_section_1(section *sect, /*@unused@*/ /*@null@*/ void *d); @@ -129,7 +131,7 @@ basic_optimize_bytecode_1(/*@observer@*/ bytecode *bc, void *d) bcr_retval = bc_resolve(bc, 0, data->sect, basic_optimize_calc_bc_dist_1); if (bcr_retval & BC_RESOLVE_UNKNOWN_LEN) { if (!(bcr_retval & BC_RESOLVE_ERROR)) - Error(bc->line, _("circular reference detected.")); + cur_we->error(bc->line, N_("circular reference detected.")); data->saw_unknown = -1; return 0; } @@ -181,7 +183,7 @@ basic_optimize_bytecode_2(/*@observer@*/ bytecode *bc, /*@null@*/ void *d) assert(data != NULL); if (bc->opt_flags != BCFLAG_DONE) - InternalError(_("Optimizer pass 1 missed a bytecode!")); + cur_we->internal_error(N_("Optimizer pass 1 missed a bytecode!")); if (!data->precbc) bc->offset = 0; @@ -203,17 +205,19 @@ basic_optimize_section_2(section *sect, /*@unused@*/ /*@null@*/ void *d) data.sect = sect; if (section_get_opt_flags(sect) != SECTFLAG_DONE) - InternalError(_("Optimizer pass 1 missed a section!")); + cur_we->internal_error(N_("Optimizer pass 1 missed a section!")); return bcs_traverse(section_get_bytecodes(sect), &data, basic_optimize_bytecode_2); } static void -basic_optimize(sectionhead *sections) +basic_optimize(sectionhead *sections, errwarn *we) { int saw_unknown = 0; + cur_we = we; + /* Optimization process: (essentially NASM's pass 1) * Determine the size of all bytecodes. * Forward references are /not/ resolved (only backward references are diff --git a/modules/parsers/nasm/Makefile.inc b/modules/parsers/nasm/Makefile.inc index 7cfd1954..80df154d 100644 --- a/modules/parsers/nasm/Makefile.inc +++ b/modules/parsers/nasm/Makefile.inc @@ -3,6 +3,7 @@ lib_LTLIBRARIES += yasm-nasm.la yasm_nasm_la_SOURCES = \ + src/parsers/nasm/nasm-parser.h \ src/parsers/nasm/nasm-parser.c \ src/parsers/nasm/nasm-defs.h \ src/parsers/nasm/nasm-bison.y \ diff --git a/modules/parsers/nasm/nasm-bison.y b/modules/parsers/nasm/nasm-bison.y index 996ef574..c8e41db3 100644 --- a/modules/parsers/nasm/nasm-bison.y +++ b/modules/parsers/nasm/nasm-bison.y @@ -42,32 +42,14 @@ RCSID("$IdPath$"); #include "arch.h" +#include "src/parsers/nasm/nasm-parser.h" #include "src/parsers/nasm/nasm-defs.h" -void init_table(void); -extern int nasm_parser_lex(void); -extern void nasm_parser_set_directive_state(void); -void nasm_parser_error(const char *); -static void nasm_parser_directive(const char *name, - valparamhead *valparams, +static void nasm_parser_error(const char *); +static void nasm_parser_directive(const char *name, valparamhead *valparams, /*@null@*/ valparamhead *objext_valparams); -extern objfmt *nasm_parser_objfmt; -extern sectionhead nasm_parser_sections; -extern section *nasm_parser_cur_section; -extern char *nasm_parser_locallabel_base; -extern size_t nasm_parser_locallabel_base_len; -extern /*@dependent@*/ arch *nasm_parser_arch; -extern /*@dependent@*/ objfmt *nasm_parser_objfmt; -extern /*@dependent@*/ linemgr *nasm_parser_linemgr; - -#define p_line_index (nasm_parser_linemgr->get_current()) - -#define p_expr_new_tree(l,o,r) expr_new_tree(l,o,r,p_line_index) -#define p_expr_new_branch(o,r) expr_new_branch(o,r,p_line_index) -#define p_expr_new_ident(r) expr_new_ident(r,p_line_index) - static /*@null@*/ bytecode *nasm_parser_prev_bc = (bytecode *)NULL; static bytecode *nasm_parser_temp_bc; @@ -162,8 +144,8 @@ line: '\n' { $$ = (bytecode *)NULL; } $$ = (bytecode *)NULL; } | error '\n' { - Error(p_line_index, - _("label or instruction expected at start of line")); + cur_we->error(cur_lindex, + N_("label or instruction expected at start of line")); $$ = (bytecode *)NULL; yyerrok; } @@ -175,7 +157,7 @@ lineexp: exp | label exp { $$ = $2; } | label TIMES expr exp { $$ = $4; bc_set_multiple($$, $3); } | label_id_equ EQU expr { - symrec_define_equ($1, $3, p_line_index); + symrec_define_equ($1, $3, cur_lindex); xfree($1); $$ = (bytecode *)NULL; } @@ -183,47 +165,45 @@ lineexp: exp exp: instr | DECLARE_DATA datavals { - $$ = bc_new_data(&$2, $1, p_line_index); + $$ = bc_new_data(&$2, $1, cur_lindex); } | RESERVE_SPACE expr { - $$ = bc_new_reserve($2, $1, p_line_index); + $$ = bc_new_reserve($2, $1, cur_lindex); } | INCBIN STRING { - $$ = bc_new_incbin($2, NULL, NULL, p_line_index); + $$ = bc_new_incbin($2, NULL, NULL, cur_lindex); } | INCBIN STRING ',' expr { - $$ = bc_new_incbin($2, $4, NULL, p_line_index); + $$ = bc_new_incbin($2, $4, NULL, cur_lindex); } | INCBIN STRING ',' expr ',' expr { - $$ = bc_new_incbin($2, $4, $6, p_line_index); + $$ = bc_new_incbin($2, $4, $6, cur_lindex); } ; instr: INSN { $$ = nasm_parser_arch->parse.new_insn($1, 0, NULL, nasm_parser_cur_section, - nasm_parser_prev_bc, - p_line_index); + nasm_parser_prev_bc, cur_lindex); } | INSN operands { $$ = nasm_parser_arch->parse.new_insn($1, $2.num_operands, &$2.operands, nasm_parser_cur_section, - nasm_parser_prev_bc, - p_line_index); + nasm_parser_prev_bc, cur_lindex); ops_delete(&$2.operands, 0); } | INSN error { - Error(p_line_index, _("expression syntax error")); + cur_we->error(cur_lindex, N_("expression syntax error")); $$ = NULL; } | PREFIX instr { $$ = $2; - nasm_parser_arch->parse.handle_prefix($$, $1, p_line_index); + nasm_parser_arch->parse.handle_prefix($$, $1, cur_lindex); } | SEGREG instr { $$ = $2; - nasm_parser_arch->parse.handle_seg_prefix($$, $1[0], p_line_index); + nasm_parser_arch->parse.handle_seg_prefix($$, $1[0], cur_lindex); } ; @@ -234,19 +214,19 @@ datavals: dataval { dvs_initialize(&$$); dvs_append(&$$, $1); } dataval: dvexpr { $$ = dv_new_expr($1); } | STRING { $$ = dv_new_string($1); } | error { - Error(p_line_index, _("expression syntax error")); + cur_we->error(cur_lindex, N_("expression syntax error")); $$ = (dataval *)NULL; } ; label: label_id { symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc, - 1, p_line_index); + 1, cur_lindex); xfree($1); } | label_id ':' { symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc, - 1, p_line_index); + 1, cur_lindex); xfree($1); } ; @@ -274,7 +254,7 @@ directive: DIRECTIVE_NAME directive_val { xfree($1); } | DIRECTIVE_NAME error { - Error(p_line_index, _("invalid arguments to [%s]"), $1); + cur_we->error(cur_lindex, N_("invalid arguments to [%s]"), $1); xfree($1); } ; @@ -318,7 +298,7 @@ memaddr: expr { } | SEGREG ':' memaddr { $$ = $3; - nasm_parser_arch->parse.handle_seg_override($$, $1[0], p_line_index); + nasm_parser_arch->parse.handle_seg_override($$, $1[0], cur_lindex); } | BYTE memaddr { $$ = $2; ea_set_len($$, 1); } | WORD memaddr { $$ = $2; ea_set_len($$, 2); } @@ -346,7 +326,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } $$ = $2; if ($$->type == INSN_OPERAND_REG && nasm_parser_arch->get_reg_size($$->data.reg) != 1) - Error(p_line_index, _("cannot override register size")); + cur_we->error(cur_lindex, N_("cannot override register size")); else $$->size = 1; } @@ -354,7 +334,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } $$ = $2; if ($$->type == INSN_OPERAND_REG && nasm_parser_arch->get_reg_size($$->data.reg) != 2) - Error(p_line_index, _("cannot override register size")); + cur_we->error(cur_lindex, N_("cannot override register size")); else $$->size = 2; } @@ -362,7 +342,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } $$ = $2; if ($$->type == INSN_OPERAND_REG && nasm_parser_arch->get_reg_size($$->data.reg) != 4) - Error(p_line_index, _("cannot override register size")); + cur_we->error(cur_lindex, N_("cannot override register size")); else $$->size = 4; } @@ -370,7 +350,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } $$ = $2; if ($$->type == INSN_OPERAND_REG && nasm_parser_arch->get_reg_size($$->data.reg) != 8) - Error(p_line_index, _("cannot override register size")); + cur_we->error(cur_lindex, N_("cannot override register size")); else $$->size = 8; } @@ -378,7 +358,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } $$ = $2; if ($$->type == INSN_OPERAND_REG && nasm_parser_arch->get_reg_size($$->data.reg) != 10) - Error(p_line_index, _("cannot override register size")); + cur_we->error(cur_lindex, N_("cannot override register size")); else $$->size = 10; } @@ -386,7 +366,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } $$ = $2; if ($$->type == INSN_OPERAND_REG && nasm_parser_arch->get_reg_size($$->data.reg) != 16) - Error(p_line_index, _("cannot override register size")); + cur_we->error(cur_lindex, N_("cannot override register size")); else $$->size = 16; } @@ -399,7 +379,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } direxpr: INTNUM { $$ = p_expr_new_ident(ExprInt($1)); } | ID { $$ = p_expr_new_ident(ExprSym(symrec_define_label($1, NULL, NULL, 0, - p_line_index))); + cur_lindex))); xfree($1); } | direxpr '|' direxpr { $$ = p_expr_new_tree($1, EXPR_OR, $3); } @@ -460,7 +440,7 @@ expr: INTNUM { $$ = p_expr_new_ident(ExprInt($1)); } | REG { $$ = p_expr_new_ident(ExprReg($1[0])); } | STRING { $$ = p_expr_new_ident(ExprInt(intnum_new_charconst_nasm($1, - p_line_index))); + cur_lindex))); xfree($1); } | explabel { $$ = p_expr_new_ident(ExprSym($1)); } @@ -495,26 +475,26 @@ expr: INTNUM { $$ = p_expr_new_ident(ExprInt($1)); } ; explabel: ID { - $$ = symrec_use($1, p_line_index); + $$ = symrec_use($1, cur_lindex); xfree($1); } | SPECIAL_ID { - $$ = symrec_use($1, p_line_index); + $$ = symrec_use($1, cur_lindex); xfree($1); } | LOCAL_ID { - $$ = symrec_use($1, p_line_index); + $$ = symrec_use($1, cur_lindex); xfree($1); } | '$' { /* "$" references the current assembly position */ $$ = symrec_define_label("$", nasm_parser_cur_section, - nasm_parser_prev_bc, 0, p_line_index); + nasm_parser_prev_bc, 0, cur_lindex); } | START_SECTION_ID { /* "$$" references the start of the current section */ $$ = symrec_define_label("$$", nasm_parser_cur_section, NULL, 0, - p_line_index); + cur_lindex); } ; @@ -527,7 +507,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams, { valparam *vp, *vp2; symrec *sym; - unsigned long lindex = p_line_index; + unsigned long lindex = cur_lindex; /* Handle (mostly) output-format independent directives here */ if (strcasecmp(name, "extern") == 0) { @@ -538,7 +518,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams, nasm_parser_objfmt->extern_declare(sym, objext_valparams, lindex); } else - Error(lindex, _("invalid argument to [%s]"), "EXTERN"); + cur_we->error(lindex, N_("invalid argument to [%s]"), "EXTERN"); } else if (strcasecmp(name, "global") == 0) { vp = vps_first(valparams); if (vp->val) { @@ -547,14 +527,15 @@ nasm_parser_directive(const char *name, valparamhead *valparams, nasm_parser_objfmt->global_declare(sym, objext_valparams, lindex); } else - Error(lindex, _("invalid argument to [%s]"), "GLOBAL"); + cur_we->error(lindex, N_("invalid argument to [%s]"), "GLOBAL"); } else if (strcasecmp(name, "common") == 0) { vp = vps_first(valparams); if (vp->val) { vp2 = vps_next(vp); if (!vp2 || (!vp2->val && !vp2->param)) - Error(lindex, _("no size specified in %s declaration"), - "COMMON"); + cur_we->error(lindex, + N_("no size specified in %s declaration"), + "COMMON"); else { if (vp2->val) { sym = symrec_declare(vp->val, SYM_COMMON, lindex); @@ -573,7 +554,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams, } } } else - Error(lindex, _("invalid argument to [%s]"), "COMMON"); + cur_we->error(lindex, N_("invalid argument to [%s]"), "COMMON"); } else if (strcasecmp(name, "section") == 0 || strcasecmp(name, "segment") == 0) { section *new_section = @@ -584,17 +565,19 @@ nasm_parser_directive(const char *name, valparamhead *valparams, nasm_parser_cur_section = new_section; nasm_parser_prev_bc = bcs_last(section_get_bytecodes(new_section)); } else - Error(lindex, _("invalid argument to [%s]"), "SECTION"); + cur_we->error(lindex, N_("invalid argument to [%s]"), "SECTION"); } else if (strcasecmp(name, "absolute") == 0) { /* it can be just an ID or a complete expression, so handle both. */ vp = vps_first(valparams); if (vp->val) nasm_parser_cur_section = sections_switch_absolute(&nasm_parser_sections, - p_expr_new_ident(ExprSym(symrec_use(vp->val, lindex)))); + p_expr_new_ident(ExprSym(symrec_use(vp->val, lindex))), + cur_we->internal_error_); else if (vp->param) { nasm_parser_cur_section = - sections_switch_absolute(&nasm_parser_sections, vp->param); + sections_switch_absolute(&nasm_parser_sections, vp->param, + cur_we->internal_error_); vp->param = NULL; } nasm_parser_prev_bc = (bytecode *)NULL; @@ -606,7 +589,8 @@ nasm_parser_directive(const char *name, valparamhead *valparams, const intnum *intcpu; intcpu = expr_get_intnum(&vp->param, NULL); if (!intcpu) - Error(lindex, _("invalid argument to [%s]"), "CPU"); + cur_we->error(lindex, N_("invalid argument to [%s]"), + "CPU"); else { char strcpu[16]; sprintf(strcpu, "%lu", intnum_get_uint(intcpu)); @@ -621,7 +605,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams, ; } else if (nasm_parser_objfmt->directive(name, valparams, objext_valparams, &nasm_parser_sections, lindex)) { - Error(lindex, _("unrecognized directive [%s]"), name); + cur_we->error(lindex, N_("unrecognized directive [%s]"), name); } vps_delete(valparams); @@ -629,9 +613,9 @@ nasm_parser_directive(const char *name, valparamhead *valparams, vps_delete(objext_valparams); } -void +static void nasm_parser_error(const char *s) { - ParserError(p_line_index, s); + cur_we->parser_error(cur_lindex, s); } diff --git a/modules/parsers/nasm/nasm-parser.c b/modules/parsers/nasm/nasm-parser.c index bb78777c..a38a28d1 100644 --- a/modules/parsers/nasm/nasm-parser.c +++ b/modules/parsers/nasm/nasm-parser.c @@ -29,35 +29,36 @@ #include "preproc.h" #include "parser.h" +#include "nasm-parser.h" -extern FILE *nasm_parser_in; -extern int nasm_parser_debug; -extern int nasm_parser_parse(void); -extern void nasm_parser_cleanup(void); - -size_t (*nasm_parser_input) (char *buf, size_t max_size, linemgr *lm); +FILE *nasm_parser_in = NULL; +size_t (*nasm_parser_input) (char *buf, size_t max_size); sectionhead nasm_parser_sections; /*@dependent@*/ section *nasm_parser_cur_section; -extern /*@only@*/ char *nasm_parser_locallabel_base; +/* last "base" label for local (.) labels */ +char *nasm_parser_locallabel_base = (char *)NULL; +size_t nasm_parser_locallabel_base_len = 0; /*@dependent@*/ arch *nasm_parser_arch; /*@dependent@*/ objfmt *nasm_parser_objfmt; /*@dependent@*/ linemgr *nasm_parser_linemgr; +/*@dependent@*/ errwarn *nasm_parser_errwarn; static /*@dependent@*/ sectionhead * -nasm_parser_do_parse(preproc *pp, arch *a, objfmt *of, linemgr *lm, FILE *f, - const char *in_filename) +nasm_parser_do_parse(preproc *pp, arch *a, objfmt *of, linemgr *lm, + errwarn *we, FILE *f, const char *in_filename) /*@globals killed nasm_parser_locallabel_base @*/ { - pp->initialize(f, in_filename); + pp->initialize(f, in_filename, lm, we); nasm_parser_in = f; nasm_parser_input = pp->input; nasm_parser_arch = a; nasm_parser_objfmt = of; nasm_parser_linemgr = lm; + nasm_parser_errwarn = we; /* Initialize section list */ nasm_parser_cur_section = sections_initialize(&nasm_parser_sections, of); diff --git a/modules/parsers/nasm/nasm-parser.h b/modules/parsers/nasm/nasm-parser.h new file mode 100644 index 00000000..f0b63c74 --- /dev/null +++ b/modules/parsers/nasm/nasm-parser.h @@ -0,0 +1,53 @@ +/* $IdPath$ + * NASM-compatible parser header file + * + * Copyright (C) 2002 Peter Johnson + * + * This file is part of YASM. + * + * YASM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * YASM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef YASM_NASM_PARSER_H +#define YASM_NASM_PARSER_H + +int nasm_parser_parse(void); +void nasm_parser_cleanup(void); +int nasm_parser_lex(void); +void nasm_parser_set_directive_state(void); + +extern FILE *nasm_parser_in; +extern int nasm_parser_debug; +extern size_t (*nasm_parser_input) (char *buf, size_t max_size); + +extern sectionhead nasm_parser_sections; +extern /*@dependent@*/ section *nasm_parser_cur_section; + +extern char *nasm_parser_locallabel_base; +extern size_t nasm_parser_locallabel_base_len; + +extern /*@dependent@*/ arch *nasm_parser_arch; +extern /*@dependent@*/ objfmt *nasm_parser_objfmt; +extern /*@dependent@*/ linemgr *nasm_parser_linemgr; +extern /*@dependent@*/ errwarn *nasm_parser_errwarn; + +#define cur_lindex (nasm_parser_linemgr->get_current()) + +#define p_expr_new_tree(l,o,r) expr_new_tree(l,o,r,cur_lindex) +#define p_expr_new_branch(o,r) expr_new_branch(o,r,cur_lindex) +#define p_expr_new_ident(r) expr_new_ident(r,cur_lindex) + +#define cur_we nasm_parser_errwarn + +#endif diff --git a/modules/parsers/nasm/nasm-token.re b/modules/parsers/nasm/nasm-token.re index fc1dd26a..46daee4c 100644 --- a/modules/parsers/nasm/nasm-token.re +++ b/modules/parsers/nasm/nasm-token.re @@ -37,6 +37,7 @@ RCSID("$IdPath$"); #include "arch.h" +#include "src/parsers/nasm/nasm-parser.h" #include "src/parsers/nasm/nasm-defs.h" #include "nasm-bison.h" @@ -59,17 +60,6 @@ RCSID("$IdPath$"); #define TOKLEN (cursor-s.tok) -void nasm_parser_cleanup(void); -void nasm_parser_set_directive_state(void); -int nasm_parser_lex(void); - -extern size_t (*nasm_parser_input) (char *buf, size_t max_size, linemgr *lm); -extern /*@dependent@*/ arch *nasm_parser_arch; -extern /*@dependent@*/ linemgr *nasm_parser_linemgr; - -#define p_line_index (nasm_parser_linemgr->get_current()) - - typedef struct Scanner { YYCTYPE *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof; unsigned int tchar, tline, cline; @@ -77,8 +67,6 @@ typedef struct Scanner { static Scanner s = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 1 }; -FILE *nasm_parser_in = NULL; - static YYCTYPE * fill(YYCTYPE *cursor) { @@ -105,8 +93,7 @@ fill(YYCTYPE *cursor) xfree(s.bot); s.bot = buf; } - if((cnt = nasm_parser_input(s.lim, BSIZE, - nasm_parser_linemgr)) != BSIZE){ + if((cnt = nasm_parser_input(s.lim, BSIZE)) != BSIZE){ s.eof = &s.lim[cnt]; *s.eof++ = '\n'; } s.lim += cnt; @@ -130,10 +117,6 @@ static char *strbuf = (char *)NULL; /* length of strbuf (including terminating NULL character) */ static size_t strbuf_size = 0; -/* last "base" label for local (.) labels */ -char *nasm_parser_locallabel_base = (char *)NULL; -size_t nasm_parser_locallabel_base_len = 0; - static int linechg_numcount; /*!re2c @@ -220,7 +203,7 @@ scan: digit+ { savech = s.tok[TOKLEN]; s.tok[TOKLEN] = '\0'; - yylval.intn = intnum_new_dec(s.tok, p_line_index); + yylval.intn = intnum_new_dec(s.tok, cur_lindex); s.tok[TOKLEN] = savech; RETURN(INTNUM); } @@ -228,21 +211,21 @@ scan: bindigit+ "b" { s.tok[TOKLEN-1] = '\0'; /* strip off 'b' */ - yylval.intn = intnum_new_bin(s.tok, p_line_index); + yylval.intn = intnum_new_bin(s.tok, cur_lindex); RETURN(INTNUM); } /* 777q - octal number */ octdigit+ "q" { s.tok[TOKLEN-1] = '\0'; /* strip off 'q' */ - yylval.intn = intnum_new_oct(s.tok, p_line_index); + yylval.intn = intnum_new_oct(s.tok, cur_lindex); RETURN(INTNUM); } /* 0AAh form of hexidecimal number */ digit hexdigit* "h" { s.tok[TOKLEN-1] = '\0'; /* strip off 'h' */ - yylval.intn = intnum_new_hex(s.tok, p_line_index); + yylval.intn = intnum_new_hex(s.tok, cur_lindex); RETURN(INTNUM); } @@ -252,10 +235,10 @@ scan: s.tok[TOKLEN] = '\0'; if (s.tok[1] == 'x') /* skip 0 and x */ - yylval.intn = intnum_new_hex(s.tok+2, p_line_index); + yylval.intn = intnum_new_hex(s.tok+2, cur_lindex); else /* don't skip 0 */ - yylval.intn = intnum_new_hex(s.tok+1, p_line_index); + yylval.intn = intnum_new_hex(s.tok+1, cur_lindex); s.tok[TOKLEN] = savech; RETURN(INTNUM); } @@ -342,8 +325,9 @@ scan: yylval.str_val = xstrndup(s.tok, TOKLEN); RETURN(ID); } else if (!nasm_parser_locallabel_base) { - Warning(p_line_index, _("no non-local label before `%s'"), - s.tok[0]); + cur_we->warning(WARN_GENERAL, cur_lindex, + N_("no non-local label before `%s'"), + s.tok[0]); yylval.str_val = xstrndup(s.tok, TOKLEN); } else { len = TOKLEN + nasm_parser_locallabel_base_len; @@ -367,7 +351,7 @@ scan: savech = s.tok[TOKLEN]; s.tok[TOKLEN] = '\0'; check_id_ret = nasm_parser_arch->parse.check_identifier( - yylval.arch_data, s.tok, p_line_index); + yylval.arch_data, s.tok, cur_lindex); s.tok[TOKLEN] = savech; switch (check_id_ret) { case ARCH_CHECK_ID_NONE: @@ -385,8 +369,8 @@ scan: case ARCH_CHECK_ID_TARGETMOD: RETURN(TARGETMOD); default: - Warning(p_line_index, - _("Arch feature not supported, treating as identifier")); + cur_we->warning(WARN_GENERAL, cur_lindex, + N_("Arch feature not supported, treating as identifier")); yylval.str_val = xstrndup(s.tok, TOKLEN); RETURN(ID); } @@ -399,10 +383,9 @@ scan: "\n" { state = INITIAL; RETURN(s.tok[0]); } any { - if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR)) - Warning(p_line_index, - _("ignoring unrecognized character `%s'"), - conv_unprint(s.tok[0])); + cur_we->warning(WARN_UNREC_CHAR, cur_lindex, + N_("ignoring unrecognized character `%s'"), + cur_we->conv_unprint(s.tok[0])); goto scan; } */ @@ -416,7 +399,7 @@ linechg: linechg_numcount++; savech = s.tok[TOKLEN]; s.tok[TOKLEN] = '\0'; - yylval.intn = intnum_new_dec(s.tok, p_line_index); + yylval.intn = intnum_new_dec(s.tok, cur_lindex); s.tok[TOKLEN] = savech; RETURN(INTNUM); } @@ -439,10 +422,9 @@ linechg: } any { - if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR)) - Warning(p_line_index, - _("ignoring unrecognized character `%s'"), - conv_unprint(s.tok[0])); + cur_we->warning(WARN_UNREC_CHAR, cur_lindex, + N_("ignoring unrecognized character `%s'"), + cur_we->conv_unprint(s.tok[0])); goto linechg; } */ @@ -482,10 +464,9 @@ directive: } any { - if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR)) - Warning(p_line_index, - _("ignoring unrecognized character `%s'"), - conv_unprint(s.tok[0])); + cur_we->warning(WARN_UNREC_CHAR, cur_lindex, + N_("ignoring unrecognized character `%s'"), + cur_we->conv_unprint(s.tok[0])); goto directive; } */ @@ -502,9 +483,10 @@ stringconst_scan: /*!re2c "\n" { if (cursor == s.eof) - Error(p_line_index, _("unexpected end of file in string")); + cur_we->error(cur_lindex, + N_("unexpected end of file in string")); else - Error(p_line_index, _("unterminated string")); + cur_we->error(cur_lindex, N_("unterminated string")); strbuf[count] = '\0'; yylval.str_val = strbuf; RETURN(STRING); diff --git a/modules/preprocs/raw/raw-preproc.c b/modules/preprocs/raw/raw-preproc.c index b251f841..95bad927 100644 --- a/modules/preprocs/raw/raw-preproc.c +++ b/modules/preprocs/raw/raw-preproc.c @@ -30,20 +30,30 @@ static int is_interactive; static FILE *in; +static linemgr *cur_lm; +static errwarn *cur_we; int isatty(int); static void -raw_preproc_initialize(FILE *f, const char *in_filename) +raw_preproc_initialize(FILE *f, const char *in_filename, linemgr *lm, + errwarn *we) { in = f; + cur_lm = lm; + cur_we = we; /*@-unrecog@*/ is_interactive = f ? (isatty(fileno(f)) > 0) : 0; /*@=unrecog@*/ } +static void +raw_preproc_cleanup(void) +{ +} + static size_t -raw_preproc_input(char *buf, size_t max_size, linemgr *lm) +raw_preproc_input(char *buf, size_t max_size) { int c = '*'; size_t n; @@ -54,9 +64,11 @@ raw_preproc_input(char *buf, size_t max_size, linemgr *lm) if (c == '\n') buf[n++] = (char)c; if (c == EOF && ferror(in)) - Error(lm->get_current(), _("error when reading from file")); + cur_we->error(cur_lm->get_current(), + N_("error when reading from file")); } else if (((n = fread(buf, 1, max_size, in)) == 0) && ferror(in)) - Error(lm->get_current(), _("error when reading from file")); + cur_we->error(cur_lm->get_current(), + N_("error when reading from file")); return n; } @@ -66,5 +78,6 @@ preproc yasm_raw_LTX_preproc = { "Disable preprocessing", "raw", raw_preproc_initialize, + raw_preproc_cleanup, raw_preproc_input }; diff --git a/modules/preprocs/yapp/yapp-preproc.c b/modules/preprocs/yapp/yapp-preproc.c index 681f7b78..a59ee5c2 100644 --- a/modules/preprocs/yapp/yapp-preproc.c +++ b/modules/preprocs/yapp/yapp-preproc.c @@ -41,7 +41,7 @@ static YAPP_Output current_output; YYSTYPE yapp_preproc_lval; /*@dependent@*/ linemgr *yapp_preproc_linemgr; -#define p_line_index (yapp_preproc_linemgr->get_current()) +/*@dependent@*/ errwarn *yapp_preproc_errwarn; int isatty(int); @@ -120,13 +120,13 @@ yapp_macro_insert (char *name, int argc, int fillargs) void yapp_macro_error_exists (YAPP_Macro *v) { - if (v) Error(p_line_index, _("Redefining macro of the same name %d:%d"), v->type, v->args); + if (v) cur_we->error(cur_lindex, N_("Redefining macro of the same name %d:%d"), v->type, v->args); } void yapp_macro_error_sameargname (YAPP_Macro *v) { - if (v) Error(p_line_index, _("Duplicate argument names in macro")); + if (v) cur_we->error(cur_lindex, N_("Duplicate argument names in macro")); } YAPP_Macro * @@ -141,7 +141,7 @@ yapp_define_insert (char *name, int argc, int fillargs) if ((argc >= 0 && ym->args < 0) || (argc < 0 && ym->args >= 0)) { - Warning(p_line_index, _("Attempted %%define both with and without parameters")); + cur_we->warning(WARN_PREPROC, cur_lindex, N_("Attempted %%define both with and without parameters")); return NULL; } } @@ -189,10 +189,10 @@ yapp_macro_delete (YAPP_Macro *ym) { while (!SLIST_EMPTY(&ym->macro_head)) { source *s = SLIST_FIRST(&ym->macro_head); - free(s); + xfree(s); SLIST_REMOVE_HEAD(&ym->macro_head, next); } - free(ym); + xfree(ym); } static YAPP_Macro * @@ -237,9 +237,12 @@ void expand_token_list(struct source_head *paramexp, struct source_head *to_head, source **to_tail); static void -yapp_preproc_initialize(FILE *f, const char *in_filename) +yapp_preproc_initialize(FILE *f, const char *in_filename, linemgr *lm, + errwarn *we) { is_interactive = f ? (isatty(fileno(f)) > 0) : 0; + yapp_preproc_linemgr = lm; + yapp_preproc_errwarn = we; yapp_preproc_current_file = xstrdup(in_filename); yapp_preproc_line_number = 1; yapp_lex_initialize(f); @@ -251,7 +254,7 @@ yapp_preproc_initialize(FILE *f, const char *in_filename) out->out = current_output = YAPP_OUTPUT; SLIST_INSERT_HEAD(&output_head, out, next); - macro_table = HAMT_new(); + macro_table = HAMT_new(we->internal_error_); source_tail = SLIST_FIRST(&source_head); macro_tail = SLIST_FIRST(¯o_head); @@ -260,6 +263,12 @@ yapp_preproc_initialize(FILE *f, const char *in_filename) append_token(LINE, &source_head, &source_tail); } +static void +yapp_preproc_cleanup(void) +{ + /* TODO: clean up */ +} + /* Generate a new level of if* context * if val is true, this module of the current level will be output IFF the * surrounding one is. @@ -321,7 +330,7 @@ pop_if(void) out = SLIST_FIRST(&output_head); current_output = out->out; SLIST_REMOVE_HEAD(&output_head, next); - free(out); + xfree(out); if (current_output != YAPP_OUTPUT) set_inhibit(); } @@ -367,7 +376,7 @@ append_token(int token, struct source_head *to_head, source **to_tail) if ((*to_tail) && (*to_tail)->token.type == LINE && (token == '\n' || token == LINE)) { - free ((*to_tail)->token.str); + xfree ((*to_tail)->token.str); (*to_tail)->token.str = xmalloc(23+strlen(yapp_preproc_current_file)); sprintf((*to_tail)->token.str, "%%line %d+1 %s\n", yapp_preproc_line_number, yapp_preproc_current_file); } @@ -409,7 +418,7 @@ append_token(int token, struct source_head *to_head, source **to_tail) break; default: - free(src); + xfree(src); return; } append_processed_token(src, to_head, to_tail); @@ -461,7 +470,7 @@ eat_through_return(struct source_head *to_head, source **to_tail) while ((token = yapp_preproc_lex()) != '\n') { if (token == 0) return 0; - Error(p_line_index, _("Skipping possibly valid %%define stuff")); + cur_we->error(cur_lindex, N_("Skipping possibly valid %%define stuff")); } append_token('\n', to_head, to_tail); return '\n'; @@ -474,7 +483,7 @@ yapp_get_ident(const char *synlvl) if (token == WHITESPACE) token = yapp_preproc_lex(); if (token != IDENT) { - Error(p_line_index, _("Identifier expected after %%%s"), synlvl); + cur_we->error(cur_lindex, N_("Identifier expected after %%%s"), synlvl); } return token; } @@ -502,7 +511,7 @@ expand_macro(char *name, ydebug(("YAPP: +Expand macro %s...\n", name)); - if (ym->expanding) InternalError(_("Recursively expanding a macro!")); + if (ym->expanding) cur_we->internal_error(N_("Recursively expanding a macro!")); if (ym->type == YAPP_DEFINE) { if (ym->args == -1) { @@ -534,7 +543,7 @@ expand_macro(char *name, /* find out what we got */ if (from_head) { - InternalError("Expanding macro with non-null from_head ugh\n"); + cur_we->internal_error(N_("Expanding macro with non-null from_head ugh\n")); } token = yapp_preproc_lex(); append_token(token, &replay_head, &replay_tail); @@ -581,9 +590,9 @@ expand_macro(char *name, default: if (token < 256) - InternalError(_("Unexpected character token in parameter expansion")); + cur_we->internal_error(N_("Unexpected character token in parameter expansion")); else - Error(p_line_index, _("Cannot handle preprocessor items inside possible macro invocation")); + cur_we->error(cur_lindex, N_("Cannot handle preprocessor items inside possible macro invocation")); } } @@ -603,7 +612,7 @@ expand_macro(char *name, ym->expanding = 1; /* so the macro exists. build a HAMT parameter table */ - param_table = HAMT_new(); + param_table = HAMT_new(cur_we->internal_error_); /* fill the entries by walking the replay buffer and create * "macros". coincidentally, clear the replay buffer. */ @@ -612,16 +621,16 @@ expand_macro(char *name, while (replay->token.type != '(') { ydebug(("YAPP: Ignoring replay token '%c' \"%s\"\n", replay->token.type, replay->token.str)); SLIST_REMOVE_HEAD(&replay_head, next); - free(replay->token.str); - free(replay); + xfree(replay->token.str); + xfree(replay); replay = SLIST_FIRST(&replay_head); } ydebug(("YAPP: Ignoring replay token '%c' \"%s\"\n", replay->token.type, replay->token.str)); /* free the open paren */ SLIST_REMOVE_HEAD(&replay_head, next); - free(replay->token.str); - free(replay); + xfree(replay->token.str); + xfree(replay); param = SLIST_FIRST(&ym->param_head); @@ -651,8 +660,8 @@ expand_macro(char *name, arg_tail = SLIST_FIRST(&arg_head); /* don't save the comma */ - free(replay->token.str); - free(replay); + xfree(replay->token.str); + xfree(replay); HAMT_insert(param_table, param->token.str, @@ -675,15 +684,15 @@ expand_macro(char *name, if (replay) SLIST_REMOVE_HEAD(&replay_head, next); } if (replay) { - free(replay->token.str); - free(replay); + xfree(replay->token.str); + xfree(replay); } else if (param) { - InternalError(_("Got to end of arglist before end of replay!")); + cur_we->internal_error(N_("Got to end of arglist before end of replay!")); } replay = SLIST_FIRST(&replay_head); if (replay || param) - InternalError(_("Count and distribution of define args mismatched!")); + cur_we->internal_error(N_("Count and distribution of define args mismatched!")); /* the param_table is set up without errors, so expansion is ready * to go */ @@ -717,7 +726,7 @@ expand_macro(char *name, } } else - InternalError(_("Invoking Macros not yet supported")); + cur_we->internal_error(N_("Invoking Macros not yet supported")); ym->expanding = 0; } @@ -743,15 +752,13 @@ expand_token_list(struct source_head *paramexp, struct source_head *to_head, sou } static size_t -yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) +yapp_preproc_input(char *buf, size_t max_size) { static YAPP_State state = YAPP_STATE_INITIAL; int n = 0; int token; int need_line_directive = 0; - yapp_preproc_linemgr = lm; - while (saved_length < max_size && state != YAPP_STATE_EOF) { token = yapp_preproc_lex(); @@ -765,7 +772,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) append_token(token, &source_head, &source_tail); /*if (append_to_return()==0) state=YAPP_STATE_EOF;*/ ydebug(("YAPP: default: '%c' \"%s\"\n", token, yapp_preproc_lval.str_val)); - /*Error(p_line_index, _("YAPP got an unhandled token."));*/ + /*cur_we->error(cur_lindex, N_("YAPP got an unhandled token."));*/ break; case IDENT: @@ -788,7 +795,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) case CLEAR: HAMT_delete(macro_table, (void (*)(void *))yapp_macro_delete); - macro_table = HAMT_new(); + macro_table = HAMT_new(cur_we->internal_error_); break; case DEFINE: @@ -834,7 +841,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) break; } else if (last_token == ',' || token != ',') - Error(p_line_index, _("Unexpected token in %%define parameters")); + cur_we->error(cur_lindex, N_("Unexpected token in %%define parameters")); last_token = token; } if (token == ')') { @@ -851,7 +858,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) append_token('\n', &source_head, &source_tail); } else { - InternalError(_("%%define ... failed miserably - neither \\n, WS, or ( followed ident")); + cur_we->internal_error(N_("%%define ... failed miserably - neither \\n, WS, or ( followed ident")); } break; @@ -914,7 +921,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) } break; default: - Error(p_line_index, _("YAPP got into a bad state")); + cur_we->error(cur_lindex, N_("YAPP got into a bad state")); } if (need_line_directive) { append_token(LINE, &source_head, &source_tail); @@ -932,8 +939,8 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) saved_length -= strlen(src->token.str); SLIST_REMOVE_HEAD(&source_head, next); - free(src->token.str); - free(src); + xfree(src->token.str); + xfree(src); } } @@ -945,5 +952,6 @@ preproc yasm_yapp_LTX_preproc = { "YAPP preprocessing (NASM style)", "yapp", yapp_preproc_initialize, + yapp_preproc_cleanup, yapp_preproc_input }; diff --git a/modules/preprocs/yapp/yapp-preproc.h b/modules/preprocs/yapp/yapp-preproc.h index 428b65f0..5e2bdf76 100644 --- a/modules/preprocs/yapp/yapp-preproc.h +++ b/modules/preprocs/yapp/yapp-preproc.h @@ -52,3 +52,9 @@ typedef enum { void yapp_lex_initialize(FILE *f); void set_inhibit(void); + +extern /*@dependent@*/ linemgr *yapp_preproc_linemgr; +extern /*@dependent@*/ errwarn *yapp_preproc_errwarn; +#define cur_lindex (yapp_preproc_linemgr->get_current()) +#define cur_we yapp_preproc_errwarn + diff --git a/modules/preprocs/yapp/yapp-token.h b/modules/preprocs/yapp/yapp-token.h index 01c67b7a..43012495 100644 --- a/modules/preprocs/yapp/yapp-token.h +++ b/modules/preprocs/yapp/yapp-token.h @@ -60,7 +60,5 @@ typedef union { extern YYSTYPE yapp_preproc_lval; extern char *yapp_preproc_current_file; extern int yapp_preproc_line_number; -extern /*@dependent@*/ linemgr *yapp_preproc_linemgr; -#define p_line_index (yapp_preproc_linemgr->get_current()) int yapp_preproc_lex(void); diff --git a/modules/preprocs/yapp/yapp-token.l b/modules/preprocs/yapp/yapp-token.l index 17072e20..d45ed613 100644 --- a/modules/preprocs/yapp/yapp-token.l +++ b/modules/preprocs/yapp/yapp-token.l @@ -124,9 +124,7 @@ DIR %[ \t]* int inch, count; char endch = yytext[0]; - strbuf = malloc(STRBUF_ALLOC_SIZE); - if(!strbuf) - Fatal(FATAL_NOMEM); + strbuf = xmalloc(STRBUF_ALLOC_SIZE); strbuf_size = STRBUF_ALLOC_SIZE; inch = input(); @@ -134,18 +132,16 @@ DIR %[ \t]* while(inch != EOF && inch != endch && inch != '\n') { strbuf[count++] = inch; if(count >= strbuf_size) { - strbuf = realloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE); - if(!strbuf) - Fatal(FATAL_NOMEM); + strbuf = xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE); strbuf_size += STRBUF_ALLOC_SIZE; } inch = input(); } if(inch == '\n') - Error(p_line_index, _("unterminated string")); + cur_we->error(cur_lindex, _("unterminated string")); else if(inch == EOF) - Error(p_line_index, _("unexpected end of file in string")); + cur_we->error(cur_lindex, _("unexpected end of file in string")); strbuf[count] = '\0'; @@ -176,9 +172,9 @@ DIR %[ \t]* /* FIXME: handle includes that aren't relative */ incfile = fopen (yytext, "r"); if(!incfile) { - Error(p_line_index, _("include file `%s': %s"), + cur_we->error(cur_lindex, _("include file `%s': %s"), yytext, strerror(errno)); - free(inc); + xfree(inc); } else { yyin = incfile; @@ -204,11 +200,11 @@ DIR %[ \t]* inc = SLIST_FIRST(&includes_head); yy_delete_buffer (YY_CURRENT_BUFFER); yy_switch_to_buffer (inc->include_state); - free(yapp_preproc_current_file); + xfree(yapp_preproc_current_file); yapp_preproc_current_file = inc->filename; yapp_preproc_line_number = inc->line_number + 1; SLIST_REMOVE_HEAD(&includes_head, next); - free(inc); + xfree(inc); BEGIN(incl); return INCLUDE; @@ -232,7 +228,7 @@ DIR %[ \t]* } {WS}+["] ; /* eat space before file */ [^ \t\n"]* { /* have the filename */ - free(yapp_preproc_current_file); + xfree(yapp_preproc_current_file); yapp_preproc_current_file = xstrdup(yytext); } ["]{WS}*\n { @@ -334,12 +330,12 @@ DIR %[ \t]* [][+*/,()-] { return yytext[0]; } . { - Warning(p_line_index, _("Unhandled character in `%s'"), conv_unprint(yytext[0])); + cur_we->warning(WARN_PREPROC, cur_lindex, _("Unhandled character in `%s'"), cur_we->conv_unprint(yytext[0])); } . { - Warning(p_line_index, _("ignoring unrecognized character `%s'"), - conv_unprint(yytext[0])); + cur_we->warning(WARN_PREPROC, cur_lindex, _("ignoring unrecognized character `%s'"), + cur_we->conv_unprint(yytext[0])); } %% diff --git a/src/Makefile.inc b/src/Makefile.inc index 1926b5ae..27ce2791 100644 --- a/src/Makefile.inc +++ b/src/Makefile.inc @@ -4,7 +4,6 @@ libyasm_la_SOURCES = \ src/bytecode.c \ src/bytecode.h \ src/bc-int.h \ - src/errwarn.c \ src/errwarn.h \ src/expr.c \ src/expr.h \ @@ -47,6 +46,7 @@ yasm_SOURCES += \ src/parser.c \ src/module.h \ src/module.c \ + src/errwarn.c \ src/linemgr.c diff --git a/src/arch.h b/src/arch.h index 3d23ea8c..fb26d312 100644 --- a/src/arch.h +++ b/src/arch.h @@ -58,6 +58,9 @@ struct arch { /* keyword used to select architecture */ const char *keyword; + void (*initialize) (errwarn *we); + void (*cleanup) (void); + struct { /* All "data" below starts the parse initialized to 0. Thus, it is * okay for a funtion to use/check previously stored data to see if diff --git a/src/arch/x86/x86arch.c b/src/arch/x86/x86arch.c index 36d3db9f..906434e6 100644 --- a/src/arch/x86/x86arch.c +++ b/src/arch/x86/x86arch.c @@ -37,6 +37,19 @@ unsigned char yasm_x86_LTX_mode_bits = 0; +/*@dependent@*/ errwarn *yasm_x86_errwarn; + + +static void +x86_initialize(errwarn *we) +{ + yasm_x86_errwarn = we; +} + +static void +x86_cleanup(void) +{ +} int x86_directive(const char *name, valparamhead *valparams, @@ -53,7 +66,7 @@ x86_directive(const char *name, valparamhead *valparams, (lval = intnum_get_int(intn)) && (lval == 16 || lval == 32)) yasm_x86_LTX_mode_bits = (unsigned char)lval; else - Error(lindex, _("invalid argument to [%s]"), "BITS"); + cur_we->error(lindex, N_("invalid argument to [%s]"), "BITS"); return 0; } else return 1; @@ -79,7 +92,7 @@ x86_get_reg_size(unsigned long reg) case X86_FPUREG: return 10; default: - InternalError(_("unknown register size")); + cur_we->internal_error(N_("unknown register size")); } return 0; } @@ -119,7 +132,7 @@ x86_reg_print(FILE *f, unsigned long reg) fprintf(f, "st%d", (int)(reg&7)); break; default: - InternalError(_("unknown register size")); + cur_we->internal_error(N_("unknown register size")); } } @@ -165,6 +178,8 @@ x86_handle_seg_override(effaddr *ea, unsigned long segreg, arch yasm_x86_LTX_arch = { "x86 (IA-32, x86-64)", "x86", + x86_initialize, + x86_cleanup, { x86_switch_cpu, x86_check_identifier, diff --git a/src/arch/x86/x86arch.h b/src/arch/x86/x86arch.h index 4674070b..724e703b 100644 --- a/src/arch/x86/x86arch.h +++ b/src/arch/x86/x86arch.h @@ -114,6 +114,8 @@ typedef struct x86_new_jmprel_data { bytecode *x86_bc_new_jmprel(x86_new_jmprel_data *d); extern unsigned char yasm_x86_LTX_mode_bits; +extern /*@dependent@*/ errwarn *yasm_x86_errwarn; +#define cur_we yasm_x86_errwarn void x86_bc_delete(bytecode *bc); void x86_bc_print(FILE *f, int indent_level, const bytecode *bc); diff --git a/src/arch/x86/x86bc.c b/src/arch/x86/x86bc.c index 26d76055..5eae04b6 100644 --- a/src/arch/x86/x86bc.c +++ b/src/arch/x86/x86bc.c @@ -170,9 +170,11 @@ x86_bc_new_jmprel(x86_new_jmprel_data *d) jmprel->op_sel = d->op_sel; if ((d->op_sel == JR_SHORT_FORCED) && (d->near_op_len == 0)) - Error(d->lindex, _("no SHORT form of that jump instruction exists")); + cur_we->error(d->lindex, + N_("no SHORT form of that jump instruction exists")); if ((d->op_sel == JR_NEAR_FORCED) && (d->short_op_len == 0)) - Error(d->lindex, _("no NEAR form of that jump instruction exists")); + cur_we->error(d->lindex, + N_("no NEAR form of that jump instruction exists")); jmprel->shortop.opcode[0] = d->short_op[0]; jmprel->shortop.opcode[1] = d->short_op[1]; @@ -203,7 +205,8 @@ x86_ea_set_segment(effaddr *ea, unsigned char segment, unsigned long lindex) return; if (segment != 0 && x86_ea->segment != 0) - Warning(lindex, _("multiple segment overrides, using leftmost")); + cur_we->warning(WARN_GENERAL, lindex, + N_("multiple segment overrides, using leftmost")); x86_ea->segment = segment; } @@ -294,7 +297,7 @@ x86_bc_insn_get_ea(bytecode *bc) return NULL; if ((x86_bytecode_type)bc->type != X86_BC_INSN) - InternalError(_("Trying to get EA of non-instruction")); + cur_we->internal_error(N_("Trying to get EA of non-instruction")); return (effaddr *)(((x86_insn *)bc)->ea); } @@ -318,7 +321,8 @@ x86_bc_insn_opersize_override(bytecode *bc, unsigned char opersize) jmprel->opersize = opersize; break; default: - InternalError(_("OperSize override applied to non-instruction")); + cur_we->internal_error( + N_("OperSize override applied to non-instruction")); } } @@ -341,7 +345,8 @@ x86_bc_insn_addrsize_override(bytecode *bc, unsigned char addrsize) jmprel->addrsize = addrsize; break; default: - InternalError(_("AddrSize override applied to non-instruction")); + cur_we->internal_error( + N_("AddrSize override applied to non-instruction")); } } @@ -366,11 +371,13 @@ x86_bc_insn_set_lockrep_prefix(bytecode *bc, unsigned char prefix, lockrep_pre = &jmprel->lockrep_pre; break; default: - InternalError(_("LockRep prefix applied to non-instruction")); + cur_we->internal_error( + N_("LockRep prefix applied to non-instruction")); } if (*lockrep_pre != 0) - Warning(lindex, _("multiple LOCK or REP prefixes, using leftmost")); + cur_we->warning(WARN_GENERAL, lindex, + N_("multiple LOCK or REP prefixes, using leftmost")); *lockrep_pre = prefix; } @@ -654,20 +661,21 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save, temp = expr_copy(jmprel->target); num = expr_get_intnum(&temp, calc_bc_dist); if (!num) { - Error(bc->line, - _("short jump target external or out of segment")); + cur_we->error(bc->line, + N_("short jump target external or out of segment")); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } else { rel = intnum_get_int(num); rel -= jmprel->shortop.opcode_len+1; /* does a short form exist? */ if (jmprel->shortop.opcode_len == 0) { - Error(bc->line, _("short jump does not exist")); + cur_we->error(bc->line, + N_("short jump does not exist")); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } /* short displacement must fit in -128 <= rel <= +127 */ if (rel < -128 || rel > 127) { - Error(bc->line, _("short jump out of range")); + cur_we->error(bc->line, N_("short jump out of range")); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } } @@ -678,7 +686,7 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save, jrshort = 0; if (save) { if (jmprel->nearop.opcode_len == 0) { - Error(bc->line, _("near jump does not exist")); + cur_we->error(bc->line, N_("near jump does not exist")); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } } @@ -713,8 +721,8 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save, * it to actually be within short range). */ if (save) { - Error(bc->line, - _("short jump out of range (near jump does not exist)")); + cur_we->error(bc->line, + N_("short jump out of range (near jump does not exist)")); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } jrshort = 1; @@ -730,8 +738,8 @@ x86_bc_resolve_jmprel(x86_jmprel *jmprel, unsigned long *len, int save, jrshort = 0; } else { if (save) { - Error(bc->line, - _("short jump out of range (near jump does not exist)")); + cur_we->error(bc->line, + N_("short jump out of range (near jump does not exist)")); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } jrshort = 1; @@ -780,7 +788,7 @@ x86_bc_resolve(bytecode *bc, int save, const section *sect, default: break; } - InternalError(_("Didn't handle bytecode type in x86 arch")); + cur_we->internal_error(N_("Didn't handle bytecode type in x86 arch")); /*@notreached@*/ return BC_RESOLVE_UNKNOWN_LEN; } @@ -806,7 +814,8 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect, WRITE_8(*bufp, 0x67); if (insn->rex != 0) { if (insn->mode_bits != 64) - InternalError(_("x86: got a REX prefix in non-64-bit mode")); + cur_we->internal_error( + N_("x86: got a REX prefix in non-64-bit mode")); WRITE_8(*bufp, insn->rex); } @@ -820,13 +829,14 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect, if (ea) { if (x86_ea->need_modrm) { if (!x86_ea->valid_modrm) - InternalError(_("invalid Mod/RM in x86 tobytes_insn")); + cur_we->internal_error( + N_("invalid Mod/RM in x86 tobytes_insn")); WRITE_8(*bufp, x86_ea->modrm); } if (x86_ea->need_sib) { if (!x86_ea->valid_sib) - InternalError(_("invalid SIB in x86 tobytes_insn")); + cur_we->internal_error(N_("invalid SIB in x86 tobytes_insn")); WRITE_8(*bufp, x86_ea->sib); } @@ -846,7 +856,7 @@ x86_bc_tobytes_insn(x86_insn *insn, unsigned char **bufp, const section *sect, &eat.valid_modrm, &eat.need_modrm, &eat.sib, &eat.valid_sib, &eat.need_sib, common_calc_bc_dist)) - InternalError(_("checkea failed")); + cur_we->internal_error(N_("checkea failed")); if (ea->disp) { if (output_expr(&ea->disp, bufp, ea->len, *bufp-bufp_orig, @@ -901,7 +911,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp, case JR_SHORT: /* 1 byte relative displacement */ if (jmprel->shortop.opcode_len == 0) - InternalError(_("short jump does not exist")); + cur_we->internal_error(N_("short jump does not exist")); /* Opcode */ for (i=0; ishortop.opcode_len; i++) @@ -916,7 +926,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp, case JR_NEAR: /* 2/4 byte relative displacement (depending on operand size) */ if (jmprel->nearop.opcode_len == 0) { - Error(bc->line, _("near jump does not exist")); + cur_we->error(bc->line, N_("near jump does not exist")); return 1; } @@ -931,7 +941,7 @@ x86_bc_tobytes_jmprel(x86_jmprel *jmprel, unsigned char **bufp, return 1; break; default: - InternalError(_("unrecognized relative jump op_sel")); + cur_we->internal_error(N_("unrecognized relative jump op_sel")); } return 0; } @@ -961,7 +971,8 @@ x86_intnum_tobytes(const intnum *intn, unsigned char **bufp, if (rel) { long val; if (valsize != 1 && valsize != 2 && valsize != 4) - InternalError(_("tried to do PC-relative offset from invalid sized value")); + cur_we->internal_error( + N_("tried to do PC-relative offset from invalid sized value")); val = intnum_get_uint(intn); val -= bc->len; switch (valsize) { diff --git a/src/arch/x86/x86expr.c b/src/arch/x86/x86expr.c index ea022f6d..c6552531 100644 --- a/src/arch/x86/x86expr.c +++ b/src/arch/x86/x86expr.c @@ -183,7 +183,7 @@ x86_expr_checkea_distcheck_reg(expr **ep) /* The reg expn *must* be EXPR_ADD at this point. Sanity check. */ if (e->terms[havereg_expr].type != EXPR_EXPR || e->terms[havereg_expr].data.expn->op != EXPR_ADD) - InternalError(_("Register expression not ADD or EXPN")); + cur_we->internal_error(N_("Register expression not ADD or EXPN")); /* Iterate over each term in reg expn */ for (i=0; iterms[havereg_expr].data.expn->numterms; i++) { @@ -282,9 +282,11 @@ x86_expr_checkea_getregusage(expr **ep, /*@null@*/ int *indexreg, void *data, * Sanity check for EXPR_INT. */ if (e->terms[i].data.expn->terms[0].type != EXPR_REG) - InternalError(_("Register not found in reg expn")); + cur_we->internal_error( + N_("Register not found in reg expn")); if (e->terms[i].data.expn->terms[1].type != EXPR_INT) - InternalError(_("Non-integer value in reg expn")); + cur_we->internal_error( + N_("Non-integer value in reg expn")); reg = get_reg(&e->terms[i].data.expn->terms[0], data); if (!reg) return 0; @@ -378,7 +380,7 @@ x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg, */ if (!intnum_check_size(intn, (size_t)wordsize, 0) && !intnum_check_size(intn, 1, 1)) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } @@ -442,8 +444,8 @@ x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg, case 2: case 4: if (wordsize != *displen) { - Error(e->line, - _("invalid effective address (displacement size)")); + cur_we->error(e->line, + N_("invalid effective address (displacement size)")); return 0; } /* TODO: Add optional warning here about 2/4 not being valid @@ -455,7 +457,7 @@ x86_checkea_calc_displen(expr **ep, unsigned int wordsize, int noreg, break; default: /* we shouldn't ever get any other size! */ - InternalError(_("strange EA displacement size")); + cur_we->internal_error(N_("strange EA displacement size")); } return 1; @@ -535,7 +537,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, calc_bc_dist)) { case 0: e = *ep; - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; case 1: return 1; @@ -557,7 +559,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, */ for (i=0; i<8; i++) { if (reg32mult[i] < 0) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } if (i != indexreg && reg32mult[i] == 1 && basereg == REG32_NONE) @@ -598,7 +600,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, */ for (i=0; i<8; i++) if (i != basereg && i != indexreg && reg32mult[i] != 0) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } @@ -606,7 +608,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, if (indexreg != REG32_NONE && reg32mult[indexreg] != 1 && reg32mult[indexreg] != 2 && reg32mult[indexreg] != 4 && reg32mult[indexreg] != 8) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } @@ -616,7 +618,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, * legal. */ if (reg32mult[REG32_ESP] > 1 || basereg == REG32_ESP) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } /* If mult==1 and basereg is not ESP, swap indexreg w/basereg. */ @@ -720,7 +722,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, calc_bc_dist)) { case 0: e = *ep; - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; case 1: return 1; @@ -732,7 +734,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, /* reg multipliers not 0 or 1 are illegal. */ if (reg16mult.bx & ~1 || reg16mult.si & ~1 || reg16mult.di & ~1 || reg16mult.bp & ~1) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } @@ -748,7 +750,7 @@ x86_expr_checkea(expr **ep, unsigned char *addrsize, unsigned char bits, /* Check the modrm value for invalid combinations. */ if (modrm16[havereg] & 0070) { - Error(e->line, _("invalid effective address")); + cur_we->error(e->line, N_("invalid effective address")); return 0; } @@ -776,17 +778,17 @@ x86_floatnum_tobytes(const floatnum *flt, unsigned char **bufp, int fltret; if (!floatnum_check_size(flt, (size_t)valsize)) { - Error(e->line, _("invalid floating point constant size")); + cur_we->error(e->line, N_("invalid floating point constant size")); return 1; } fltret = floatnum_get_sized(flt, *bufp, (size_t)valsize); if (fltret < 0) { - Error(e->line, _("underflow in floating point expression")); + cur_we->error(e->line, N_("underflow in floating point expression")); return 1; } if (fltret > 0) { - Error(e->line, _("overflow in floating point expression")); + cur_we->error(e->line, N_("overflow in floating point expression")); return 1; } *bufp += valsize; diff --git a/src/arch/x86/x86id.re b/src/arch/x86/x86id.re index 4cee4eed..b57ea32a 100644 --- a/src/arch/x86/x86id.re +++ b/src/arch/x86/x86id.re @@ -1322,7 +1322,7 @@ x86_new_jmprel(const unsigned long data[4], int num_operands, /* We know the target is in operand 0, but sanity check for Imm. */ op = ops_first(operands); if (op->type != INSN_OPERAND_IMM) - InternalError(_("invalid operand conversion")); + cur_we->internal_error(N_("invalid operand conversion")); d.target = expr_new(EXPR_SUB, ExprExpr(op->data.val), ExprSym(symrec_define_label("$", cur_section, prev_bc, 0, lindex)), lindex); @@ -1556,7 +1556,7 @@ x86_new_insn(const unsigned long data[4], int num_operands, mismatch = 1; break; default: - InternalError(_("invalid operand type")); + cur_we->internal_error(N_("invalid operand type")); } if (mismatch) @@ -1606,7 +1606,7 @@ x86_new_insn(const unsigned long data[4], int num_operands, mismatch = 1; break; default: - InternalError(_("invalid target modifier type")); + cur_we->internal_error(N_("invalid target modifier type")); } } @@ -1618,7 +1618,8 @@ x86_new_insn(const unsigned long data[4], int num_operands, if (!found) { /* Didn't find a matching one */ - Error(lindex, _("invalid combination of opcode and operands")); + cur_we->error(lindex, + N_("invalid combination of opcode and operands")); return NULL; } @@ -1630,23 +1631,25 @@ x86_new_insn(const unsigned long data[4], int num_operands, case MOD_ExtErr: switch ((info->modifiers & MOD_ExtIndex_MASK)>>MOD_ExtIndex_SHIFT) { case 0: - Error(lindex, _("mismatch in operand sizes")); + cur_we->error(lindex, N_("mismatch in operand sizes")); break; case 1: - Error(lindex, _("operand size not specified")); + cur_we->error(lindex, N_("operand size not specified")); break; default: - InternalError(_("unrecognized x86 ext mod index")); + cur_we->internal_error( + N_("unrecognized x86 ext mod index")); } return NULL; /* It was an error */ case MOD_ExtWarn: switch ((info->modifiers & MOD_ExtIndex_MASK)>>MOD_ExtIndex_SHIFT) { default: - InternalError(_("unrecognized x86 ext mod index")); + cur_we->internal_error( + N_("unrecognized x86 ext mod index")); } break; default: - InternalError(_("unrecognized x86 extended modifier")); + cur_we->internal_error(N_("unrecognized x86 extended modifier")); } /* Shortcut to JmpRel */ @@ -1726,7 +1729,8 @@ x86_new_insn(const unsigned long data[4], int num_operands, d.ea = x86_ea_new_reg((unsigned char)op->data.reg); break; case INSN_OPERAND_SEGREG: - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); case INSN_OPERAND_MEMORY: d.ea = op->data.ea; if ((info->operands[i] & OPT_MASK) == OPT_MemOffs) @@ -1746,7 +1750,8 @@ x86_new_insn(const unsigned long data[4], int num_operands, d.im_len = size_lookup[(info->operands[i] & OPS_MASK)>>OPS_SHIFT]; } else - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); break; case OPA_SImm: if (op->type == INSN_OPERAND_IMM) { @@ -1755,36 +1760,41 @@ x86_new_insn(const unsigned long data[4], int num_operands, OPS_MASK)>>OPS_SHIFT]; d.im_sign = 1; } else - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); break; case OPA_Spare: if (op->type == INSN_OPERAND_REG || op->type == INSN_OPERAND_SEGREG) d.spare = (unsigned char)(op->data.reg&7); else - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); break; case OPA_Op0Add: if (op->type == INSN_OPERAND_REG) d.op[0] += (unsigned char)(op->data.reg&7); else - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); break; case OPA_Op1Add: if (op->type == INSN_OPERAND_REG) d.op[1] += (unsigned char)(op->data.reg&7); else - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); break; case OPA_SpareEA: if (op->type == INSN_OPERAND_REG) { d.spare = (unsigned char)(op->data.reg&7); d.ea = x86_ea_new_reg((unsigned char)op->data.reg); } else - InternalError(_("invalid operand conversion")); + cur_we->internal_error( + N_("invalid operand conversion")); break; default: - InternalError(_("unknown operand action")); + cur_we->internal_error(N_("unknown operand action")); } switch (info->operands[i] & OPAP_MASK) { @@ -1797,7 +1807,8 @@ x86_new_insn(const unsigned long data[4], int num_operands, d.signext_imm8_op = 1; break; default: - InternalError(_("unknown operand postponed action")); + cur_we->internal_error( + N_("unknown operand postponed action")); } } } @@ -1953,11 +1964,13 @@ x86_switch_cpu(const char *id, unsigned long lindex) /* catchalls */ [\001-\377]+ { - Warning(lindex, _("unrecognized CPU identifier `%s'"), id); + cur_we->warning(WARN_GENERAL, lindex, + N_("unrecognized CPU identifier `%s'"), id); return; } [\000] { - Warning(lindex, _("unrecognized CPU identifier `%s'"), id); + cur_we->warning(WARN_GENERAL, lindex, + N_("unrecognized CPU identifier `%s'"), id); return; } */ diff --git a/src/bytecode.c b/src/bytecode.c index 3a1132d3..2f84a64e 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -96,12 +96,14 @@ typedef struct bytecode_objfmt_data { unsigned char bytes_static[16]; /*@dependent@*/ static arch *cur_arch; +/*@dependent@*/ static errwarn *cur_we; void -bc_initialize(arch *a) +bc_initialize(arch *a, errwarn *we) { cur_arch = a; + cur_we = we; } immval * @@ -328,13 +330,14 @@ bc_delete(bytecode *bc) objfmt_data->of->bc_objfmt_data_delete(objfmt_data->type, objfmt_data->data); else - InternalError(_("objfmt can't handle its own objfmt data bytecode")); + cur_we->internal_error( + N_("objfmt can't handle its own objfmt data bytecode")); break; default: if (bc->type < cur_arch->bc.type_max) cur_arch->bc.bc_delete(bc); else - InternalError(_("Unknown bytecode type")); + cur_we->internal_error(N_("Unknown bytecode type")); break; } /*@=branchstate@*/ @@ -500,10 +503,11 @@ bc_resolve_reserve(bytecode_reserve *reserve, unsigned long *len, int save, * the circular reference error to filter through. */ if (temp && expr_contains(temp, EXPR_FLOAT)) - Error(line, _("expression must not contain floating point value")); + cur_we->error(line, + N_("expression must not contain floating point value")); else - Error(line, - _("attempt to reserve non-constant quantity of space")); + cur_we->error(line, + N_("attempt to reserve non-constant quantity of space")); retval = BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } else *len += intnum_get_uint(num)*reserve->itemsize; @@ -565,12 +569,13 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save, /* Open file and determine its length */ f = fopen(incbin->filename, "rb"); if (!f) { - Error(line, _("`incbin': unable to open file `%s'"), incbin->filename); + cur_we->error(line, N_("`incbin': unable to open file `%s'"), + incbin->filename); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } if (fseek(f, 0L, SEEK_END) < 0) { - Error(line, _("`incbin': unable to seek on file `%s'"), - incbin->filename); + cur_we->error(line, N_("`incbin': unable to seek on file `%s'"), + incbin->filename); return BC_RESOLVE_ERROR | BC_RESOLVE_UNKNOWN_LEN; } flen = (unsigned long)ftell(f); @@ -578,8 +583,9 @@ bc_resolve_incbin(bytecode_incbin *incbin, unsigned long *len, int save, /* Compute length of incbin from start, maxlen, and len */ if (start > flen) { - Warning(line, _("`incbin': start past end of file `%s'"), - incbin->filename); + cur_we->warning(WARN_GENERAL, line, + N_("`incbin': start past end of file `%s'"), + incbin->filename); start = flen; } flen -= start; @@ -603,7 +609,7 @@ bc_resolve(bytecode *bc, int save, const section *sect, switch (bc->type) { case BC_EMPTY: - InternalError(_("got empty bytecode in bc_calc_len")); + cur_we->internal_error(N_("got empty bytecode in bc_calc_len")); case BC_DATA: retval = bc_resolve_data((bytecode_data *)bc, &bc->len); break; @@ -617,17 +623,18 @@ bc_resolve(bytecode *bc, int save, const section *sect, break; case BC_ALIGN: /* TODO */ - InternalError(_("TODO: align bytecode not implemented!")); + cur_we->internal_error( + N_("TODO: align bytecode not implemented!")); /*break;*/ case BC_OBJFMT_DATA: - InternalError(_("resolving objfmt data bytecode?")); + cur_we->internal_error(N_("resolving objfmt data bytecode?")); /*break;*/ default: if (bc->type < cur_arch->bc.type_max) retval = cur_arch->bc.bc_resolve(bc, save, sect, calc_bc_dist); else - InternalError(_("Unknown bytecode type")); + cur_we->internal_error(N_("Unknown bytecode type")); } /* Multiply len by number of multiples */ @@ -644,8 +651,8 @@ bc_resolve(bytecode *bc, int save, const section *sect, if (!num) { retval = BC_RESOLVE_UNKNOWN_LEN; if (temp && expr_contains(temp, EXPR_FLOAT)) { - Error(bc->line, - _("expression must not contain floating point value")); + cur_we->error(bc->line, + N_("expression must not contain floating point value")); retval |= BC_RESOLVE_ERROR; } } else @@ -711,29 +718,32 @@ bc_tobytes_incbin(bytecode_incbin *incbin, unsigned char **bufp, if (incbin->start) { num = expr_get_intnum(&incbin->start, NULL); if (!num) - InternalError(_("could not determine start in bc_tobytes_incbin")); + cur_we->internal_error( + N_("could not determine start in bc_tobytes_incbin")); start = intnum_get_uint(num); } /* Open file */ f = fopen(incbin->filename, "rb"); if (!f) { - Error(line, _("`incbin': unable to open file `%s'"), incbin->filename); + cur_we->error(line, N_("`incbin': unable to open file `%s'"), + incbin->filename); return 1; } /* Seek to start of data */ if (fseek(f, (long)start, SEEK_SET) < 0) { - Error(line, _("`incbin': unable to seek on file `%s'"), - incbin->filename); + cur_we->error(line, N_("`incbin': unable to seek on file `%s'"), + incbin->filename); fclose(f); return 1; } /* Read len bytes */ if (fread(*bufp, (size_t)len, 1, f) < (size_t)len) { - Error(line, _("`incbin': unable to read %lu bytes from file `%s'"), - len, incbin->filename); + cur_we->error(line, + N_("`incbin': unable to read %lu bytes from file `%s'"), + len, incbin->filename); fclose(f); return 1; } @@ -760,7 +770,8 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize, if (bc->multiple) { num = expr_get_intnum(&bc->multiple, NULL); if (!num) - InternalError(_("could not determine multiple in bc_tobytes")); + cur_we->internal_error( + N_("could not determine multiple in bc_tobytes")); *multiple = intnum_get_uint(num); if (*multiple == 0) { *bufsize = 0; @@ -790,7 +801,7 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize, switch (bc->type) { case BC_EMPTY: - InternalError(_("got empty bytecode in bc_tobytes")); + cur_we->internal_error(N_("got empty bytecode in bc_tobytes")); case BC_DATA: error = bc_tobytes_data((bytecode_data *)bc, &destbuf, sect, bc, d, output_expr); @@ -801,7 +812,8 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize, break; case BC_ALIGN: /* TODO */ - InternalError(_("TODO: align bytecode not implemented!")); + cur_we->internal_error( + N_("TODO: align bytecode not implemented!")); /*break;*/ case BC_OBJFMT_DATA: objfmt_data = (bytecode_objfmt_data *)bc; @@ -809,18 +821,20 @@ bc_tobytes(bytecode *bc, unsigned char *buf, unsigned long *bufsize, error = output_bc_objfmt_data(objfmt_data->type, objfmt_data->data, &destbuf); else - InternalError(_("Have objfmt data bytecode but no way to output it")); + cur_we->internal_error( + N_("Have objfmt data bytecode but no way to output it")); break; default: if (bc->type < cur_arch->bc.type_max) error = cur_arch->bc.bc_tobytes(bc, &destbuf, sect, d, output_expr); else - InternalError(_("Unknown bytecode type")); + cur_we->internal_error(N_("Unknown bytecode type")); } if (!error && ((unsigned long)(destbuf - origbuf) != datasize)) - InternalError(_("written length does not match optimized length")); + cur_we->internal_error( + N_("written length does not match optimized length")); return mybuf; } diff --git a/src/bytecode.h b/src/bytecode.h index f2938ef4..2259400e 100644 --- a/src/bytecode.h +++ b/src/bytecode.h @@ -40,7 +40,7 @@ typedef enum { } bytecode_type; #define BYTECODE_TYPE_BASE BC_OBJFMT_DATA+1 -void bc_initialize(arch *a); +void bc_initialize(arch *a, errwarn *we); /*@only@*/ immval *imm_new_int(unsigned long int_val, unsigned long lindex); /*@only@*/ immval *imm_new_expr(/*@keep@*/ expr *e); diff --git a/src/coretype.h b/src/coretype.h index d1585fa9..0701d56d 100644 --- a/src/coretype.h +++ b/src/coretype.h @@ -43,6 +43,7 @@ typedef struct intnum intnum; typedef struct floatnum floatnum; typedef struct linemgr linemgr; +typedef struct errwarn errwarn; typedef enum { EXPR_ADD, diff --git a/src/errwarn.c b/src/errwarn.c index c74d5337..6278a3e1 100644 --- a/src/errwarn.c +++ b/src/errwarn.c @@ -34,29 +34,18 @@ #define MSG_MAXSIZE 1024 -/* ALL warnings are disabled if this is nonzero. */ -int warnings_disabled = 0; +/* Enabled warnings. See errwarn.h for a list. */ +static unsigned long warn_class_enabled; -/* Warnings are treated as errors if this is nonzero. - * =2 indicates that warnings are treated as errors, and the message to the - * user saying that has been output. - */ -int warning_error = 0; +/* Total error count */ +static unsigned int error_count; -/* Default enabled warnings. See errwarn.h for a list. */ -unsigned long warning_flags = - (1UL<= 0 on finish. */ -static unsigned int error_count = 0; - -/* Total warning count for entire assembler run. - * Should not affect exit value of assembler. */ -static unsigned int warning_count = 0; +/* Total warning count */ +static unsigned int warning_count; /* See errwarn.h for constants that match up to these strings. - * When adding a string here, keep errwarn.h in sync! */ + * When adding a string here, keep errwarn.h in sync! + */ /* Fatal error messages. Match up with fatal_num enum in errwarn.h. */ /*@-observertrans@*/ @@ -66,12 +55,12 @@ static const char *fatal_msgs[] = { }; /*@=observertrans@*/ -typedef /*@reldef@*/ SLIST_HEAD(errwarnhead_s, errwarn_s) errwarnhead; -static /*@only@*/ /*@null@*/ errwarnhead errwarns = - SLIST_HEAD_INITIALIZER(errwarns); +typedef /*@reldef@*/ SLIST_HEAD(errwarndatahead_s, errwarn_data) + errwarndatahead; +static /*@only@*/ /*@null@*/ errwarndatahead errwarns; -typedef struct errwarn_s { - /*@reldef@*/ SLIST_ENTRY(errwarn_s) link; +typedef struct errwarn_data { + /*@reldef@*/ SLIST_ENTRY(errwarn_data) link; enum { WE_UNKNOWN, WE_ERROR, WE_WARNING, WE_PARSERERROR } type; @@ -79,18 +68,47 @@ typedef struct errwarn_s { /* FIXME: This should not be a fixed size. But we don't have vasprintf() * right now. */ char msg[MSG_MAXSIZE]; -} errwarn; +} errwarn_data; /* Last inserted error/warning. Used to speed up insertions. */ -static /*@null@*/ errwarn *previous_we = NULL; +static /*@null@*/ errwarn_data *previous_we; /* Static buffer for use by conv_unprint(). */ static char unprint[5]; + +static void +yasm_errwarn_initialize(void) +{ + /* Default enabled warnings. See errwarn.h for a list. */ + warn_class_enabled = + (1UL<type = WE_UNKNOWN; we->line = lindex; @@ -184,7 +205,8 @@ errwarn_new(unsigned long lindex, int replace_parser_error) assert(ins_we != NULL); SLIST_INSERT_AFTER(ins_we, we, link); } else - InternalError(_("Unexpected errwarn insert action")); + yasm_errwarn_internal_error_(__FILE__, __LINE__, + N_("Unexpected errwarn insert action")); } /* Remember previous err/warn */ @@ -193,40 +215,52 @@ errwarn_new(unsigned long lindex, int replace_parser_error) return we; } -/* Register an error. Does not print the error, only stores it for - * OutputAllErrorWarning() to print. +/* Register an error at line lindex. Does not print the error, only stores it + * for output_all() to print. */ static void -error_common(unsigned long lindex, const char *fmt, va_list ap) +yasm_errwarn_error(unsigned long lindex, const char *fmt, ...) { - errwarn *we = errwarn_new(lindex, 1); + va_list va; + errwarn_data *we = errwarn_data_new(lindex, 1); we->type = WE_ERROR; + va_start(va, fmt); #ifdef HAVE_VSNPRINTF - vsnprintf(we->msg, MSG_MAXSIZE, fmt, ap); + vsnprintf(we->msg, MSG_MAXSIZE, gettext(fmt), va); #else - vsprintf(we->msg, fmt, ap); + vsprintf(we->msg, gettext(fmt), va); #endif + va_end(va); error_count++; } -/* Register an warning. Does not print the warning, only stores it for - * OutputAllErrorWarning() to print. +/* Register an warning at line lindex. Does not print the warning, only stores + * it for output_all() to print. */ static void -warning_common(unsigned long lindex, const char *fmt, va_list va) +yasm_errwarn_warning(warn_class_num num, unsigned long lindex, const char *fmt, + ...) { - errwarn *we = errwarn_new(lindex, 0); + va_list va; + errwarn_data *we; + + if (!(warn_class_enabled & (1UL<type = WE_WARNING; + va_start(va, fmt); #ifdef HAVE_VSNPRINTF - vsnprintf(we->msg, MSG_MAXSIZE, fmt, va); + vsnprintf(we->msg, MSG_MAXSIZE, gettext(fmt), va); #else - vsprintf(we->msg, fmt, va); + vsprintf(we->msg, gettext(fmt), va); #endif + va_end(va); warning_count++; } @@ -234,92 +268,59 @@ warning_common(unsigned long lindex, const char *fmt, va_list va) /* Parser error handler. Moves YACC-style error into our error handling * system. */ -void -ParserError(unsigned long lindex, const char *s) +static void +yasm_errwarn_parser_error(unsigned long lindex, const char *s) { - Error(lindex, "%s %s", _("parser error:"), s); + yasm_errwarn_error(lindex, N_("parser error: %s"), s); previous_we->type = WE_PARSERERROR; } -/* Register an error at line lindex. Does not print the error, only stores it - * for OutputAllErrorWarning() to print. - */ -void -Error(unsigned long lindex, const char *fmt, ...) +static void +yasm_errwarn_warn_enable(warn_class_num num) { - va_list va; - va_start(va, fmt); - error_common(lindex, fmt, va); - va_end(va); + warn_class_enabled |= (1UL<lookup(we->line, &filename, &line); if (we->type == WE_ERROR) @@ -327,9 +328,21 @@ OutputAllErrorWarning(linemgr *lm) else fprintf(stderr, "%s:%lu: %s %s\n", filename, line, _("warning:"), we->msg); - - /* Delete */ - SLIST_REMOVE_HEAD(&errwarns, link); - xfree(we); } } + +errwarn yasm_errwarn = { + yasm_errwarn_initialize, + yasm_errwarn_cleanup, + yasm_errwarn_internal_error_, + yasm_errwarn_fatal, + yasm_errwarn_error, + yasm_errwarn_warning, + yasm_errwarn_parser_error, + yasm_errwarn_warn_enable, + yasm_errwarn_warn_disable, + yasm_errwarn_warn_disable_all, + yasm_errwarn_get_num_errors, + yasm_errwarn_output_all, + yasm_errwarn_conv_unprint +}; diff --git a/src/errwarn.h b/src/errwarn.h index 75ee91a3..e3c3014e 100644 --- a/src/errwarn.h +++ b/src/errwarn.h @@ -22,66 +22,66 @@ #ifndef YASM_ERRWARN_H #define YASM_ERRWARN_H -/* ALL warnings disabled? */ -extern int warnings_disabled; - -/* Warnings treated as errors? */ -extern int warning_error; - -/* Warning flags. Currently a maximum of 32 are allowed. This can be - * increased by making this an array and modifying the WARN_ macros to use the - * proper array index based on the warning number. - * - * If a bit is 1, it means that particular warning is enabled. The bit numbers - * are assigned according to the warn_flag_num enum. - * - * See errwarn.c for what warnings are enabled by default. - */ -extern unsigned long warning_flags; +/* Warning classes (may be enabled/disabled). */ typedef enum { - WARN_UNRECOGNIZED_CHAR = 0 -} warn_flag_num; - -/* Tests the warning flags to see if warning "warn" is enabled */ -#define WARN_ENABLED(warn) (warning_flags & (1<<(warn))) -/* Sets warning "warn" to be enabled or disabled based on "s" (1=en, 0=dis). */ -#define WARN_ENABLE(warn, s) do { \ - warning_flags &= ~(1<<(warn)); \ - warning_flags |= (s)<<(warn); \ - } while(0) + WARN_GENERAL = 0, /* non-specific warnings */ + WARN_UNREC_CHAR, /* unrecognized characters (while tokenizing) */ + WARN_PREPROC /* preprocessor warnings */ +} warn_class_num; /* Fatal error constants. * See fatal_msgs in errwarn.c for strings that match up to these constants. - * When adding a constant here, keep errwarn.c in sync! */ + * When adding a constant here, keep errwarn.c in sync! + */ typedef enum { FATAL_UNKNOWN = 0, FATAL_NOMEM } fatal_num; -/*@shared@*/ char *conv_unprint(char ch); +struct errwarn { + /* Initialize any internal data structures. */ + void (*initialize) (void); -void ParserError(unsigned long lindex, const char *); + /* Cleans up any memory allocated by initialize or other functions. */ + void (*cleanup) (void); -/*@exits@*/ void InternalError_(const char *file, unsigned int line, - const char *message); -#define InternalError(msg) InternalError_(__FILE__, __LINE__, msg) + /* Reporting point of internal errors. These are usually due to sanity + * check failures in the code. + * This function must NOT return to calling code. Either exit or longjmp. + */ + /*@exits@*/ void (*internal_error_) (const char *file, unsigned int line, + const char *message); +#define internal_error(msg) internal_error_(__FILE__, __LINE__, msg) -/*@exits@*/ void Fatal(fatal_num); + /* Reporting point of fatal errors. + * This function must NOT return to calling code. Either exit or longjmp. + */ + /*@exits@*/ void (*fatal) (fatal_num); -void Error(unsigned long lindex, const char *, ...) /*@printflike@*/; -void Warning(unsigned long lindex, const char *, ...) /*@printflike@*/; + void (*error) (unsigned long lindex, const char *, ...) /*@printflike@*/; + void (*warning) (warn_class_num, unsigned long lindex, const char *, ...) + /*@printflike@*/; -/* These two functions immediately output the error or warning, with no file - * or line information. They should be used for errors and warnings outside - * the parser stage (at program startup, for instance). - */ -void ErrorNow(const char *, ...) /*@printflike@*/; -void WarningNow(const char *, ...) /*@printflike@*/; + /* Logs a parser error. These can be overwritten by non-parser errors on + * the same line. + */ + void (*parser_error) (unsigned long lindex, const char *); -/* Returns total number of errors to this point in assembly. */ -unsigned int GetNumErrors(void); + /* Enables/disables a class of warnings. */ + void (*warn_enable) (warn_class_num); + void (*warn_disable) (warn_class_num); + void (*warn_disable_all) (void); -/* Outputs all errors/warnings to standard error. */ -void OutputAllErrorWarning(linemgr *lm); + /* Returns total number of errors logged to this point. + * If warning_as_error is nonzero, warnings are treated as errors. + */ + unsigned int (*get_num_errors) (int warning_as_error); + + /* Outputs all errors/warnings (e.g. to stderr or elsewhere). */ + void (*output_all) (linemgr *lm, int warning_as_error); + + /* Convert a possibly unprintable character into a printable string. */ + char * (*conv_unprint) (char ch); +}; #endif diff --git a/src/expr.c b/src/expr.c index a56762aa..8f76aec0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -43,12 +43,14 @@ static int expr_traverse_nodes_post(/*@null@*/ expr *e, /*@null@*/ void *d, /*@null@*/ void *d)); static /*@dependent@*/ arch *cur_arch; +static /*@dependent@*/ errwarn *cur_we; void -expr_initialize(arch *a) +expr_initialize(arch *a, errwarn *we) { cur_arch = a; + cur_we = we; } /* allocate a new expression node, with children as defined. @@ -81,7 +83,7 @@ expr_new(ExprOp op, ExprItem *left, ExprItem *right, unsigned long lindex) /*@=usereleased@*/ } } else { - InternalError(_("Right side of expression must exist")); + cur_we->internal_error(N_("Right side of expression must exist")); } if (right) { @@ -700,7 +702,8 @@ expr_level_tree(expr *e, int fold_const, int simplify_ident, /* Check for circular reference */ SLIST_FOREACH(np, eh, next) { if (np->e == equ_expr) { - Error(e->line, _("circular reference detected.")); + cur_we->error(e->line, + N_("circular reference detected.")); return e; } } diff --git a/src/expr.h b/src/expr.h index 36e53972..73aee925 100644 --- a/src/expr.h +++ b/src/expr.h @@ -24,7 +24,7 @@ typedef struct ExprItem ExprItem; -void expr_initialize(arch *a); +void expr_initialize(arch *a, errwarn *we); /*@only@*/ expr *expr_new(ExprOp, /*@only@*/ ExprItem *, /*@only@*/ /*@null@*/ ExprItem *, diff --git a/src/file.c b/src/file.c index 77f1aa9e..ae05f513 100644 --- a/src/file.c +++ b/src/file.c @@ -24,55 +24,6 @@ #include "file.h" -#include "errwarn.h" - - -char * -replace_extension(const char *orig, /*@null@*/ const char *ext, - const char *def) -{ - char *out, *outext; - - /* allocate enough space for full existing name + extension */ - out = xmalloc(strlen(orig)+(ext ? (strlen(ext)+2) : 1)); - strcpy(out, orig); - outext = strrchr(out, '.'); - if (outext) { - /* Existing extension: make sure it's not the same as the replacement - * (as we don't want to overwrite the source file). - */ - outext++; /* advance past '.' */ - if (ext && strcmp(outext, ext) == 0) { - outext = NULL; /* indicate default should be used */ - WarningNow(_("file name already ends in `.%s': output will be in `%s'"), - ext, def); - } - } else { - /* No extension: make sure the output extension is not empty - * (again, we don't want to overwrite the source file). - */ - if (!ext) - WarningNow(_("file name already has no extension: output will be in `%s'"), - def); - else { - outext = strrchr(out, '\0'); /* point to end of the string */ - *outext++ = '.'; /* append '.' */ - } - } - - /* replace extension or use default name */ - if (outext) { - if (!ext) { - /* Back up and replace '.' with string terminator */ - outext--; - *outext = '\0'; - } else - strcpy(outext, ext); - } else - strcpy(out, def); - - return out; -} size_t fwrite_16_l(unsigned short val, FILE *f) diff --git a/src/file.h b/src/file.h index 39407478..be83f779 100644 --- a/src/file.h +++ b/src/file.h @@ -22,15 +22,6 @@ #ifndef YASM_FILE_H #define YASM_FILE_H -/* Replace extension on a filename (or append one if none is present). - * If output filename would be identical to input (same extension out as in), - * returns (copy of) def. - * A NULL ext means the trailing '.' should NOT be included, whereas a "" ext - * means the trailing '.' should be included. - */ -/*@only@*/ char *replace_extension(const char *orig, /*@null@*/ - const char *ext, const char *def); - /* These functions only work properly if p is an (unsigned char *) */ #define WRITE_8(ptr, val) \ diff --git a/src/floatnum.c b/src/floatnum.c index f7b4fe60..73da72d9 100644 --- a/src/floatnum.c +++ b/src/floatnum.c @@ -84,9 +84,7 @@ typedef struct POT_Entry_Source_s { * entry[12-n] = 10 ** (-2 ** n) for 0 <= n <= 12. * entry[13] = 1.0 */ -/*@-nullassign@*/ -static /*@only@*/ POT_Entry *POT_TableN = (POT_Entry *)NULL; -/*@=nullassign@*/ +static /*@only@*/ POT_Entry *POT_TableN; static POT_Entry_Source POT_TableN_Source[] = { {{0xe3,0x2d,0xde,0x9f,0xce,0xd2,0xc8,0x04,0xdd,0xa6},0x4ad8}, /* 1e-4096 */ {{0x25,0x49,0xe4,0x2d,0x36,0x34,0x4f,0x53,0xae,0xce},0x656b}, /* 1e-2048 */ @@ -132,6 +130,9 @@ static POT_Entry_Source POT_TableP_Source[] = { {{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80},0x7fff}, /* 1e+0 */ }; +static /*@dependent@*/ errwarn *cur_we; + + static void POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp) { @@ -153,14 +154,16 @@ POT_Table_Init_Entry(/*@out@*/ POT_Entry *e, POT_Entry_Source *s, int dec_exp) } /*@-compdef@*/ -static void -POT_Table_Init(void) +void +floatnum_initialize(errwarn *we) /*@globals undef POT_TableN, undef POT_TableP, POT_TableP_Source, POT_TableN_Source @*/ { int dec_exp = 1; int i; + cur_we = we; + /* Allocate space for two POT tables */ POT_TableN = xmalloc(14*sizeof(POT_Entry)); POT_TableP = xmalloc(15*sizeof(POT_Entry)); /* note 1 extra for -1 */ @@ -186,13 +189,10 @@ POT_Table_Init(void) /*@-globstate@*/ void -floatnum_shutdown(void) +floatnum_cleanup(void) { int i; - if (!POT_TableN) - return; - /* Un-offset POT_TableP */ POT_TableP--; @@ -310,10 +310,6 @@ floatnum_new(const char *str) int decimal_pt; boolean carry; - /* Initialize POT tables if necessary */ - if (!POT_TableN) - POT_Table_Init(); - flt = xmalloc(sizeof(floatnum)); flt->mantissa = BitVector_Create(MANT_BITS, TRUE); @@ -515,7 +511,8 @@ floatnum_calc(floatnum *acc, ExprOp op, /*@unused@*/ floatnum *operand, unsigned long lindex) { if (op != EXPR_NEG) - Error(lindex, _("Unsupported floating-point arithmetic operation")); + cur_we->error(lindex, + N_("Unsupported floating-point arithmetic operation")); else acc->sign ^= 1; } @@ -590,7 +587,7 @@ floatnum_get_common(const floatnum *flt, /*@out@*/ unsigned char *ptr, /* underflow and overflow both set!? */ if (underflow && overflow) - InternalError(_("Both underflow and overflow set")); + cur_we->internal_error(N_("Both underflow and overflow set")); /* check for underflow or overflow and set up appropriate output */ if (underflow) { @@ -613,7 +610,8 @@ floatnum_get_common(const floatnum *flt, /*@out@*/ unsigned char *ptr, /* get little-endian bytes */ buf = BitVector_Block_Read(output, &len); if (len < byte_size) - InternalError(_("Byte length of BitVector does not match bit length")); + cur_we->internal_error( + N_("Byte length of BitVector does not match bit length")); /* copy to output */ memcpy(ptr, buf, byte_size*sizeof(unsigned char)); @@ -667,7 +665,7 @@ floatnum_get_sized(const floatnum *flt, unsigned char *ptr, size_t size) case 10: return floatnum_get_common(flt, ptr, 10, 64, 0, 15); default: - InternalError(_("Invalid float conversion size")); + cur_we->internal_error(N_("Invalid float conversion size")); /*@notreached@*/ return 1; /* never reached, but silence GCC warning */ } diff --git a/src/floatnum.h b/src/floatnum.h index a5d05bba..60f20050 100644 --- a/src/floatnum.h +++ b/src/floatnum.h @@ -24,8 +24,9 @@ #ifndef YASM_FLOATNUM_H #define YASM_FLOATNUM_H +void floatnum_initialize(errwarn *we); /* Clean up internal allocations */ -void floatnum_shutdown(void); +void floatnum_cleanup(void); /*@only@*/ floatnum *floatnum_new(const char *str); /*@only@*/ floatnum *floatnum_copy(const floatnum *flt); diff --git a/src/hamt.c b/src/hamt.c index 26606d70..a1fa2c3b 100644 --- a/src/hamt.c +++ b/src/hamt.c @@ -35,7 +35,6 @@ #include "util.h" /*@unused@*/ RCSID("$IdPath$"); -#include "errwarn.h" #include "hamt.h" typedef struct HAMTEntry { @@ -52,6 +51,8 @@ typedef struct HAMTNode { struct HAMT { SLIST_HEAD(HAMTEntryHead, HAMTEntry) entries; HAMTNode *root; + /*@exits@*/ void (*error_func) (const char *file, unsigned int line, + const char *message); }; /* XXX make a portable version of this. This depends on the pointer being @@ -59,9 +60,10 @@ struct HAMT { * the subtrie flag! */ #define IsSubTrie(n) ((unsigned long)((n)->BaseValue) & 1) -#define SetSubTrie(n, v) do { \ +#define SetSubTrie(h, n, v) do { \ if ((unsigned long)(v) & 1) \ - InternalError(_("Subtrie is seen as subtrie before flag is set (misaligned?)")); \ + h->error_func(__FILE__, __LINE__, \ + N_("Subtrie is seen as subtrie before flag is set (misaligned?)")); \ (n)->BaseValue = (void *)((unsigned long)(v) | 1); \ } while (0) #define GetSubTrie(n) (HAMTNode *)((unsigned long)((n)->BaseValue)&~1UL) @@ -85,7 +87,8 @@ ReHashKey(const char *key, int Level) } HAMT * -HAMT_new(void) +HAMT_new(/*@exits@*/ void (*error_func) (const char *file, unsigned int line, + const char *message)) { /*@out@*/ HAMT *hamt = xmalloc(sizeof(HAMT)); int i; @@ -98,6 +101,8 @@ HAMT_new(void) hamt->root[i].BaseValue = NULL; } + hamt->error_func = error_func; + return hamt; } @@ -174,7 +179,8 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace, SLIST_INSERT_HEAD(&hamt->entries, entry, next); node->BaseValue = entry; if (IsSubTrie(node)) - InternalError(_("Data is seen as subtrie (misaligned?)")); + hamt->error_func(__FILE__, __LINE__, + N_("Data is seen as subtrie (misaligned?)")); *replace = 1; return data; } @@ -216,7 +222,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace, newnodes = xmalloc(sizeof(HAMTNode)); newnodes[0] = *node; /* structure copy */ node->BitMapKey = 1<BitMapKey = (1UL<data = data; SLIST_INSERT_HEAD(&hamt->entries, entry, next); newnodes[Map].BaseValue = entry; - SetSubTrie(node, newnodes); + SetSubTrie(hamt, node, newnodes); *replace = 1; return data; diff --git a/src/hamt.h b/src/hamt.h index b3cd7931..c21d5201 100644 --- a/src/hamt.h +++ b/src/hamt.h @@ -32,8 +32,12 @@ typedef struct HAMT HAMT; -/* Creates new, empty, HAMT. */ -HAMT *HAMT_new(void); +/* Creates new, empty, HAMT. error_func() is called when an internal error is + * encountered--it should NOT return to the calling function. + */ +HAMT *HAMT_new(/*@exits@*/ void (*error_func) (const char *file, + unsigned int line, + const char *message)); /* Deletes HAMT and all data associated with it using deletefunc() on each data * item. diff --git a/src/intnum.c b/src/intnum.c index 3ca4775d..5fba7ab7 100644 --- a/src/intnum.c +++ b/src/intnum.c @@ -43,15 +43,23 @@ struct intnum { }; /* static bitvect used for conversions */ -static /*@only@*/ /*@null@*/ wordptr conv_bv = NULL; +static /*@only@*/ wordptr conv_bv; +static /*@dependent@*/ errwarn *cur_we; + void -intnum_shutdown(void) +intnum_initialize(errwarn *we) { - if (conv_bv) { - BitVector_Destroy(conv_bv); - conv_bv = NULL; - } + cur_we = we; + + conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE); + BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE); +} + +void +intnum_cleanup(void) +{ + BitVector_Destroy(conv_bv); BitVector_from_Dec_static_Shutdown(); } @@ -62,13 +70,10 @@ intnum_new_dec(char *str, unsigned long lindex) intn->origsize = 0; /* no reliable way to figure this out */ - if (!conv_bv) { - conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE); - BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE); - } if (BitVector_from_Dec_static(conv_bv, (unsigned char *)str) == ErrCode_Ovfl) - Warning(lindex, _("Numeric constant too large for internal format")); + cur_we->warning(WARN_GENERAL, lindex, + N_("Numeric constant too large for internal format")); if (Set_Max(conv_bv) < 32) { intn->type = INTNUM_UL; intn->val.ul = BitVector_Chunk_Read(conv_bv, 32, 0); @@ -88,12 +93,9 @@ intnum_new_bin(char *str, unsigned long lindex) intn->origsize = (unsigned char)strlen(str); if(intn->origsize > BITVECT_ALLOC_SIZE) - Warning(lindex, _("Numeric constant too large for internal format")); + cur_we->warning(WARN_GENERAL, lindex, + N_("Numeric constant too large for internal format")); - if (!conv_bv) { - conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE); - BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE); - } BitVector_from_Bin(conv_bv, (unsigned char *)str); if (Set_Max(conv_bv) < 32) { intn->type = INTNUM_UL; @@ -114,12 +116,9 @@ intnum_new_oct(char *str, unsigned long lindex) intn->origsize = strlen(str)*3; if(intn->origsize > BITVECT_ALLOC_SIZE) - Warning(lindex, _("Numeric constant too large for internal format")); + cur_we->warning(WARN_GENERAL, lindex, + N_("Numeric constant too large for internal format")); - if (!conv_bv) { - conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE); - BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE); - } BitVector_from_Oct(conv_bv, (unsigned char *)str); if (Set_Max(conv_bv) < 32) { intn->type = INTNUM_UL; @@ -140,12 +139,9 @@ intnum_new_hex(char *str, unsigned long lindex) intn->origsize = strlen(str)*4; if(intn->origsize > BITVECT_ALLOC_SIZE) - Warning(lindex, _("Numeric constant too large for internal format")); + cur_we->warning(WARN_GENERAL, lindex, + N_("Numeric constant too large for internal format")); - if (!conv_bv) { - conv_bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE); - BitVector_from_Dec_static_Boot(BITVECT_ALLOC_SIZE); - } BitVector_from_Hex(conv_bv, (unsigned char *)str); if (Set_Max(conv_bv) < 32) { intn->type = INTNUM_UL; @@ -166,8 +162,8 @@ intnum_new_charconst_nasm(const char *str, unsigned long lindex) size_t len = strlen(str); if (len > 4) - Warning(lindex, - _("character constant too large, ignoring trailing characters")); + cur_we->warning(WARN_GENERAL, lindex, + N_("character constant too large, ignoring trailing characters")); intn->val.ul = 0; intn->type = INTNUM_UL; @@ -273,7 +269,7 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand) } if (!operand && op != EXPR_NEG && op != EXPR_NOT && op != EXPR_LNOT) - InternalError(_("Operation needs an operand")); + cur_we->internal_error(N_("Operation needs an operand")); /* A operation does a bitvector computation if result is allocated. */ switch (op) { @@ -444,7 +440,8 @@ intnum_calc(intnum *acc, ExprOp op, intnum *operand) BitVector_Copy(result, op1); break; default: - InternalError(_("invalid operation in intnum calculation")); + cur_we->internal_error( + N_("invalid operation in intnum calculation")); } /* If we were doing a bitvector computation... */ @@ -507,7 +504,7 @@ intnum_get_uint(const intnum *intn) case INTNUM_BV: return BitVector_Chunk_Read(intn->val.bv, 32, 0); default: - InternalError(_("unknown intnum type")); + cur_we->internal_error(N_("unknown intnum type")); /*@notreached@*/ return 0; } @@ -535,7 +532,7 @@ intnum_get_int(const intnum *intn) } else return (long)BitVector_Chunk_Read(intn->val.bv, 32, 0); default: - InternalError(_("unknown intnum type")); + cur_we->internal_error(N_("unknown intnum type")); /*@notreached@*/ return 0; } @@ -560,7 +557,8 @@ intnum_get_sized(const intnum *intn, unsigned char *ptr, size_t size) case INTNUM_BV: buf = BitVector_Block_Read(intn->val.bv, &len); if (len < (unsigned int)size) - InternalError(_("Invalid size specified (too large)")); + cur_we->internal_error( + N_("Invalid size specified (too large)")); memcpy(ptr, buf, size); xfree(buf); break; diff --git a/src/intnum.h b/src/intnum.h index 99f1a105..cd05c737 100644 --- a/src/intnum.h +++ b/src/intnum.h @@ -22,8 +22,9 @@ #ifndef YASM_INTNUM_H #define YASM_INTNUM_H +void intnum_initialize(errwarn *we); /* Clean up internal allocations */ -void intnum_shutdown(void); +void intnum_cleanup(void); /*@only@*/ intnum *intnum_new_dec(char *str, unsigned long lindex); /*@only@*/ intnum *intnum_new_bin(char *str, unsigned long lindex); diff --git a/src/linemgr.c b/src/linemgr.c index 718b01b9..5bdbc7ae 100644 --- a/src/linemgr.c +++ b/src/linemgr.c @@ -93,9 +93,12 @@ yasm_linemgr_set(const char *filename, unsigned long line, } static void -yasm_linemgr_initialize(void) +yasm_linemgr_initialize(/*@exits@*/ + void (*error_func) (const char *file, + unsigned int line, + const char *message)) { - filename_table = HAMT_new(); + filename_table = HAMT_new(error_func); line_index = 1; diff --git a/src/linemgr.h b/src/linemgr.h index 85d474e0..0412df6f 100644 --- a/src/linemgr.h +++ b/src/linemgr.h @@ -24,7 +24,10 @@ struct linemgr { /* Initialize cur_lindex and any manager internal data structures. */ - void (*initialize) (void); + void (*initialize) (/*@exits@*/ + void (*error_func) (const char *file, + unsigned int line, + const char *message)); /* Cleans up any memory allocated by initialize. */ void (*cleanup) (void); diff --git a/src/main.c b/src/main.c index a63bc53f..b8689b13 100644 --- a/src/main.c +++ b/src/main.c @@ -50,6 +50,9 @@ /* YASM's line manager (for parse stage). */ extern linemgr yasm_linemgr; +/* YASM's errwarn handlers. */ +extern errwarn yasm_errwarn; + /* Extra path to search for our modules. */ #ifndef YASM_MODULE_PATH_ENV # define YASM_MODULE_PATH_ENV "YASM_MODULE_PATH" @@ -67,6 +70,7 @@ static int special_options = 0; /*@null@*/ /*@dependent@*/ static optimizer *cur_optimizer = NULL; /*@null@*/ /*@dependent@*/ static dbgfmt *cur_dbgfmt = NULL; static int preproc_only = 0; +static int warning_error = 0; /* warnings being treated as errors */ /*@null@*/ /*@dependent@*/ static FILE *open_obj(const char *mode); static void cleanup(/*@null@*/ sectionhead *sections); @@ -81,6 +85,9 @@ static int opt_objfile_handler(char *cmd, /*@null@*/ char *param, int extra); static int opt_warning_handler(char *cmd, /*@null@*/ char *param, int extra); static int preproc_only_handler(char *cmd, /*@null@*/ char *param, int extra); +static /*@only@*/ char *replace_extension(const char *orig, /*@null@*/ + const char *ext, const char *def); + /* values for special_options */ #define SPECIAL_SHOW_HELP 0x01 #define SPECIAL_SHOW_VERSION 0x02 @@ -102,15 +109,16 @@ static opt_option options[] = /* version message */ /*@observer@*/ static const char *version_msg[] = { - N_("yasm " VERSION "\n"), - N_("Copyright (c) 2001-2002 Peter Johnson and other " PACKAGE " developers\n"), + PACKAGE " " VERSION "\n", + N_("Copyright (c) 2001-2002 Peter Johnson and other"), " " PACKAGE " ", + N_("developers.\n"), N_("This program is free software; you may redistribute it under the\n"), N_("terms of the GNU General Public License. Portions of this program\n"), N_("are licensed under the GNU Lesser General Public License or the\n"), N_("3-clause BSD license; see individual file comments for details.\n"), N_("This program has absolutely no warranty; not even for\n"), N_("merchantibility or fitness for a particular purpose.\n"), - N_("Compiled on " __DATE__ ".\n"), + N_("Compiled on"), " " __DATE__ ".\n", }; /* help messages */ @@ -144,6 +152,12 @@ main(int argc, char *argv[]) #endif textdomain(PACKAGE); + /* Initialize errwarn handling */ + yasm_errwarn.initialize(); + + /* Initialize memory allocation */ + xalloc_initialize((void (*) (int))yasm_errwarn.fatal, FATAL_NOMEM); + /* Set libltdl malloc/free functions. */ #ifdef WITH_DMALLOC lt_dlmalloc = malloc; @@ -166,7 +180,7 @@ main(int argc, char *argv[]) errors = lt_dladdsearchdir(path); } if (errors != 0) { - ErrorNow(_("Module loader initialization failed")); + fprintf(stderr, _("Module loader initialization failed")); return EXIT_FAILURE; } @@ -186,7 +200,7 @@ main(int argc, char *argv[]) /* Initialize BitVector (needed for floating point). */ if (BitVector_Boot() != ErrCode_Ok) { - ErrorNow(_("Could not initialize BitVector")); + fprintf(stderr, _("Could not initialize BitVector")); return EXIT_FAILURE; } @@ -194,7 +208,7 @@ main(int argc, char *argv[]) /* Open the input file (if not standard input) */ in = fopen(in_filename, "rt"); if (!in) { - ErrorNow(_("could not open file `%s'"), in_filename); + fprintf(stderr, _("could not open file `%s'"), in_filename); xfree(in_filename); if (obj_filename) xfree(obj_filename); @@ -208,9 +222,16 @@ main(int argc, char *argv[]) } /* Initialize line manager */ - yasm_linemgr.initialize(); + yasm_linemgr.initialize(yasm_errwarn.internal_error_); yasm_linemgr.set(in_filename, 1, 1); + /* Initialize intnum and floatnum */ + intnum_initialize(&yasm_errwarn); + floatnum_initialize(&yasm_errwarn); + + /* Initialize symbol table */ + symrec_initialize(&yasm_errwarn); + /* handle preproc-only case here */ if (preproc_only) { char *preproc_buf = xmalloc(PREPROC_BUF_SIZE); @@ -233,15 +254,14 @@ main(int argc, char *argv[]) cur_preproc = load_preproc("yapp"); if (!cur_preproc) { - ErrorNow(_("Could not load default preprocessor")); + fprintf(stderr, _("Could not load default preprocessor")); cleanup(NULL); return EXIT_FAILURE; } /* Pre-process until done */ - cur_preproc->initialize(in, in_filename); - while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE, - &yasm_linemgr)) != 0) + cur_preproc->initialize(in, in_filename, &yasm_linemgr, &yasm_errwarn); + while ((got = cur_preproc->input(preproc_buf, PREPROC_BUF_SIZE)) != 0) fwrite(preproc_buf, got, 1, obj); if (in != stdin) @@ -250,8 +270,8 @@ main(int argc, char *argv[]) if (obj != stdout) fclose(obj); - if (GetNumErrors() > 0) { - OutputAllErrorWarning(&yasm_linemgr); + if (yasm_errwarn.get_num_errors(warning_error) > 0) { + yasm_errwarn.output_all(&yasm_linemgr, warning_error); if (obj != stdout) remove(obj_filename); xfree(preproc_buf); @@ -267,28 +287,30 @@ main(int argc, char *argv[]) cur_arch = load_arch("x86"); if (!cur_arch) { - ErrorNow(_("Could not load default architecture")); + fprintf(stderr, _("Could not load default architecture")); return EXIT_FAILURE; } + cur_arch->initialize(&yasm_errwarn); + /* Set basic as the optimizer (TODO: user choice) */ cur_optimizer = load_optimizer("basic"); if (!cur_optimizer) { - ErrorNow(_("Could not load default optimizer")); + fprintf(stderr, _("Could not load default optimizer")); return EXIT_FAILURE; } arch_common_initialize(cur_arch); - expr_initialize(cur_arch); - bc_initialize(cur_arch); + expr_initialize(cur_arch, &yasm_errwarn); + bc_initialize(cur_arch, &yasm_errwarn); /* If not already specified, default to bin as the object format. */ if (!cur_objfmt) cur_objfmt = load_objfmt("bin"); if (!cur_objfmt) { - ErrorNow(_("Could not load default object format")); + fprintf(stderr, _("Could not load default object format")); return EXIT_FAILURE; } @@ -305,8 +327,9 @@ main(int argc, char *argv[]) cur_dbgfmt->keyword) == 0) matched_dbgfmt = 1; if (!matched_dbgfmt) { - ErrorNow(_("`%s' is not a valid debug format for object format `%s'"), - cur_dbgfmt->keyword, cur_objfmt->keyword); + fprintf(stderr, + _("`%s' is not a valid debug format for object format `%s'"), + cur_dbgfmt->keyword, cur_objfmt->keyword); if (in != stdin) fclose(in); cleanup(NULL); @@ -315,7 +338,7 @@ main(int argc, char *argv[]) } if (!cur_dbgfmt) { - ErrorNow(_("Could not load default debug format")); + fprintf(stderr, _("Could not load default debug format")); return EXIT_FAILURE; } @@ -334,12 +357,12 @@ main(int argc, char *argv[]) /* Initialize the object format */ if (cur_objfmt->initialize) cur_objfmt->initialize(in_filename, obj_filename, cur_dbgfmt, - cur_arch); + cur_arch, &yasm_errwarn); /* Set NASM as the parser */ cur_parser = load_parser("nasm"); if (!cur_parser) { - ErrorNow(_("unrecognized parser `%s'"), "nasm"); + fprintf(stderr, _("unrecognized parser `%s'"), "nasm"); cleanup(NULL); return EXIT_FAILURE; } @@ -357,8 +380,9 @@ main(int argc, char *argv[]) cur_preproc->keyword) == 0) matched_preproc = 1; if (!matched_preproc) { - ErrorNow(_("`%s' is not a valid preprocessor for parser `%s'"), - cur_preproc->keyword, cur_parser->keyword); + fprintf(stderr, + _("`%s' is not a valid preprocessor for parser `%s'"), + cur_preproc->keyword, cur_parser->keyword); if (in != stdin) fclose(in); cleanup(NULL); @@ -376,23 +400,24 @@ main(int argc, char *argv[]) /* Parse! */ sections = cur_parser->do_parse(cur_preproc, cur_arch, cur_objfmt, - &yasm_linemgr, in, in_filename); + &yasm_linemgr, &yasm_errwarn, in, + in_filename); /* Close input file */ if (in != stdin) fclose(in); - if (GetNumErrors() > 0) { - OutputAllErrorWarning(&yasm_linemgr); + if (yasm_errwarn.get_num_errors(warning_error) > 0) { + yasm_errwarn.output_all(&yasm_linemgr, warning_error); cleanup(sections); return EXIT_FAILURE; } symrec_parser_finalize(); - cur_optimizer->optimize(sections); + cur_optimizer->optimize(sections, &yasm_errwarn); - if (GetNumErrors() > 0) { - OutputAllErrorWarning(&yasm_linemgr); + if (yasm_errwarn.get_num_errors(warning_error) > 0) { + yasm_errwarn.output_all(&yasm_linemgr, warning_error); cleanup(sections); return EXIT_FAILURE; } @@ -416,14 +441,14 @@ main(int argc, char *argv[]) /* If we had an error at this point, we also need to delete the output * object file (to make sure it's not left newer than the source). */ - if (GetNumErrors() > 0) { - OutputAllErrorWarning(&yasm_linemgr); + if (yasm_errwarn.get_num_errors(warning_error) > 0) { + yasm_errwarn.output_all(&yasm_linemgr, warning_error); remove(obj_filename); cleanup(sections); return EXIT_FAILURE; } - OutputAllErrorWarning(&yasm_linemgr); + yasm_errwarn.output_all(&yasm_linemgr, warning_error); cleanup(sections); return EXIT_SUCCESS; @@ -440,7 +465,7 @@ open_obj(const char *mode) obj = fopen(obj_filename, mode); if (!obj) - ErrorNow(_("could not open file `%s'"), obj_filename); + fprintf(stderr, _("could not open file `%s'"), obj_filename); return obj; } @@ -450,13 +475,21 @@ cleanup(sectionhead *sections) { if (cur_objfmt && cur_objfmt->cleanup) cur_objfmt->cleanup(); + if (cur_dbgfmt && cur_dbgfmt->cleanup) + cur_dbgfmt->cleanup(); + if (cur_preproc) + cur_preproc->cleanup(); if (sections) sections_delete(sections); - symrec_delete_all(); - yasm_linemgr.cleanup(); + symrec_cleanup(); + if (cur_arch) + cur_arch->cleanup(); - floatnum_shutdown(); - intnum_shutdown(); + floatnum_cleanup(); + intnum_cleanup(); + + yasm_errwarn.cleanup(); + yasm_linemgr.cleanup(); BitVector_Shutdown(); @@ -478,7 +511,8 @@ int not_an_option_handler(char *param) { if (in_filename) { - WarningNow(_("can open only one input file, only the last file will be processed")); + fprintf(stderr, + _("warning: can open only one input file, only the last file will be processed")); xfree(in_filename); } @@ -501,7 +535,7 @@ opt_parser_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) assert(param != NULL); cur_parser = load_parser(param); if (!cur_parser) { - ErrorNow(_("unrecognized parser `%s'"), param); + fprintf(stderr, _("unrecognized parser `%s'"), param); return 1; } return 0; @@ -513,7 +547,7 @@ opt_preproc_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) assert(param != NULL); cur_preproc = load_preproc(param); if (!cur_preproc) { - ErrorNow(_("unrecognized preprocessor `%s'"), param); + fprintf(stderr, _("unrecognized preprocessor `%s'"), param); return 1; } return 0; @@ -525,7 +559,7 @@ opt_objfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) assert(param != NULL); cur_objfmt = load_objfmt(param); if (!cur_objfmt) { - ErrorNow(_("unrecognized object format `%s'"), param); + fprintf(stderr, _("unrecognized object format `%s'"), param); return 1; } return 0; @@ -537,7 +571,7 @@ opt_dbgfmt_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) assert(param != NULL); cur_dbgfmt = load_objfmt(param); if (!cur_dbgfmt) { - ErrorNow(_("unrecognized debugging format `%s'"), param); + fprintf(stderr, _("unrecognized debugging format `%s'"), param); return 1; } return 0; @@ -548,7 +582,8 @@ opt_objfile_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra) { if (obj_filename) { - WarningNow(_("can output to only one object file, last specified used")); + fprintf(stderr, + _("warning: can output to only one object file, last specified used")); xfree(obj_filename); } @@ -565,7 +600,7 @@ opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra) if (extra == 1) { /* -w, disable warnings */ - warnings_disabled = 1; + yasm_errwarn.warn_disable_all(); return 0; } @@ -584,7 +619,10 @@ opt_warning_handler(char *cmd, /*@unused@*/ char *param, int extra) else if (strcmp(cmd, "error") == 0) { warning_error = enable; } else if (strcmp(cmd, "unrecognized-char") == 0) { - WARN_ENABLE(WARN_UNRECOGNIZED_CHAR, enable); + if (enable) + yasm_errwarn.warn_enable(WARN_UNREC_CHAR); + else + yasm_errwarn.warn_disable(WARN_UNREC_CHAR); } else return 1; @@ -598,3 +636,58 @@ preproc_only_handler(/*@unused@*/ char *cmd, /*@unused@*/ char *param, preproc_only = 1; return 0; } + +/* Replace extension on a filename (or append one if none is present). + * If output filename would be identical to input (same extension out as in), + * returns (copy of) def. + * A NULL ext means the trailing '.' should NOT be included, whereas a "" ext + * means the trailing '.' should be included. + */ +static char * +replace_extension(const char *orig, /*@null@*/ const char *ext, + const char *def) +{ + char *out, *outext; + + /* allocate enough space for full existing name + extension */ + out = xmalloc(strlen(orig)+(ext ? (strlen(ext)+2) : 1)); + strcpy(out, orig); + outext = strrchr(out, '.'); + if (outext) { + /* Existing extension: make sure it's not the same as the replacement + * (as we don't want to overwrite the source file). + */ + outext++; /* advance past '.' */ + if (ext && strcmp(outext, ext) == 0) { + outext = NULL; /* indicate default should be used */ + fprintf(stderr, + _("file name already ends in `.%s': output will be in `%s'"), + ext, def); + } + } else { + /* No extension: make sure the output extension is not empty + * (again, we don't want to overwrite the source file). + */ + if (!ext) + fprintf(stderr, + _("file name already has no extension: output will be in `%s'"), + def); + else { + outext = strrchr(out, '\0'); /* point to end of the string */ + *outext++ = '.'; /* append '.' */ + } + } + + /* replace extension or use default name */ + if (outext) { + if (!ext) { + /* Back up and replace '.' with string terminator */ + outext--; + *outext = '\0'; + } else + strcpy(outext, ext); + } else + strcpy(out, def); + + return out; +} diff --git a/src/objfmt.h b/src/objfmt.h index 55f7b9cc..9735ae4e 100644 --- a/src/objfmt.h +++ b/src/objfmt.h @@ -57,7 +57,7 @@ struct objfmt { * provided solely for informational purposes. */ void (*initialize) (const char *in_filename, const char *obj_filename, - dbgfmt *df, arch *a); + dbgfmt *df, arch *a, errwarn *we); /* Write out (post-optimized) sections to the object file. * This function may call symrec functions as necessary (including diff --git a/src/objfmts/bin/bin-objfmt.c b/src/objfmts/bin/bin-objfmt.c index 1ff0534c..d28bac1c 100644 --- a/src/objfmts/bin/bin-objfmt.c +++ b/src/objfmts/bin/bin-objfmt.c @@ -44,14 +44,16 @@ objfmt yasm_bin_LTX_objfmt; static /*@dependent@*/ arch *cur_arch; +static /*@dependent@*/ errwarn *cur_we; static void bin_objfmt_initialize(/*@unused@*/ const char *in_filename, /*@unused@*/ const char *obj_filename, - /*@unused@*/ dbgfmt *df, arch *a) + /*@unused@*/ dbgfmt *df, arch *a, errwarn *we) { cur_arch = a; + cur_we = we; } /* Aligns sect to either its specified alignment (in its objfmt-specific data) @@ -163,13 +165,14 @@ bin_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize, /* Check for complex float expressions */ if (expr_contains(*ep, EXPR_FLOAT)) { - Error((*ep)->line, _("floating point expression too complex")); + cur_we->error((*ep)->line, + N_("floating point expression too complex")); return 1; } /* Couldn't output, assume it contains an external reference. */ - Error((*ep)->line, - _("binary object format does not support external references")); + cur_we->error((*ep)->line, + N_("binary object format does not support external references")); return 1; } @@ -198,8 +201,8 @@ bin_objfmt_output_bytecode(bytecode *bc, /*@null@*/ void *d) /* Warn that gaps are converted to 0 and write out the 0's. */ if (gap) { unsigned long left; - Warning(bc->line, - _("uninitialized space declared in code/data section: zeroing")); + cur_we->warning(WARN_GENERAL, bc->line, + N_("uninitialized space declared in code/data section: zeroing")); /* Write out in chunks */ memset(info->buf, 0, REGULAR_OUTBUF_SIZE); left = multiple*size; @@ -241,7 +244,7 @@ bin_objfmt_output(FILE *f, sectionhead *sections) bss = sections_find_general(sections, ".bss"); if (!text) - InternalError(_("No `.text' section in bin objfmt output")); + cur_we->internal_error(N_("No `.text' section in bin objfmt output")); /* First determine the actual starting offsets for .data and .bss. * As the order in the file is .text -> .data -> .bss (not present), @@ -255,7 +258,8 @@ bin_objfmt_output(FILE *f, sectionhead *sections) assert(startexpr != NULL); startnum = expr_get_intnum(&startexpr, NULL); if (!startnum) - InternalError(_("Complex expr for start in bin objfmt output")); + cur_we->internal_error( + N_("Complex expr for start in bin objfmt output")); start = intnum_get_uint(startnum); expr_delete(startexpr); textstart = start; @@ -340,7 +344,8 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, resonly = 1; } else { /* other section names not recognized. */ - Error(lindex, _("segment name `%s' not recognized"), sectname); + cur_we->error(lindex, N_("segment name `%s' not recognized"), + sectname); return NULL; } @@ -351,16 +356,17 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, unsigned long bitcnt; if (strcmp(sectname, ".text") == 0) { - Error(lindex, - _("cannot specify an alignment to the `%s' section"), - sectname); + cur_we->error(lindex, + N_("cannot specify an alignment to the `%s' section"), + sectname); return NULL; } align = expr_get_intnum(&vp->param, NULL); if (!align) { - Error(lindex, _("argument to `%s' is not a power of two"), - vp->val); + cur_we->error(lindex, + N_("argument to `%s' is not a power of two"), + vp->val); return NULL; } alignval = intnum_get_uint(align); @@ -370,8 +376,9 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, */ BitCount(bitcnt, alignval); if (bitcnt > 1) { - Error(lindex, _("argument to `%s' is not a power of two"), - vp->val); + cur_we->error(lindex, + N_("argument to `%s' is not a power of two"), + vp->val); return NULL; } @@ -380,7 +387,8 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, } retval = sections_switch_general(headp, sectname, start, resonly, - &isnew, lindex); + &isnew, lindex, + cur_we->internal_error_); if (isnew) { if (have_alignval) { @@ -391,8 +399,8 @@ bin_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, symrec_define_label(sectname, retval, (bytecode *)NULL, 1, lindex); } else if (have_alignval) - Warning(lindex, - _("alignment value ignored on section redeclaration")); + cur_we->warning(WARN_GENERAL, lindex, + N_("alignment value ignored on section redeclaration")); return retval; } else @@ -411,7 +419,8 @@ bin_objfmt_common_declare(/*@unused@*/ symrec *sym, /*@only@*/ expr *size, valparamhead *objext_valparams, unsigned long lindex) { expr_delete(size); - Error(lindex, _("binary object format does not support common variables")); + cur_we->error(lindex, + N_("binary object format does not support common variables")); } static int @@ -428,20 +437,21 @@ bin_objfmt_directive(const char *name, valparamhead *valparams, /* ORG takes just a simple integer as param */ vp = vps_first(valparams); if (vp->val) { - Error(lindex, _("argument to ORG should be numeric")); + cur_we->error(lindex, N_("argument to ORG should be numeric")); return 0; } else if (vp->param) start = expr_get_intnum(&vp->param, NULL); if (!start) { - Error(lindex, _("argument to ORG should be numeric")); + cur_we->error(lindex, N_("argument to ORG should be numeric")); return 0; } /* ORG changes the start of the .text section */ sect = sections_find_general(headp, ".text"); if (!sect) - InternalError(_("bin objfmt: .text section does not exist before ORG is called?")); + cur_we->internal_error( + N_("bin objfmt: .text section does not exist before ORG is called?")); section_set_start(sect, intnum_get_uint(start), lindex); return 0; /* directive recognized */ diff --git a/src/objfmts/coff/coff-objfmt.c b/src/objfmts/coff/coff-objfmt.c index db6d3075..c7c28432 100644 --- a/src/objfmts/coff/coff-objfmt.c +++ b/src/objfmts/coff/coff-objfmt.c @@ -158,6 +158,7 @@ static coff_symtab_head coff_symtab; /* symbol table of indexed syms */ objfmt yasm_coff_LTX_objfmt; static /*@dependent@*/ arch *cur_arch; +static /*@dependent@*/ errwarn *cur_we; static /*@dependent@*/ coff_symtab_entry * @@ -170,7 +171,7 @@ coff_objfmt_symtab_append(symrec *sym, coff_symrec_sclass sclass, coff_symtab_entry *entry; if (STAILQ_EMPTY(&coff_symtab)) - InternalError(_("empty COFF symbol table")); + cur_we->internal_error(N_("empty COFF symbol table")); entry = STAILQ_LAST(&coff_symtab, coff_symtab_entry, link); sym_data_prev = symrec_get_of_data(entry->sym); assert(sym_data_prev != NULL); @@ -194,13 +195,14 @@ coff_objfmt_symtab_append(symrec *sym, coff_symrec_sclass sclass, static void coff_objfmt_initialize(const char *in_filename, /*@unused@*/ const char *obj_filename, - /*@unused@*/ dbgfmt *df, arch *a) + /*@unused@*/ dbgfmt *df, arch *a, errwarn *we) { symrec *filesym; coff_symrec_data *data; coff_symtab_entry *entry; cur_arch = a; + cur_we = we; coff_objfmt_parse_scnum = 1; /* section numbering starts at 1 */ STAILQ_INIT(&coff_symtab); @@ -273,7 +275,7 @@ coff_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize, SymVisibility vis; if (valsize != 4) { - Error((*ep)->line, _("coff: invalid relocation size")); + cur_we->error((*ep)->line, N_("coff: invalid relocation size")); return 1; } @@ -326,11 +328,12 @@ coff_objfmt_output_expr(expr **ep, unsigned char **bufp, unsigned long valsize, /* Check for complex float expressions */ if (expr_contains(*ep, EXPR_FLOAT)) { - Error((*ep)->line, _("floating point expression too complex")); + cur_we->error((*ep)->line, + N_("floating point expression too complex")); return 1; } - Error((*ep)->line, _("coff: relocation too complex")); + cur_we->error((*ep)->line, N_("coff: relocation too complex")); return 1; } @@ -361,8 +364,8 @@ coff_objfmt_output_bytecode(bytecode *bc, /*@null@*/ void *d) /* Warn that gaps are converted to 0 and write out the 0's. */ if (gap) { unsigned long left; - Warning(bc->line, - _("uninitialized space declared in code/data section: zeroing")); + cur_we->warning(WARN_GENERAL, bc->line, + N_("uninitialized space declared in code/data section: zeroing")); /* Write out in chunks */ memset(info->buf, 0, REGULAR_OUTBUF_SIZE); left = multiple*size; @@ -414,7 +417,7 @@ coff_objfmt_output_section(section *sect, /*@null@*/ void *d) } else { pos = ftell(info->f); if (pos == -1) { - ErrorNow(_("could not get file position on output file")); + cur_we->error(0, N_("could not get file position on output file")); return 1; } @@ -437,7 +440,7 @@ coff_objfmt_output_section(section *sect, /*@null@*/ void *d) pos = ftell(info->f); if (pos == -1) { - ErrorNow(_("could not get file position on output file")); + cur_we->error(0, N_("could not get file position on output file")); return 1; } csd->relptr = (unsigned long)pos; @@ -448,7 +451,8 @@ coff_objfmt_output_section(section *sect, /*@null@*/ void *d) csymd = symrec_get_of_data(reloc->sym); if (!csymd) - InternalError(_("coff: no symbol data for relocated symbol")); + cur_we->internal_error( + N_("coff: no symbol data for relocated symbol")); WRITE_32_L(localbuf, reloc->addr); /* address of relocation */ WRITE_32_L(localbuf, csymd->index); /* relocated symbol */ @@ -487,8 +491,9 @@ coff_objfmt_output_secthead(section *sect, /*@null@*/ void *d) WRITE_32_L(localbuf, csd->relptr); /* file ptr to relocs */ WRITE_32_L(localbuf, 0); /* file ptr to line nums */ if (csd->nreloc >= 64*1024) { - WarningNow(_("too many relocations in section `%s'"), - section_get_name(sect)); + cur_we->warning(WARN_GENERAL, 0, + N_("too many relocations in section `%s'"), + section_get_name(sect)); WRITE_16_L(localbuf, 0xFFFF); /* max out */ } else WRITE_16_L(localbuf, csd->nreloc); /* number of relocation entries */ @@ -515,7 +520,7 @@ coff_objfmt_output(FILE *f, sectionhead *sections) /* Allocate space for headers by seeking forward */ if (fseek(f, 20+40*(coff_objfmt_parse_scnum-1), SEEK_SET) < 0) { - ErrorNow(_("could not seek on output file")); + cur_we->error(0, N_("could not seek on output file")); return; } @@ -537,7 +542,7 @@ coff_objfmt_output(FILE *f, sectionhead *sections) /* Symbol table */ pos = ftell(f); if (pos == -1) { - ErrorNow(_("could not get file position on output file")); + cur_we->error(0, N_("could not get file position on output file")); return; } symtab_pos = (unsigned long)pos; @@ -556,7 +561,8 @@ coff_objfmt_output(FILE *f, sectionhead *sections) /* Get symrec's of_data (needed for storage class) */ csymd = symrec_get_of_data(entry->sym); if (!csymd) - InternalError(_("coff: expected sym data to be present")); + cur_we->internal_error( + N_("coff: expected sym data to be present")); /* Look at symrec for value/scnum/etc. */ if (symrec_get_label(entry->sym, §, &precbc)) { @@ -580,8 +586,8 @@ coff_objfmt_output(FILE *f, sectionhead *sections) const intnum *intn; intn = expr_get_intnum(&csymd->size, common_calc_bc_dist); if (!intn) - Error(csymd->size->line, - _("COMMON data size not an integer expression")); + cur_we->error(csymd->size->line, + N_("COMMON data size not an integer expression")); else value = intnum_get_uint(intn); scnum = 0; @@ -627,7 +633,8 @@ coff_objfmt_output(FILE *f, sectionhead *sections) strncpy((char *)localbuf, entry->aux[0].fname, 14); break; default: - InternalError(_("coff: unrecognized aux symtab type")); + cur_we->internal_error( + N_("coff: unrecognized aux symtab type")); } fwrite(info.buf, 18, 1, f); symtab_count++; @@ -659,7 +666,7 @@ coff_objfmt_output(FILE *f, sectionhead *sections) /* Write headers */ if (fseek(f, 0, SEEK_SET) < 0) { - ErrorNow(_("could not seek on output file")); + cur_we->error(0, N_("could not seek on output file")); return; } @@ -713,8 +720,8 @@ coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, sectname = vp->val; if (strlen(sectname) > 8) { - Warning(lindex, - _("COFF section names limited to 8 characters: truncating")); + cur_we->warning(WARN_GENERAL, lindex, + N_("COFF section names limited to 8 characters: truncating")); sectname[8] = '\0'; } @@ -742,7 +749,7 @@ coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, } retval = sections_switch_general(headp, sectname, 0, resonly, &isnew, - lindex); + lindex, cur_we->internal_error_); if (isnew) { coff_section_data *data; @@ -765,7 +772,8 @@ coff_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, COFF_SYMTAB_AUX_SECT); data->sym = sym; } else if (flags_override) - Warning(lindex, _("section flags ignored on section redeclaration")); + cur_we->warning(WARN_GENERAL, lindex, + N_("section flags ignored on section redeclaration")); return retval; } diff --git a/src/objfmts/dbg/dbg-objfmt.c b/src/objfmts/dbg/dbg-objfmt.c index 3b10a442..5f2233ab 100644 --- a/src/objfmts/dbg/dbg-objfmt.c +++ b/src/objfmts/dbg/dbg-objfmt.c @@ -46,14 +46,17 @@ objfmt yasm_dbg_LTX_objfmt; */ static FILE *dbg_objfmt_file; +static /*@dependent@*/ errwarn *cur_we; static void dbg_objfmt_initialize(const char *in_filename, const char *obj_filename, - dbgfmt *df, arch *a) + dbgfmt *df, arch *a, errwarn *we) { + cur_we = we; + dbg_objfmt_file = fopen(obj_filename, "wt"); if (!dbg_objfmt_file) { - ErrorNow(_("could not open file `%s'"), obj_filename); + fprintf(stderr, N_("could not open file `%s'"), obj_filename); return; } fprintf(dbg_objfmt_file, @@ -95,7 +98,7 @@ dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams, if ((vp = vps_first(valparams)) && !vp->param && vp->val != NULL) { retval = sections_switch_general(headp, vp->val, 200, 0, &isnew, - lindex); + lindex, cur_we->internal_error_); if (isnew) { fprintf(dbg_objfmt_file, "(new) "); symrec_define_label(vp->val, retval, (bytecode *)NULL, 1, lindex); diff --git a/src/optimizer.h b/src/optimizer.h index 56c90720..44c6a124 100644 --- a/src/optimizer.h +++ b/src/optimizer.h @@ -37,7 +37,7 @@ struct optimizer { * object file. (A failure is indicated by calling ErrorAt() from within * this function). */ - void (*optimize) (sectionhead *sections); + void (*optimize) (sectionhead *sections, errwarn *we); }; #endif diff --git a/src/optimizers/basic/basic-optimizer.c b/src/optimizers/basic/basic-optimizer.c index 5c654b7d..1b87423c 100644 --- a/src/optimizers/basic/basic-optimizer.c +++ b/src/optimizers/basic/basic-optimizer.c @@ -43,6 +43,8 @@ #define BCFLAG_INPROGRESS (1UL<<0) #define BCFLAG_DONE (1UL<<1) +static /*@dependent@*/ errwarn *cur_we; + static int basic_optimize_section_1(section *sect, /*@unused@*/ /*@null@*/ void *d); @@ -129,7 +131,7 @@ basic_optimize_bytecode_1(/*@observer@*/ bytecode *bc, void *d) bcr_retval = bc_resolve(bc, 0, data->sect, basic_optimize_calc_bc_dist_1); if (bcr_retval & BC_RESOLVE_UNKNOWN_LEN) { if (!(bcr_retval & BC_RESOLVE_ERROR)) - Error(bc->line, _("circular reference detected.")); + cur_we->error(bc->line, N_("circular reference detected.")); data->saw_unknown = -1; return 0; } @@ -181,7 +183,7 @@ basic_optimize_bytecode_2(/*@observer@*/ bytecode *bc, /*@null@*/ void *d) assert(data != NULL); if (bc->opt_flags != BCFLAG_DONE) - InternalError(_("Optimizer pass 1 missed a bytecode!")); + cur_we->internal_error(N_("Optimizer pass 1 missed a bytecode!")); if (!data->precbc) bc->offset = 0; @@ -203,17 +205,19 @@ basic_optimize_section_2(section *sect, /*@unused@*/ /*@null@*/ void *d) data.sect = sect; if (section_get_opt_flags(sect) != SECTFLAG_DONE) - InternalError(_("Optimizer pass 1 missed a section!")); + cur_we->internal_error(N_("Optimizer pass 1 missed a section!")); return bcs_traverse(section_get_bytecodes(sect), &data, basic_optimize_bytecode_2); } static void -basic_optimize(sectionhead *sections) +basic_optimize(sectionhead *sections, errwarn *we) { int saw_unknown = 0; + cur_we = we; + /* Optimization process: (essentially NASM's pass 1) * Determine the size of all bytecodes. * Forward references are /not/ resolved (only backward references are diff --git a/src/options.c b/src/options.c index 9b4c7faa..f48dfb4e 100644 --- a/src/options.c +++ b/src/options.c @@ -67,9 +67,9 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts) if (options[i].takes_param) { param = strchr(&argv[0][2], '='); if (!param) { - ErrorNow(_ - ("option '--%s' needs an argument!"), - options[i].lopt); + fprintf(stderr, + _("option '--%s' needs an argument!"), + options[i].lopt); errors++; goto fail; } else { @@ -86,7 +86,7 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts) } } if (!got_it) { - ErrorNow(_("unrecognized option '%s'"), argv[0]); + fprintf(stderr, _("unrecognized option '%s'"), argv[0]); errors++; } } else { /* sopt */ @@ -101,8 +101,9 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts) if (argv[0][2] != '\0') param = &argv[0][2]; else if (param == NULL || *param == '-') { - ErrorNow(_("option '-%c' needs an argument!"), - options[i].sopt); + fprintf(stderr, + _("option '-%c' needs an argument!"), + options[i].sopt); errors++; goto fail; } else { @@ -118,7 +119,7 @@ parse_cmdline(int argc, char **argv, opt_option *options, size_t nopts) } } if (!got_it) { - ErrorNow(_("unrecognized option '%s'"), argv[0]); + fprintf(stderr, _("unrecognized option '%s'"), argv[0]); errors++; } } diff --git a/src/parser.h b/src/parser.h index 01b0db32..c2e606ff 100644 --- a/src/parser.h +++ b/src/parser.h @@ -51,7 +51,7 @@ struct parser { * (whatever was in the file). */ sectionhead *(*do_parse) (preproc *pp, arch *a, objfmt *of, linemgr *lm, - FILE *f, const char *in_filename); + errwarn *we, FILE *f, const char *in_filename); }; /* Generic functions for all parsers - implemented in src/parser.c */ diff --git a/src/parsers/nasm/Makefile.inc b/src/parsers/nasm/Makefile.inc index 7cfd1954..80df154d 100644 --- a/src/parsers/nasm/Makefile.inc +++ b/src/parsers/nasm/Makefile.inc @@ -3,6 +3,7 @@ lib_LTLIBRARIES += yasm-nasm.la yasm_nasm_la_SOURCES = \ + src/parsers/nasm/nasm-parser.h \ src/parsers/nasm/nasm-parser.c \ src/parsers/nasm/nasm-defs.h \ src/parsers/nasm/nasm-bison.y \ diff --git a/src/parsers/nasm/nasm-bison.y b/src/parsers/nasm/nasm-bison.y index 996ef574..c8e41db3 100644 --- a/src/parsers/nasm/nasm-bison.y +++ b/src/parsers/nasm/nasm-bison.y @@ -42,32 +42,14 @@ RCSID("$IdPath$"); #include "arch.h" +#include "src/parsers/nasm/nasm-parser.h" #include "src/parsers/nasm/nasm-defs.h" -void init_table(void); -extern int nasm_parser_lex(void); -extern void nasm_parser_set_directive_state(void); -void nasm_parser_error(const char *); -static void nasm_parser_directive(const char *name, - valparamhead *valparams, +static void nasm_parser_error(const char *); +static void nasm_parser_directive(const char *name, valparamhead *valparams, /*@null@*/ valparamhead *objext_valparams); -extern objfmt *nasm_parser_objfmt; -extern sectionhead nasm_parser_sections; -extern section *nasm_parser_cur_section; -extern char *nasm_parser_locallabel_base; -extern size_t nasm_parser_locallabel_base_len; -extern /*@dependent@*/ arch *nasm_parser_arch; -extern /*@dependent@*/ objfmt *nasm_parser_objfmt; -extern /*@dependent@*/ linemgr *nasm_parser_linemgr; - -#define p_line_index (nasm_parser_linemgr->get_current()) - -#define p_expr_new_tree(l,o,r) expr_new_tree(l,o,r,p_line_index) -#define p_expr_new_branch(o,r) expr_new_branch(o,r,p_line_index) -#define p_expr_new_ident(r) expr_new_ident(r,p_line_index) - static /*@null@*/ bytecode *nasm_parser_prev_bc = (bytecode *)NULL; static bytecode *nasm_parser_temp_bc; @@ -162,8 +144,8 @@ line: '\n' { $$ = (bytecode *)NULL; } $$ = (bytecode *)NULL; } | error '\n' { - Error(p_line_index, - _("label or instruction expected at start of line")); + cur_we->error(cur_lindex, + N_("label or instruction expected at start of line")); $$ = (bytecode *)NULL; yyerrok; } @@ -175,7 +157,7 @@ lineexp: exp | label exp { $$ = $2; } | label TIMES expr exp { $$ = $4; bc_set_multiple($$, $3); } | label_id_equ EQU expr { - symrec_define_equ($1, $3, p_line_index); + symrec_define_equ($1, $3, cur_lindex); xfree($1); $$ = (bytecode *)NULL; } @@ -183,47 +165,45 @@ lineexp: exp exp: instr | DECLARE_DATA datavals { - $$ = bc_new_data(&$2, $1, p_line_index); + $$ = bc_new_data(&$2, $1, cur_lindex); } | RESERVE_SPACE expr { - $$ = bc_new_reserve($2, $1, p_line_index); + $$ = bc_new_reserve($2, $1, cur_lindex); } | INCBIN STRING { - $$ = bc_new_incbin($2, NULL, NULL, p_line_index); + $$ = bc_new_incbin($2, NULL, NULL, cur_lindex); } | INCBIN STRING ',' expr { - $$ = bc_new_incbin($2, $4, NULL, p_line_index); + $$ = bc_new_incbin($2, $4, NULL, cur_lindex); } | INCBIN STRING ',' expr ',' expr { - $$ = bc_new_incbin($2, $4, $6, p_line_index); + $$ = bc_new_incbin($2, $4, $6, cur_lindex); } ; instr: INSN { $$ = nasm_parser_arch->parse.new_insn($1, 0, NULL, nasm_parser_cur_section, - nasm_parser_prev_bc, - p_line_index); + nasm_parser_prev_bc, cur_lindex); } | INSN operands { $$ = nasm_parser_arch->parse.new_insn($1, $2.num_operands, &$2.operands, nasm_parser_cur_section, - nasm_parser_prev_bc, - p_line_index); + nasm_parser_prev_bc, cur_lindex); ops_delete(&$2.operands, 0); } | INSN error { - Error(p_line_index, _("expression syntax error")); + cur_we->error(cur_lindex, N_("expression syntax error")); $$ = NULL; } | PREFIX instr { $$ = $2; - nasm_parser_arch->parse.handle_prefix($$, $1, p_line_index); + nasm_parser_arch->parse.handle_prefix($$, $1, cur_lindex); } | SEGREG instr { $$ = $2; - nasm_parser_arch->parse.handle_seg_prefix($$, $1[0], p_line_index); + nasm_parser_arch->parse.handle_seg_prefix($$, $1[0], cur_lindex); } ; @@ -234,19 +214,19 @@ datavals: dataval { dvs_initialize(&$$); dvs_append(&$$, $1); } dataval: dvexpr { $$ = dv_new_expr($1); } | STRING { $$ = dv_new_string($1); } | error { - Error(p_line_index, _("expression syntax error")); + cur_we->error(cur_lindex, N_("expression syntax error")); $$ = (dataval *)NULL; } ; label: label_id { symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc, - 1, p_line_index); + 1, cur_lindex); xfree($1); } | label_id ':' { symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc, - 1, p_line_index); + 1, cur_lindex); xfree($1); } ; @@ -274,7 +254,7 @@ directive: DIRECTIVE_NAME directive_val { xfree($1); } | DIRECTIVE_NAME error { - Error(p_line_index, _("invalid arguments to [%s]"), $1); + cur_we->error(cur_lindex, N_("invalid arguments to [%s]"), $1); xfree($1); } ; @@ -318,7 +298,7 @@ memaddr: expr { } | SEGREG ':' memaddr { $$ = $3; - nasm_parser_arch->parse.handle_seg_override($$, $1[0], p_line_index); + nasm_parser_arch->parse.handle_seg_override($$, $1[0], cur_lindex); } | BYTE memaddr { $$ = $2; ea_set_len($$, 1); } | WORD memaddr { $$ = $2; ea_set_len($$, 2); } @@ -346,7 +326,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } $$ = $2; if ($$->type == INSN_OPERAND_REG && nasm_parser_arch->get_reg_size($$->data.reg) != 1) - Error(p_line_index, _("cannot override register size")); + cur_we->error(cur_lindex, N_("cannot override register size")); else $$->size = 1; } @@ -354,7 +334,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } $$ = $2; if ($$->type == INSN_OPERAND_REG && nasm_parser_arch->get_reg_size($$->data.reg) != 2) - Error(p_line_index, _("cannot override register size")); + cur_we->error(cur_lindex, N_("cannot override register size")); else $$->size = 2; } @@ -362,7 +342,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } $$ = $2; if ($$->type == INSN_OPERAND_REG && nasm_parser_arch->get_reg_size($$->data.reg) != 4) - Error(p_line_index, _("cannot override register size")); + cur_we->error(cur_lindex, N_("cannot override register size")); else $$->size = 4; } @@ -370,7 +350,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } $$ = $2; if ($$->type == INSN_OPERAND_REG && nasm_parser_arch->get_reg_size($$->data.reg) != 8) - Error(p_line_index, _("cannot override register size")); + cur_we->error(cur_lindex, N_("cannot override register size")); else $$->size = 8; } @@ -378,7 +358,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } $$ = $2; if ($$->type == INSN_OPERAND_REG && nasm_parser_arch->get_reg_size($$->data.reg) != 10) - Error(p_line_index, _("cannot override register size")); + cur_we->error(cur_lindex, N_("cannot override register size")); else $$->size = 10; } @@ -386,7 +366,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } $$ = $2; if ($$->type == INSN_OPERAND_REG && nasm_parser_arch->get_reg_size($$->data.reg) != 16) - Error(p_line_index, _("cannot override register size")); + cur_we->error(cur_lindex, N_("cannot override register size")); else $$->size = 16; } @@ -399,7 +379,7 @@ operand: '[' memaddr ']' { $$ = operand_new_mem($2); } direxpr: INTNUM { $$ = p_expr_new_ident(ExprInt($1)); } | ID { $$ = p_expr_new_ident(ExprSym(symrec_define_label($1, NULL, NULL, 0, - p_line_index))); + cur_lindex))); xfree($1); } | direxpr '|' direxpr { $$ = p_expr_new_tree($1, EXPR_OR, $3); } @@ -460,7 +440,7 @@ expr: INTNUM { $$ = p_expr_new_ident(ExprInt($1)); } | REG { $$ = p_expr_new_ident(ExprReg($1[0])); } | STRING { $$ = p_expr_new_ident(ExprInt(intnum_new_charconst_nasm($1, - p_line_index))); + cur_lindex))); xfree($1); } | explabel { $$ = p_expr_new_ident(ExprSym($1)); } @@ -495,26 +475,26 @@ expr: INTNUM { $$ = p_expr_new_ident(ExprInt($1)); } ; explabel: ID { - $$ = symrec_use($1, p_line_index); + $$ = symrec_use($1, cur_lindex); xfree($1); } | SPECIAL_ID { - $$ = symrec_use($1, p_line_index); + $$ = symrec_use($1, cur_lindex); xfree($1); } | LOCAL_ID { - $$ = symrec_use($1, p_line_index); + $$ = symrec_use($1, cur_lindex); xfree($1); } | '$' { /* "$" references the current assembly position */ $$ = symrec_define_label("$", nasm_parser_cur_section, - nasm_parser_prev_bc, 0, p_line_index); + nasm_parser_prev_bc, 0, cur_lindex); } | START_SECTION_ID { /* "$$" references the start of the current section */ $$ = symrec_define_label("$$", nasm_parser_cur_section, NULL, 0, - p_line_index); + cur_lindex); } ; @@ -527,7 +507,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams, { valparam *vp, *vp2; symrec *sym; - unsigned long lindex = p_line_index; + unsigned long lindex = cur_lindex; /* Handle (mostly) output-format independent directives here */ if (strcasecmp(name, "extern") == 0) { @@ -538,7 +518,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams, nasm_parser_objfmt->extern_declare(sym, objext_valparams, lindex); } else - Error(lindex, _("invalid argument to [%s]"), "EXTERN"); + cur_we->error(lindex, N_("invalid argument to [%s]"), "EXTERN"); } else if (strcasecmp(name, "global") == 0) { vp = vps_first(valparams); if (vp->val) { @@ -547,14 +527,15 @@ nasm_parser_directive(const char *name, valparamhead *valparams, nasm_parser_objfmt->global_declare(sym, objext_valparams, lindex); } else - Error(lindex, _("invalid argument to [%s]"), "GLOBAL"); + cur_we->error(lindex, N_("invalid argument to [%s]"), "GLOBAL"); } else if (strcasecmp(name, "common") == 0) { vp = vps_first(valparams); if (vp->val) { vp2 = vps_next(vp); if (!vp2 || (!vp2->val && !vp2->param)) - Error(lindex, _("no size specified in %s declaration"), - "COMMON"); + cur_we->error(lindex, + N_("no size specified in %s declaration"), + "COMMON"); else { if (vp2->val) { sym = symrec_declare(vp->val, SYM_COMMON, lindex); @@ -573,7 +554,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams, } } } else - Error(lindex, _("invalid argument to [%s]"), "COMMON"); + cur_we->error(lindex, N_("invalid argument to [%s]"), "COMMON"); } else if (strcasecmp(name, "section") == 0 || strcasecmp(name, "segment") == 0) { section *new_section = @@ -584,17 +565,19 @@ nasm_parser_directive(const char *name, valparamhead *valparams, nasm_parser_cur_section = new_section; nasm_parser_prev_bc = bcs_last(section_get_bytecodes(new_section)); } else - Error(lindex, _("invalid argument to [%s]"), "SECTION"); + cur_we->error(lindex, N_("invalid argument to [%s]"), "SECTION"); } else if (strcasecmp(name, "absolute") == 0) { /* it can be just an ID or a complete expression, so handle both. */ vp = vps_first(valparams); if (vp->val) nasm_parser_cur_section = sections_switch_absolute(&nasm_parser_sections, - p_expr_new_ident(ExprSym(symrec_use(vp->val, lindex)))); + p_expr_new_ident(ExprSym(symrec_use(vp->val, lindex))), + cur_we->internal_error_); else if (vp->param) { nasm_parser_cur_section = - sections_switch_absolute(&nasm_parser_sections, vp->param); + sections_switch_absolute(&nasm_parser_sections, vp->param, + cur_we->internal_error_); vp->param = NULL; } nasm_parser_prev_bc = (bytecode *)NULL; @@ -606,7 +589,8 @@ nasm_parser_directive(const char *name, valparamhead *valparams, const intnum *intcpu; intcpu = expr_get_intnum(&vp->param, NULL); if (!intcpu) - Error(lindex, _("invalid argument to [%s]"), "CPU"); + cur_we->error(lindex, N_("invalid argument to [%s]"), + "CPU"); else { char strcpu[16]; sprintf(strcpu, "%lu", intnum_get_uint(intcpu)); @@ -621,7 +605,7 @@ nasm_parser_directive(const char *name, valparamhead *valparams, ; } else if (nasm_parser_objfmt->directive(name, valparams, objext_valparams, &nasm_parser_sections, lindex)) { - Error(lindex, _("unrecognized directive [%s]"), name); + cur_we->error(lindex, N_("unrecognized directive [%s]"), name); } vps_delete(valparams); @@ -629,9 +613,9 @@ nasm_parser_directive(const char *name, valparamhead *valparams, vps_delete(objext_valparams); } -void +static void nasm_parser_error(const char *s) { - ParserError(p_line_index, s); + cur_we->parser_error(cur_lindex, s); } diff --git a/src/parsers/nasm/nasm-parser.c b/src/parsers/nasm/nasm-parser.c index bb78777c..a38a28d1 100644 --- a/src/parsers/nasm/nasm-parser.c +++ b/src/parsers/nasm/nasm-parser.c @@ -29,35 +29,36 @@ #include "preproc.h" #include "parser.h" +#include "nasm-parser.h" -extern FILE *nasm_parser_in; -extern int nasm_parser_debug; -extern int nasm_parser_parse(void); -extern void nasm_parser_cleanup(void); - -size_t (*nasm_parser_input) (char *buf, size_t max_size, linemgr *lm); +FILE *nasm_parser_in = NULL; +size_t (*nasm_parser_input) (char *buf, size_t max_size); sectionhead nasm_parser_sections; /*@dependent@*/ section *nasm_parser_cur_section; -extern /*@only@*/ char *nasm_parser_locallabel_base; +/* last "base" label for local (.) labels */ +char *nasm_parser_locallabel_base = (char *)NULL; +size_t nasm_parser_locallabel_base_len = 0; /*@dependent@*/ arch *nasm_parser_arch; /*@dependent@*/ objfmt *nasm_parser_objfmt; /*@dependent@*/ linemgr *nasm_parser_linemgr; +/*@dependent@*/ errwarn *nasm_parser_errwarn; static /*@dependent@*/ sectionhead * -nasm_parser_do_parse(preproc *pp, arch *a, objfmt *of, linemgr *lm, FILE *f, - const char *in_filename) +nasm_parser_do_parse(preproc *pp, arch *a, objfmt *of, linemgr *lm, + errwarn *we, FILE *f, const char *in_filename) /*@globals killed nasm_parser_locallabel_base @*/ { - pp->initialize(f, in_filename); + pp->initialize(f, in_filename, lm, we); nasm_parser_in = f; nasm_parser_input = pp->input; nasm_parser_arch = a; nasm_parser_objfmt = of; nasm_parser_linemgr = lm; + nasm_parser_errwarn = we; /* Initialize section list */ nasm_parser_cur_section = sections_initialize(&nasm_parser_sections, of); diff --git a/src/parsers/nasm/nasm-parser.h b/src/parsers/nasm/nasm-parser.h new file mode 100644 index 00000000..f0b63c74 --- /dev/null +++ b/src/parsers/nasm/nasm-parser.h @@ -0,0 +1,53 @@ +/* $IdPath$ + * NASM-compatible parser header file + * + * Copyright (C) 2002 Peter Johnson + * + * This file is part of YASM. + * + * YASM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * YASM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#ifndef YASM_NASM_PARSER_H +#define YASM_NASM_PARSER_H + +int nasm_parser_parse(void); +void nasm_parser_cleanup(void); +int nasm_parser_lex(void); +void nasm_parser_set_directive_state(void); + +extern FILE *nasm_parser_in; +extern int nasm_parser_debug; +extern size_t (*nasm_parser_input) (char *buf, size_t max_size); + +extern sectionhead nasm_parser_sections; +extern /*@dependent@*/ section *nasm_parser_cur_section; + +extern char *nasm_parser_locallabel_base; +extern size_t nasm_parser_locallabel_base_len; + +extern /*@dependent@*/ arch *nasm_parser_arch; +extern /*@dependent@*/ objfmt *nasm_parser_objfmt; +extern /*@dependent@*/ linemgr *nasm_parser_linemgr; +extern /*@dependent@*/ errwarn *nasm_parser_errwarn; + +#define cur_lindex (nasm_parser_linemgr->get_current()) + +#define p_expr_new_tree(l,o,r) expr_new_tree(l,o,r,cur_lindex) +#define p_expr_new_branch(o,r) expr_new_branch(o,r,cur_lindex) +#define p_expr_new_ident(r) expr_new_ident(r,cur_lindex) + +#define cur_we nasm_parser_errwarn + +#endif diff --git a/src/parsers/nasm/nasm-token.re b/src/parsers/nasm/nasm-token.re index fc1dd26a..46daee4c 100644 --- a/src/parsers/nasm/nasm-token.re +++ b/src/parsers/nasm/nasm-token.re @@ -37,6 +37,7 @@ RCSID("$IdPath$"); #include "arch.h" +#include "src/parsers/nasm/nasm-parser.h" #include "src/parsers/nasm/nasm-defs.h" #include "nasm-bison.h" @@ -59,17 +60,6 @@ RCSID("$IdPath$"); #define TOKLEN (cursor-s.tok) -void nasm_parser_cleanup(void); -void nasm_parser_set_directive_state(void); -int nasm_parser_lex(void); - -extern size_t (*nasm_parser_input) (char *buf, size_t max_size, linemgr *lm); -extern /*@dependent@*/ arch *nasm_parser_arch; -extern /*@dependent@*/ linemgr *nasm_parser_linemgr; - -#define p_line_index (nasm_parser_linemgr->get_current()) - - typedef struct Scanner { YYCTYPE *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof; unsigned int tchar, tline, cline; @@ -77,8 +67,6 @@ typedef struct Scanner { static Scanner s = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 1 }; -FILE *nasm_parser_in = NULL; - static YYCTYPE * fill(YYCTYPE *cursor) { @@ -105,8 +93,7 @@ fill(YYCTYPE *cursor) xfree(s.bot); s.bot = buf; } - if((cnt = nasm_parser_input(s.lim, BSIZE, - nasm_parser_linemgr)) != BSIZE){ + if((cnt = nasm_parser_input(s.lim, BSIZE)) != BSIZE){ s.eof = &s.lim[cnt]; *s.eof++ = '\n'; } s.lim += cnt; @@ -130,10 +117,6 @@ static char *strbuf = (char *)NULL; /* length of strbuf (including terminating NULL character) */ static size_t strbuf_size = 0; -/* last "base" label for local (.) labels */ -char *nasm_parser_locallabel_base = (char *)NULL; -size_t nasm_parser_locallabel_base_len = 0; - static int linechg_numcount; /*!re2c @@ -220,7 +203,7 @@ scan: digit+ { savech = s.tok[TOKLEN]; s.tok[TOKLEN] = '\0'; - yylval.intn = intnum_new_dec(s.tok, p_line_index); + yylval.intn = intnum_new_dec(s.tok, cur_lindex); s.tok[TOKLEN] = savech; RETURN(INTNUM); } @@ -228,21 +211,21 @@ scan: bindigit+ "b" { s.tok[TOKLEN-1] = '\0'; /* strip off 'b' */ - yylval.intn = intnum_new_bin(s.tok, p_line_index); + yylval.intn = intnum_new_bin(s.tok, cur_lindex); RETURN(INTNUM); } /* 777q - octal number */ octdigit+ "q" { s.tok[TOKLEN-1] = '\0'; /* strip off 'q' */ - yylval.intn = intnum_new_oct(s.tok, p_line_index); + yylval.intn = intnum_new_oct(s.tok, cur_lindex); RETURN(INTNUM); } /* 0AAh form of hexidecimal number */ digit hexdigit* "h" { s.tok[TOKLEN-1] = '\0'; /* strip off 'h' */ - yylval.intn = intnum_new_hex(s.tok, p_line_index); + yylval.intn = intnum_new_hex(s.tok, cur_lindex); RETURN(INTNUM); } @@ -252,10 +235,10 @@ scan: s.tok[TOKLEN] = '\0'; if (s.tok[1] == 'x') /* skip 0 and x */ - yylval.intn = intnum_new_hex(s.tok+2, p_line_index); + yylval.intn = intnum_new_hex(s.tok+2, cur_lindex); else /* don't skip 0 */ - yylval.intn = intnum_new_hex(s.tok+1, p_line_index); + yylval.intn = intnum_new_hex(s.tok+1, cur_lindex); s.tok[TOKLEN] = savech; RETURN(INTNUM); } @@ -342,8 +325,9 @@ scan: yylval.str_val = xstrndup(s.tok, TOKLEN); RETURN(ID); } else if (!nasm_parser_locallabel_base) { - Warning(p_line_index, _("no non-local label before `%s'"), - s.tok[0]); + cur_we->warning(WARN_GENERAL, cur_lindex, + N_("no non-local label before `%s'"), + s.tok[0]); yylval.str_val = xstrndup(s.tok, TOKLEN); } else { len = TOKLEN + nasm_parser_locallabel_base_len; @@ -367,7 +351,7 @@ scan: savech = s.tok[TOKLEN]; s.tok[TOKLEN] = '\0'; check_id_ret = nasm_parser_arch->parse.check_identifier( - yylval.arch_data, s.tok, p_line_index); + yylval.arch_data, s.tok, cur_lindex); s.tok[TOKLEN] = savech; switch (check_id_ret) { case ARCH_CHECK_ID_NONE: @@ -385,8 +369,8 @@ scan: case ARCH_CHECK_ID_TARGETMOD: RETURN(TARGETMOD); default: - Warning(p_line_index, - _("Arch feature not supported, treating as identifier")); + cur_we->warning(WARN_GENERAL, cur_lindex, + N_("Arch feature not supported, treating as identifier")); yylval.str_val = xstrndup(s.tok, TOKLEN); RETURN(ID); } @@ -399,10 +383,9 @@ scan: "\n" { state = INITIAL; RETURN(s.tok[0]); } any { - if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR)) - Warning(p_line_index, - _("ignoring unrecognized character `%s'"), - conv_unprint(s.tok[0])); + cur_we->warning(WARN_UNREC_CHAR, cur_lindex, + N_("ignoring unrecognized character `%s'"), + cur_we->conv_unprint(s.tok[0])); goto scan; } */ @@ -416,7 +399,7 @@ linechg: linechg_numcount++; savech = s.tok[TOKLEN]; s.tok[TOKLEN] = '\0'; - yylval.intn = intnum_new_dec(s.tok, p_line_index); + yylval.intn = intnum_new_dec(s.tok, cur_lindex); s.tok[TOKLEN] = savech; RETURN(INTNUM); } @@ -439,10 +422,9 @@ linechg: } any { - if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR)) - Warning(p_line_index, - _("ignoring unrecognized character `%s'"), - conv_unprint(s.tok[0])); + cur_we->warning(WARN_UNREC_CHAR, cur_lindex, + N_("ignoring unrecognized character `%s'"), + cur_we->conv_unprint(s.tok[0])); goto linechg; } */ @@ -482,10 +464,9 @@ directive: } any { - if (WARN_ENABLED(WARN_UNRECOGNIZED_CHAR)) - Warning(p_line_index, - _("ignoring unrecognized character `%s'"), - conv_unprint(s.tok[0])); + cur_we->warning(WARN_UNREC_CHAR, cur_lindex, + N_("ignoring unrecognized character `%s'"), + cur_we->conv_unprint(s.tok[0])); goto directive; } */ @@ -502,9 +483,10 @@ stringconst_scan: /*!re2c "\n" { if (cursor == s.eof) - Error(p_line_index, _("unexpected end of file in string")); + cur_we->error(cur_lindex, + N_("unexpected end of file in string")); else - Error(p_line_index, _("unterminated string")); + cur_we->error(cur_lindex, N_("unterminated string")); strbuf[count] = '\0'; yylval.str_val = strbuf; RETURN(STRING); diff --git a/src/preproc.h b/src/preproc.h index 9b4874bb..96d07cff 100644 --- a/src/preproc.h +++ b/src/preproc.h @@ -38,11 +38,15 @@ struct preproc { * This function also takes the FILE * to the initial starting file and * the filename. */ - void (*initialize) (FILE *f, const char *in_filename); + void (*initialize) (FILE *f, const char *in_filename, linemgr *lm, + errwarn *we); + + /* Cleans up any allocated memory. */ + void (*cleanup) (void); /* Gets more preprocessed source code (up to max_size bytes) into buf. * Note that more than a single line may be returned in buf. */ - size_t (*input) (/*@out@*/ char *buf, size_t max_size, linemgr *lm); + size_t (*input) (/*@out@*/ char *buf, size_t max_size); }; #endif diff --git a/src/preprocs/raw/raw-preproc.c b/src/preprocs/raw/raw-preproc.c index b251f841..95bad927 100644 --- a/src/preprocs/raw/raw-preproc.c +++ b/src/preprocs/raw/raw-preproc.c @@ -30,20 +30,30 @@ static int is_interactive; static FILE *in; +static linemgr *cur_lm; +static errwarn *cur_we; int isatty(int); static void -raw_preproc_initialize(FILE *f, const char *in_filename) +raw_preproc_initialize(FILE *f, const char *in_filename, linemgr *lm, + errwarn *we) { in = f; + cur_lm = lm; + cur_we = we; /*@-unrecog@*/ is_interactive = f ? (isatty(fileno(f)) > 0) : 0; /*@=unrecog@*/ } +static void +raw_preproc_cleanup(void) +{ +} + static size_t -raw_preproc_input(char *buf, size_t max_size, linemgr *lm) +raw_preproc_input(char *buf, size_t max_size) { int c = '*'; size_t n; @@ -54,9 +64,11 @@ raw_preproc_input(char *buf, size_t max_size, linemgr *lm) if (c == '\n') buf[n++] = (char)c; if (c == EOF && ferror(in)) - Error(lm->get_current(), _("error when reading from file")); + cur_we->error(cur_lm->get_current(), + N_("error when reading from file")); } else if (((n = fread(buf, 1, max_size, in)) == 0) && ferror(in)) - Error(lm->get_current(), _("error when reading from file")); + cur_we->error(cur_lm->get_current(), + N_("error when reading from file")); return n; } @@ -66,5 +78,6 @@ preproc yasm_raw_LTX_preproc = { "Disable preprocessing", "raw", raw_preproc_initialize, + raw_preproc_cleanup, raw_preproc_input }; diff --git a/src/preprocs/yapp/yapp-preproc.c b/src/preprocs/yapp/yapp-preproc.c index 681f7b78..a59ee5c2 100644 --- a/src/preprocs/yapp/yapp-preproc.c +++ b/src/preprocs/yapp/yapp-preproc.c @@ -41,7 +41,7 @@ static YAPP_Output current_output; YYSTYPE yapp_preproc_lval; /*@dependent@*/ linemgr *yapp_preproc_linemgr; -#define p_line_index (yapp_preproc_linemgr->get_current()) +/*@dependent@*/ errwarn *yapp_preproc_errwarn; int isatty(int); @@ -120,13 +120,13 @@ yapp_macro_insert (char *name, int argc, int fillargs) void yapp_macro_error_exists (YAPP_Macro *v) { - if (v) Error(p_line_index, _("Redefining macro of the same name %d:%d"), v->type, v->args); + if (v) cur_we->error(cur_lindex, N_("Redefining macro of the same name %d:%d"), v->type, v->args); } void yapp_macro_error_sameargname (YAPP_Macro *v) { - if (v) Error(p_line_index, _("Duplicate argument names in macro")); + if (v) cur_we->error(cur_lindex, N_("Duplicate argument names in macro")); } YAPP_Macro * @@ -141,7 +141,7 @@ yapp_define_insert (char *name, int argc, int fillargs) if ((argc >= 0 && ym->args < 0) || (argc < 0 && ym->args >= 0)) { - Warning(p_line_index, _("Attempted %%define both with and without parameters")); + cur_we->warning(WARN_PREPROC, cur_lindex, N_("Attempted %%define both with and without parameters")); return NULL; } } @@ -189,10 +189,10 @@ yapp_macro_delete (YAPP_Macro *ym) { while (!SLIST_EMPTY(&ym->macro_head)) { source *s = SLIST_FIRST(&ym->macro_head); - free(s); + xfree(s); SLIST_REMOVE_HEAD(&ym->macro_head, next); } - free(ym); + xfree(ym); } static YAPP_Macro * @@ -237,9 +237,12 @@ void expand_token_list(struct source_head *paramexp, struct source_head *to_head, source **to_tail); static void -yapp_preproc_initialize(FILE *f, const char *in_filename) +yapp_preproc_initialize(FILE *f, const char *in_filename, linemgr *lm, + errwarn *we) { is_interactive = f ? (isatty(fileno(f)) > 0) : 0; + yapp_preproc_linemgr = lm; + yapp_preproc_errwarn = we; yapp_preproc_current_file = xstrdup(in_filename); yapp_preproc_line_number = 1; yapp_lex_initialize(f); @@ -251,7 +254,7 @@ yapp_preproc_initialize(FILE *f, const char *in_filename) out->out = current_output = YAPP_OUTPUT; SLIST_INSERT_HEAD(&output_head, out, next); - macro_table = HAMT_new(); + macro_table = HAMT_new(we->internal_error_); source_tail = SLIST_FIRST(&source_head); macro_tail = SLIST_FIRST(¯o_head); @@ -260,6 +263,12 @@ yapp_preproc_initialize(FILE *f, const char *in_filename) append_token(LINE, &source_head, &source_tail); } +static void +yapp_preproc_cleanup(void) +{ + /* TODO: clean up */ +} + /* Generate a new level of if* context * if val is true, this module of the current level will be output IFF the * surrounding one is. @@ -321,7 +330,7 @@ pop_if(void) out = SLIST_FIRST(&output_head); current_output = out->out; SLIST_REMOVE_HEAD(&output_head, next); - free(out); + xfree(out); if (current_output != YAPP_OUTPUT) set_inhibit(); } @@ -367,7 +376,7 @@ append_token(int token, struct source_head *to_head, source **to_tail) if ((*to_tail) && (*to_tail)->token.type == LINE && (token == '\n' || token == LINE)) { - free ((*to_tail)->token.str); + xfree ((*to_tail)->token.str); (*to_tail)->token.str = xmalloc(23+strlen(yapp_preproc_current_file)); sprintf((*to_tail)->token.str, "%%line %d+1 %s\n", yapp_preproc_line_number, yapp_preproc_current_file); } @@ -409,7 +418,7 @@ append_token(int token, struct source_head *to_head, source **to_tail) break; default: - free(src); + xfree(src); return; } append_processed_token(src, to_head, to_tail); @@ -461,7 +470,7 @@ eat_through_return(struct source_head *to_head, source **to_tail) while ((token = yapp_preproc_lex()) != '\n') { if (token == 0) return 0; - Error(p_line_index, _("Skipping possibly valid %%define stuff")); + cur_we->error(cur_lindex, N_("Skipping possibly valid %%define stuff")); } append_token('\n', to_head, to_tail); return '\n'; @@ -474,7 +483,7 @@ yapp_get_ident(const char *synlvl) if (token == WHITESPACE) token = yapp_preproc_lex(); if (token != IDENT) { - Error(p_line_index, _("Identifier expected after %%%s"), synlvl); + cur_we->error(cur_lindex, N_("Identifier expected after %%%s"), synlvl); } return token; } @@ -502,7 +511,7 @@ expand_macro(char *name, ydebug(("YAPP: +Expand macro %s...\n", name)); - if (ym->expanding) InternalError(_("Recursively expanding a macro!")); + if (ym->expanding) cur_we->internal_error(N_("Recursively expanding a macro!")); if (ym->type == YAPP_DEFINE) { if (ym->args == -1) { @@ -534,7 +543,7 @@ expand_macro(char *name, /* find out what we got */ if (from_head) { - InternalError("Expanding macro with non-null from_head ugh\n"); + cur_we->internal_error(N_("Expanding macro with non-null from_head ugh\n")); } token = yapp_preproc_lex(); append_token(token, &replay_head, &replay_tail); @@ -581,9 +590,9 @@ expand_macro(char *name, default: if (token < 256) - InternalError(_("Unexpected character token in parameter expansion")); + cur_we->internal_error(N_("Unexpected character token in parameter expansion")); else - Error(p_line_index, _("Cannot handle preprocessor items inside possible macro invocation")); + cur_we->error(cur_lindex, N_("Cannot handle preprocessor items inside possible macro invocation")); } } @@ -603,7 +612,7 @@ expand_macro(char *name, ym->expanding = 1; /* so the macro exists. build a HAMT parameter table */ - param_table = HAMT_new(); + param_table = HAMT_new(cur_we->internal_error_); /* fill the entries by walking the replay buffer and create * "macros". coincidentally, clear the replay buffer. */ @@ -612,16 +621,16 @@ expand_macro(char *name, while (replay->token.type != '(') { ydebug(("YAPP: Ignoring replay token '%c' \"%s\"\n", replay->token.type, replay->token.str)); SLIST_REMOVE_HEAD(&replay_head, next); - free(replay->token.str); - free(replay); + xfree(replay->token.str); + xfree(replay); replay = SLIST_FIRST(&replay_head); } ydebug(("YAPP: Ignoring replay token '%c' \"%s\"\n", replay->token.type, replay->token.str)); /* free the open paren */ SLIST_REMOVE_HEAD(&replay_head, next); - free(replay->token.str); - free(replay); + xfree(replay->token.str); + xfree(replay); param = SLIST_FIRST(&ym->param_head); @@ -651,8 +660,8 @@ expand_macro(char *name, arg_tail = SLIST_FIRST(&arg_head); /* don't save the comma */ - free(replay->token.str); - free(replay); + xfree(replay->token.str); + xfree(replay); HAMT_insert(param_table, param->token.str, @@ -675,15 +684,15 @@ expand_macro(char *name, if (replay) SLIST_REMOVE_HEAD(&replay_head, next); } if (replay) { - free(replay->token.str); - free(replay); + xfree(replay->token.str); + xfree(replay); } else if (param) { - InternalError(_("Got to end of arglist before end of replay!")); + cur_we->internal_error(N_("Got to end of arglist before end of replay!")); } replay = SLIST_FIRST(&replay_head); if (replay || param) - InternalError(_("Count and distribution of define args mismatched!")); + cur_we->internal_error(N_("Count and distribution of define args mismatched!")); /* the param_table is set up without errors, so expansion is ready * to go */ @@ -717,7 +726,7 @@ expand_macro(char *name, } } else - InternalError(_("Invoking Macros not yet supported")); + cur_we->internal_error(N_("Invoking Macros not yet supported")); ym->expanding = 0; } @@ -743,15 +752,13 @@ expand_token_list(struct source_head *paramexp, struct source_head *to_head, sou } static size_t -yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) +yapp_preproc_input(char *buf, size_t max_size) { static YAPP_State state = YAPP_STATE_INITIAL; int n = 0; int token; int need_line_directive = 0; - yapp_preproc_linemgr = lm; - while (saved_length < max_size && state != YAPP_STATE_EOF) { token = yapp_preproc_lex(); @@ -765,7 +772,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) append_token(token, &source_head, &source_tail); /*if (append_to_return()==0) state=YAPP_STATE_EOF;*/ ydebug(("YAPP: default: '%c' \"%s\"\n", token, yapp_preproc_lval.str_val)); - /*Error(p_line_index, _("YAPP got an unhandled token."));*/ + /*cur_we->error(cur_lindex, N_("YAPP got an unhandled token."));*/ break; case IDENT: @@ -788,7 +795,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) case CLEAR: HAMT_delete(macro_table, (void (*)(void *))yapp_macro_delete); - macro_table = HAMT_new(); + macro_table = HAMT_new(cur_we->internal_error_); break; case DEFINE: @@ -834,7 +841,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) break; } else if (last_token == ',' || token != ',') - Error(p_line_index, _("Unexpected token in %%define parameters")); + cur_we->error(cur_lindex, N_("Unexpected token in %%define parameters")); last_token = token; } if (token == ')') { @@ -851,7 +858,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) append_token('\n', &source_head, &source_tail); } else { - InternalError(_("%%define ... failed miserably - neither \\n, WS, or ( followed ident")); + cur_we->internal_error(N_("%%define ... failed miserably - neither \\n, WS, or ( followed ident")); } break; @@ -914,7 +921,7 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) } break; default: - Error(p_line_index, _("YAPP got into a bad state")); + cur_we->error(cur_lindex, N_("YAPP got into a bad state")); } if (need_line_directive) { append_token(LINE, &source_head, &source_tail); @@ -932,8 +939,8 @@ yapp_preproc_input(char *buf, size_t max_size, linemgr *lm) saved_length -= strlen(src->token.str); SLIST_REMOVE_HEAD(&source_head, next); - free(src->token.str); - free(src); + xfree(src->token.str); + xfree(src); } } @@ -945,5 +952,6 @@ preproc yasm_yapp_LTX_preproc = { "YAPP preprocessing (NASM style)", "yapp", yapp_preproc_initialize, + yapp_preproc_cleanup, yapp_preproc_input }; diff --git a/src/preprocs/yapp/yapp-preproc.h b/src/preprocs/yapp/yapp-preproc.h index 428b65f0..5e2bdf76 100644 --- a/src/preprocs/yapp/yapp-preproc.h +++ b/src/preprocs/yapp/yapp-preproc.h @@ -52,3 +52,9 @@ typedef enum { void yapp_lex_initialize(FILE *f); void set_inhibit(void); + +extern /*@dependent@*/ linemgr *yapp_preproc_linemgr; +extern /*@dependent@*/ errwarn *yapp_preproc_errwarn; +#define cur_lindex (yapp_preproc_linemgr->get_current()) +#define cur_we yapp_preproc_errwarn + diff --git a/src/preprocs/yapp/yapp-token.h b/src/preprocs/yapp/yapp-token.h index 01c67b7a..43012495 100644 --- a/src/preprocs/yapp/yapp-token.h +++ b/src/preprocs/yapp/yapp-token.h @@ -60,7 +60,5 @@ typedef union { extern YYSTYPE yapp_preproc_lval; extern char *yapp_preproc_current_file; extern int yapp_preproc_line_number; -extern /*@dependent@*/ linemgr *yapp_preproc_linemgr; -#define p_line_index (yapp_preproc_linemgr->get_current()) int yapp_preproc_lex(void); diff --git a/src/preprocs/yapp/yapp-token.l b/src/preprocs/yapp/yapp-token.l index 17072e20..d45ed613 100644 --- a/src/preprocs/yapp/yapp-token.l +++ b/src/preprocs/yapp/yapp-token.l @@ -124,9 +124,7 @@ DIR %[ \t]* int inch, count; char endch = yytext[0]; - strbuf = malloc(STRBUF_ALLOC_SIZE); - if(!strbuf) - Fatal(FATAL_NOMEM); + strbuf = xmalloc(STRBUF_ALLOC_SIZE); strbuf_size = STRBUF_ALLOC_SIZE; inch = input(); @@ -134,18 +132,16 @@ DIR %[ \t]* while(inch != EOF && inch != endch && inch != '\n') { strbuf[count++] = inch; if(count >= strbuf_size) { - strbuf = realloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE); - if(!strbuf) - Fatal(FATAL_NOMEM); + strbuf = xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE); strbuf_size += STRBUF_ALLOC_SIZE; } inch = input(); } if(inch == '\n') - Error(p_line_index, _("unterminated string")); + cur_we->error(cur_lindex, _("unterminated string")); else if(inch == EOF) - Error(p_line_index, _("unexpected end of file in string")); + cur_we->error(cur_lindex, _("unexpected end of file in string")); strbuf[count] = '\0'; @@ -176,9 +172,9 @@ DIR %[ \t]* /* FIXME: handle includes that aren't relative */ incfile = fopen (yytext, "r"); if(!incfile) { - Error(p_line_index, _("include file `%s': %s"), + cur_we->error(cur_lindex, _("include file `%s': %s"), yytext, strerror(errno)); - free(inc); + xfree(inc); } else { yyin = incfile; @@ -204,11 +200,11 @@ DIR %[ \t]* inc = SLIST_FIRST(&includes_head); yy_delete_buffer (YY_CURRENT_BUFFER); yy_switch_to_buffer (inc->include_state); - free(yapp_preproc_current_file); + xfree(yapp_preproc_current_file); yapp_preproc_current_file = inc->filename; yapp_preproc_line_number = inc->line_number + 1; SLIST_REMOVE_HEAD(&includes_head, next); - free(inc); + xfree(inc); BEGIN(incl); return INCLUDE; @@ -232,7 +228,7 @@ DIR %[ \t]* } {WS}+["] ; /* eat space before file */ [^ \t\n"]* { /* have the filename */ - free(yapp_preproc_current_file); + xfree(yapp_preproc_current_file); yapp_preproc_current_file = xstrdup(yytext); } ["]{WS}*\n { @@ -334,12 +330,12 @@ DIR %[ \t]* [][+*/,()-] { return yytext[0]; } . { - Warning(p_line_index, _("Unhandled character in `%s'"), conv_unprint(yytext[0])); + cur_we->warning(WARN_PREPROC, cur_lindex, _("Unhandled character in `%s'"), cur_we->conv_unprint(yytext[0])); } . { - Warning(p_line_index, _("ignoring unrecognized character `%s'"), - conv_unprint(yytext[0])); + cur_we->warning(WARN_PREPROC, cur_lindex, _("ignoring unrecognized character `%s'"), + cur_we->conv_unprint(yytext[0])); } %% diff --git a/src/section.c b/src/section.c index 430c73bf..a8581137 100644 --- a/src/section.c +++ b/src/section.c @@ -54,6 +54,9 @@ struct section { int res_only; /* allow only resb family of bytecodes? */ bytecodehead bc; /* the bytecodes for the section's contents */ + + /*@exits@*/ void (*error_func) (const char *file, unsigned int line, + const char *message); }; /*@-compdestroy@*/ @@ -82,7 +85,10 @@ sections_initialize(sectionhead *headp, objfmt *of) section * sections_switch_general(sectionhead *headp, const char *name, unsigned long start, int res_only, int *isnew, - unsigned long lindex) + unsigned long lindex, + /*@exits@*/ void (*error_func) (const char *file, + unsigned int line, + const char *message)) { section *s; @@ -113,6 +119,8 @@ sections_switch_general(sectionhead *headp, const char *name, s->opt_flags = 0; s->res_only = res_only; + s->error_func = error_func; + *isnew = 1; return s; } @@ -120,7 +128,10 @@ sections_switch_general(sectionhead *headp, const char *name, /*@-onlytrans@*/ section * -sections_switch_absolute(sectionhead *headp, expr *start) +sections_switch_absolute(sectionhead *headp, expr *start, + /*@exits@*/ void (*error_func) (const char *file, + unsigned int line, + const char *message)) { section *s; @@ -134,6 +145,8 @@ sections_switch_absolute(sectionhead *headp, expr *start) s->opt_flags = 0; s->res_only = 1; + s->error_func = error_func; + return s; } /*@=onlytrans@*/ @@ -164,7 +177,8 @@ section_set_of_data(section *sect, objfmt *of, void *of_data) if (of->section_data_delete) of->section_data_delete(of_data); else - InternalError(_("don't know how to delete objfmt-specific section data")); + sect->error_func(__FILE__, __LINE__, + N_("don't know how to delete objfmt-specific section data")); return; } @@ -174,7 +188,8 @@ section_set_of_data(section *sect, objfmt *of, void *of_data) if (of2->section_data_delete) of2->section_data_delete(sect->data.general.of_data); else - InternalError(_("don't know how to delete objfmt-specific section data")); + sect->error_func(__FILE__, __LINE__, + N_("don't know how to delete objfmt-specific section data")); } /* Assign new of_data */ @@ -285,7 +300,8 @@ section_delete(section *sect) if (of->section_data_delete) of->section_data_delete(sect->data.general.of_data); else - InternalError(_("don't know how to delete objfmt-specific section data")); + sect->error_func(__FILE__, __LINE__, + N_("don't know how to delete objfmt-specific section data")); } } expr_delete(sect->start); diff --git a/src/section.h b/src/section.h index c7f5e954..82536fd7 100644 --- a/src/section.h +++ b/src/section.h @@ -25,14 +25,15 @@ /*@dependent@*/ section *sections_initialize(sectionhead *headp, objfmt *of); /*@dependent@*/ section *sections_switch_general(sectionhead *headp, - const char *name, - unsigned long start, - int res_only, - /*@out@*/ int *isnew, - unsigned long lindex); + const char *name, unsigned long start, int res_only, /*@out@*/ int *isnew, + unsigned long lindex, + /*@exits@*/ void (*error_func) (const char *file, unsigned int line, + const char *message)); /*@dependent@*/ section *sections_switch_absolute(sectionhead *headp, - /*@keep@*/ expr *start); + /*@keep@*/ expr *start, + /*@exits@*/ void (*error_func) (const char *file, unsigned int line, + const char *message)); int section_is_absolute(section *sect); diff --git a/src/symrec.c b/src/symrec.c index fe32457b..80e6f4d4 100644 --- a/src/symrec.c +++ b/src/symrec.c @@ -76,7 +76,7 @@ struct symrec { }; /* The symbol table: a hash array mapped trie (HAMT). */ -static /*@only@*/ /*@null@*/ HAMT *sym_table = NULL; +static /*@only@*/ HAMT *sym_table; /* Linked list of symbols not in the symbol table. */ typedef struct non_table_symrec_s { @@ -85,8 +85,20 @@ typedef struct non_table_symrec_s { } non_table_symrec; typedef /*@reldef@*/ SLIST_HEAD(nontablesymhead_s, non_table_symrec_s) nontablesymhead; -static /*@only@*/ /*@null@*/ nontablesymhead *non_table_syms = NULL; +static /*@only@*/ nontablesymhead *non_table_syms; +static /*@dependent@*/ errwarn *cur_we; + + +void +symrec_initialize(errwarn *we) +{ + cur_we = we; + + sym_table = HAMT_new(cur_we->internal_error_); + non_table_syms = xmalloc(sizeof(nontablesymhead)); + SLIST_INIT(non_table_syms); +} static void symrec_delete_one(/*@only@*/ void *d) @@ -99,7 +111,8 @@ symrec_delete_one(/*@only@*/ void *d) if (sym->of->symrec_data_delete) sym->of->symrec_data_delete(sym->of_data); else - InternalError(_("don't know how to delete objfmt-specific data")); + cur_we->internal_error( + N_("don't know how to delete objfmt-specific data")); } xfree(sym); } @@ -124,9 +137,6 @@ symrec_get_or_new_in_table(/*@only@*/ char *name) symrec *rec = symrec_new_common(name); int replace = 0; - if (!sym_table) - sym_table = HAMT_new(); - rec->status = SYM_NOSTATUS; return HAMT_insert(sym_table, name, rec, &replace, symrec_delete_one); @@ -138,11 +148,6 @@ symrec_get_or_new_not_in_table(/*@only@*/ char *name) non_table_symrec *sym = xmalloc(sizeof(non_table_symrec)); sym->rec = symrec_new_common(name); - if (!non_table_syms) { - non_table_syms = xmalloc(sizeof(nontablesymhead)); - SLIST_INIT(non_table_syms); - } - sym->rec->status = SYM_NOTINTABLE; SLIST_INSERT_HEAD(non_table_syms, sym, link); @@ -169,10 +174,7 @@ symrec_get_or_new(const char *name, int in_table) int symrec_traverse(void *d, int (*func) (symrec *sym, void *d)) { - if (sym_table) - return HAMT_traverse(sym_table, d, (int (*) (void *, void *))func); - else - return 1; + return HAMT_traverse(sym_table, d, (int (*) (void *, void *))func); } symrec * @@ -194,9 +196,9 @@ symrec_define(const char *name, SymType type, int in_table, /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */ if ((rec->status & SYM_DEFINED) || (rec->visibility & (SYM_COMMON | SYM_EXTERN))) { - Error(lindex, - _("duplicate definition of `%s'; first defined on line %lu"), - name, rec->line); + cur_we->error(lindex, + N_("duplicate definition of `%s'; first defined on line %lu"), + name, rec->line); } else { rec->line = lindex; /* set line number of definition */ rec->type = type; @@ -247,9 +249,9 @@ symrec_declare(const char *name, SymVisibility vis, unsigned long lindex) ((rec->visibility & SYM_EXTERN) && (vis == SYM_EXTERN))))) rec->visibility |= vis; else - Error(lindex, - _("duplicate definition of `%s'; first defined on line %lu"), - name, rec->line); + cur_we->error(lindex, + N_("duplicate definition of `%s'; first defined on line %lu"), + name, rec->line); return rec; } @@ -312,7 +314,8 @@ symrec_set_of_data(symrec *sym, objfmt *of, void *of_data) if (sym->of->symrec_data_delete) sym->of->symrec_data_delete(sym->of_data); else - InternalError(_("don't know how to delete objfmt-specific data")); + cur_we->internal_error( + N_("don't know how to delete objfmt-specific data")); } sym->of = of; sym->of_data = of_data; @@ -325,7 +328,8 @@ symrec_parser_finalize_checksym(symrec *sym, /*@unused@*/ /*@null@*/ void *d) /* error if a symbol is used but never defined or extern/common declared */ if ((sym->status & SYM_USED) && !(sym->status & SYM_DEFINED) && !(sym->visibility & (SYM_EXTERN | SYM_COMMON))) { - Error(sym->line, _("undefined symbol `%s' (first use)"), sym->name); + cur_we->error(sym->line, N_("undefined symbol `%s' (first use)"), + sym->name); if (sym->line < firstundef_line) firstundef_line = sym->line; } @@ -339,27 +343,22 @@ symrec_parser_finalize(void) firstundef_line = ULONG_MAX; symrec_traverse(NULL, symrec_parser_finalize_checksym); if (firstundef_line < ULONG_MAX) - Error(firstundef_line, - _(" (Each undefined symbol is reported only once.)")); + cur_we->error(firstundef_line, + N_(" (Each undefined symbol is reported only once.)")); } void -symrec_delete_all(void) +symrec_cleanup(void) { - if (sym_table) { - HAMT_delete(sym_table, symrec_delete_one); - sym_table = NULL; - } - if (non_table_syms) { - while (!SLIST_EMPTY(non_table_syms)) { - non_table_symrec *sym = SLIST_FIRST(non_table_syms); - SLIST_REMOVE_HEAD(non_table_syms, link); - symrec_delete_one(sym->rec); - xfree(sym); - } - xfree(non_table_syms); - non_table_syms = NULL; + HAMT_delete(sym_table, symrec_delete_one); + + while (!SLIST_EMPTY(non_table_syms)) { + non_table_symrec *sym = SLIST_FIRST(non_table_syms); + SLIST_REMOVE_HEAD(non_table_syms, link); + symrec_delete_one(sym->rec); + xfree(sym); } + xfree(non_table_syms); } typedef struct symrec_print_data { diff --git a/src/symrec.h b/src/symrec.h index 47d148e8..b4c8231a 100644 --- a/src/symrec.h +++ b/src/symrec.h @@ -22,6 +22,8 @@ #ifndef YASM_SYMREC_H #define YASM_SYMREC_H +void symrec_initialize(errwarn *we); + /*@dependent@*/ symrec *symrec_use(const char *name, unsigned long lindex); /*@dependent@*/ symrec *symrec_define_equ(const char *name, /*@keep@*/ expr *e, unsigned long lindex); @@ -64,7 +66,7 @@ int /*@alt void@*/ symrec_traverse(/*@null@*/ void *d, void symrec_parser_finalize(void); -void symrec_delete_all(void); +void symrec_cleanup(void); void symrec_print_all(FILE *f, int indent_level); diff --git a/src/tests/floatnum_test.c b/src/tests/floatnum_test.c index 84a4bdad..6972c937 100644 --- a/src/tests/floatnum_test.c +++ b/src/tests/floatnum_test.c @@ -421,6 +421,7 @@ main(void) Suite *s = floatnum_suite(); SRunner *sr = srunner_create(s); BitVector_Boot(); + floatnum_initialize(NULL); srunner_run_all(sr, CRNORMAL); nf = srunner_ntests_failed(sr); srunner_free(sr); diff --git a/src/util.h b/src/util.h index c9d2e2bd..89fa46c8 100644 --- a/src/util.h +++ b/src/util.h @@ -129,6 +129,8 @@ int strncasecmp(const char *s1, const char *s2, size_t n); /*@only@*/ char *xstrdup(const char *str); /* Error-checking memory allocation routines in xmalloc.c. */ +void xalloc_initialize(/*@exits@*/ void (*fatal_func) (int type), + int nomem_fatal_type); /*@only@*/ /*@out@*/ void *xmalloc(size_t size); /*@only@*/ void *xcalloc(size_t nelem, size_t elsize); /*@only@*/ void *xrealloc(/*@only@*/ /*@out@*/ /*@returned@*/ /*@null@*/ diff --git a/src/xmalloc.c b/src/xmalloc.c index c1a38d45..5691f3bf 100644 --- a/src/xmalloc.c +++ b/src/xmalloc.c @@ -22,8 +22,17 @@ #include "util.h" RCSID("$IdPath$"); -#include "errwarn.h" +static /*@exits@*/ void (*fatal_func) (int type); +static int nomem_fatal_type; + + +void +xalloc_initialize(/*@exits@*/ void (*f) (int type), int t) +{ + fatal_func = f; + nomem_fatal_type = t; +} #ifndef WITH_DMALLOC @@ -36,7 +45,7 @@ xmalloc(size_t size) size = 1; newmem = malloc(size); if (!newmem) - Fatal(FATAL_NOMEM); + fatal_func(nomem_fatal_type); return newmem; } @@ -51,7 +60,7 @@ xcalloc(size_t nelem, size_t elsize) newmem = calloc(nelem, elsize); if (!newmem) - Fatal(FATAL_NOMEM); + fatal_func(nomem_fatal_type); return newmem; } @@ -68,7 +77,7 @@ xrealloc(void *oldmem, size_t size) else newmem = realloc(oldmem, size); if (!newmem) - Fatal(FATAL_NOMEM); + fatal_func(nomem_fatal_type); return newmem; } diff --git a/util.h b/util.h index c9d2e2bd..89fa46c8 100644 --- a/util.h +++ b/util.h @@ -129,6 +129,8 @@ int strncasecmp(const char *s1, const char *s2, size_t n); /*@only@*/ char *xstrdup(const char *str); /* Error-checking memory allocation routines in xmalloc.c. */ +void xalloc_initialize(/*@exits@*/ void (*fatal_func) (int type), + int nomem_fatal_type); /*@only@*/ /*@out@*/ void *xmalloc(size_t size); /*@only@*/ void *xcalloc(size_t nelem, size_t elsize); /*@only@*/ void *xrealloc(/*@only@*/ /*@out@*/ /*@returned@*/ /*@null@*/