aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xexamples/ex_weak.c11
-rw-r--r--examples/weak_f.c6
-rw-r--r--libtcc.c8
-rw-r--r--tcc.h4
-rw-r--r--tccgen.c4
-rw-r--r--tcctok.h2
6 files changed, 32 insertions, 3 deletions
diff --git a/examples/ex_weak.c b/examples/ex_weak.c
new file mode 100755
index 0000000..2a2bd19
--- /dev/null
+++ b/examples/ex_weak.c
@@ -0,0 +1,11 @@
+#! /usr/local/bin/tcc -run
+#include <tcclib.h>
+
+extern void weak_f (void) __attribute__ ((weak));
+
+int main ()
+{
+ if (weak_f) {
+ weak_f();
+ }
+}
diff --git a/examples/weak_f.c b/examples/weak_f.c
new file mode 100644
index 0000000..e744531
--- /dev/null
+++ b/examples/weak_f.c
@@ -0,0 +1,6 @@
+#include <tcclib.h>
+
+void weak_f (void)
+{
+ printf("Weak\n");
+}
diff --git a/libtcc.c b/libtcc.c
index bea52de..feb30bc 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -424,8 +424,12 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section,
if (sym->type.t & VT_STATIC)
sym_bind = STB_LOCAL;
- else
- sym_bind = STB_GLOBAL;
+ else {
+ if (FUNC_WEAK(sym->type.ref->r))
+ sym_bind = STB_WEAK;
+ else
+ sym_bind = STB_GLOBAL;
+ }
if (!sym->c) {
name = get_tok_str(sym->v, NULL);
diff --git a/tcc.h b/tcc.h
index 0170f11..21cce75 100644
--- a/tcc.h
+++ b/tcc.h
@@ -272,7 +272,8 @@ typedef struct AttributeDef {
func_import : 1,
func_args : 5,
mode : 4,
- fill : 12;
+ weak : 1,
+ fill : 11;
struct Section *section;
} AttributeDef;
@@ -283,6 +284,7 @@ typedef struct AttributeDef {
#define FUNC_ARGS(r) (((AttributeDef*)&(r))->func_args)
#define FUNC_ALIGN(r) (((AttributeDef*)&(r))->aligned)
#define FUNC_PACKED(r) (((AttributeDef*)&(r))->packed)
+#define FUNC_WEAK(r) (((AttributeDef*)&(r))->weak)
#define ATTR_MODE(r) (((AttributeDef*)&(r))->mode)
#define INT_ATTR(ad) (*(int*)(ad))
diff --git a/tccgen.c b/tccgen.c
index e761f91..805410b 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -2462,6 +2462,10 @@ static void parse_attribute(AttributeDef *ad)
case TOK_PACKED2:
ad->packed = 1;
break;
+ case TOK_WEAK1:
+ case TOK_WEAK2:
+ ad->weak = 1;
+ break;
case TOK_UNUSED1:
case TOK_UNUSED2:
/* currently, no need to handle it because tcc does not
diff --git a/tcctok.h b/tcctok.h
index 9075865..a69f6f9 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -93,6 +93,8 @@
DEF(TOK_ALIGNED2, "__aligned__")
DEF(TOK_PACKED1, "packed")
DEF(TOK_PACKED2, "__packed__")
+ DEF(TOK_WEAK1, "weak")
+ DEF(TOK_WEAK2, "__weak__")
DEF(TOK_UNUSED1, "unused")
DEF(TOK_UNUSED2, "__unused__")
DEF(TOK_CDECL1, "cdecl")