exports the global symbol \c{hashlookup} as a function and
\c{hashtable} as a data object.
+Optionally, you can control the ELF visibility of the symbol. Just
+add one of the visibility keywords: \i\c{default}, \i\c{internal},
+\i\c{hidden}, or \i\c{protected}. The default is \i\c{default} of
+course. For example, to make \c{hashlookup} hidden:
+
+\c global hashlookup:function hidden
+
You can also specify the size of the data associated with the
symbol, as a numeric expression (which may involve labels, and even
forward references) after the type specifier. Like this:
int32_t strpos; /* string table position of name */
int32_t section; /* section ID of the symbol */
int type; /* symbol type */
+ int other; /* symbol visibility */
int32_t value; /* address, or COMMON variable align */
int32_t size; /* size of symbol */
int32_t globnum; /* symbol table offset if global */
#define SYM_SECTION 0x04
#define SYM_GLOBAL 0x10
+#define SYM_NOTYPE 0x00
#define SYM_DATA 0x01
#define SYM_FUNCTION 0x02
+#define STV_DEFAULT 0
+#define STV_INTERNAL 1
+#define STV_HIDDEN 2
+#define STV_PROTECTED 3
+
#define GLOBAL_TEMP_BASE 16 /* bigger than any constant sym id */
#define SEG_ALIGN 16 /* alignment of sections in file */
sym->strpos = pos;
sym->type = is_global ? SYM_GLOBAL : 0;
+ sym->other = STV_DEFAULT;
sym->size = 0;
if (segment == NO_SEG)
sym->section = SHN_ABS;
sects[sym->section - 1]->gsyms = sym;
if (special) {
- int n = strcspn(special, " ");
+ int n = strcspn(special, " \t");
if (!nasm_strnicmp(special, "function", n))
sym->type |= SYM_FUNCTION;
else if (!nasm_strnicmp(special, "data", n) ||
!nasm_strnicmp(special, "object", n))
sym->type |= SYM_DATA;
+ else if (!nasm_strnicmp(special, "notype", n))
+ sym->type |= SYM_NOTYPE;
else
error(ERR_NONFATAL, "unrecognised symbol type `%.*s'",
n, special);
- if (special[n]) {
+ special += n;
+
+ while (isspace(*special))
+ ++special;
+ if (*special) {
+ n = strcspn(special, " \t");
+ if (!nasm_strnicmp(special, "default", n))
+ sym->other = STV_DEFAULT;
+ else if (!nasm_strnicmp(special, "internal", n))
+ sym->other = STV_INTERNAL;
+ else if (!nasm_strnicmp(special, "hidden", n))
+ sym->other = STV_HIDDEN;
+ else if (!nasm_strnicmp(special, "protected", n))
+ sym->other = STV_PROTECTED;
+ else
+ n = 0;
+ special += n;
+ }
+
+ if (*special) {
struct tokenval tokval;
expr *e;
int fwd = FALSE;
WRITELONG(p, sym->strpos);
WRITELONG(p, sym->value);
WRITELONG(p, sym->size);
- WRITESHORT(p, sym->type); /* local non-typed thing */
+ WRITECHAR(p, sym->type); /* local non-typed thing */
+ WRITECHAR(p, sym->other);
WRITESHORT(p, sym->section);
saa_wbytes(s, entry, 16L);
*len += 16;
WRITELONG(p, sym->strpos);
WRITELONG(p, sym->value);
WRITELONG(p, sym->size);
- WRITESHORT(p, sym->type); /* global non-typed thing */
+ WRITECHAR(p, sym->type); /* global non-typed thing */
+ WRITECHAR(p, sym->other);
WRITESHORT(p, sym->section);
saa_wbytes(s, entry, 16L);
*len += 16;
int32_t strpos; /* string table position of name */
int32_t section; /* section ID of the symbol */
int type; /* symbol type */
+ int other; /* symbol visibility */
int32_t value; /* address, or COMMON variable align */
int32_t size; /* size of symbol */
int32_t globnum; /* symbol table offset if global */
#define SYM_SECTION 0x04
#define SYM_GLOBAL 0x10
+#define SYM_NOTYPE 0x00
#define SYM_DATA 0x01
#define SYM_FUNCTION 0x02
+#define STV_DEFAULT 0
+#define STV_INTERNAL 1
+#define STV_HIDDEN 2
+#define STV_PROTECTED 3
+
#define GLOBAL_TEMP_BASE 16 /* bigger than any constant sym id */
#define SEG_ALIGN 16 /* alignment of sections in file */
sym->strpos = pos;
sym->type = is_global ? SYM_GLOBAL : 0;
+ sym->other = STV_DEFAULT;
sym->size = 0;
if (segment == NO_SEG)
sym->section = SHN_ABS;
sects[sym->section - 1]->gsyms = sym;
if (special) {
- int n = strcspn(special, " ");
+ int n = strcspn(special, " \t");
if (!nasm_strnicmp(special, "function", n))
sym->type |= SYM_FUNCTION;
else if (!nasm_strnicmp(special, "data", n) ||
!nasm_strnicmp(special, "object", n))
sym->type |= SYM_DATA;
+ else if (!nasm_strnicmp(special, "notype", n))
+ sym->type |= SYM_NOTYPE;
else
error(ERR_NONFATAL, "unrecognised symbol type `%.*s'",
n, special);
- if (special[n]) {
+ special += n;
+
+ while (isspace(*special))
+ ++special;
+ if (*special) {
+ n = strcspn(special, " \t");
+ if (!nasm_strnicmp(special, "default", n))
+ sym->other = STV_DEFAULT;
+ else if (!nasm_strnicmp(special, "internal", n))
+ sym->other = STV_INTERNAL;
+ else if (!nasm_strnicmp(special, "hidden", n))
+ sym->other = STV_HIDDEN;
+ else if (!nasm_strnicmp(special, "protected", n))
+ sym->other = STV_PROTECTED;
+ else
+ n = 0;
+ special += n;
+ }
+
+ if (*special) {
struct tokenval tokval;
expr *e;
int fwd = FALSE;
continue;
p = entry;
WRITELONG(p, sym->strpos);
- WRITESHORT(p, sym->type); /* local non-typed thing */
+ WRITECHAR(p, sym->type); /* local non-typed thing */
+ WRITECHAR(p, sym->other);
WRITESHORT(p, sym->section);
WRITEDLONG(p, (int64_t)sym->value);
WRITEDLONG(p, (int64_t)sym->size);
continue;
p = entry;
WRITELONG(p, sym->strpos);
- WRITESHORT(p, sym->type); /* global non-typed thing */
+ WRITECHAR(p, sym->type); /* global non-typed thing */
+ WRITECHAR(p, sym->other);
WRITESHORT(p, sym->section);
WRITEDLONG(p, (int64_t)sym->value);
WRITEDLONG(p, (int64_t)sym->size);