diff options
author | H. Peter Anvin (Intel) <hpa@zytor.com> | 2018-06-25 21:04:11 -0700 |
---|---|---|
committer | H. Peter Anvin (Intel) <hpa@zytor.com> | 2018-06-25 21:04:11 -0700 |
commit | bc7c4aba2a3ab304eea6cecc26cbd2b2fefc407a (patch) | |
tree | 67bda50ab94cb9ce8f2dc331592236e04ef4ffb7 | |
parent | b90d5c77617cda3e6d8aa5e7c687252889ee9780 (diff) | |
download | nasm-bc7c4aba2a3ab304eea6cecc26cbd2b2fefc407a.tar.gz |
labels: global/common/extern/static can now force the external name
Add an option to the global/common/extern/static directives to force
the external name to be used for a label. The syntax is:
GLOBAL symbol "external_name" ...
where "external_name" is any NASM quoted string without control
characters.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
-rw-r--r-- | asm/directiv.c | 23 | ||||
-rw-r--r-- | asm/labels.c | 25 | ||||
-rw-r--r-- | include/labels.h | 2 | ||||
-rw-r--r-- | test/ctxlocal.asm | 2 |
4 files changed, 38 insertions, 14 deletions
diff --git a/asm/directiv.c b/asm/directiv.c index 89750c8c..193951ca 100644 --- a/asm/directiv.c +++ b/asm/directiv.c @@ -55,6 +55,7 @@ #include "listing.h" #include "labels.h" #include "iflag.h" +#include "quote.h" struct cpunames { const char *name; @@ -314,9 +315,11 @@ bool process_directives(char *directive) { bool validid = true; int64_t size = 0; - char *sizestr; + char *mangled, *sizestr; bool rn_error; + mangled = sizestr = NULL; + if (*value == '$') value++; /* skip initial $ if present */ @@ -340,10 +343,18 @@ bool process_directives(char *directive) if (nasm_isspace(*q)) { *q++ = '\0'; + q = nasm_skip_spaces(q); + if (isquote(*q)) { + mangled = q; + q = nasm_unquote_cstr(q, directive); + if (nasm_isspace(*q)) + q = nasm_skip_spaces(q); + } + } + + if (*q && *q != ':') { sizestr = q = nasm_skip_spaces(q); q = strchr(q, ':'); - } else { - sizestr = NULL; } if (q && *q == ':') { @@ -365,13 +376,13 @@ bool process_directives(char *directive) directive); } - if (!declare_label(value, type, special)) + if (!declare_label(value, type, mangled, special)) break; - + if (type == LBL_COMMON || type == LBL_EXTERN) define_label(value, 0, size, false); - break; + break; } case D_ABSOLUTE: /* [ABSOLUTE address] */ diff --git a/asm/labels.c b/asm/labels.c index 93a687ea..2d5d976a 100644 --- a/asm/labels.c +++ b/asm/labels.c @@ -305,7 +305,8 @@ static const char *mangle_label_name(union label *lptr) const char *suffix; if (likely(lptr->defn.mangled && - lptr->defn.mangled_type == lptr->defn.type)) + (lptr->defn.mangled_type == lptr->defn.type || + lptr->defn.mangled_type == LBL_SPECIAL))) return lptr->defn.mangled; /* Already mangled */ switch (lptr->defn.type) { @@ -363,12 +364,23 @@ handle_herelabel(union label *lptr, int32_t *segment, int64_t *offset) } } -static bool declare_label_lptr(union label *lptr, - enum label_type type, const char *special) +static bool declare_label_lptr(union label *lptr, enum label_type type, + const char *mangled, const char *special) { if (special && !special[0]) special = NULL; + if (mangled) { + if (lptr->defn.mangled && lptr->defn.mangled_type == LBL_SPECIAL) { + if (strcmp(lptr->defn.mangled, mangled)) + nasm_error(ERR_NONFATAL, "symbol `%s' has inconsistent external names: `%s' and `%s'", + lptr->defn.label, lptr->defn.mangled, mangled); + } else { + lptr->defn.mangled = perm_copy(mangled); + lptr->defn.mangled_type = LBL_SPECIAL; /* Forced manually */ + } + } + if (lptr->defn.type == type || (pass0 == 0 && lptr->defn.type == LBL_LOCAL)) { lptr->defn.type = type; @@ -407,13 +419,14 @@ static bool declare_label_lptr(union label *lptr, return false; } -bool declare_label(const char *label, enum label_type type, const char *special) +bool declare_label(const char *label, enum label_type type, + const char *mangled, const char *special) { union label *lptr; bool created; lptr = find_label(label, true, &created); - return declare_label_lptr(lptr, type, special); + return declare_label_lptr(lptr, type, mangled, special); } /* @@ -491,7 +504,7 @@ void define_label(const char *label, int32_t segment, */ void backend_label(const char *label, int32_t segment, int64_t offset) { - if (!declare_label(label, LBL_BACKEND, NULL)) + if (!declare_label(label, LBL_BACKEND, NULL, NULL)) return; define_label(label, segment, offset, false); diff --git a/include/labels.h b/include/labels.h index 9cf57c1b..65d6e10b 100644 --- a/include/labels.h +++ b/include/labels.h @@ -63,7 +63,7 @@ void define_label(const char *label, int32_t segment, int64_t offset, bool normal); void backend_label(const char *label, int32_t segment, int64_t offset); bool declare_label(const char *label, enum label_type type, - const char *special); + const char *mangled, const char *special); void set_label_mangle(enum mangle_index which, const char *what); int init_labels(void); void cleanup_labels(void); diff --git a/test/ctxlocal.asm b/test/ctxlocal.asm index 93e9fcae..7e52e828 100644 --- a/test/ctxlocal.asm +++ b/test/ctxlocal.asm @@ -19,7 +19,7 @@ here: everywhere: ret - global everywhere + global everywhere "hejsan" tjosan: ret |