aboutsummaryrefslogtreecommitdiff
path: root/tccelf.c
diff options
context:
space:
mode:
authorgrischka <grischka>2016-10-01 21:58:23 +0200
committergrischka <grischka>2016-10-01 22:01:33 +0200
commite03306d1709d13d2e67349d42488a93abc4dc32a (patch)
tree3f5d14a60f3b4589a3f418110ac698f379f7780d /tccelf.c
parent332cf5327fa090ce39089e29881e2c2effb753a4 (diff)
downloadtinycc-e03306d1709d13d2e67349d42488a93abc4dc32a.tar.gz
tinycc-e03306d1709d13d2e67349d42488a93abc4dc32a.tar.bz2
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
Diffstat (limited to 'tccelf.c')
-rw-r--r--tccelf.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/tccelf.c b/tccelf.c
index 0aa7014..23c7e9b 100644
--- a/tccelf.c
+++ b/tccelf.c
@@ -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 */
} else if (sym_vis == STV_HIDDEN || sym_vis == STV_INTERNAL) {
/* ignore hidden symbols after */
- } else if (esym->st_shndx == SHN_COMMON
- && (sh_num < SHN_LORESERVE || sh_num == SHN_COMMON)) {
- /* gr: Happens with 'tcc ... -static tcctest.c' on e.g. Ubuntu 6.01
- No idea if this is the correct solution ... */
+ } else if ((esym->st_shndx == SHN_COMMON
+ || esym->st_shndx == bss_section->sh_num)
+ && (sh_num < SHN_LORESERVE
+ && sh_num != bss_section->sh_num)) {
+ /* data symbol gets precedence over common/bss */
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) {
/* we accept that two DLL define the same symbol */
} 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",
sym_bind, sh_num, new_vis, esym_bind, esym->st_shndx, esym_vis);
#endif
- tcc_error_noabort("'%s' defined twice... may be -fcommon is needed?", name);
+ tcc_error_noabort("'%s' defined twice", name);
}
} else {
do_patch: