]>
Commit | Line | Data |
---|---|---|
b53d1f41 MF |
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; |