History

Parse and emit hidden visibility

This adds parsing of (GCC compatible) visibility attribute in order to mark selected global symbols as hidden. The generated .o files contain hidden symbols already, the TCC linker doesn't yet do the right thing.

Michael Matz committed 12 years ago

Commit fbda78a1 parent 11214813 files · +69 −5Browse files

Unified · Split

3 files
  1. tcc.h +10 −2
  2. tccgen.c +57 −3
  3. tcctok.h +2 −0
tcc.h+10−2
@@ -375,7 +375,8 @@ struct Attribute { · 374 unmodified lines
375375 func_proto : 1,
376376 mode : 4,
377377 weak : 1,
378− fill : 10; // 10 bits left to fit well in union below
378+ visibility : 2,
379+ fill : 8; // 8 bits left to fit well in union below
379380 };
380381
381382 /* GNUC attribute definition */
@@ -787,11 +788,18 @@ struct TCCState { · 405 unmodified lines
787788 #define VT_EXPORT 0x00008000 /* win32: data exported from dll */
788789 #define VT_WEAK 0x00010000 /* weak symbol */
789790 #define VT_TLS 0x00040000 /* thread-local storage */
791+#define VT_VIS_SHIFT 19 /* shift for symbol visibility, overlapping
792+ bitfield values, because bitfields never
793+ have linkage and hence never have
794+ visibility. */
795+#define VT_VIS_SIZE 2 /* We have four visibilities. */
796+#define VT_VIS_MASK (((1 << VT_VIS_SIZE)-1) << VT_VIS_SHIFT)
790797
791798 #define VT_STRUCT_SHIFT 19 /* shift for bitfield shift values (max: 32 - 2*6) */
792799
800+
793801 /* type mask (except storage) */
794−#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT | VT_WEAK)
802+#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT | VT_WEAK | VT_VIS_MASK)
795803 #define VT_TYPE (~(VT_STORAGE))
796804
797805 /* token values */
tccgen.c+57−3
@@ -300,6 +300,29 @@ static void weaken_symbol(Sym *sym) · 299 unmodified lines
300300 }
301301 }
302302
303+static void apply_visibility(Sym *sym, CType *type)
304+{
305+ int vis = sym->type.t & VT_VIS_MASK;
306+ int vis2 = type->t & VT_VIS_MASK;
307+ if (vis == (STV_DEFAULT << VT_VIS_SHIFT))
308+ vis = vis2;
309+ else if (vis2 == (STV_DEFAULT << VT_VIS_SHIFT))
310+ ;
311+ else
312+ vis = (vis < vis2) ? vis : vis2;
313+ sym->type.t &= ~VT_VIS_MASK;
314+ sym->type.t |= vis;
315+
316+ if (sym->c > 0) {
317+ int esym_type;
318+ ElfW(Sym) *esym;
319+
320+ esym = &((ElfW(Sym) *)symtab_section->data)[sym->c];
321+ vis >>= VT_VIS_SHIFT;
322+ esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1)) | vis;
323+ }
324+}
325+
303326 /* ------------------------------------------------------------------------- */
304327
305328 ST_FUNC void swap(int *p, int *q)
@@ -436,6 +459,13 @@ static Sym *external_sym(int v, CType *type, int r, char *asm_label) · 130 unmodified lines
436459 tcc_error("incompatible types for redefinition of '%s'",
437460 get_tok_str(v, NULL));
438461 }
462+ /* Merge some storage attributes. */
463+ if (type->t & VT_WEAK)
464+ weaken_symbol(s);
465+
466+ if (type->t & VT_VIS_MASK)
467+ apply_visibility(s, type);
468+
439469 return s;
440470 }
441471
@@ -2662,6 +2692,24 @@ static void parse_attribute(AttributeDef *ad) · 2220 unmodified lines
26622692 next();
26632693 skip(')');
26642694 break;
2695+ case TOK_VISIBILITY1:
2696+ case TOK_VISIBILITY2:
2697+ skip('(');
2698+ if (tok != TOK_STR)
2699+ expect("visibility(\"default|hidden|internal|protected\")");
2700+ if (!strcmp (tokc.cstr->data, "default"))
2701+ ad->a.visibility = STV_DEFAULT;
2702+ else if (!strcmp (tokc.cstr->data, "hidden"))
2703+ ad->a.visibility = STV_HIDDEN;
2704+ else if (!strcmp (tokc.cstr->data, "internal"))
2705+ ad->a.visibility = STV_INTERNAL;
2706+ else if (!strcmp (tokc.cstr->data, "protected"))
2707+ ad->a.visibility = STV_PROTECTED;
2708+ else
2709+ expect("visibility(\"default|hidden|internal|protected\")");
2710+ next();
2711+ skip(')');
2712+ break;
26652713 case TOK_ALIGNED1:
26662714 case TOK_ALIGNED2:
26672715 if (tok == '(') {
@@ -5656,6 +5704,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 2988 unmodified lines
56565704 /* patch symbol weakness */
56575705 if (type->t & VT_WEAK)
56585706 weaken_symbol(sym);
5707+ apply_visibility(sym, type);
56595708 #ifdef CONFIG_TCC_BCHECK
56605709 /* handles bounds now because the symbol must be defined
56615710 before for the relocation */
@@ -5801,6 +5850,7 @@ static void gen_function(Sym *sym) · 139 unmodified lines
58015850 /* patch symbol weakness (this definition overrules any prototype) */
58025851 if (sym->type.t & VT_WEAK)
58035852 weaken_symbol(sym);
5853+ apply_visibility(sym, &sym->type);
58045854 if (tcc_state->do_debug) {
58055855 put_stabn(N_FUN, 0, 0, ind - func_ind);
58065856 }
@@ -5934,6 +5984,8 @@ static int decl0(int l, int is_for_loop_init) · 127 unmodified lines
59345984 if (ad.a.func_export)
59355985 type.t |= VT_EXPORT;
59365986 #endif
5987+ type.t |= ad.a.visibility << VT_VIS_SHIFT;
5988+
59375989 if (tok == '{') {
59385990 if (l == VT_LOCAL)
59395991 tcc_error("cannot use local functions");
@@ -5973,6 +6025,11 @@ static int decl0(int l, int is_for_loop_init) · 33 unmodified lines
59736025 if (sym->type.t & VT_STATIC)
59746026 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
59756027
6028+ /* If the definition has no visibility use the
6029+ one from prototype. */
6030+ if (! (type.t & VT_VIS_MASK))
6031+ type.t |= sym->type.t & VT_VIS_MASK;
6032+
59766033 if (!is_compatible_types(&sym->type, &type)) {
59776034 func_error1:
59786035 tcc_error("incompatible types for redefinition of '%s'",
@@ -6063,9 +6120,6 @@ static int decl0(int l, int is_for_loop_init) · 84 unmodified lines
60636120 extern */
60646121 sym = external_sym(v, &type, r, asm_label);
60656122
6066− if (type.t & VT_WEAK)
6067− weaken_symbol(sym);
6068−
60696123 if (ad.alias_target) {
60706124 Section tsec;
60716125 Elf32_Sym *esym;
tcctok.h+2−0
@@ -121,6 +121,8 @@ · 120 unmodified lines
121121 DEF(TOK_DLLIMPORT, "dllimport")
122122 DEF(TOK_NORETURN1, "noreturn")
123123 DEF(TOK_NORETURN2, "__noreturn__")
124+ DEF(TOK_VISIBILITY1, "visibility")
125+ DEF(TOK_VISIBILITY2, "__visibility__")
124126 DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
125127 DEF(TOK_builtin_constant_p, "__builtin_constant_p")
126128 DEF(TOK_builtin_frame_address, "__builtin_frame_address")

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t