Unified · Split
| @@ -429,7 +429,7 @@ ST_FUNC void put_extern_sym2(Sym *sym, Section *section, · 428 unmodified lines | |||
| 429 | if (sym->type.t & VT_STATIC) | 429 | if (sym->type.t & VT_STATIC) |
| 430 | sym_bind = STB_LOCAL; | 430 | sym_bind = STB_LOCAL; |
| 431 | else { | 431 | else { |
| 432 | if (sym_type == STT_FUNC && sym->type.ref && FUNC_WEAK(sym->type.ref->r)) | 432 | if (sym->type.t & VT_WEAK) |
| 433 | sym_bind = STB_WEAK; | 433 | sym_bind = STB_WEAK; |
| 434 | else | 434 | else |
| 435 | sym_bind = STB_GLOBAL; | 435 | sym_bind = STB_GLOBAL; |
| @@ -293,7 +293,6 @@ typedef struct AttributeDef { · 292 unmodified lines | |||
| 293 | #define FUNC_ARGS(r) (((AttributeDef*)&(r))->func_args) | 293 | #define FUNC_ARGS(r) (((AttributeDef*)&(r))->func_args) |
| 294 | #define FUNC_ALIGN(r) (((AttributeDef*)&(r))->aligned) | 294 | #define FUNC_ALIGN(r) (((AttributeDef*)&(r))->aligned) |
| 295 | #define FUNC_PACKED(r) (((AttributeDef*)&(r))->packed) | 295 | #define FUNC_PACKED(r) (((AttributeDef*)&(r))->packed) |
| 296 | #define FUNC_WEAK(r) (((AttributeDef*)&(r))->weak) | ||
| 297 | #define ATTR_MODE(r) (((AttributeDef*)&(r))->mode) | 296 | #define ATTR_MODE(r) (((AttributeDef*)&(r))->mode) |
| 298 | #define INT_ATTR(ad) (*(int*)(ad)) | 297 | #define INT_ATTR(ad) (*(int*)(ad)) |
| 299 | 298 | ||
| @@ -629,11 +628,12 @@ struct TCCState { · 329 unmodified lines | |||
| 629 | #define VT_INLINE 0x00000400 /* inline definition */ | 628 | #define VT_INLINE 0x00000400 /* inline definition */ |
| 630 | #define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */ | 629 | #define VT_IMPORT 0x00004000 /* win32: extern data imported from dll */ |
| 631 | #define VT_EXPORT 0x00008000 /* win32: data exported from dll */ | 630 | #define VT_EXPORT 0x00008000 /* win32: data exported from dll */ |
| 631 | #define VT_WEAK 0x00010000 /* win32: data exported from dll */ | ||
| 632 | 632 | ||
| 633 | #define VT_STRUCT_SHIFT 16 /* shift for bitfield shift values */ | 633 | #define VT_STRUCT_SHIFT 17 /* shift for bitfield shift values */ |
| 634 | 634 | ||
| 635 | /* type mask (except storage) */ | 635 | /* type mask (except storage) */ |
| 636 | #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT) | 636 | #define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE | VT_IMPORT | VT_EXPORT | VT_WEAK) |
| 637 | #define VT_TYPE (~(VT_STORAGE)) | 637 | #define VT_TYPE (~(VT_STORAGE)) |
| 638 | 638 | ||
| 639 | /* token values */ | 639 | /* token values */ |
| @@ -2922,6 +2922,9 @@ static int parse_btype(CType *type, AttributeDef *ad) · 2921 unmodified lines | |||
| 2922 | case TOK_ATTRIBUTE1: | 2922 | case TOK_ATTRIBUTE1: |
| 2923 | case TOK_ATTRIBUTE2: | 2923 | case TOK_ATTRIBUTE2: |
| 2924 | parse_attribute(ad); | 2924 | parse_attribute(ad); |
| 2925 | if (ad->weak) { | ||
| 2926 | t |= VT_WEAK; | ||
| 2927 | } | ||
| 2925 | if (ad->mode) { | 2928 | if (ad->mode) { |
| 2926 | u = ad->mode -1; | 2929 | u = ad->mode -1; |
| 2927 | t = (t & ~VT_BTYPE) | u; | 2930 | t = (t & ~VT_BTYPE) | u; |
| @@ -3189,6 +3192,10 @@ static void type_decl(CType *type, AttributeDef *ad, int *v, int td) · 261 unmodified lines | |||
| 3189 | post_type(type, ad); | 3192 | post_type(type, ad); |
| 3190 | if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) | 3193 | if (tok == TOK_ATTRIBUTE1 || tok == TOK_ATTRIBUTE2) |
| 3191 | parse_attribute(ad); | 3194 | parse_attribute(ad); |
| 3195 | |||
| 3196 | if (ad->weak) | ||
| 3197 | type->t |= VT_WEAK; | ||
| 3198 | |||
| 3192 | if (!type1.t) | 3199 | if (!type1.t) |
| 3193 | return; | 3200 | return; |
| 3194 | /* append type at the end of type1 */ | 3201 | /* append type at the end of type1 */ |
| @@ -82,6 +82,7 @@ void local_label_test(void); · 81 unmodified lines | |||
| 82 | void statement_expr_test(void); | 82 | void statement_expr_test(void); |
| 83 | void asm_test(void); | 83 | void asm_test(void); |
| 84 | void builtin_test(void); | 84 | void builtin_test(void); |
| 85 | void weak_test(void); | ||
| 85 | 86 | ||
| 86 | int fib(int n); | 87 | int fib(int n); |
| 87 | void num(int n); | 88 | void num(int n); |
| @@ -537,6 +538,7 @@ int main(int argc, char **argv) · 449 unmodified lines | |||
| 537 | local_label_test(); | 538 | local_label_test(); |
| 538 | asm_test(); | 539 | asm_test(); |
| 539 | builtin_test(); | 540 | builtin_test(); |
| 541 | weak_test(); | ||
| 540 | return 0; | 542 | return 0; |
| 541 | } | 543 | } |
| 542 | 544 | ||
| @@ -2227,6 +2229,22 @@ void builtin_test(void) · 1684 unmodified lines | |||
| 2227 | } | 2229 | } |
| 2228 | 2230 | ||
| 2229 | 2231 | ||
| 2232 | extern int __attribute__((weak)) weak_f1(void); | ||
| 2233 | extern int __attribute__((weak)) weak_f2(void); | ||
| 2234 | extern int __attribute__((weak)) weak_v1; | ||
| 2235 | extern int __attribute__((weak)) weak_v2; | ||
| 2236 | |||
| 2237 | void __attribute__((weak)) weak_test(void) | ||
| 2238 | { | ||
| 2239 | printf("weak_f1=%d\n", weak_f1 ? weak_f1() : 123); | ||
| 2240 | printf("weak_f2=%d\n", weak_f2 ? weak_f2() : 123); | ||
| 2241 | printf("weak_v1=%d\n",&weak_v1 ? weak_v1 : 123); | ||
| 2242 | printf("weak_v2=%d\n",&weak_v2 ? weak_v2 : 123); | ||
| 2243 | } | ||
| 2244 | |||
| 2245 | int __attribute__((weak)) weak_f2() { return 222; } | ||
| 2246 | int __attribute__((weak)) weak_v2 = 222; | ||
| 2247 | |||
| 2230 | void const_func(const int a) | 2248 | void const_func(const int a) |
| 2231 | { | 2249 | { |
| 2232 | } | 2250 | } |