]> git.wh0rd.org - patches.git/blobdiff - nasm-elf-visibility-r2.patch
more random patches. who knows.
[patches.git] / nasm-elf-visibility-r2.patch
diff --git a/nasm-elf-visibility-r2.patch b/nasm-elf-visibility-r2.patch
new file mode 100644 (file)
index 0000000..d4f1948
--- /dev/null
@@ -0,0 +1,107 @@
+Add support for declaring elf visibility attributes.  Used to
+help cleanup TEXTRELs in misc libraries (like libsdl).
+
+Syntax to declare function foo hidden:
+GLOBAL foo:function hidden
+
+Patch by Mike Frysinger <vapier@gentoo.org>
+
+http://sourceforge.net/mailarchive/forum.php?thread_id=9230919&forum_id=4978
+
+--- nasm/output/outelf.c
++++ nasm/output/outelf.c
+@@ -50,6 +50,7 @@ struct Symbol {
+     long strpos;                /* string table position of name */
+     long section;               /* section ID of the symbol */
+     int type;                   /* symbol type */
++    int other;                  /* symbol visibility */
+     long value;                 /* address, or COMMON variable align */
+     long size;                  /* size of symbol */
+     long globnum;               /* symbol table offset if global */
+@@ -113,9 +114,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 */
+@@ -493,6 +500,7 @@ static void elf_deflabel(char *name, lon
+     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;
+@@ -570,18 +578,39 @@ static void elf_deflabel(char *name, lon
+             sym->next = sects[sym->section - 1]->gsyms;
+             sects[sym->section - 1]->gsyms = sym;
++            /* ELF syntax: GLOBAL name[:type [visibility]] */
+             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);
++                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[n]) {
++                if (*special) {
+                     struct tokenval tokval;
+                     expr *e;
+                     int fwd = FALSE;
+@@ -1120,7 +1149,8 @@ static struct SAA *elf_build_symtab(long
+         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;
+@@ -1138,7 +1168,8 @@ static struct SAA *elf_build_symtab(long
+         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;