mirror of
https://github.com/yasm/yasm
synced 2026-08-26 22:26:05 -04:00
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
This commit is contained in:
parent
6fd648a146
commit
9f6cb6783f
105 changed files with 1926 additions and 1468 deletions
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ typedef struct intnum intnum;
|
|||
typedef struct floatnum floatnum;
|
||||
|
||||
typedef struct linemgr linemgr;
|
||||
typedef struct errwarn errwarn;
|
||||
|
||||
typedef enum {
|
||||
EXPR_ADD,
|
||||
|
|
|
|||
|
|
@ -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<<WARN_UNRECOGNIZED_CHAR);
|
||||
|
||||
/* Total error count for entire assembler run.
|
||||
* Assembler should exit with EXIT_FAILURE if this is >= 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<<WARN_GENERAL) | (1UL<<WARN_UNREC_CHAR) | (1UL<<WARN_PREPROC);
|
||||
|
||||
error_count = 0;
|
||||
warning_count = 0;
|
||||
SLIST_INIT(&errwarns);
|
||||
previous_we = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
yasm_errwarn_cleanup(void)
|
||||
{
|
||||
errwarn_data *we;
|
||||
|
||||
/* Delete all error/warnings */
|
||||
while (!SLIST_EMPTY(&errwarns)) {
|
||||
we = SLIST_FIRST(&errwarns);
|
||||
|
||||
SLIST_REMOVE_HEAD(&errwarns, link);
|
||||
xfree(we);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert a possibly unprintable character into a printable string, using
|
||||
* standard cat(1) convention for unprintable characters. */
|
||||
char *
|
||||
conv_unprint(char ch)
|
||||
* standard cat(1) convention for unprintable characters.
|
||||
*/
|
||||
static char *
|
||||
yasm_errwarn_conv_unprint(char ch)
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
|
|
@ -110,12 +128,14 @@ conv_unprint(char ch)
|
|||
}
|
||||
|
||||
/* Report an internal error. Essentially a fatal error with trace info.
|
||||
* Exit immediately because it's essentially an assert() trap. */
|
||||
void
|
||||
InternalError_(const char *file, unsigned int line, const char *message)
|
||||
* Exit immediately because it's essentially an assert() trap.
|
||||
*/
|
||||
static void
|
||||
yasm_errwarn_internal_error_(const char *file, unsigned int line,
|
||||
const char *message)
|
||||
{
|
||||
fprintf(stderr, _("INTERNAL ERROR at %s, line %u: %s\n"), file, line,
|
||||
message);
|
||||
gettext(message));
|
||||
#ifdef HAVE_ABORT
|
||||
abort();
|
||||
#else
|
||||
|
|
@ -124,11 +144,12 @@ InternalError_(const char *file, unsigned int line, const char *message)
|
|||
}
|
||||
|
||||
/* Report a fatal error. These are unrecoverable (such as running out of
|
||||
* memory), so just exit immediately. */
|
||||
void
|
||||
Fatal(fatal_num num)
|
||||
* memory), so just exit immediately.
|
||||
*/
|
||||
static void
|
||||
yasm_errwarn_fatal(fatal_num num)
|
||||
{
|
||||
fprintf(stderr, "%s %s\n", _("FATAL:"), gettext(fatal_msgs[num]));
|
||||
fprintf(stderr, _("FATAL: %s\n"), gettext(fatal_msgs[num]));
|
||||
#ifdef HAVE_ABORT
|
||||
abort();
|
||||
#else
|
||||
|
|
@ -140,10 +161,10 @@ Fatal(fatal_num num)
|
|||
* If replace_parser_error is nonzero, overwrites the last error if its
|
||||
* type is WE_PARSERERROR.
|
||||
*/
|
||||
static errwarn *
|
||||
errwarn_new(unsigned long lindex, int replace_parser_error)
|
||||
static errwarn_data *
|
||||
errwarn_data_new(unsigned long lindex, int replace_parser_error)
|
||||
{
|
||||
errwarn *first, *next, *ins_we, *we;
|
||||
errwarn_data *first, *next, *ins_we, *we;
|
||||
enum { INS_NONE, INS_HEAD, INS_AFTER } action = INS_NONE;
|
||||
|
||||
/* Find the entry with either line=lindex or the last one with line<lindex.
|
||||
|
|
@ -173,7 +194,7 @@ errwarn_new(unsigned long lindex, int replace_parser_error)
|
|||
we = ins_we;
|
||||
} else {
|
||||
/* add a new error */
|
||||
we = xmalloc(sizeof(errwarn));
|
||||
we = xmalloc(sizeof(errwarn_data));
|
||||
|
||||
we->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<<num)))
|
||||
return; /* warning is part of disabled class */
|
||||
|
||||
we = errwarn_data_new(lindex, 0);
|
||||
|
||||
we->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<<num);
|
||||
}
|
||||
|
||||
/* Register an warning at line lindex. Does not print the warning, only stores
|
||||
* it for OutputAllErrorWarning() to print.
|
||||
*/
|
||||
void
|
||||
Warning(unsigned long lindex, const char *fmt, ...)
|
||||
static void
|
||||
yasm_errwarn_warn_disable(warn_class_num num)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
warning_common(lindex, fmt, va);
|
||||
va_end(va);
|
||||
warn_class_enabled &= ~(1UL<<num);
|
||||
}
|
||||
|
||||
void
|
||||
ErrorNow(const char *fmt, ...)
|
||||
static void
|
||||
yasm_errwarn_warn_disable_all(void)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
WarningNow(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (warnings_disabled)
|
||||
return;
|
||||
|
||||
fprintf(stderr, "%s ", _("warning:"));
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
warn_class_enabled = 0;
|
||||
}
|
||||
|
||||
/* Get the number of errors (including warnings if warnings are being treated
|
||||
* as errors).
|
||||
*/
|
||||
unsigned int
|
||||
GetNumErrors(void)
|
||||
static unsigned int
|
||||
yasm_errwarn_get_num_errors(int warning_as_error)
|
||||
{
|
||||
if (warning_error)
|
||||
if (warning_as_error)
|
||||
return error_count+warning_count;
|
||||
else
|
||||
return error_count;
|
||||
}
|
||||
|
||||
/* Output all previously stored errors and warnings to stderr. */
|
||||
void
|
||||
OutputAllErrorWarning(linemgr *lm)
|
||||
static void
|
||||
yasm_errwarn_output_all(linemgr *lm, int warning_as_error)
|
||||
{
|
||||
errwarn *we;
|
||||
errwarn_data *we;
|
||||
const char *filename;
|
||||
unsigned long line;
|
||||
|
||||
/* If we're treating warnings as errors, tell the user about it. */
|
||||
if (warning_error && warning_error != 2) {
|
||||
if (warning_as_error && warning_as_error != 2) {
|
||||
fprintf(stderr, "%s\n", _("warnings being treated as errors"));
|
||||
warning_error = 2;
|
||||
warning_as_error = 2;
|
||||
}
|
||||
|
||||
/* Output error/warning, then delete each message. */
|
||||
while (!SLIST_EMPTY(&errwarns)) {
|
||||
we = SLIST_FIRST(&errwarns);
|
||||
/* Output error/warnings. */
|
||||
SLIST_FOREACH(we, &errwarns, link) {
|
||||
/* Output error/warning */
|
||||
lm->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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 *,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<<keypart;
|
||||
SetSubTrie(node, newnodes);
|
||||
SetSubTrie(hamt, node, newnodes);
|
||||
node = &newnodes[0];
|
||||
level++;
|
||||
} else {
|
||||
|
|
@ -241,7 +247,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
|
|||
|
||||
/* Set bits in bitmap corresponding to keys */
|
||||
node->BitMapKey = (1UL<<keypart) | (1UL<<keypart2);
|
||||
SetSubTrie(node, newnodes);
|
||||
SetSubTrie(hamt, node, newnodes);
|
||||
*replace = 1;
|
||||
return data;
|
||||
}
|
||||
|
|
@ -285,7 +291,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
|
|||
entry->data = data;
|
||||
SLIST_INSERT_HEAD(&hamt->entries, entry, next);
|
||||
newnodes[Map].BaseValue = entry;
|
||||
SetSubTrie(node, newnodes);
|
||||
SetSubTrie(hamt, node, newnodes);
|
||||
|
||||
*replace = 1;
|
||||
return data;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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@*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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; i<jmprel->shortop.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) {
|
||||
|
|
|
|||
|
|
@ -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; i<e->terms[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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
53
modules/parsers/nasm/nasm-parser.h
Normal file
53
modules/parsers/nasm/nasm-parser.h
Normal file
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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]*
|
|||
}
|
||||
<line>{WS}+["] ; /* eat space before file */
|
||||
<line>[^ \t\n"]* { /* have the filename */
|
||||
free(yapp_preproc_current_file);
|
||||
xfree(yapp_preproc_current_file);
|
||||
yapp_preproc_current_file = xstrdup(yytext);
|
||||
}
|
||||
<line>["]{WS}*\n {
|
||||
|
|
@ -334,12 +330,12 @@ DIR %[ \t]*
|
|||
[][+*/,()-] { return yytext[0]; }
|
||||
|
||||
<inhibit>. {
|
||||
Warning(p_line_index, _("Unhandled character in <inhibit> `%s'"), conv_unprint(yytext[0]));
|
||||
cur_we->warning(WARN_PREPROC, cur_lindex, _("Unhandled character in <inhibit> `%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]));
|
||||
}
|
||||
|
||||
%%
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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; i<jmprel->shortop.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) {
|
||||
|
|
|
|||
|
|
@ -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; i<e->terms[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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ typedef struct intnum intnum;
|
|||
typedef struct floatnum floatnum;
|
||||
|
||||
typedef struct linemgr linemgr;
|
||||
typedef struct errwarn errwarn;
|
||||
|
||||
typedef enum {
|
||||
EXPR_ADD,
|
||||
|
|
|
|||
239
src/errwarn.c
239
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<<WARN_UNRECOGNIZED_CHAR);
|
||||
|
||||
/* Total error count for entire assembler run.
|
||||
* Assembler should exit with EXIT_FAILURE if this is >= 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<<WARN_GENERAL) | (1UL<<WARN_UNREC_CHAR) | (1UL<<WARN_PREPROC);
|
||||
|
||||
error_count = 0;
|
||||
warning_count = 0;
|
||||
SLIST_INIT(&errwarns);
|
||||
previous_we = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
yasm_errwarn_cleanup(void)
|
||||
{
|
||||
errwarn_data *we;
|
||||
|
||||
/* Delete all error/warnings */
|
||||
while (!SLIST_EMPTY(&errwarns)) {
|
||||
we = SLIST_FIRST(&errwarns);
|
||||
|
||||
SLIST_REMOVE_HEAD(&errwarns, link);
|
||||
xfree(we);
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert a possibly unprintable character into a printable string, using
|
||||
* standard cat(1) convention for unprintable characters. */
|
||||
char *
|
||||
conv_unprint(char ch)
|
||||
* standard cat(1) convention for unprintable characters.
|
||||
*/
|
||||
static char *
|
||||
yasm_errwarn_conv_unprint(char ch)
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
|
|
@ -110,12 +128,14 @@ conv_unprint(char ch)
|
|||
}
|
||||
|
||||
/* Report an internal error. Essentially a fatal error with trace info.
|
||||
* Exit immediately because it's essentially an assert() trap. */
|
||||
void
|
||||
InternalError_(const char *file, unsigned int line, const char *message)
|
||||
* Exit immediately because it's essentially an assert() trap.
|
||||
*/
|
||||
static void
|
||||
yasm_errwarn_internal_error_(const char *file, unsigned int line,
|
||||
const char *message)
|
||||
{
|
||||
fprintf(stderr, _("INTERNAL ERROR at %s, line %u: %s\n"), file, line,
|
||||
message);
|
||||
gettext(message));
|
||||
#ifdef HAVE_ABORT
|
||||
abort();
|
||||
#else
|
||||
|
|
@ -124,11 +144,12 @@ InternalError_(const char *file, unsigned int line, const char *message)
|
|||
}
|
||||
|
||||
/* Report a fatal error. These are unrecoverable (such as running out of
|
||||
* memory), so just exit immediately. */
|
||||
void
|
||||
Fatal(fatal_num num)
|
||||
* memory), so just exit immediately.
|
||||
*/
|
||||
static void
|
||||
yasm_errwarn_fatal(fatal_num num)
|
||||
{
|
||||
fprintf(stderr, "%s %s\n", _("FATAL:"), gettext(fatal_msgs[num]));
|
||||
fprintf(stderr, _("FATAL: %s\n"), gettext(fatal_msgs[num]));
|
||||
#ifdef HAVE_ABORT
|
||||
abort();
|
||||
#else
|
||||
|
|
@ -140,10 +161,10 @@ Fatal(fatal_num num)
|
|||
* If replace_parser_error is nonzero, overwrites the last error if its
|
||||
* type is WE_PARSERERROR.
|
||||
*/
|
||||
static errwarn *
|
||||
errwarn_new(unsigned long lindex, int replace_parser_error)
|
||||
static errwarn_data *
|
||||
errwarn_data_new(unsigned long lindex, int replace_parser_error)
|
||||
{
|
||||
errwarn *first, *next, *ins_we, *we;
|
||||
errwarn_data *first, *next, *ins_we, *we;
|
||||
enum { INS_NONE, INS_HEAD, INS_AFTER } action = INS_NONE;
|
||||
|
||||
/* Find the entry with either line=lindex or the last one with line<lindex.
|
||||
|
|
@ -173,7 +194,7 @@ errwarn_new(unsigned long lindex, int replace_parser_error)
|
|||
we = ins_we;
|
||||
} else {
|
||||
/* add a new error */
|
||||
we = xmalloc(sizeof(errwarn));
|
||||
we = xmalloc(sizeof(errwarn_data));
|
||||
|
||||
we->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<<num)))
|
||||
return; /* warning is part of disabled class */
|
||||
|
||||
we = errwarn_data_new(lindex, 0);
|
||||
|
||||
we->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<<num);
|
||||
}
|
||||
|
||||
/* Register an warning at line lindex. Does not print the warning, only stores
|
||||
* it for OutputAllErrorWarning() to print.
|
||||
*/
|
||||
void
|
||||
Warning(unsigned long lindex, const char *fmt, ...)
|
||||
static void
|
||||
yasm_errwarn_warn_disable(warn_class_num num)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
warning_common(lindex, fmt, va);
|
||||
va_end(va);
|
||||
warn_class_enabled &= ~(1UL<<num);
|
||||
}
|
||||
|
||||
void
|
||||
ErrorNow(const char *fmt, ...)
|
||||
static void
|
||||
yasm_errwarn_warn_disable_all(void)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
WarningNow(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (warnings_disabled)
|
||||
return;
|
||||
|
||||
fprintf(stderr, "%s ", _("warning:"));
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
fprintf(stderr, "\n");
|
||||
warn_class_enabled = 0;
|
||||
}
|
||||
|
||||
/* Get the number of errors (including warnings if warnings are being treated
|
||||
* as errors).
|
||||
*/
|
||||
unsigned int
|
||||
GetNumErrors(void)
|
||||
static unsigned int
|
||||
yasm_errwarn_get_num_errors(int warning_as_error)
|
||||
{
|
||||
if (warning_error)
|
||||
if (warning_as_error)
|
||||
return error_count+warning_count;
|
||||
else
|
||||
return error_count;
|
||||
}
|
||||
|
||||
/* Output all previously stored errors and warnings to stderr. */
|
||||
void
|
||||
OutputAllErrorWarning(linemgr *lm)
|
||||
static void
|
||||
yasm_errwarn_output_all(linemgr *lm, int warning_as_error)
|
||||
{
|
||||
errwarn *we;
|
||||
errwarn_data *we;
|
||||
const char *filename;
|
||||
unsigned long line;
|
||||
|
||||
/* If we're treating warnings as errors, tell the user about it. */
|
||||
if (warning_error && warning_error != 2) {
|
||||
if (warning_as_error && warning_as_error != 2) {
|
||||
fprintf(stderr, "%s\n", _("warnings being treated as errors"));
|
||||
warning_error = 2;
|
||||
warning_as_error = 2;
|
||||
}
|
||||
|
||||
/* Output error/warning, then delete each message. */
|
||||
while (!SLIST_EMPTY(&errwarns)) {
|
||||
we = SLIST_FIRST(&errwarns);
|
||||
/* Output error/warnings. */
|
||||
SLIST_FOREACH(we, &errwarns, link) {
|
||||
/* Output error/warning */
|
||||
lm->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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 *,
|
||||
|
|
|
|||
49
src/file.c
49
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)
|
||||
|
|
|
|||
|
|
@ -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) \
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
22
src/hamt.c
22
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<<keypart;
|
||||
SetSubTrie(node, newnodes);
|
||||
SetSubTrie(hamt, node, newnodes);
|
||||
node = &newnodes[0];
|
||||
level++;
|
||||
} else {
|
||||
|
|
@ -241,7 +247,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
|
|||
|
||||
/* Set bits in bitmap corresponding to keys */
|
||||
node->BitMapKey = (1UL<<keypart) | (1UL<<keypart2);
|
||||
SetSubTrie(node, newnodes);
|
||||
SetSubTrie(hamt, node, newnodes);
|
||||
*replace = 1;
|
||||
return data;
|
||||
}
|
||||
|
|
@ -285,7 +291,7 @@ HAMT_insert(HAMT *hamt, const char *str, void *data, int *replace,
|
|||
entry->data = data;
|
||||
SLIST_INSERT_HEAD(&hamt->entries, entry, next);
|
||||
newnodes[Map].BaseValue = entry;
|
||||
SetSubTrie(node, newnodes);
|
||||
SetSubTrie(hamt, node, newnodes);
|
||||
|
||||
*replace = 1;
|
||||
return data;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
64
src/intnum.c
64
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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
187
src/main.c
187
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
53
src/parsers/nasm/nasm-parser.h
Normal file
53
src/parsers/nasm/nasm-parser.h
Normal file
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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]*
|
|||
}
|
||||
<line>{WS}+["] ; /* eat space before file */
|
||||
<line>[^ \t\n"]* { /* have the filename */
|
||||
free(yapp_preproc_current_file);
|
||||
xfree(yapp_preproc_current_file);
|
||||
yapp_preproc_current_file = xstrdup(yytext);
|
||||
}
|
||||
<line>["]{WS}*\n {
|
||||
|
|
@ -334,12 +330,12 @@ DIR %[ \t]*
|
|||
[][+*/,()-] { return yytext[0]; }
|
||||
|
||||
<inhibit>. {
|
||||
Warning(p_line_index, _("Unhandled character in <inhibit> `%s'"), conv_unprint(yytext[0]));
|
||||
cur_we->warning(WARN_PREPROC, cur_lindex, _("Unhandled character in <inhibit> `%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]));
|
||||
}
|
||||
|
||||
%%
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
77
src/symrec.c
77
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 {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue