summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2020-07-09 20:03:55 -0700
committerH. Peter Anvin (Intel) <hpa@zytor.com>2020-07-09 20:06:18 -0700
commit2f171ddeecc991245815bd83c49a2fc583fc2e62 (patch)
tree68a3460dbafbca7bf976b0c67cd4605ff452efa8
parent771e714c71782474526e931eb14083c33ea81939 (diff)
downloadnasm-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.c24
-rw-r--r--asm/srcfile.h12
-rw-r--r--include/nasm.h1
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 */
};
/*