aboutsummaryrefslogtreecommitdiff
path: root/tccasm.c
diff options
context:
space:
mode:
authorMichael Matz <matz@suse.de>2017-12-10 06:18:27 +0100
committerMichael Matz <matz@suse.de>2017-12-10 06:50:58 +0100
commit8490c54dbd756130962825adf32ab955137da8a4 (patch)
treef86e81108aca1053fc810f6fdc77c62ef547a976 /tccasm.c
parent3ae1a2af1c10f9b64631d8e18d948498e14b283d (diff)
downloadtinycc-8490c54dbd756130962825adf32ab955137da8a4.tar.gz
tinycc-8490c54dbd756130962825adf32ab955137da8a4.tar.bz2
Fix some multi-file corner cases with asm
for this we have to create also asm symbols as VT_STATIC initially except if there's an indication that it should be global (.globl or undefined at end of unit). For this to work we need to be able to globalize symbols after they were local and enter them into the ELF hash tables, and also adjust the symbols that were potentially already used in relocs when they were still local. The easiest is to do a proper symbol resolution step also in multi-file mode, for regular symbols (the non-dynamic ones, i.e. not from shared libs).
Diffstat (limited to 'tccasm.c')
-rw-r--r--tccasm.c21
1 files changed, 6 insertions, 15 deletions
diff --git a/tccasm.c b/tccasm.c
index 4fe3f32..355d158 100644
--- a/tccasm.c
+++ b/tccasm.c
@@ -42,13 +42,12 @@ static Sym *asm_label_find(int v)
return sym;
}
-static Sym *asm_label_push(int v, int t)
+static Sym *asm_label_push(int v)
{
- Sym *sym = global_identifier_push(v, t, 0);
/* We always add VT_EXTERN, for sym definition that's tentative
(for .set, removed for real defs), for mere references it's correct
as is. */
- sym->type.t |= VT_ASM | VT_EXTERN;
+ Sym *sym = global_identifier_push(v, VT_ASM | VT_EXTERN | VT_STATIC, 0);
sym->r = VT_CONST | VT_SYM;
return sym;
}
@@ -67,7 +66,7 @@ ST_FUNC Sym* get_asm_sym(int name, Sym *csym)
{
Sym *sym = asm_label_find(name);
if (!sym) {
- sym = asm_label_push(name, 0);
+ sym = asm_label_push(name);
if (csym)
sym->c = csym->c;
}
@@ -102,7 +101,7 @@ static void asm_expr_unary(TCCState *s1, ExprValue *pe)
/* forward */
if (!sym || (sym->c && elfsym(sym)->st_shndx != SHN_UNDEF)) {
/* if the last label is defined, then define a new one */
- sym = asm_label_push(label, VT_STATIC);
+ sym = asm_label_push(label);
}
}
pe->v = 0;
@@ -381,7 +380,7 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local,
}
} else {
new_label:
- sym = asm_label_push(label, is_local == 1 ? VT_STATIC : 0);
+ sym = asm_label_push(label);
}
if (!sym->c)
put_extern_sym2(sym, NULL, 0, 0, 0);
@@ -392,11 +391,6 @@ static Sym* asm_new_label1(TCCState *s1, int label, int is_local,
if (is_local != 2)
sym->type.t &= ~VT_EXTERN;
- if (IS_ASM_SYM(sym) && !(sym->type.t & VT_ASM_GLOBAL)) {
- sym->type.t |= VT_STATIC;
- update_storage(sym);
- }
-
return sym;
}
@@ -679,11 +673,8 @@ static void asm_parse_directive(TCCState *s1, int global)
Sym *sym;
next();
sym = get_asm_sym(tok, NULL);
- if (tok1 != TOK_ASMDIR_hidden) {
+ if (tok1 != TOK_ASMDIR_hidden)
sym->type.t &= ~VT_STATIC;
- if (IS_ASM_SYM(sym))
- sym->type.t |= VT_ASM_GLOBAL;
- }
if (tok1 == TOK_ASMDIR_weak)
sym->a.weak = 1;
else if (tok1 == TOK_ASMDIR_hidden)