summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin, Intel <h.peter.anvin@intel.com>2018-06-25 12:39:42 -0700
committerH. Peter Anvin, Intel <h.peter.anvin@intel.com>2018-06-25 12:45:14 -0700
commitbc77f9c5874db1729bc1fae13d9bf38ba579d3d1 (patch)
tree09daa6281b58e1b38e501b5f642e066c21076190
parent5ce7d1e8975d54eb885e1eba675daf6d3fc13a8e (diff)
downloadnasm-bc77f9c5874db1729bc1fae13d9bf38ba579d3d1.tar.gz
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: <balducci@units.it> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com> Cc: Cyrill Gorcunov <gorcunov@gmail.com> Cc: Bae, Chang Seok <chang.seok.bae@intel.com>
-rw-r--r--asm/labels.c32
1 files 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;