From 32a682b88febf983420406a4ec5087d07761a8bc Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Mon, 7 Feb 2011 22:42:38 +0100 Subject: [PATCH] Fix fct asm label: only valid for declaration - Fix function assembly label mechanism introduced in commit 9b09fc376e8c212a767c875e71ca003e3b9a0d2e to only accept alternative name for function declaration. - merge the code with the one introduced in commit 264a103610e3ee86b27b8cbb0e4ec81cd654d980. - Don't memorize token for asm label but directly the asm label. --- libtcc.c | 8 +++--- tcc.h | 2 +- tccgen.c | 74 ++++++++++++++++---------------------------------------- 3 files changed, 26 insertions(+), 58 deletions(-) diff --git a/libtcc.c b/libtcc.c index 64e5519..613374e 100644 --- a/libtcc.c +++ b/libtcc.c @@ -436,10 +436,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, } if (!sym->c) { - if (sym->a) - name = get_tok_str(sym->a, NULL); - else - name = get_tok_str(sym->v, NULL); + name = get_tok_str(sym->v, NULL); #ifdef CONFIG_TCC_BCHECK if (tcc_state->do_bounds_check) { char buf[32]; @@ -496,6 +493,9 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, pstrcpy(buf1 + 1, sizeof(buf1) - 1, name); name = buf1; } + if (sym->asm_label) { + name = sym->asm_label; + } info = ELFW(ST_INFO)(sym_bind, sym_type); sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name); } else { diff --git a/tcc.h b/tcc.h index a3a9c78..441adac 100644 --- a/tcc.h +++ b/tcc.h @@ -219,7 +219,7 @@ typedef struct SValue { /* symbol management */ typedef struct Sym { int v; /* symbol token */ - int a; /* asm symbol token */ + char *asm_label; /* associated asm label */ long r; /* associated register */ union { long c; /* associated number */ diff --git a/tccgen.c b/tccgen.c index d806a38..1daad9d 100644 --- a/tccgen.c +++ b/tccgen.c @@ -128,6 +128,7 @@ static inline Sym *sym_malloc(void) ST_INLN void sym_free(Sym *sym) { sym->next = sym_free_first; + tcc_free(sym->asm_label); sym_free_first = sym; } @@ -136,7 +137,7 @@ ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c) { Sym *s; s = sym_malloc(); - s->a = 0; + s->asm_label = NULL; s->v = v; s->type.t = t; s->type.ref = NULL; @@ -360,8 +361,10 @@ ST_FUNC Sym *external_global_sym(int v, CType *type, int r) return s; } -/* define a new external reference to a symbol 'v' of type 'u' */ -static Sym *external_sym(int v, CType *type, int r) +/* define a new external reference to a symbol 'v' with alternate asm + name 'asm_label' of type 'u'. 'asm_label' is equal to NULL if there + is no alternate name (most cases) */ +static Sym *external_sym(int v, CType *type, int r, char *asm_label) { Sym *s; @@ -369,8 +372,7 @@ static Sym *external_sym(int v, CType *type, int r) if (!s) { /* push forward reference */ s = sym_push(v, type, r | VT_CONST | VT_SYM, 0); - if (type && type->ref && type->ref->a) - s->a = type->ref->a; + s->asm_label = asm_label; s->type.t |= VT_EXTERN; } else if (s->type.ref == func_old_type.ref) { s->type.ref = type->ref; @@ -3029,8 +3031,6 @@ static void post_type(CType *type, AttributeDef *ad) CType pt; if (tok == '(') { - TokenSym *ts = NULL; - /* function declaration */ next(); l = 0; @@ -3086,19 +3086,10 @@ static void post_type(CType *type, AttributeDef *ad) /* NOTE: const is ignored in returned type as it has a special meaning in gcc / C++ */ type->t &= ~(VT_STORAGE | VT_CONSTANT); - if (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3) { - CString astr; - - asm_label_instr(&astr); - ts = tok_alloc(astr.data, strlen(astr.data)); - cstr_free(&astr); - } post_type(type, ad); /* we push a anonymous symbol which will contain the function prototype */ ad->func_args = arg_size; s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l); - if (ts != NULL) - s->a = ts->tok; s->next = first; type->t = t1 | VT_FUNC; type->ref = s; @@ -5251,7 +5242,8 @@ static void func_decl_list(Sym *func_sym) CType btype, type; /* parse each declaration */ - while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF) { + while (tok != '{' && tok != ';' && tok != ',' && tok != TOK_EOF && + tok != TOK_ASM1 && tok != TOK_ASM2 && tok != TOK_ASM3) { if (!parse_btype(&btype, &ad)) expect("declaration list"); if (((btype.t & VT_BTYPE) == VT_ENUM || @@ -5298,10 +5290,7 @@ static void gen_function(Sym *sym) ind = cur_text_section->data_offset; /* NOTE: we patch the symbol size later */ put_extern_sym(sym, cur_text_section, ind, 0); - if (sym->a) - funcname = get_tok_str(sym->a, NULL); - else - funcname = get_tok_str(sym->v, NULL); + funcname = get_tok_str(sym->v, NULL); func_ind = ind; /* put debug symbol */ if (tcc_state->do_debug) @@ -5387,12 +5376,6 @@ ST_FUNC void decl(int l) Sym *sym; AttributeDef ad; - /* - * type.ref must be either a valid reference or NULL for external_sym to - * work. As type = btype is executed before external_sym is call, setting - * btype.ref to 0 is enough. - */ - btype.ref = 0; while (1) { if (!parse_btype(&btype, &ad)) { /* skip redundant ';' */ @@ -5548,39 +5531,24 @@ ST_FUNC void decl(int l) sym = sym_push(v, &type, INT_ATTR(&ad), 0); sym->type.t |= VT_TYPEDEF; } else if ((type.t & VT_BTYPE) == VT_FUNC) { + char *asm_label; // associated asm label Sym *fn; + + asm_label = NULL; /* external function definition */ /* specific case for func_call attribute */ type.ref->r = INT_ATTR(&ad); - fn = external_sym(v, &type, 0); if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) { - char target[256]; + CString astr; - *target = 0; - next(); - skip('('); - /* Part 1: __USER_LABEL_PREFIX__ (user defined) */ - if (tok == TOK_STR) - pstrcat(target, sizeof(target), tokc.cstr->data); - else - pstrcat(target, sizeof(target), get_tok_str(tok, NULL)); - - next(); - /* Part 2: api name */ - if (tok == TOK_STR) - pstrcat(target, sizeof(target), tokc.cstr->data); - else - pstrcat(target, sizeof(target), get_tok_str(tok, NULL)); - - next(); - skip(')'); - if (tcc_state->warn_unsupported) - warning("ignoring redirection from %s to %s\n", get_tok_str(v, NULL), target); - - if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) - parse_attribute((AttributeDef *) &fn->type.ref->r); + asm_label_instr(&astr); + asm_label = tcc_strdup(astr.data); + cstr_free(&astr); } + fn = external_sym(v, &type, 0, asm_label); + if (gnu_ext && (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2)) + parse_attribute((AttributeDef *) &fn->type.ref->r); } else { /* not lvalue if array */ r = 0; @@ -5594,7 +5562,7 @@ ST_FUNC void decl(int l) /* NOTE: as GCC, uninitialized global static arrays of null size are considered as extern */ - external_sym(v, &type, r); + external_sym(v, &type, r, NULL); } else { type.t |= (btype.t & VT_STATIC); /* Retain "static". */ if (type.t & VT_STATIC)