diff options
author | H. Peter Anvin (Intel) <hpa@zytor.com> | 2020-07-09 20:03:55 -0700 |
---|---|---|
committer | H. Peter Anvin (Intel) <hpa@zytor.com> | 2020-07-09 20:06:18 -0700 |
commit | 2f171ddeecc991245815bd83c49a2fc583fc2e62 (patch) | |
tree | 68a3460dbafbca7bf976b0c67cd4605ff452efa8 | |
parent | 771e714c71782474526e931eb14083c33ea81939 (diff) | |
download | nasm-2f171ddeecc991245815bd83c49a2fc583fc2e62.tar.gz |
debug: invoke dfmt->linenum when the segment number changes
If the segment number changes, we also need to invoke dfmt->linenum(),
as a .nolist macro may end up emitting to more than one section.
This also adds the source location explicitly to the output data
structure; the cost for that is minimal, and will enable a more
sophisticated debug backend to receive the entire data structure in
the future.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
-rw-r--r-- | asm/assemble.c | 24 | ||||
-rw-r--r-- | asm/srcfile.h | 12 | ||||
-rw-r--r-- | include/nasm.h | 1 |
3 files changed, 26 insertions, 11 deletions
diff --git a/asm/assemble.c b/asm/assemble.c index e5d5682c..270262ae 100644 --- a/asm/assemble.c +++ b/asm/assemble.c @@ -341,8 +341,10 @@ static void warn_overflow_out(int64_t data, int size, enum out_sign sign) */ static void out(struct out_data *data) { - static int32_t lineno = 0; /* static!!! */ - static const char *lnfname = NULL; + static struct last_debug_info { + struct src_location where; + int32_t segment; + } dbg; union { uint8_t b[8]; uint64_t q; @@ -398,16 +400,16 @@ static void out(struct out_data *data) } /* - * this call to src_get determines when we call the - * debug-format-specific "linenum" function - * it updates lineno and lnfname to the current values - * returning 0 if "same as last time", -2 if lnfname - * changed, and the amount by which lineno changed, - * if it did. thus, these variables must be static + * If the source location or output segment has changed, + * let the debug backend know. */ - - if (src_get(&lineno, &lnfname)) - dfmt->linenum(lnfname, lineno, data->segment); + data->where = src_where(); + if (!src_location_same(data->where, dbg.where) | + (data->segment != dbg.segment)) { + dbg.where = data->where; + dbg.segment = data->segment; + dfmt->linenum(dbg.where.filename, dbg.where.lineno, data->segment); + } if (asize > amax) { if (data->type == OUT_RELADDR || data->sign == OUT_SIGNED) { diff --git a/asm/srcfile.h b/asm/srcfile.h index a26e1e4f..ec9965d3 100644 --- a/asm/srcfile.h +++ b/asm/srcfile.h @@ -43,6 +43,18 @@ struct src_location { const char *filename; int32_t lineno; }; + +/* + * Comparing the *pointer value* of filenames is valid, because the + * filename hash system guarantees that each unique filename string is + * permanently allocated in exactly one location. + */ +static inline bool +src_location_same(struct src_location here, struct src_location there) +{ + return here.filename == there.filename && here.lineno == there.lineno; +} + struct src_location_stack { struct src_location l; struct src_location_stack *up, *down; diff --git a/include/nasm.h b/include/nasm.h index efeb6190..6cffaf5d 100644 --- a/include/nasm.h +++ b/include/nasm.h @@ -137,6 +137,7 @@ struct out_data { int32_t tsegment; /* Target segment for relocation */ int32_t twrt; /* Relocation with respect to */ int64_t relbase; /* Relative base for OUT_RELADDR */ + struct src_location where; /* Source file and line */ }; /* |