finally commit Mike Frysinger's "elf-visibility" patch
authorFrank Kotler <fbkotler@users.sourceforge.net>
Sun, 26 Aug 2007 05:10:24 +0000 (05:10 +0000)
committerFrank Kotler <fbkotler@users.sourceforge.net>
Sun, 26 Aug 2007 05:10:24 +0000 (05:10 +0000)
doc/nasmdoc.src
output/outelf32.c
output/outelf64.c

index 48c5bdf..ee8c0f6 100644 (file)
@@ -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:
index 739417d..6c16645 100644 (file)
@@ -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;
index f53a022..b83bab7 100644 (file)
@@ -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);