From 155eef6a3d309fdfef45f4476590234007fdbf9b Mon Sep 17 00:00:00 2001 From: Frank Kotler Date: Sun, 26 Aug 2007 05:10:24 +0000 Subject: [PATCH] finally commit Mike Frysinger's "elf-visibility" patch --- doc/nasmdoc.src | 7 +++++++ output/outelf32.c | 39 +++++++++++++++++++++++++++++++++++---- output/outelf64.c | 39 +++++++++++++++++++++++++++++++++++---- 3 files changed, 77 insertions(+), 8 deletions(-) diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src index 48c5bdf..ee8c0f6 100644 --- a/doc/nasmdoc.src +++ b/doc/nasmdoc.src @@ -4408,6 +4408,13 @@ object by suffixing the name with a colon and the word 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: diff --git a/output/outelf32.c b/output/outelf32.c index 739417d..6c16645 100644 --- a/output/outelf32.c +++ b/output/outelf32.c @@ -51,6 +51,7 @@ struct Symbol { 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 */ @@ -115,9 +116,15 @@ extern struct ofmt of_elf; #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 */ @@ -495,6 +502,7 @@ static void elf_deflabel(char *name, int32_t segment, int32_t offset, 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; @@ -566,17 +574,38 @@ static void elf_deflabel(char *name, int32_t segment, int32_t offset, 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; @@ -1115,7 +1144,8 @@ static struct SAA *elf_build_symtab(int32_t *len, int32_t *local) 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; @@ -1133,7 +1163,8 @@ static struct SAA *elf_build_symtab(int32_t *len, int32_t *local) 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; diff --git a/output/outelf64.c b/output/outelf64.c index f53a022..b83bab7 100644 --- a/output/outelf64.c +++ b/output/outelf64.c @@ -71,6 +71,7 @@ struct Symbol { 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 */ @@ -126,9 +127,15 @@ extern struct ofmt of_elf64; #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 */ @@ -507,6 +514,7 @@ static void elf_deflabel(char *name, int32_t segment, int32_t offset, 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; @@ -578,17 +586,38 @@ static void elf_deflabel(char *name, int32_t segment, int32_t offset, 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; @@ -1127,7 +1156,8 @@ static struct SAA *elf_build_symtab(int32_t *len, int32_t *local) 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); @@ -1145,7 +1175,8 @@ static struct SAA *elf_build_symtab(int32_t *len, int32_t *local) 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); -- 2.7.4