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>
This commit is contained in:
H. Peter Anvin (Intel) 2018-06-25 21:04:11 -07:00
parent b90d5c7761
commit bc7c4aba2a
4 changed files with 38 additions and 14 deletions

View file

@ -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] */

View file

@ -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);

View file

@ -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);

View file

@ -19,7 +19,7 @@ here:
everywhere:
ret
global everywhere
global everywhere "hejsan"
tjosan:
ret