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
375 func_proto : 1,375 func_proto : 1,
376 mode : 4,376 mode : 4,
377 weak : 1,377 weak : 1,
378 fill : 10; // 10 bits left to fit well in union below378 visibility : 2,
379 fill : 8; // 8 bits left to fit well in union below
379};380};
380 381
381/* GNUC attribute definition */382/* GNUC attribute definition */
@@ -787,11 +788,18 @@ struct TCCState { · 405 unmodified lines
787#define VT_EXPORT 0x00008000 /* win32: data exported from dll */788#define VT_EXPORT 0x00008000 /* win32: data exported from dll */
788#define VT_WEAK 0x00010000 /* weak symbol */789#define VT_WEAK 0x00010000 /* weak symbol */
789#define VT_TLS 0x00040000 /* thread-local storage */790#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)
790 797
791#define VT_STRUCT_SHIFT 19 /* shift for bitfield shift values (max: 32 - 2*6) */798#define VT_STRUCT_SHIFT 19 /* shift for bitfield shift values (max: 32 - 2*6) */
792 799
800
793/* type mask (except storage) */801/* 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)
795#define VT_TYPE (~(VT_STORAGE))803#define VT_TYPE (~(VT_STORAGE))
796 804
797/* token values */805/* token values */
tccgen.c+57−3
@@ -300,6 +300,29 @@ static void weaken_symbol(Sym *sym) · 299 unmodified lines
300 }300 }
301}301}
302 302
303static 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
303/* ------------------------------------------------------------------------- */326/* ------------------------------------------------------------------------- */
304 327
305ST_FUNC void swap(int *p, int *q)328ST_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
436 tcc_error("incompatible types for redefinition of '%s'", 459 tcc_error("incompatible types for redefinition of '%s'",
437 get_tok_str(v, NULL));460 get_tok_str(v, NULL));
438 }461 }
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
439 return s;469 return s;
440}470}
441 471
@@ -2662,6 +2692,24 @@ static void parse_attribute(AttributeDef *ad) · 2220 unmodified lines
2662 next();2692 next();
2663 skip(')');2693 skip(')');
2664 break;2694 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;
2665 case TOK_ALIGNED1:2713 case TOK_ALIGNED1:
2666 case TOK_ALIGNED2:2714 case TOK_ALIGNED2:
2667 if (tok == '(') {2715 if (tok == '(') {
@@ -5656,6 +5704,7 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r, · 2988 unmodified lines
5656 /* patch symbol weakness */5704 /* patch symbol weakness */
5657 if (type->t & VT_WEAK)5705 if (type->t & VT_WEAK)
5658 weaken_symbol(sym);5706 weaken_symbol(sym);
5707 apply_visibility(sym, type);
5659#ifdef CONFIG_TCC_BCHECK5708#ifdef CONFIG_TCC_BCHECK
5660 /* handles bounds now because the symbol must be defined5709 /* handles bounds now because the symbol must be defined
5661 before for the relocation */5710 before for the relocation */
@@ -5801,6 +5850,7 @@ static void gen_function(Sym *sym) · 139 unmodified lines
5801 /* patch symbol weakness (this definition overrules any prototype) */5850 /* patch symbol weakness (this definition overrules any prototype) */
5802 if (sym->type.t & VT_WEAK)5851 if (sym->type.t & VT_WEAK)
5803 weaken_symbol(sym);5852 weaken_symbol(sym);
5853 apply_visibility(sym, &sym->type);
5804 if (tcc_state->do_debug) {5854 if (tcc_state->do_debug) {
5805 put_stabn(N_FUN, 0, 0, ind - func_ind);5855 put_stabn(N_FUN, 0, 0, ind - func_ind);
5806 }5856 }
@@ -5934,6 +5984,8 @@ static int decl0(int l, int is_for_loop_init) · 127 unmodified lines
5934 if (ad.a.func_export)5984 if (ad.a.func_export)
5935 type.t |= VT_EXPORT;5985 type.t |= VT_EXPORT;
5936#endif5986#endif
5987 type.t |= ad.a.visibility << VT_VIS_SHIFT;
5988
5937 if (tok == '{') {5989 if (tok == '{') {
5938 if (l == VT_LOCAL)5990 if (l == VT_LOCAL)
5939 tcc_error("cannot use local functions");5991 tcc_error("cannot use local functions");
@@ -5973,6 +6025,11 @@ static int decl0(int l, int is_for_loop_init) · 33 unmodified lines
5973 if (sym->type.t & VT_STATIC)6025 if (sym->type.t & VT_STATIC)
5974 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;6026 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
5975 6027
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
5976 if (!is_compatible_types(&sym->type, &type)) {6033 if (!is_compatible_types(&sym->type, &type)) {
5977 func_error1:6034 func_error1:
5978 tcc_error("incompatible types for redefinition of '%s'", 6035 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
6063 extern */6120 extern */
6064 sym = external_sym(v, &type, r, asm_label);6121 sym = external_sym(v, &type, r, asm_label);
6065 6122
6066 if (type.t & VT_WEAK)
6067 weaken_symbol(sym);
6068
6069 if (ad.alias_target) {6123 if (ad.alias_target) {
6070 Section tsec;6124 Section tsec;
6071 Elf32_Sym *esym;6125 Elf32_Sym *esym;
tcctok.h+2−0
@@ -121,6 +121,8 @@ · 120 unmodified lines
121 DEF(TOK_DLLIMPORT, "dllimport")121 DEF(TOK_DLLIMPORT, "dllimport")
122 DEF(TOK_NORETURN1, "noreturn")122 DEF(TOK_NORETURN1, "noreturn")
123 DEF(TOK_NORETURN2, "__noreturn__")123 DEF(TOK_NORETURN2, "__noreturn__")
124 DEF(TOK_VISIBILITY1, "visibility")
125 DEF(TOK_VISIBILITY2, "__visibility__")
124 DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")126 DEF(TOK_builtin_types_compatible_p, "__builtin_types_compatible_p")
125 DEF(TOK_builtin_constant_p, "__builtin_constant_p")127 DEF(TOK_builtin_constant_p, "__builtin_constant_p")
126 DEF(TOK_builtin_frame_address, "__builtin_frame_address")128 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