tccelf: allow multiple declaration of bss/common symbols

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
master
grischka 2016-10-01 21:58:23 +02:00
parent 332cf5327f
commit e03306d170
1 changed files with 8 additions and 5 deletions

View File

@ -236,11 +236,14 @@ ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
/* keep first-found weak definition, ignore subsequents */ /* keep first-found weak definition, ignore subsequents */
} else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) { } else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
/* ignore hidden symbols after */ /* ignore hidden symbols after */
} else if (esym->st_shndx == SHN_COMMON } else if ((esym->st_shndx == SHN_COMMON
&& (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) { || esym->st_shndx == bss_section->sh_num)
/* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01 && (sh_num < SHN_LORESERVE
No idea if this is the correct solution ... */ && sh_num != bss_section->sh_num)) {
/* data symbol gets precedence over common/bss */
goto do_patch; goto do_patch;
} else if (sh_num == SHN_COMMON || sh_num == bss_section->sh_num) {
/* data symbol keeps precedence over common/bss */
} else if (s == tcc_state->dynsymtab_section) { } else if (s == tcc_state->dynsymtab_section) {
/* we accept that two DLL define the same symbol */ /* we accept that two DLL define the same symbol */
} else { } else {
@ -248,7 +251,7 @@ ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n", printf("new_bind=%x new_shndx=%x new_vis=%x old_bind=%x old_shndx=%x old_vis=%x\n",
sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis); sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
#endif #endif
tcc_error_noabort("'%s' defined twice... may be -fcommon is needed?", name); tcc_error_noabort("'%s' defined twice", name);
} }
} else { } else {
do_patch: do_patch: