Fix fct asm label: only valid for declaration
- Fix function assembly label mechanism introduced in commit9b09fc376eto only accept alternative name for function declaration. - merge the code with the one introduced in commit264a103610. - Don't memorize token for asm label but directly the asm label.
This commit is contained in:
		
							parent
							
								
									c23400278a
								
							
						
					
					
						commit
						32a682b88f
					
				
					 3 changed files with 26 additions and 58 deletions
				
			
		
							
								
								
									
										8
									
								
								libtcc.c
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								libtcc.c
									
										
									
									
									
								
							| 
						 | 
					@ -436,10 +436,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!sym->c) {
 | 
					    if (!sym->c) {
 | 
				
			||||||
        if (sym->a)
 | 
					        name = get_tok_str(sym->v, NULL);
 | 
				
			||||||
          name = get_tok_str(sym->a, NULL);
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
          name = get_tok_str(sym->v, NULL);
 | 
					 | 
				
			||||||
#ifdef CONFIG_TCC_BCHECK
 | 
					#ifdef CONFIG_TCC_BCHECK
 | 
				
			||||||
        if (tcc_state->do_bounds_check) {
 | 
					        if (tcc_state->do_bounds_check) {
 | 
				
			||||||
            char buf[32];
 | 
					            char buf[32];
 | 
				
			||||||
| 
						 | 
					@ -496,6 +493,9 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
 | 
				
			||||||
            pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
 | 
					            pstrcpy(buf1 + 1, sizeof(buf1) - 1, name);
 | 
				
			||||||
            name = buf1;
 | 
					            name = buf1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if (sym->asm_label) {
 | 
				
			||||||
 | 
					            name = sym->asm_label;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        info = ELFW(ST_INFO)(sym_bind, sym_type);
 | 
					        info = ELFW(ST_INFO)(sym_bind, sym_type);
 | 
				
			||||||
        sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name);
 | 
					        sym->c = add_elf_sym(symtab_section, value, size, info, other, sh_num, name);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								tcc.h
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								tcc.h
									
										
									
									
									
								
							| 
						 | 
					@ -219,7 +219,7 @@ typedef struct SValue {
 | 
				
			||||||
/* symbol management */
 | 
					/* symbol management */
 | 
				
			||||||
typedef struct Sym {
 | 
					typedef struct Sym {
 | 
				
			||||||
    int v;    /* symbol token */
 | 
					    int v;    /* symbol token */
 | 
				
			||||||
    int a;    /* asm symbol token */
 | 
					    char *asm_label;    /* associated asm label */
 | 
				
			||||||
    long r;    /* associated register */
 | 
					    long r;    /* associated register */
 | 
				
			||||||
    union {
 | 
					    union {
 | 
				
			||||||
        long c;    /* associated number */
 | 
					        long c;    /* associated number */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										74
									
								
								tccgen.c
									
										
									
									
									
								
							
							
						
						
									
										74
									
								
								tccgen.c
									
										
									
									
									
								
							| 
						 | 
					@ -128,6 +128,7 @@ static inline Sym *sym_malloc(void)
 | 
				
			||||||
ST_INLN void sym_free(Sym *sym)
 | 
					ST_INLN void sym_free(Sym *sym)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    sym->next = sym_free_first;
 | 
					    sym->next = sym_free_first;
 | 
				
			||||||
 | 
					    tcc_free(sym->asm_label);
 | 
				
			||||||
    sym_free_first = sym;
 | 
					    sym_free_first = sym;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -136,7 +137,7 @@ ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    Sym *s;
 | 
					    Sym *s;
 | 
				
			||||||
    s = sym_malloc();
 | 
					    s = sym_malloc();
 | 
				
			||||||
    s->a = 0;
 | 
					    s->asm_label = NULL;
 | 
				
			||||||
    s->v = v;
 | 
					    s->v = v;
 | 
				
			||||||
    s->type.t = t;
 | 
					    s->type.t = t;
 | 
				
			||||||
    s->type.ref = NULL;
 | 
					    s->type.ref = NULL;
 | 
				
			||||||
| 
						 | 
					@ -360,8 +361,10 @@ ST_FUNC Sym *external_global_sym(int v, CType *type, int r)
 | 
				
			||||||
    return s;
 | 
					    return s;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* define a new external reference to a symbol 'v' of type 'u' */
 | 
					/* define a new external reference to a symbol 'v' with alternate asm
 | 
				
			||||||
static Sym *external_sym(int v, CType *type, int r)
 | 
					   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;
 | 
					    Sym *s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -369,8 +372,7 @@ static Sym *external_sym(int v, CType *type, int r)
 | 
				
			||||||
    if (!s) {
 | 
					    if (!s) {
 | 
				
			||||||
        /* push forward reference */
 | 
					        /* push forward reference */
 | 
				
			||||||
        s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
 | 
					        s = sym_push(v, type, r | VT_CONST | VT_SYM, 0);
 | 
				
			||||||
        if (type && type->ref && type->ref->a)
 | 
					        s->asm_label = asm_label;
 | 
				
			||||||
            s->a = type->ref->a;
 | 
					 | 
				
			||||||
        s->type.t |= VT_EXTERN;
 | 
					        s->type.t |= VT_EXTERN;
 | 
				
			||||||
    } else if (s->type.ref == func_old_type.ref) {
 | 
					    } else if (s->type.ref == func_old_type.ref) {
 | 
				
			||||||
        s->type.ref = type->ref;
 | 
					        s->type.ref = type->ref;
 | 
				
			||||||
| 
						 | 
					@ -3029,8 +3031,6 @@ static void post_type(CType *type, AttributeDef *ad)
 | 
				
			||||||
    CType pt;
 | 
					    CType pt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (tok == '(') {
 | 
					    if (tok == '(') {
 | 
				
			||||||
        TokenSym *ts = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* function declaration */
 | 
					        /* function declaration */
 | 
				
			||||||
        next();
 | 
					        next();
 | 
				
			||||||
        l = 0;
 | 
					        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
 | 
					        /* NOTE: const is ignored in returned type as it has a special
 | 
				
			||||||
           meaning in gcc / C++ */
 | 
					           meaning in gcc / C++ */
 | 
				
			||||||
        type->t &= ~(VT_STORAGE | VT_CONSTANT); 
 | 
					        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);
 | 
					        post_type(type, ad);
 | 
				
			||||||
        /* we push a anonymous symbol which will contain the function prototype */
 | 
					        /* we push a anonymous symbol which will contain the function prototype */
 | 
				
			||||||
        ad->func_args = arg_size;
 | 
					        ad->func_args = arg_size;
 | 
				
			||||||
        s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
 | 
					        s = sym_push(SYM_FIELD, type, INT_ATTR(ad), l);
 | 
				
			||||||
        if (ts != NULL)
 | 
					 | 
				
			||||||
          s->a = ts->tok;
 | 
					 | 
				
			||||||
        s->next = first;
 | 
					        s->next = first;
 | 
				
			||||||
        type->t = t1 | VT_FUNC;
 | 
					        type->t = t1 | VT_FUNC;
 | 
				
			||||||
        type->ref = s;
 | 
					        type->ref = s;
 | 
				
			||||||
| 
						 | 
					@ -5251,7 +5242,8 @@ static void func_decl_list(Sym *func_sym)
 | 
				
			||||||
    CType btype, type;
 | 
					    CType btype, type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* parse each declaration */
 | 
					    /* 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)) 
 | 
					        if (!parse_btype(&btype, &ad)) 
 | 
				
			||||||
            expect("declaration list");
 | 
					            expect("declaration list");
 | 
				
			||||||
        if (((btype.t & VT_BTYPE) == VT_ENUM ||
 | 
					        if (((btype.t & VT_BTYPE) == VT_ENUM ||
 | 
				
			||||||
| 
						 | 
					@ -5298,10 +5290,7 @@ static void gen_function(Sym *sym)
 | 
				
			||||||
    ind = cur_text_section->data_offset;
 | 
					    ind = cur_text_section->data_offset;
 | 
				
			||||||
    /* NOTE: we patch the symbol size later */
 | 
					    /* NOTE: we patch the symbol size later */
 | 
				
			||||||
    put_extern_sym(sym, cur_text_section, ind, 0);
 | 
					    put_extern_sym(sym, cur_text_section, ind, 0);
 | 
				
			||||||
    if (sym->a)
 | 
					    funcname = get_tok_str(sym->v, NULL);
 | 
				
			||||||
      funcname = get_tok_str(sym->a, NULL);
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      funcname = get_tok_str(sym->v, NULL);
 | 
					 | 
				
			||||||
    func_ind = ind;
 | 
					    func_ind = ind;
 | 
				
			||||||
    /* put debug symbol */
 | 
					    /* put debug symbol */
 | 
				
			||||||
    if (tcc_state->do_debug)
 | 
					    if (tcc_state->do_debug)
 | 
				
			||||||
| 
						 | 
					@ -5387,12 +5376,6 @@ ST_FUNC void decl(int l)
 | 
				
			||||||
    Sym *sym;
 | 
					    Sym *sym;
 | 
				
			||||||
    AttributeDef ad;
 | 
					    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) {
 | 
					    while (1) {
 | 
				
			||||||
        if (!parse_btype(&btype, &ad)) {
 | 
					        if (!parse_btype(&btype, &ad)) {
 | 
				
			||||||
            /* skip redundant ';' */
 | 
					            /* skip redundant ';' */
 | 
				
			||||||
| 
						 | 
					@ -5548,39 +5531,24 @@ ST_FUNC void decl(int l)
 | 
				
			||||||
                    sym = sym_push(v, &type, INT_ATTR(&ad), 0);
 | 
					                    sym = sym_push(v, &type, INT_ATTR(&ad), 0);
 | 
				
			||||||
                    sym->type.t |= VT_TYPEDEF;
 | 
					                    sym->type.t |= VT_TYPEDEF;
 | 
				
			||||||
                } else if ((type.t & VT_BTYPE) == VT_FUNC) {
 | 
					                } else if ((type.t & VT_BTYPE) == VT_FUNC) {
 | 
				
			||||||
 | 
					                    char *asm_label; // associated asm label
 | 
				
			||||||
                    Sym *fn;
 | 
					                    Sym *fn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    asm_label = NULL;
 | 
				
			||||||
                    /* external function definition */
 | 
					                    /* external function definition */
 | 
				
			||||||
                    /* specific case for func_call attribute */
 | 
					                    /* specific case for func_call attribute */
 | 
				
			||||||
                    type.ref->r = INT_ATTR(&ad);
 | 
					                    type.ref->r = INT_ATTR(&ad);
 | 
				
			||||||
                    fn = external_sym(v, &type, 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
 | 
					                    if (gnu_ext && (tok == TOK_ASM1 || tok == TOK_ASM2 || tok == TOK_ASM3)) {
 | 
				
			||||||
                        char target[256];
 | 
					                        CString astr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        *target = 0;
 | 
					                        asm_label_instr(&astr);
 | 
				
			||||||
                        next();
 | 
					                        asm_label = tcc_strdup(astr.data);
 | 
				
			||||||
                        skip('(');
 | 
					                        cstr_free(&astr);
 | 
				
			||||||
                        /* 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);
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    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 {
 | 
					                } else {
 | 
				
			||||||
                    /* not lvalue if array */
 | 
					                    /* not lvalue if array */
 | 
				
			||||||
                    r = 0;
 | 
					                    r = 0;
 | 
				
			||||||
| 
						 | 
					@ -5594,7 +5562,7 @@ ST_FUNC void decl(int l)
 | 
				
			||||||
                        /* NOTE: as GCC, uninitialized global static
 | 
					                        /* NOTE: as GCC, uninitialized global static
 | 
				
			||||||
                           arrays of null size are considered as
 | 
					                           arrays of null size are considered as
 | 
				
			||||||
                           extern */
 | 
					                           extern */
 | 
				
			||||||
                        external_sym(v, &type, r);
 | 
					                        external_sym(v, &type, r, NULL);
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        type.t |= (btype.t & VT_STATIC); /* Retain "static". */
 | 
					                        type.t |= (btype.t & VT_STATIC); /* Retain "static". */
 | 
				
			||||||
                        if (type.t & VT_STATIC)
 | 
					                        if (type.t & VT_STATIC)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue