aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2019-08-09 04:28:55 -0700
committerH. Peter Anvin (Intel) <hpa@zytor.com>2019-08-09 04:28:55 -0700
commitd66927a677f75d3c3f5e835054f19f80b4b27179 (patch)
tree1a335914604892c6792e74bf0f9974bfce305a2c
parent524918394d3fd4c2fb03cc01c015c96403524365 (diff)
downloadnasm-d66927a677f75d3c3f5e835054f19f80b4b27179.tar.gz
nasm-d66927a677f75d3c3f5e835054f19f80b4b27179.tar.xz
nasm-d66927a677f75d3c3f5e835054f19f80b4b27179.zip
Diagnostics: make debug more dynamic, note -> info, add listmsg level
Make debug messages more dynamic by making it easy to conditionalize the messages. Change ERR_NOTE to ERR_INFO which reflects the usage better. Other compilers use note: for additional information. Don't unwind the macro stack with ERR_HERE; it is only going to give confusing results as it will unwind the wrong macro stack. Add ERR_LISTMSG level which is *always* suppressed, but will still appear in the list file. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
-rw-r--r--asm/error.c3
-rw-r--r--asm/nasm.c58
-rw-r--r--include/error.h31
-rw-r--r--output/outbin.c22
-rw-r--r--output/outelf.c9
-rw-r--r--output/outobj.c14
6 files changed, 86 insertions, 51 deletions
diff --git a/asm/error.c b/asm/error.c
index b4ff8bad..95d7bef4 100644
--- a/asm/error.c
+++ b/asm/error.c
@@ -70,8 +70,9 @@ _type nasm_ ## _name (const char *fmt, ...) \
abort(); \
}
+nasm_err_helpers(void, listmsg, ERR_LISTMSG)
nasm_err_helpers(void, debug, ERR_DEBUG)
-nasm_err_helpers(void, note, ERR_NOTE)
+nasm_err_helpers(void, info, ERR_INFO)
nasm_err_helpers(void, nonfatal, ERR_NONFATAL)
nasm_err_helpers(fatal_func, fatal, ERR_FATAL)
nasm_err_helpers(fatal_func, panic, ERR_PANIC)
diff --git a/asm/nasm.c b/asm/nasm.c
index 618aa35a..676ff872 100644
--- a/asm/nasm.c
+++ b/asm/nasm.c
@@ -87,6 +87,8 @@ static const struct error_format errfmt_msvc = { "(", ")", " : " };
static const struct error_format *errfmt = &errfmt_gnu;
static struct strlist *warn_list;
+unsigned int debug_nasm; /* Debugging messages? */
+
static bool using_debug_info, opt_verbose_info;
static const char *debug_format;
@@ -832,7 +834,8 @@ enum text_options {
OPT_BEFORE,
OPT_LIMIT,
OPT_KEEP_ALL,
- OPT_NO_LINE
+ OPT_NO_LINE,
+ OPT_DEBUG
};
struct textargs {
const char *label;
@@ -857,6 +860,7 @@ static const struct textargs textopts[] = {
{"limit-", OPT_LIMIT, true, 0},
{"keep-all", OPT_KEEP_ALL, false, 0},
{"no-line", OPT_NO_LINE, false, 0},
+ {"debug", OPT_DEBUG, false, 0},
{NULL, OPT_BOGUS, false, 0}
};
@@ -1197,6 +1201,9 @@ static bool process_arg(char *p, char *q, int pass)
case OPT_NO_LINE:
pp_noline = true;
break;
+ case OPT_DEBUG:
+ debug_nasm = param ? strtoul(param, NULL, 10) : 1;
+ break;
case OPT_HELP:
help(0);
exit(0);
@@ -1592,7 +1599,7 @@ static void assemble_file(const char *fname, struct strlist *depend_list)
"after %"PRId64" passes; "
"stalled for %"PRId64", giving up.",
pass_count(), stall_count);
- nasm_notef(ERR_UNDEAD,
+ nasm_nonfatalf(ERR_UNDEAD,
"Possible causes: recursive EQUs, macro abuse.");
}
break;
@@ -1625,8 +1632,7 @@ static void assemble_file(const char *fname, struct strlist *depend_list)
if (opt_verbose_info && pass_final()) {
/* -On and -Ov switches */
- nasm_note("info: assembly required 1+%"PRId64"+2 passes\n",
- pass_count()-3);
+ nasm_info("assembly required 1+%"PRId64"+2 passes\n", pass_count()-3);
}
strlist_free(&warn_list);
@@ -1654,14 +1660,24 @@ static size_t warn_index(errflags severity)
static bool skip_this_pass(errflags severity)
{
+ errflags type = severity & ERR_MASK;
+
/*
* See if it's a pass-specific error or warning which should be skipped.
* We can never skip fatal errors as by definition they cannot be
* resumed from.
*/
- if ((severity & ERR_MASK) >= ERR_FATAL)
+ if (type >= ERR_FATAL)
return false;
+ /*
+ * ERR_LISTMSG messages are always skipped; the list file
+ * receives them anyway as this function is not consulted
+ * for sending to the list file.
+ */
+ if (type == ERR_LISTMSG)
+ return true;
+
/* This message not applicable unless pass_final */
return (severity & ERR_PASS2) && !pass_final();
}
@@ -1726,13 +1742,12 @@ static void nasm_verror_asm(errflags severity, const char *fmt, va_list args)
char warnsuf[64];
char linestr[64];
const char *pfx;
- errflags spec_type = severity & ERR_MASK; /* type originally specified */
errflags true_type = true_error_type(severity);
const char *currentfile = NULL;
int32_t lineno = 0;
static const char * const pfx_table[ERR_MASK+1] = {
- "debug: ", "note: ", "warning: ", "error: ",
- "", "", "fatal: ", "panic: "
+ ";;; ", "debug: ", "info: ", "warning: ",
+ "error: ", "", "fatal: ", "panic: "
};
if (is_suppressed(severity))
@@ -1749,13 +1764,6 @@ static void nasm_verror_asm(errflags severity, const char *fmt, va_list args)
}
}
- /*
- * For a debug/warning/note event, if ERR_HERE is set don't
- * output anything if there is no current filename available
- */
- if (!currentfile && (severity & ERR_HERE) && true_type <= ERR_WARNING)
- return;
-
if (severity & ERR_NO_SEVERITY)
pfx = "";
else
@@ -1763,7 +1771,11 @@ static void nasm_verror_asm(errflags severity, const char *fmt, va_list args)
vsnprintf(msg, sizeof msg, fmt, args);
*warnsuf = 0;
- if (spec_type == ERR_WARNING) {
+ if ((severity & (ERR_MASK|ERR_HERE|ERR_PP_LISTMACRO)) == ERR_WARNING) {
+ /*
+ * It's a warning without ERR_HERE defined, and we are not already
+ * unwinding the macros that led us here.
+ */
snprintf(warnsuf, sizeof warnsuf, " [-w+%s%s]",
(true_type >= ERR_NONFATAL) ? "error=" : "",
warning_name[warn_index(severity)]);
@@ -1777,7 +1789,10 @@ static void nasm_verror_asm(errflags severity, const char *fmt, va_list args)
if (!skip_this_pass(severity)) {
const char *file = currentfile ? currentfile : "nasm";
- const char *here = (severity & ERR_HERE) ? " here" : "";
+ const char *here = "";
+
+ if (severity & ERR_HERE)
+ here = currentfile ? " here" : " in an unknown location";
if (warn_list && true_type < ERR_NONFATAL &&
!(pass_first() && (severity & ERR_PASS1)))
@@ -1822,7 +1837,7 @@ static void nasm_verror_asm(errflags severity, const char *fmt, va_list args)
lfmt->error(severity, "%s%s in file %s%s",
pfx, msg, currentfile, warnsuf);
else
- lfmt->error(severity, "%s%s in unknown location%s",
+ lfmt->error(severity, "%s%s in an unknown location%s",
pfx, msg, warnsuf);
} else {
lfmt->error(severity, "%s%s%s", pfx, msg, warnsuf);
@@ -1834,11 +1849,14 @@ static void nasm_verror_asm(errflags severity, const char *fmt, va_list args)
if (severity & ERR_USAGE)
want_usage = true;
- preproc->error_list_macros(severity);
+ /* error_list_macros can for obvious reasons not work with ERR_HERE */
+ if (!(severity & ERR_HERE))
+ preproc->error_list_macros(severity);
switch (true_type) {
- case ERR_NOTE:
+ case ERR_LISTMSG:
case ERR_DEBUG:
+ case ERR_INFO:
case ERR_WARNING:
/* no further action, by definition */
break;
diff --git a/include/error.h b/include/error.h
index 9091fe81..85fcbe06 100644
--- a/include/error.h
+++ b/include/error.h
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 1996-2018 The NASM Authors - All Rights Reserved
+ * Copyright 1996-2019 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@@ -54,10 +54,12 @@ typedef uint32_t errflags;
* An error reporting function should look like this.
*/
void printf_func(2, 3) nasm_error(errflags severity, const char *fmt, ...);
+void printf_func(1, 2) nasm_listmsg(const char *fmt, ...);
+void printf_func(2, 3) nasm_listmsgf(errflags flags, const char *fmt, ...);
void printf_func(1, 2) nasm_debug(const char *fmt, ...);
void printf_func(2, 3) nasm_debugf(errflags flags, const char *fmt, ...);
-void printf_func(1, 2) nasm_note(const char *fmt, ...);
-void printf_func(2, 3) nasm_notef(errflags flags, const char *fmt, ...);
+void printf_func(1, 2) nasm_info(const char *fmt, ...);
+void printf_func(2, 3) nasm_intof(errflags flags, const char *fmt, ...);
void printf_func(2, 3) nasm_warn(errflags flags, const char *fmt, ...);
void printf_func(1, 2) nasm_nonfatal(const char *fmt, ...);
void printf_func(2, 3) nasm_nonfatalf(errflags flags, const char *fmt, ...);
@@ -82,10 +84,11 @@ static inline vefunc nasm_set_verror(vefunc ve)
* These are the error severity codes which get passed as the first
* argument to an efunc.
*/
-#define ERR_DEBUG 0x00000000 /* put out debugging message */
-#define ERR_NOTE 0x00000001 /* additional error information */
-#define ERR_WARNING 0x00000002 /* warn only: no further action */
-#define ERR_NONFATAL 0x00000003 /* terminate assembly after phase */
+#define ERR_LISTMSG 0x00000000 /* for the listing file only */
+#define ERR_DEBUG 0x00000001 /* debugging message */
+#define ERR_INFO 0x00000002 /* information for the list file */
+#define ERR_WARNING 0x00000003 /* warn only: no further action */
+#define ERR_NONFATAL 0x00000004 /* terminate assembly after phase */
#define ERR_FATAL 0x00000006 /* instantly fatal: exit with error */
#define ERR_PANIC 0x00000007 /* internal error: panic instantly
* and dump core for reference */
@@ -131,4 +134,18 @@ void reset_warnings(void);
/* Should be included from within error.h only */
#include "warnings.h"
+/* By defining MAX_DEBUG, we can compile out messages entirely */
+#ifndef MAX_DEBUG
+# define MAX_DEBUG (~0U)
+#endif
+
+/* Debug level checks */
+static inline bool debug_level(unsigned int level)
+{
+ extern unsigned int debug_nasm;
+ if (is_constant(level) && level > MAX_DEBUG)
+ return false;
+ return unlikely(level <= debug_nasm);
+}
+
#endif /* NASM_ERROR_H */
diff --git a/output/outbin.c b/output/outbin.c
index 95885b26..6b617096 100644
--- a/output/outbin.c
+++ b/output/outbin.c
@@ -228,11 +228,11 @@ static void bin_cleanup(void)
uint64_t pend;
int h;
-#ifdef DEBUG
- nasm_debug("bin_cleanup: Sections were initially referenced in this order:\n");
- for (h = 0, s = sections; s; h++, s = s->next)
- fprintf(stdout, "%i. %s\n", h, s->name);
-#endif
+ if (debug_level(1)) {
+ nasm_debug("bin_cleanup: Sections were initially referenced in this order:\n");
+ for (h = 0, s = sections; s; h++, s = s->next)
+ nasm_debug("%i. %s\n", h, s->name);
+ }
/* Assembly has completed, so now we need to generate the output file.
* Step 1: Separate progbits and nobits sections into separate lists.
@@ -511,12 +511,12 @@ static void bin_cleanup(void)
if (h)
nasm_fatal("circular vfollows path detected");
-#ifdef DEBUG
- nasm_debug("bin_cleanup: Confirm final section order for output file:\n");
- for (h = 0, s = sections; s && (s->flags & TYPE_PROGBITS);
- h++, s = s->next)
- fprintf(stdout, "%i. %s\n", h, s->name);
-#endif
+ if (debug_level(1)) {
+ nasm_debug("bin_cleanup: Confirm final section order for output file:\n");
+ for (h = 0, s = sections; s && (s->flags & TYPE_PROGBITS);
+ h++, s = s->next)
+ nasm_debug("%i. %s\n", h, s->name);
+ }
/* Step 5: Apply relocations. */
diff --git a/output/outelf.c b/output/outelf.c
index 1ebb0262..ee7ab8bc 100644
--- a/output/outelf.c
+++ b/output/outelf.c
@@ -734,10 +734,11 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset,
struct elf_symbol *sym;
bool special_used = false;
-#if defined(DEBUG) && DEBUG>2
- nasm_debug(" elf_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
- name, segment, offset, is_global, special);
-#endif
+ if (debug_level(2)) {
+ nasm_debug(" elf_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
+ name, segment, offset, is_global, special);
+ }
+
if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
/*
* This is a NASM special symbol. We never allow it into
diff --git a/output/outobj.c b/output/outobj.c
index a5936279..2612892a 100644
--- a/output/outobj.c
+++ b/output/outobj.c
@@ -771,10 +771,9 @@ static void obj_deflabel(char *name, int32_t segment,
int i;
bool used_special = false; /* have we used the special text? */
-#if defined(DEBUG) && DEBUG>2
- nasm_debug(" obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
- name, segment, offset, is_global, special);
-#endif
+ if (debug_level(2))
+ nasm_debug(" obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
+ name, segment, offset, is_global, special);
/*
* If it's a special-retry from pass two, discard it.
@@ -1330,10 +1329,9 @@ static int32_t obj_segment(char *name, int *bits)
* using the pointer it gets passed. That way we save memory,
* by sponging off the label manager.
*/
-#if defined(DEBUG) && DEBUG>=3
- nasm_debug(" obj_segment: < %s >, pass=%d, *bits=%d\n",
- name, pass, *bits);
-#endif
+ if (debug_level(3))
+ nasm_debug(" obj_segment: < %s >, *bits=%d\n", name, *bits);
+
if (!name) {
*bits = 16;
current_seg = NULL;