History

tccasm: use global(_symbol)_stack

* removed asm_label stack * removed asm_free_labels() post-processing * using "impossible C type" for asm labels (VT_ASM) * tccgen.c:update_storage(): use it to refresh symbol attributes * tccelf.c:find_elf_sym(): ignore STB_LOCAL symbols * tccgen.c:unary(): asm symbols are supposed to be undeclared in C

grischka committed 8 years ago

Commit 877e1641 parent cc6cb7f4 files · +67 −84Browse files

Unified · Split

4 files
  1. tcc.h +9 −5
  2. tccasm.c +23 −44
  3. tccelf.c +4 −6
  4. tccgen.c +31 −29
tcc.h+9−5
@@ -440,8 +440,7 @@ struct SymAttr { · 439 unmodified lines
440440 visibility : 2,
441441 dllexport : 1,
442442 dllimport : 1,
443− asmexport : 1,
444− unused : 4;
443+ unused : 5;
445444 };
446445
447446 /* function attributes or temporary attributes for parsing */
@@ -796,8 +795,8 @@ struct TCCState { · 348 unmodified lines
796795 /* extra attributes (eg. GOT/PLT value) for symtab symbols */
797796 struct sym_attr *sym_attrs;
798797 int nb_sym_attrs;
798+
799799 /* tiny assembler state */
800− Sym *asm_labels;
801800 ElfSym esym_dot;
802801
803802 #ifdef TCC_TARGET_PE
@@ -911,6 +910,11 @@ struct filespec { · 107 unmodified lines
911910 #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
912911 #define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))
913912
913+/* symbol was created by tccasm.c first */
914+#define VT_ASM (VT_VOID | VT_UNSIGNED)
915+#define VT_ASM_GLOBAL VT_DEFSIGN
916+#define IS_ASM_SYM(sym) (((sym)->type.t & (VT_BTYPE | VT_ASM)) == VT_ASM)
917+
914918 /* token values */
915919
916920 /* warning: the following compare tokens depend on i386 asm code */
@@ -1147,7 +1151,7 @@ ST_FUNC Sym *sym_push(int v, CType *type, int r, int c); · 230 unmodified lines
11471151 ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep);
11481152 ST_INLN Sym *struct_find(int v);
11491153 ST_INLN Sym *sym_find(int v);
1150−ST_FUNC Sym *global_identifier_push_1(Sym **, int v, int t, int c);
1154+ST_FUNC Sym *global_identifier_push(int v, int t, int c);
11511155
11521156 ST_FUNC void tcc_open_bf(TCCState *s1, const char *filename, int initlen);
11531157 ST_FUNC int tcc_open(TCCState *s1, const char *filename);
@@ -1317,6 +1321,7 @@ ST_FUNC int ieee_finite(double d); · 163 unmodified lines
13171321 ST_FUNC void test_lvalue(void);
13181322 ST_FUNC void vpushi(int v);
13191323 ST_FUNC ElfSym *elfsym(Sym *);
1324+ST_FUNC void update_storage(Sym *sym);
13201325 ST_FUNC Sym *external_global_sym(int v, CType *type, int r);
13211326 ST_FUNC void vset(CType *type, int r, int v);
13221327 ST_FUNC void vswap(void);
@@ -1588,7 +1593,6 @@ ST_FUNC Sym* get_asm_sym(int name, Sym *csym); · 265 unmodified lines
15881593 ST_FUNC void asm_expr(TCCState *s1, ExprValue *pe);
15891594 ST_FUNC int asm_int_expr(TCCState *s1);
15901595 ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess);
1591−ST_FUNC void asm_free_labels(TCCState *st);
15921596 /* ------------ i386-asm.c ------------ */
15931597 ST_FUNC void gen_expr32(ExprValue *pe);
15941598 #ifdef TCC_TARGET_X86_64
tccasm.c+23−44
@@ -44,11 +44,11 @@ static Sym *asm_label_find(int v) · 43 unmodified lines
4444
4545 static Sym *asm_label_push(int v, int t)
4646 {
47− Sym *sym = global_identifier_push_1(&tcc_state->asm_labels, v, t, 0);
47+ Sym *sym = global_identifier_push(v, t, 0);
4848 /* We always add VT_EXTERN, for sym definition that's tentative
4949 (for .set, removed for real defs), for mere references it's correct
5050 as is. */
51− sym->type.t |= VT_VOID | VT_EXTERN;
51+ sym->type.t |= VT_ASM | VT_EXTERN;
5252 sym->r = VT_CONST | VT_SYM;
5353 return sym;
5454 }
@@ -149,7 +149,7 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe) · 94 unmodified lines
149149 pe->v = 0;
150150 pe->sym = &sym_dot;
151151 pe->pcrel = 0;
152− sym_dot.type.t = VT_VOID | VT_STATIC;
152+ sym_dot.type.t = VT_ASM | VT_STATIC;
153153 sym_dot.c = -1;
154154 tcc_state->esym_dot.st_shndx = cur_text_section->sh_num;
155155 tcc_state->esym_dot.st_value = ind;
@@ -371,7 +371,7 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local, · 215 unmodified lines
371371 definitions won't have VT_EXTERN set. */
372372 if (esym && esym->st_shndx != SHN_UNDEF && !(sym->type.t & VT_EXTERN)) {
373373 /* the label is already defined */
374− if (!is_local) {
374+ if (is_local != 1) {
375375 tcc_error("assembler label '%s' already defined",
376376 get_tok_str(label, NULL));
377377 } else {
@@ -381,13 +381,22 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local, · 3 unmodified lines
381381 }
382382 } else {
383383 new_label:
384− sym = asm_label_push(label, is_local ? VT_STATIC : 0);
384+ sym = asm_label_push(label, is_local == 1 ? VT_STATIC : 0);
385385 }
386386 if (!sym->c)
387387 put_extern_sym2(sym, NULL, 0, 0, 0);
388388 esym = elfsym(sym);
389389 esym->st_shndx = sh_num;
390390 esym->st_value = value;
391+
392+ if (is_local != 2)
393+ sym->type.t &= ~VT_EXTERN;
394+
395+ if (IS_ASM_SYM(sym) && !(sym->type.t & VT_ASM_GLOBAL)) {
396+ sym->type.t |= VT_STATIC;
397+ update_storage(sym);
398+ }
399+
391400 return sym;
392401 }
393402
@@ -410,39 +419,11 @@ static Sym* set_symbol(TCCState *s1, int label) · 16 unmodified lines
410419 esym = elfsym(e.sym);
411420 if (esym)
412421 n += esym->st_value;
413− sym = asm_new_label1(s1, label, 0, esym ? esym->st_shndx : SHN_ABS, n);
422+ sym = asm_new_label1(s1, label, 2, esym ? esym->st_shndx : SHN_ABS, n);
414423 elfsym(sym)->st_other |= ST_ASM_SET;
415424 return sym;
416425 }
417426
418−ST_FUNC void asm_free_labels(TCCState *st)
419−{
420− Sym *s, *s1;
421−
422− for(s = st->asm_labels; s != NULL; s = s1) {
423− ElfSym *esym = elfsym(s);
424− s1 = s->prev;
425− /* Possibly update binding and visibility from asm directives
426− if the symbol has no C decl (type is VT_VOID).*/
427− s->type.t &= ~VT_EXTERN;
428− if (esym && s->type.t == VT_VOID) {
429− if (!s->a.asmexport && esym->st_shndx != SHN_UNDEF)
430− s->type.t |= VT_STATIC;
431− if (s->a.visibility)
432− esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
433− | s->a.visibility;
434− esym->st_info = ELFW(ST_INFO)(s->a.weak ? STB_WEAK
435− : (s->type.t & VT_STATIC) ? STB_LOCAL
436− : STB_GLOBAL,
437− ELFW(ST_TYPE)(esym->st_info));
438− }
439− /* remove label */
440− table_ident[s->v - TOK_IDENT]->sym_identifier = s->prev_tok;
441− sym_free(s);
442− }
443− st->asm_labels = NULL;
444−}
445−
446427 static void use_section1(TCCState *s1, Section *sec)
447428 {
448429 cur_text_section->data_offset = ind;
@@ -696,15 +677,18 @@ static void asm_parse_directive(TCCState *s1, int global) · 247 unmodified lines
696677 tok1 = tok;
697678 do {
698679 Sym *sym;
699−
700680 next();
701681 sym = get_asm_sym(tok, NULL);
702− if (tok1 != TOK_ASMDIR_hidden)
703− sym->type.t &= ~VT_STATIC, sym->a.asmexport = 1;
682+ if (tok1 != TOK_ASMDIR_hidden) {
683+ sym->type.t &= ~VT_STATIC;
684+ if (IS_ASM_SYM(sym))
685+ sym->type.t |= VT_ASM_GLOBAL;
686+ }
704687 if (tok1 == TOK_ASMDIR_weak)
705688 sym->a.weak = 1;
706689 else if (tok1 == TOK_ASMDIR_hidden)
707690 sym->a.visibility = STV_HIDDEN;
691+ update_storage(sym);
708692 next();
709693 } while (tok == ',');
710694 break;
@@ -947,7 +931,6 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) · 236 unmodified lines
947931 } else if (tok >= TOK_ASMDIR_FIRST && tok <= TOK_ASMDIR_LAST) {
948932 asm_parse_directive(s1, global);
949933 } else if (tok == TOK_PPNUM) {
950− Sym *sym;
951934 const char *p;
952935 int n;
953936 p = tokc.str.data;
@@ -955,9 +938,7 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) · 1 unmodified line
955938 if (*p != '\0')
956939 expect("':'");
957940 /* new local label */
958− sym = asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
959− /* Remove the marker for tentative definitions. */
960− sym->type.t &= ~VT_EXTERN;
941+ asm_new_label(s1, asm_get_local_label_name(s1, n), 1);
961942 next();
962943 skip(':');
963944 goto redo;
@@ -967,8 +948,7 @@ static int tcc_assemble_internal(TCCState *s1, int do_preprocess, int global) · 3 unmodified lines
967948 next();
968949 if (tok == ':') {
969950 /* new label */
970− Sym *sym = asm_new_label(s1, opcode, 0);
971− sym->type.t &= ~VT_EXTERN;
951+ asm_new_label(s1, opcode, 0);
972952 next();
973953 goto redo;
974954 } else if (tok == '=') {
@@ -998,7 +978,6 @@ ST_FUNC int tcc_assemble(TCCState *s1, int do_preprocess) · 23 unmodified lines
998978 ind = cur_text_section->data_offset;
999979 nocode_wanted = 0;
1000980 ret = tcc_assemble_internal(s1, do_preprocess, 1);
1001− asm_free_labels(s1);
1002981 cur_text_section->data_offset = ind;
1003982 tcc_debug_end(s1);
1004983 return ret;
tccelf.c+4−6
@@ -310,8 +310,7 @@ static void rebuild_hash(Section *s, unsigned int nb_buckets) · 309 unmodified lines
310310
311311 sym = (ElfW(Sym) *)s->data + 1;
312312 for(sym_index = 1; sym_index < nb_syms; sym_index++) {
313− if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL
314− || sym->st_shndx == SHN_UNDEF) {
313+ if (ELFW(ST_BIND)(sym->st_info) != STB_LOCAL) {
315314 h = elf_hash(strtab + sym->st_name) % nb_buckets;
316315 *ptr = hash[h];
317316 hash[h] = sym_index;
@@ -350,9 +349,8 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, · 32 unmodified lines
350349 int *ptr, *base;
351350 ptr = section_ptr_add(hs, sizeof(int));
352351 base = (int *)hs->data;
353− /* only add global, weak or undef symbols. The latter might
354− become global late (from asm references). */
355− if (ELFW(ST_BIND)(info) != STB_LOCAL || shndx == SHN_UNDEF) {
352+ /* only add global or weak symbols. */
353+ if (ELFW(ST_BIND)(info) != STB_LOCAL) {
356354 /* add another hashing entry */
357355 nbuckets = base[0];
358356 h = elf_hash((unsigned char *) name) % nbuckets;
@@ -390,7 +388,7 @@ ST_FUNC int find_elf_sym(Section *s, const char *name) · 31 unmodified lines
390388 while (sym_index != 0) {
391389 sym = &((ElfW(Sym) *)s->data)[sym_index];
392390 name1 = (char *) s->link->data + sym->st_name;
393− if (!strcmp(name, name1))
391+ if (!strcmp(name, name1) && ELFW(ST_BIND)(sym->st_info) != STB_LOCAL)
394392 return sym_index;
395393 sym_index = ((int *)hs->data)[2 + nbuckets + sym_index];
396394 }
tccgen.c+31−29
@@ -275,11 +275,6 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 274 unmodified lines
275275 decl(VT_CONST);
276276 gen_inline_functions(s1);
277277 check_vstack();
278−
279−#ifdef CONFIG_TCC_ASM
280− asm_free_labels(s1);
281−#endif
282−
283278 /* end of translation unit info */
284279 tcc_debug_end(s1);
285280 return 0;
@@ -297,28 +292,42 @@ ST_FUNC ElfSym *elfsym(Sym *s) · 11 unmodified lines
297292 }
298293
299294 /* apply storage attributes to Elf symbol */
300−
301−static void update_storage(Sym *sym)
295+ST_FUNC void update_storage(Sym *sym)
302296 {
303− ElfSym *esym = elfsym(sym);
297+ ElfSym *esym;
298+ int sym_bind, old_sym_bind;
299+
300+ esym = elfsym(sym);
304301 if (!esym)
305302 return;
303+
306304 if (sym->a.visibility)
307305 esym->st_other = (esym->st_other & ~ELFW(ST_VISIBILITY)(-1))
308306 | sym->a.visibility;
309− if (sym->a.weak)
310− esym->st_info = ELFW(ST_INFO)(STB_WEAK, ELFW(ST_TYPE)(esym->st_info));
307+
308+ if (sym->type.t & VT_STATIC)
309+ sym_bind = STB_LOCAL;
310+ else if (sym->a.weak)
311+ sym_bind = STB_WEAK;
312+ else
313+ sym_bind = STB_GLOBAL;
314+ old_sym_bind = ELFW(ST_BIND)(esym->st_info);
315+ if (sym_bind != old_sym_bind) {
316+ esym->st_info = ELFW(ST_INFO)(sym_bind, ELFW(ST_TYPE)(esym->st_info));
317+ }
318+
311319 #ifdef TCC_TARGET_PE
312320 if (sym->a.dllimport)
313321 esym->st_other |= ST_PE_IMPORT;
314322 if (sym->a.dllexport)
315323 esym->st_other |= ST_PE_EXPORT;
316324 #endif
325+
317326 #if 0
318− printf("storage %s: vis=%d weak=%d exp=%d imp=%d\n",
327+ printf("storage %s: bind=%c vis=%d exp=%d imp=%d\n",
319328 get_tok_str(sym->v, NULL),
329+ sym_bind == STB_WEAK ? 'w' : sym_bind == STB_LOCAL ? 'l' : 'g',
320330 sym->a.visibility,
321− sym->a.weak,
322331 sym->a.dllexport,
323332 sym->a.dllimport
324333 );
@@ -578,10 +587,10 @@ ST_FUNC Sym *sym_push(int v, CType *type, int r, int c) · 253 unmodified lines
578587 }
579588
580589 /* push a global identifier */
581−ST_FUNC Sym *global_identifier_push_1(Sym **ptop, int v, int t, int c)
590+ST_FUNC Sym *global_identifier_push(int v, int t, int c)
582591 {
583592 Sym *s, **ps;
584− s = sym_push2(ptop, v, t, c);
593+ s = sym_push2(&global_stack, v, t, c);
585594 /* don't record anonymous symbol */
586595 if (v < SYM_FIRST_ANOM) {
587596 ps = &table_ident[v - TOK_IDENT]->sym_identifier;
@@ -595,11 +604,6 @@ ST_FUNC Sym *global_identifier_push_1(Sym **ptop, int v, int t, int c) · 7 unmodified lines
595604 return s;
596605 }
597606
598−static Sym *global_identifier_push(int v, int t, int c)
599−{
600− return global_identifier_push_1(&global_stack, v, t, c);
601−}
602−
603607 /* pop symbols until top reaches 'b'. If KEEP is non-zero don't really
604608 pop them yet from the list, but do remove them from the token array. */
605609 ST_FUNC void sym_pop(Sym **ptop, Sym *b, int keep)
@@ -841,6 +845,9 @@ ST_FUNC Sym *external_global_sym(int v, CType *type, int r) · 235 unmodified lines
841845 s = global_identifier_push(v, type->t | VT_EXTERN, 0);
842846 s->type.ref = type->ref;
843847 s->r = r | VT_CONST | VT_SYM;
848+ } else if (IS_ASM_SYM(s)) {
849+ s->type.t = type->t | (s->type.t & VT_EXTERN);
850+ s->type.ref = type->ref;
844851 }
845852 return s;
846853 }
@@ -849,7 +856,7 @@ ST_FUNC Sym *external_global_sym(int v, CType *type, int r) · 2 unmodified lines
849856 static void patch_storage(Sym *sym, AttributeDef *ad, CType *type)
850857 {
851858 if (type) {
852− if ((sym->type.t & VT_BTYPE) == VT_VOID) /* from asm */
859+ if (IS_ASM_SYM(sym))
853860 sym->type = *type;
854861 else if (!is_compatible_types(&sym->type, type))
855862 tcc_error("incompatible types for redefinition of '%s'",
@@ -5026,7 +5033,7 @@ ST_FUNC void unary(void) · 4170 unmodified lines
50265033 if (t < TOK_UIDENT)
50275034 expect("identifier");
50285035 s = sym_find(t);
5029− if (!s) {
5036+ if (!s || IS_ASM_SYM(s)) {
50305037 const char *name = get_tok_str(t, NULL);
50315038 if (tok != '(')
50325039 tcc_error("'%s' undeclared", name);
@@ -7223,12 +7230,8 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 2190 unmodified lines
72237230 type.t = (type.t & ~VT_EXTERN) | VT_STATIC;
72247231
72257232 sym = sym_find(v);
7226− if (sym) {
7233+ if (sym && !IS_ASM_SYM(sym)) {
72277234 Sym *ref;
7228− /* If type is VT_VOID the symbol was created by tccasm
7229− first, and we see the first reference from C now. */
7230− if ((sym->type.t & VT_BTYPE) == VT_VOID)
7231− sym->type = type;
72327235
72337236 if ((sym->type.t & VT_BTYPE) != VT_FUNC)
72347237 goto func_error1;
@@ -7261,15 +7264,14 @@ static int decl0(int l, int is_for_loop_init, Sym *func_sym) · 26 unmodified lines
72617264 tcc_error("redefinition of '%s'", get_tok_str(v, NULL));
72627265 /* if symbol is already defined, then put complete type */
72637266 sym->type = type;
7267+ sym->r = VT_SYM | VT_CONST;
72647268
72657269 } else {
72667270 /* put function symbol */
7267− sym = global_identifier_push(v, type.t, 0);
7268− sym->type.ref = type.ref;
7271+ sym = external_global_sym(v, &type, 0);
72697272 }
72707273
72717274 sym->type.ref->f.func_body = 1;
7272− sym->r = VT_SYM | VT_CONST;
72737275 patch_storage(sym, &ad, NULL);
72747276
72757277 /* static inline functions are just recorded as a kind

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