summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin (Intel) <hpa@zytor.com>2018-06-25 21:04:11 -0700
committerH. Peter Anvin (Intel) <hpa@zytor.com>2018-06-25 21:04:11 -0700
commitbc7c4aba2a3ab304eea6cecc26cbd2b2fefc407a (patch)
tree67bda50ab94cb9ce8f2dc331592236e04ef4ffb7
parentb90d5c77617cda3e6d8aa5e7c687252889ee9780 (diff)
downloadnasm-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.c23
-rw-r--r--asm/labels.c25
-rw-r--r--include/labels.h2
-rw-r--r--test/ctxlocal.asm2
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