From bc77f9c5874db1729bc1fae13d9bf38ba579d3d1 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin, Intel" Date: Mon, 25 Jun 2018 12:39:42 -0700 Subject: labels: don't update the local variable base for *ANY* dot labels ..@ labels (macro-local) are NASM specials, although not "magic": they are explicitly defined to not preturb the local label base name. However, they return false for both islocal() and ismagic(), so we need to add a new function containing the correct test for when the local label base should be advanced. Reported-by: Signed-off-by: H. Peter Anvin (Intel) Cc: Cyrill Gorcunov Cc: Bae, Chang Seok --- asm/labels.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/asm/labels.c b/asm/labels.c index 32f13180..8c4e6f22 100644 --- a/asm/labels.c +++ b/asm/labels.c @@ -72,6 +72,21 @@ static bool ismagic(const char *l) return l[0] == '.' && l[1] == '.' && l[2] != '@'; } +/* + * Return true if we should update the local label base + * as a result of this symbol. We must exclude local labels + * as well as any kind of special labels, including ..@ ones. + */ +static bool set_prevlabel(const char *l) +{ + if (tasm_compatible_mode) { + if (l[0] == '@' && l[1] == '@') + return false; + } + + return l[0] != '.'; +} + #define LABEL_BLOCK 128 /* no. of labels/block */ #define LBLK_SIZE (LABEL_BLOCK * sizeof(union label)) @@ -419,11 +434,6 @@ void define_label(const char *label, int32_t segment, */ lptr = find_label(label, true, &created); - if (pass0 > 1) { - if (created) - nasm_error(ERR_WARNING, "label `%s' defined on pass two", label); - } - if (!segment) segment = lptr->defn.segment ? lptr->defn.segment : seg_alloc(); @@ -436,9 +446,8 @@ void define_label(const char *label, int32_t segment, if (ismagic(label) && lptr->defn.type == LBL_LOCAL) lptr->defn.type = LBL_SPECIAL; - if (!islocal(label) && normal) { + if (set_prevlabel(label) && normal) prevlabel = lptr->defn.label; - } if (lptr->defn.type == LBL_COMMON) { size = offset; @@ -447,7 +456,8 @@ void define_label(const char *label, int32_t segment, size = 0; /* This is a hack... */ } - changed = !lptr->defn.defined || lptr->defn.segment != segment || + changed = created || !lptr->defn.defined || + lptr->defn.segment != segment || lptr->defn.offset != offset || lptr->defn.size != size; global_offset_changed += changed; @@ -456,9 +466,11 @@ void define_label(const char *label, int32_t segment, * special case, LBL_SPECIAL symbols are allowed to be changed * even during the last pass. */ - if (changed && pass0 == 2 && lptr->defn.type != LBL_SPECIAL) - nasm_error(ERR_WARNING, "label `%s' changed during code generation", + if (changed && pass0 > 1 && lptr->defn.type != LBL_SPECIAL) { + nasm_error(ERR_WARNING, "label `%s' %s during code generation", + created ? "defined" : "changed", lptr->defn.label); + } lptr->defn.segment = segment; lptr->defn.offset = offset; -- cgit v1.2.1