also in combination with one initialized: For example 1.c int xxx; 2.c int xxx = 2; 3.c int xxx; tcc 1.c 2.c 3.c
Unified · Split
| @@ -236,11 +236,14 @@ ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, · 235 unmodified lines | ||
| 236 | 236 | /* keep first-found weak definition, ignore subsequents */ |
| 237 | 237 | } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) { |
| 238 | 238 | /* ignore hidden symbols after */ |
| 239 | − } else if (esym->st_shndx == SHN_COMMON | |
| 240 | − && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) { | |
| 241 | − /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01 | |
| 242 | − No idea if this is the correct solution ... */ | |
| 239 | + } else if ((esym->st_shndx == SHN_COMMON | |
| 240 | + || esym->st_shndx == bss_section->sh_num) | |
| 241 | + && (sh_num < SHN_LORESERVE | |
| 242 | + && sh_num != bss_section->sh_num)) { | |
| 243 | + /* data symbol gets precedence over common/bss */ | |
| 243 | 244 | goto do_patch; |
| 245 | + } else if (sh_num == SHN_COMMON || sh_num == bss_section->sh_num) { | |
| 246 | + /* data symbol keeps precedence over common/bss */ | |
| 244 | 247 | } else if (s == tcc_state->dynsymtab_section) { |
| 245 | 248 | /* we accept that two DLL define the same symbol */ |
| 246 | 249 | } else { |
| @@ -248,7 +251,7 @@ ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, · 1 unmodified line | ||
| 248 | 251 | printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n", |
| 249 | 252 | sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis); |
| 250 | 253 | #endif |
| 251 | − tcc_error_noabort("'%s' defined twice... may be -fcommon is needed?", name); | |
| 254 | + tcc_error_noabort("'%s' defined twice", name); | |
| 252 | 255 | } |
| 253 | 256 | } else { |
| 254 | 257 | do_patch: |