mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-09-22 10:43:39 -04:00
Sanitize the handling of messsages; improve info and debug
Make the handling of messages saner. In particular, regularize the handling of info and debug messages, so that nasm_info() and nasm_debug() actually become useful. Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
67
asm/error.c
67
asm/error.c
@@ -1,6 +1,6 @@
|
||||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
* Copyright 1996-2024 The NASM Authors - All Rights Reserved
|
||||
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
*
|
||||
@@ -36,13 +36,15 @@
|
||||
*/
|
||||
|
||||
#include "compiler.h"
|
||||
|
||||
|
||||
#include "nasmlib.h"
|
||||
#include "error.h"
|
||||
|
||||
unsigned int debug_nasm; /* Debugging messages? */
|
||||
unsigned int opt_verbose_info; /* Informational messages? */
|
||||
|
||||
/* Common function body */
|
||||
#define nasm_do_error(_sev,_flags) \
|
||||
do { \
|
||||
va_list ap; \
|
||||
va_start(ap, fmt); \
|
||||
if ((_sev) >= ERR_CRITICAL) \
|
||||
@@ -51,12 +53,17 @@
|
||||
nasm_verror((_sev)|(_flags), fmt, ap); \
|
||||
va_end(ap); \
|
||||
if ((_sev) >= ERR_FATAL) \
|
||||
abort();
|
||||
abort(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
void nasm_error(errflags severity, const char *fmt, ...)
|
||||
/*
|
||||
* This is the generic function to use when the error type is not
|
||||
* known a priori. For ERR_DEBUG and ERR_INFO the level can be
|
||||
* included by
|
||||
*/
|
||||
void nasm_error(errflags flags, const char *fmt, ...)
|
||||
{
|
||||
nasm_do_error(severity & ERR_MASK, severity & ~ERR_MASK);
|
||||
nasm_do_error(flags & ERR_MASK, flags);
|
||||
}
|
||||
|
||||
#define nasm_err_helpers(_type, _name, _sev) \
|
||||
@@ -71,8 +78,6 @@ _type nasm_ ## _name (const char *fmt, ...) \
|
||||
|
||||
nasm_err_helpers(void, listmsg, ERR_LISTMSG)
|
||||
nasm_err_helpers(void, note, ERR_NOTE)
|
||||
nasm_err_helpers(void, debug, ERR_DEBUG)
|
||||
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, critical, ERR_CRITICAL)
|
||||
@@ -91,6 +96,21 @@ void nasm_warn_(errflags flags, const char *fmt, ...)
|
||||
nasm_do_error(ERR_WARNING, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* nasm_info() and nasm_debug() takes mandatory enabling levels.
|
||||
*/
|
||||
void nasm_info_(unsigned int level, const char *fmt, ...)
|
||||
{
|
||||
if (info_level(level))
|
||||
nasm_do_error(ERR_INFO, LEVEL(level));
|
||||
}
|
||||
|
||||
void nasm_debug_(unsigned int level, const char *fmt, ...)
|
||||
{
|
||||
if (debug_level(level))
|
||||
nasm_do_error(ERR_DEBUG, LEVEL(level));
|
||||
}
|
||||
|
||||
fatal_func nasm_panic_from_macro(const char *func, const char *file, int line)
|
||||
{
|
||||
if (!func)
|
||||
@@ -297,3 +317,32 @@ bool set_warning_status(const char *value)
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* The various error type prefixes
|
||||
*/
|
||||
const char *error_pfx(errflags severity)
|
||||
{
|
||||
switch (severity & ERR_MASK) {
|
||||
case ERR_LISTMSG:
|
||||
return ";;; ";
|
||||
case ERR_NOTE:
|
||||
return "note: ";
|
||||
case ERR_DEBUG:
|
||||
return "debug: ";
|
||||
case ERR_INFO:
|
||||
return "info: ";
|
||||
case ERR_WARNING:
|
||||
return "warning: ";
|
||||
case ERR_NONFATAL:
|
||||
return "error: ";
|
||||
case ERR_FATAL:
|
||||
return "fatal: ";
|
||||
case ERR_CRITICAL:
|
||||
return "critical: ";
|
||||
case ERR_PANIC:
|
||||
return "panic: ";
|
||||
default:
|
||||
return "internal error: ";
|
||||
}
|
||||
}
|
||||
|
153
asm/nasm.c
153
asm/nasm.c
@@ -90,9 +90,7 @@ static const struct error_format *errfmt = &errfmt_gnu;
|
||||
static struct strlist *warn_list;
|
||||
static struct nasm_errhold *errhold_stack;
|
||||
|
||||
unsigned int debug_nasm; /* Debugging messages? */
|
||||
|
||||
static bool using_debug_info, opt_verbose_info;
|
||||
static bool using_debug_info;
|
||||
static const char *debug_format;
|
||||
|
||||
#ifndef ABORT_ON_PANIC
|
||||
@@ -122,7 +120,8 @@ const struct ofmt *ofmt = &OF_DEFAULT;
|
||||
const struct ofmt_alias *ofmt_alias = NULL;
|
||||
const struct dfmt *dfmt;
|
||||
|
||||
FILE *error_file; /* Where to write error messages */
|
||||
static FILE *error_file; /* Where to write error messages */
|
||||
errflags errflags_never = 0; /* Error flags to unconditionally suppress */
|
||||
|
||||
FILE *ofile = NULL;
|
||||
enum optimization optimizing = OPTIM_DEFAULT;
|
||||
@@ -942,6 +941,7 @@ enum text_options {
|
||||
OPT_KEEP_ALL,
|
||||
OPT_NO_LINE,
|
||||
OPT_DEBUG,
|
||||
OPT_INFO,
|
||||
OPT_REPRODUCIBLE
|
||||
};
|
||||
enum need_arg {
|
||||
@@ -973,6 +973,8 @@ static const struct textargs textopts[] = {
|
||||
{"limit-", OPT_LIMIT, ARG_YES, 0},
|
||||
{"keep-all", OPT_KEEP_ALL, ARG_NO, 0},
|
||||
{"no-line", OPT_NO_LINE, ARG_NO, 0},
|
||||
{"info", OPT_INFO , ARG_MAYBE, 0},
|
||||
{"verbose", OPT_INFO , ARG_MAYBE, 0},
|
||||
{"debug", OPT_DEBUG, ARG_MAYBE, 0},
|
||||
{"reproducible", OPT_REPRODUCIBLE, ARG_NO, 0},
|
||||
{NULL, OPT_BOGUS, ARG_NO, 0}
|
||||
@@ -1050,7 +1052,7 @@ static bool process_arg(char *p, char *q, int pass)
|
||||
case 'v':
|
||||
case '+':
|
||||
param++;
|
||||
opt_verbose_info = true;
|
||||
opt_verbose_info++;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
@@ -1341,9 +1343,15 @@ static bool process_arg(char *p, char *q, int pass)
|
||||
ppopt |= PP_NOLINE;
|
||||
break;
|
||||
case OPT_DEBUG:
|
||||
if (pass == 1)
|
||||
debug_nasm = param ?
|
||||
strtoul(param, NULL, 10) : debug_nasm+1;
|
||||
break;
|
||||
case OPT_INFO:
|
||||
if (pass == 1)
|
||||
opt_verbose_info = param ?
|
||||
strtoul(param, NULL, 10) : opt_verbose_info+1;
|
||||
break;
|
||||
case OPT_REPRODUCIBLE:
|
||||
reproducible = true;
|
||||
break;
|
||||
@@ -1647,6 +1655,11 @@ static void assemble_file(const char *fname, struct strlist *depend_list)
|
||||
if (!pass_final() && !warn_list)
|
||||
warn_list = strlist_alloc(false);
|
||||
|
||||
/* Suppress ERR_PASS2 unless we are actually in the final pass */
|
||||
errflags_never = 0;
|
||||
if (!pass_final())
|
||||
errflags_never |= ERR_PASS2;
|
||||
|
||||
globl.bits = cmd_sb; /* set 'bits' to command line default */
|
||||
globl.bnd = false;
|
||||
globl.rel = false;
|
||||
@@ -1767,34 +1780,15 @@ static void assemble_file(const char *fname, struct strlist *depend_list)
|
||||
reset_warnings();
|
||||
}
|
||||
|
||||
if (opt_verbose_info && pass_final()) {
|
||||
if (pass_final()) {
|
||||
/* -On and -Ov switches */
|
||||
nasm_info("assembly required 1+%"PRId64"+2 passes\n", pass_count()-3);
|
||||
nasm_info(1, "assembly required 1+%"PRId64"+2 passes\n", pass_count()-3);
|
||||
}
|
||||
|
||||
lfmt->cleanup();
|
||||
strlist_free(&warn_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* get warning index; 0 if this is non-suppressible.
|
||||
*/
|
||||
static size_t pure_func warn_index(errflags severity)
|
||||
{
|
||||
size_t index;
|
||||
|
||||
if ((severity & ERR_MASK) >= ERR_FATAL)
|
||||
return 0; /* Fatal errors are never suppressible */
|
||||
|
||||
/* Warnings MUST HAVE a warning category specifier! */
|
||||
nasm_assert((severity & (ERR_MASK|WARN_MASK)) != ERR_WARNING);
|
||||
|
||||
index = WARN_IDX(severity);
|
||||
nasm_assert(index < WARN_IDX_ALL);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
static bool skip_this_pass(errflags severity)
|
||||
{
|
||||
errflags type = severity & ERR_MASK;
|
||||
@@ -1830,21 +1824,42 @@ static bool skip_this_pass(errflags severity)
|
||||
* @param severity the severity of the warning or error
|
||||
* @return true if we should abort error/warning printing
|
||||
*/
|
||||
static bool is_suppressed(errflags severity)
|
||||
static bool is_suppressed(errflags flags)
|
||||
{
|
||||
/* Fatal errors must never be suppressed */
|
||||
if ((severity & ERR_MASK) >= ERR_FATAL)
|
||||
const errflags severity = flags & ERR_MASK;
|
||||
const errflags level = WARN_IDX(flags);
|
||||
|
||||
if (severity >= ERR_FATAL) {
|
||||
/* Fatal errors or higher can never be suppressed */
|
||||
return false;
|
||||
}
|
||||
|
||||
/* This error/warning is pointless if we are dead anyway */
|
||||
if ((severity & ERR_UNDEAD) && terminate_after_phase)
|
||||
if (flags & errflags_never)
|
||||
return true;
|
||||
|
||||
if (!(warning_state[warn_index(severity)] & WARN_ST_ENABLED))
|
||||
switch (severity) {
|
||||
case ERR_WARNING:
|
||||
if (!(warning_state[level] & WARN_ST_ENABLED))
|
||||
return true;
|
||||
break;
|
||||
|
||||
if (!(severity & ERR_PP_LISTMACRO))
|
||||
return pp_suppress_error(severity);
|
||||
case ERR_INFO:
|
||||
if (!info_level(level))
|
||||
return true;
|
||||
break;
|
||||
|
||||
case ERR_DEBUG:
|
||||
if (!debug_level(level))
|
||||
return true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Suppressed by the preprocessor? */
|
||||
if (!(flags & ERR_PP_LISTMACRO))
|
||||
return pp_suppress_error(flags);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1866,7 +1881,7 @@ static errflags pure_func true_error_type(errflags severity)
|
||||
|
||||
/* Promote warning to error? */
|
||||
if (type == ERR_WARNING) {
|
||||
uint8_t state = warning_state[warn_index(severity)];
|
||||
uint8_t state = warning_state[WARN_IDX(severity)];
|
||||
if ((state & warn_is_err) == warn_is_err)
|
||||
type = ERR_NONFATAL;
|
||||
}
|
||||
@@ -1874,37 +1889,6 @@ static errflags pure_func true_error_type(errflags severity)
|
||||
return type;
|
||||
}
|
||||
|
||||
/*
|
||||
* The various error type prefixes
|
||||
*/
|
||||
/*
|
||||
* The various error type prefixes
|
||||
*/
|
||||
static inline const char *error_pfx(errflags severity)
|
||||
{
|
||||
switch (severity & ERR_MASK) {
|
||||
case ERR_LISTMSG:
|
||||
return ";;; ";
|
||||
case ERR_NOTE:
|
||||
return "note: ";
|
||||
case ERR_DEBUG:
|
||||
return "debug: ";
|
||||
case ERR_INFO:
|
||||
return "info: ";
|
||||
case ERR_WARNING:
|
||||
return "warning: ";
|
||||
case ERR_NONFATAL:
|
||||
return "error: ";
|
||||
case ERR_FATAL:
|
||||
return "fatal: ";
|
||||
case ERR_CRITICAL:
|
||||
return "critical: ";
|
||||
case ERR_PANIC:
|
||||
return "panic: ";
|
||||
default:
|
||||
return "internal error: ";
|
||||
}
|
||||
}
|
||||
static const char no_file_name[] = "nasm"; /* What to print if no file name */
|
||||
|
||||
/*
|
||||
@@ -2084,8 +2068,10 @@ void nasm_verror(errflags severity, const char *fmt, va_list args)
|
||||
struct nasm_errtext *et;
|
||||
errflags true_type = true_error_type(severity);
|
||||
|
||||
if (true_type >= ERR_CRITICAL)
|
||||
if (true_type >= ERR_CRITICAL) {
|
||||
nasm_verror_critical(severity, fmt, args);
|
||||
abort();
|
||||
}
|
||||
|
||||
if (is_suppressed(severity))
|
||||
return;
|
||||
@@ -2133,14 +2119,25 @@ static void nasm_issue_error(struct nasm_errtext *et)
|
||||
pfx = error_pfx(true_type);
|
||||
|
||||
*warnsuf = 0;
|
||||
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.
|
||||
*/
|
||||
if (!(severity & (ERR_HERE|ERR_PP_LISTMACRO))) {
|
||||
const unsigned int level = WARN_IDX(severity);
|
||||
|
||||
switch (severity & ERR_MASK) {
|
||||
case ERR_WARNING:
|
||||
snprintf(warnsuf, sizeof warnsuf, " [-w+%s%s]",
|
||||
(true_type >= ERR_NONFATAL) ? "error=" : "",
|
||||
warning_name[warn_index(severity)]);
|
||||
warning_name[level]);
|
||||
break;
|
||||
case ERR_DEBUG:
|
||||
snprintf(warnsuf, sizeof warnsuf, " [--debug=%u]", debug_nasm);
|
||||
break;
|
||||
case ERR_INFO:
|
||||
snprintf(warnsuf, sizeof warnsuf, " [--info=%u]", opt_verbose_info);
|
||||
break;
|
||||
default:
|
||||
/* Not WARNING, DEBUG or INFO, not suppressible */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*linestr = 0;
|
||||
@@ -2208,8 +2205,10 @@ static void nasm_issue_error(struct nasm_errtext *et)
|
||||
|
||||
if (true_type >= ERR_FATAL)
|
||||
die_hard(true_type, severity);
|
||||
else if (true_type >= ERR_NONFATAL)
|
||||
else if (true_type >= ERR_NONFATAL) {
|
||||
terminate_after_phase = true;
|
||||
errflags_never |= ERR_UNDEAD;
|
||||
}
|
||||
|
||||
done:
|
||||
nasm_free_error(et);
|
||||
@@ -2360,8 +2359,10 @@ static void help(FILE *out, const char *what)
|
||||
}
|
||||
if (help_opt(with)) {
|
||||
fputs(
|
||||
" -s redirect error messages to stdout\n"
|
||||
" -Zfile redirect error messages to file\n"
|
||||
" -s redirect messages to stdout\n"
|
||||
" -Zfile redirect messages to file\n"
|
||||
" --info[=lvl] display optional informational messages\n"
|
||||
" --debug[=lvl] display NASM internal debugging messages\n"
|
||||
, out);
|
||||
}
|
||||
if (help_optor(with, 'M')) {
|
||||
|
@@ -396,7 +396,7 @@ static MMacro *pop_mmacro(MMacro **mp, MMacro *next)
|
||||
nasm_assert(m->refcnt > 0);
|
||||
if (!--m->refcnt) {
|
||||
if (m->name) {
|
||||
nasm_info("freeing macro `%s'", m->name);
|
||||
nasm_debug(2, "freeing macro `%s'", m->name);
|
||||
check_mmacro_refcounts();
|
||||
}
|
||||
nasm_assert(!m->next);
|
||||
|
@@ -82,6 +82,8 @@ fatal_func nasm_verror_critical(errflags severity, const char *fmt, va_list val)
|
||||
abort();
|
||||
}
|
||||
|
||||
errflags errflags_never = 0;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
uint8_t buffer[INSN_MAX * 2], *p;
|
||||
|
144
include/error.h
144
include/error.h
@@ -40,11 +40,6 @@
|
||||
|
||||
#include "compiler.h"
|
||||
|
||||
/*
|
||||
* File pointer for error messages
|
||||
*/
|
||||
extern FILE *error_file; /* Error file descriptor */
|
||||
|
||||
/*
|
||||
* Typedef for the severity field
|
||||
*/
|
||||
@@ -56,10 +51,8 @@ typedef uint32_t errflags;
|
||||
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_info(const char *fmt, ...);
|
||||
void printf_func(2, 3) nasm_infof(errflags flags, const char *fmt, ...);
|
||||
void printf_func(2, 3) nasm_debug_(unsigned int level, const char *fmt, ...);
|
||||
void printf_func(2, 3) nasm_info_(unsigned int level, 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(2, 3) nasm_warn_(errflags flags, const char *fmt, ...);
|
||||
@@ -77,20 +70,44 @@ fatal_func nasm_panic_from_macro(const char *func, const char *file, int line);
|
||||
void vprintf_func(2) nasm_verror(errflags severity, const char *fmt, va_list ap);
|
||||
fatal_func vprintf_func(2) nasm_verror_critical(errflags severity, const char *fmt, va_list ap);
|
||||
|
||||
const char *error_pfx(errflags severity);
|
||||
|
||||
/*
|
||||
* These are the error severity codes which get passed as the first
|
||||
* argument to an efunc.
|
||||
* argument to an efunc. The order here matters!
|
||||
*/
|
||||
#define ERR_LISTMSG 0x00000000 /* for the listing file only (no prefix) */
|
||||
|
||||
/* For the list file only */
|
||||
#define ERR_LISTMSG 0x00000000 /* for the listing file only (comment prefix) */
|
||||
#define ERR_NOTE 0x00000001 /* for the listing file only (with prefix) */
|
||||
#define ERR_DEBUG 0x00000002 /* debugging message */
|
||||
#define ERR_INFO 0x00000003 /* information for the list file */
|
||||
#define ERR_WARNING 0x00000004 /* warn only: no further action */
|
||||
#define ERR_NONFATAL 0x00000008 /* terminate assembly after phase */
|
||||
#define ERR_FATAL 0x00000009 /* instantly fatal: exit with error */
|
||||
|
||||
/* Non-terminating diagnostics; can be suppressed */
|
||||
#define ERR_DEBUG 0x00000004 /* internal debugging message */
|
||||
#define ERR_INFO 0x00000005 /* informational message */
|
||||
#define ERR_WARNING 0x00000006 /* warning */
|
||||
|
||||
/* Errors which terminate assembly without output */
|
||||
#define ERR_NONFATAL 0x00000008 /* terminate assembly after the current pass */
|
||||
|
||||
/*
|
||||
* From this point, errors cannot be suppressed, and the C compiler is
|
||||
* told that the call to nasm_verror() is terminating, to remove the
|
||||
* need to generate further code.
|
||||
*/
|
||||
#define ERR_FATAL 0x0000000c /* terminate immediately, but perform cleanup */
|
||||
|
||||
/*
|
||||
* Abort conditions - terminate with minimal or no cleanup.
|
||||
*
|
||||
* ERR_CRITICAL is used for system errors like out of memory, where the normal
|
||||
* error and cleanup paths may impede informing the user of the nature of the failure.
|
||||
*
|
||||
* ERR_PANIC is used exclusively to trigger on bugs in the NASM code itself.
|
||||
*/
|
||||
#define ERR_CRITICAL 0x0000000e /* fatal, but minimize code before exit */
|
||||
#define ERR_PANIC 0x0000000f /* internal error: panic instantly
|
||||
* and dump core for reference */
|
||||
* and call abort() to dump core for reference */
|
||||
|
||||
#define ERR_MASK 0x0000000f /* mask off the above codes */
|
||||
#define ERR_UNDEAD 0x00000010 /* skip if we already have errors */
|
||||
#define ERR_NOFILE 0x00000020 /* don't give source file name/line */
|
||||
@@ -111,6 +128,11 @@ fatal_func vprintf_func(2) nasm_verror_critical(errflags severity, const char *f
|
||||
#define WARN_SHR 16 /* how far to shift right */
|
||||
#define WARN_IDX(x) (((errflags)(x)) >> WARN_SHR)
|
||||
#define WARN_MASK ((~(errflags)0) << WARN_SHR)
|
||||
#define WARNING(x) ((errflags)(x) << WARN_SHR)
|
||||
|
||||
/* The same field is used for debug and info levels */
|
||||
#define LEVEL_SHR WARN_SHR
|
||||
#define LEVEL(x) WARNING(x)
|
||||
|
||||
/* This is a bitmask */
|
||||
#define WARN_ST_ENABLED 1 /* Warning is currently enabled */
|
||||
@@ -154,38 +176,88 @@ errflags nasm_error_hold_pop(errhold hold, bool issue);
|
||||
#include "warnings.h"
|
||||
|
||||
/* True if a warning is enabled, either as a warning or an error */
|
||||
extern errflags errflags_never;
|
||||
static inline bool warn_active(errflags warn)
|
||||
{
|
||||
enum warn_index wa = WARN_IDX(warn);
|
||||
return unlikely(warning_state[wa] & WARN_ST_ENABLED);
|
||||
if (warn & errflags_never)
|
||||
return false;
|
||||
|
||||
return !!(warning_state[WARN_IDX(warn)] & WARN_ST_ENABLED);
|
||||
}
|
||||
|
||||
#ifdef HAVE_VARIADIC_MACROS
|
||||
|
||||
#define nasm_warn(w, ...) \
|
||||
do { \
|
||||
if (unlikely(warn_active(w))) \
|
||||
nasm_warn_(w, __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define nasm_warn nasm_warn_
|
||||
|
||||
#endif
|
||||
|
||||
/* By defining MAX_DEBUG, we can compile out messages entirely */
|
||||
/*
|
||||
* By defining MAX_DEBUG or MAX_INFO, it is possible to
|
||||
* compile out messages entirely.
|
||||
*/
|
||||
#ifndef MAX_DEBUG
|
||||
# define MAX_DEBUG (~0U)
|
||||
# define MAX_DEBUG UINT_MAX
|
||||
#endif
|
||||
#ifndef MAX_INFO
|
||||
# define MAX_INFO UINT_MAX
|
||||
#endif
|
||||
|
||||
/* Debug level checks */
|
||||
extern unsigned int debug_nasm;
|
||||
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);
|
||||
}
|
||||
|
||||
/* Info level checks */
|
||||
extern unsigned int opt_verbose_info;
|
||||
static inline bool info_level(unsigned int level)
|
||||
{
|
||||
if (is_constant(level) && level > MAX_INFO)
|
||||
return false;
|
||||
return unlikely(level <= opt_verbose_info);
|
||||
}
|
||||
|
||||
#ifdef HAVE_VARIADIC_MACROS
|
||||
|
||||
/*
|
||||
* Marked unlikely() to avoid excessive speed penalties on disabled warnings;
|
||||
* if the warning is issued then the performance penalty is substantial
|
||||
* anyway.
|
||||
*/
|
||||
#define nasm_warn(w, ...) \
|
||||
do { \
|
||||
const errflags _w = (w); \
|
||||
if (unlikely(warn_active(_w))) { \
|
||||
nasm_warn_(_w, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define nasm_info(l, ...) \
|
||||
do { \
|
||||
const unsigned int _l = (l); \
|
||||
if (unlikely(info_level(_l))) \
|
||||
nasm_info_(_l, __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define nasm_debug(l, ...) \
|
||||
do { \
|
||||
const unsigned int _l = (l); \
|
||||
if (unlikely(debug_level(_l))) \
|
||||
nasm_debug_(_l, __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define nasm_warn nasm_warn_
|
||||
#if MAX_DEBUG
|
||||
# define nasm_debug nasm_debug_
|
||||
#else
|
||||
# define nasm_debug (void)
|
||||
#endif
|
||||
#if MAX_INFO
|
||||
# define nasm_info nasm_info_
|
||||
#else
|
||||
# define nasm_info (void)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* NASM_ERROR_H */
|
||||
|
@@ -1,3 +0,0 @@
|
||||
#include "compiler.h"
|
||||
|
||||
FILE *error_file;
|
@@ -228,10 +228,10 @@ static void bin_cleanup(void)
|
||||
uint64_t pend;
|
||||
int h;
|
||||
|
||||
if (debug_level(1)) {
|
||||
nasm_debug("bin_cleanup: Sections were initially referenced in this order:\n");
|
||||
if (debug_level(2)) {
|
||||
nasm_debug(2, "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);
|
||||
nasm_debug(2, "%i. %s\n", h, s->name);
|
||||
}
|
||||
|
||||
/* Assembly has completed, so now we need to generate the output file.
|
||||
@@ -513,11 +513,11 @@ static void bin_cleanup(void)
|
||||
if (h)
|
||||
nasm_fatal("circular vfollows path detected");
|
||||
|
||||
if (debug_level(1)) {
|
||||
nasm_debug("bin_cleanup: Confirm final section order for output file:\n");
|
||||
if (debug_level(2)) {
|
||||
nasm_debug(2, "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);
|
||||
nasm_debug(2, "%i. %s\n", h, s->name);
|
||||
}
|
||||
|
||||
/* Step 5: Apply relocations. */
|
||||
|
@@ -760,10 +760,8 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset,
|
||||
int bind, type; /* st_info components */
|
||||
const struct elf_section *sec = NULL;
|
||||
|
||||
if (debug_level(2)) {
|
||||
nasm_debug(" elf_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
|
||||
nasm_debug(2, " 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] != '@') {
|
||||
/*
|
||||
|
@@ -781,8 +781,7 @@ static void obj_deflabel(char *name, int32_t segment,
|
||||
int i;
|
||||
bool used_special = false; /* have we used the special text? */
|
||||
|
||||
if (debug_level(2))
|
||||
nasm_debug(" obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
|
||||
nasm_debug(2, " obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
|
||||
name, segment, offset, is_global, special);
|
||||
|
||||
/*
|
||||
@@ -1337,8 +1336,7 @@ 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 (debug_level(3))
|
||||
nasm_debug(" obj_segment: < %s >, *bits=%d\n", name, *bits);
|
||||
nasm_debug(3, " obj_segment: < %s >, *bits=%d\n", name, *bits);
|
||||
|
||||
if (!name) {
|
||||
*bits = 16;
|
||||
|
Reference in New Issue
Block a user