more random patches. who knows.
[patches.git] / nasm-elf-visibility-r2.patch
1 Add support for declaring elf visibility attributes. Used to
2 help cleanup TEXTRELs in misc libraries (like libsdl).
3
4 Syntax to declare function foo hidden:
5 GLOBAL foo:function hidden
6
7 Patch by Mike Frysinger <vapier@gentoo.org>
8
9 http://sourceforge.net/mailarchive/forum.php?thread_id=9230919&forum_id=4978
10
11 --- nasm/output/outelf.c
12 +++ nasm/output/outelf.c
13 @@ -50,6 +50,7 @@ struct Symbol {
14 long strpos; /* string table position of name */
15 long section; /* section ID of the symbol */
16 int type; /* symbol type */
17 + int other; /* symbol visibility */
18 long value; /* address, or COMMON variable align */
19 long size; /* size of symbol */
20 long globnum; /* symbol table offset if global */
21 @@ -113,9 +114,15 @@ extern struct ofmt of_elf;
22
23 #define SYM_SECTION 0x04
24 #define SYM_GLOBAL 0x10
25 +#define SYM_NOTYPE 0x00
26 #define SYM_DATA 0x01
27 #define SYM_FUNCTION 0x02
28
29 +#define STV_DEFAULT 0
30 +#define STV_INTERNAL 1
31 +#define STV_HIDDEN 2
32 +#define STV_PROTECTED 3
33 +
34 #define GLOBAL_TEMP_BASE 16 /* bigger than any constant sym id */
35
36 #define SEG_ALIGN 16 /* alignment of sections in file */
37 @@ -493,6 +500,7 @@ static void elf_deflabel(char *name, lon
38
39 sym->strpos = pos;
40 sym->type = is_global ? SYM_GLOBAL : 0;
41 + sym->other = STV_DEFAULT;
42 sym->size = 0;
43 if (segment == NO_SEG)
44 sym->section = SHN_ABS;
45 @@ -570,18 +578,39 @@ static void elf_deflabel(char *name, lon
46 sym->next = sects[sym->section - 1]->gsyms;
47 sects[sym->section - 1]->gsyms = sym;
48
49 + /* ELF syntax: GLOBAL name[:type [visibility]] */
50 if (special) {
51 - int n = strcspn(special, " ");
52 -
53 + int n = strcspn(special, " \t");
54 if (!nasm_strnicmp(special, "function", n))
55 sym->type |= SYM_FUNCTION;
56 else if (!nasm_strnicmp(special, "data", n) ||
57 !nasm_strnicmp(special, "object", n))
58 sym->type |= SYM_DATA;
59 + else if (!nasm_strnicmp(special, "notype", n))
60 + sym->type |= SYM_NOTYPE;
61 else
62 error(ERR_NONFATAL, "unrecognised symbol type `%.*s'",
63 n, special);
64 + special += n;
65 +
66 + while (isspace(*special))
67 + ++special;
68 + if (*special) {
69 + n = strcspn(special, " \t");
70 + if (!nasm_strnicmp(special, "default", n))
71 + sym->other = STV_DEFAULT;
72 + else if (!nasm_strnicmp(special, "internal", n))
73 + sym->other = STV_INTERNAL;
74 + else if (!nasm_strnicmp(special, "hidden", n))
75 + sym->other = STV_HIDDEN;
76 + else if (!nasm_strnicmp(special, "protected", n))
77 + sym->other = STV_PROTECTED;
78 + else
79 + n = 0;
80 + special += n;
81 + }
82 +
83 - if (special[n]) {
84 + if (*special) {
85 struct tokenval tokval;
86 expr *e;
87 int fwd = FALSE;
88 @@ -1120,7 +1149,8 @@ static struct SAA *elf_build_symtab(long
89 WRITELONG(p, sym->strpos);
90 WRITELONG(p, sym->value);
91 WRITELONG(p, sym->size);
92 - WRITESHORT(p, sym->type); /* local non-typed thing */
93 + WRITECHAR(p, sym->type); /* local non-typed thing */
94 + WRITECHAR(p, sym->other);
95 WRITESHORT(p, sym->section);
96 saa_wbytes(s, entry, 16L);
97 *len += 16;
98 @@ -1138,7 +1168,8 @@ static struct SAA *elf_build_symtab(long
99 WRITELONG(p, sym->strpos);
100 WRITELONG(p, sym->value);
101 WRITELONG(p, sym->size);
102 - WRITESHORT(p, sym->type); /* global non-typed thing */
103 + WRITECHAR(p, sym->type); /* global non-typed thing */
104 + WRITECHAR(p, sym->other);
105 WRITESHORT(p, sym->section);
106 saa_wbytes(s, entry, 16L);
107 *len += 16;