aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tcc.h1
-rw-r--r--tccgen.c25
-rw-r--r--tcctok.h2
3 files changed, 27 insertions, 1 deletions
diff --git a/tcc.h b/tcc.h
index 5f8b145..6d37860 100644
--- a/tcc.h
+++ b/tcc.h
@@ -285,6 +285,7 @@ typedef struct AttributeDef {
resize : 1,
fill : 10;
struct Section *section;
+ int alias_target; /* token */
} AttributeDef;
/* gr: wrappers for casting sym->r for other purposes */
diff --git a/tccgen.c b/tccgen.c
index 22d58ec..da970fd 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -2472,6 +2472,16 @@ static void parse_attribute(AttributeDef *ad)
next();
skip(')');
break;
+ case TOK_ALIAS1:
+ case TOK_ALIAS2:
+ skip('(');
+ if (tok != TOK_STR)
+ expect("alias(\"target\")");
+ ad->alias_target = /* save string as token, for later */
+ tok_alloc((char*)tokc.cstr->data, tokc.cstr->size-1)->tok;
+ next();
+ skip(')');
+ break;
case TOK_ALIGNED1:
case TOK_ALIGNED2:
if (tok == '(') {
@@ -5578,7 +5588,20 @@ 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, asm_label);
+ sym = external_sym(v, &type, r, asm_label);
+
+ if (ad.alias_target) {
+ Section tsec;
+ Elf32_Sym *esym;
+ Sym *alias_target;
+
+ alias_target = sym_find(ad.alias_target);
+ if (!alias_target || !alias_target->c)
+ error("unsupported forward __alias__ attribute");
+ esym = &((Elf32_Sym *)symtab_section->data)[alias_target->c];
+ tsec.sh_num = esym->st_shndx;
+ put_extern_sym2(sym, &tsec, esym->st_value, esym->st_size, 0);
+ }
} else {
type.t |= (btype.t & VT_STATIC); /* Retain "static". */
if (type.t & VT_STATIC)
diff --git a/tcctok.h b/tcctok.h
index ec14c1a..aabbd05 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -100,6 +100,8 @@
DEF(TOK_PACKED2, "__packed__")
DEF(TOK_WEAK1, "weak")
DEF(TOK_WEAK2, "__weak__")
+ DEF(TOK_ALIAS1, "alias")
+ DEF(TOK_ALIAS2, "__alias__")
DEF(TOK_UNUSED1, "unused")
DEF(TOK_UNUSED2, "__unused__")
DEF(TOK_CDECL1, "cdecl")