diff --git a/tccelf.c b/tccelf.c index 4837936d..049d9cda 100644 --- a/tccelf.c +++ b/tccelf.c @@ -1586,9 +1586,13 @@ static void provide_linker_sym(TCCState *s1, const char *name, { int sym_index = find_elf_sym(symtab_section, name); - if (!sym_index - || ((ElfW(Sym) *)symtab_section->data)[sym_index].st_shndx != SHN_UNDEF) + if (sym_index) { + if (((ElfW(Sym) *)symtab_section->data)[sym_index].st_shndx != SHN_UNDEF) + return; + } else if (!s1->dynsymtab_section + || !find_elf_sym(s1->dynsymtab_section, name)) { return; + } set_linker_sym(s1, name, sec, offs); } diff --git a/tests/tests2/151+_dso_linker_symbol.c b/tests/tests2/151+_dso_linker_symbol.c new file mode 100644 index 00000000..b3a9dcf1 --- /dev/null +++ b/tests/tests2/151+_dso_linker_symbol.c @@ -0,0 +1,6 @@ +char end = 7; + +char *get_dso_end(void) +{ + return &end; +} diff --git a/tests/tests2/151_dso_linker_symbol.c b/tests/tests2/151_dso_linker_symbol.c new file mode 100644 index 00000000..26e5491c --- /dev/null +++ b/tests/tests2/151_dso_linker_symbol.c @@ -0,0 +1,12 @@ +#include + +extern char _end[]; +extern char *get_dso_end(void); + +int main(void) +{ + int errors = get_dso_end() != _end; + + printf("DSO linker symbol errors: %d\n", errors); + return errors; +} diff --git a/tests/tests2/151_dso_linker_symbol.expect b/tests/tests2/151_dso_linker_symbol.expect new file mode 100644 index 00000000..6e81c47a --- /dev/null +++ b/tests/tests2/151_dso_linker_symbol.expect @@ -0,0 +1 @@ +DSO linker symbol errors: 0 diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile index 1c094d42..d8c4ebb8 100644 --- a/tests/tests2/Makefile +++ b/tests/tests2/Makefile @@ -38,7 +38,7 @@ ifeq ($(CONFIG_bcheck),no) endif ifeq ($(CONFIG_dll),no) SKIP += 113_btdll.test 147_def_library.test # no shared lib support yet - SKIP += 149_end_copy_reloc.test + SKIP += 149_end_copy_reloc.test 151_dso_linker_symbol.test endif ifeq (-$(findstring gcc,$(CC))-,--) SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS)) @@ -56,7 +56,7 @@ ifeq (-$(CONFIG_WIN32)-,-yes-) SKIP += 124_atomic_counter.test # No pthread support SKIP += 144_tls.test 146_tls_extern.test # TLS runtime not supported SKIP += 148_linker_symbols.test 149_end_copy_reloc.test # ELF linker tests - SKIP += 150_linker_boundaries.test + SKIP += 150_linker_boundaries.test 151_dso_linker_symbol.test endif ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS))) SKIP += 106_versym.test # no pthread_condattr_setpshared @@ -70,7 +70,7 @@ endif ifeq ($(CONFIG_OSX),yes) SKIP += 144_tls.test 146_tls_extern.test # TLS runtime not supported on Mach-O SKIP += 148_linker_symbols.test 149_end_copy_reloc.test # ELF linker tests - SKIP += 150_linker_boundaries.test + SKIP += 150_linker_boundaries.test 151_dso_linker_symbol.test endif ifeq ($(CONFIG_pie),yes) SKIP += 149_end_copy_reloc.test # PIE executables do not use copy relocations @@ -183,6 +183,15 @@ GEN-ALWAYS = ./$(basename $@).exe \ ) +# A linker symbol needed only by a DSO must be provided by the executable. +151_dso_linker_symbol.test: NORUN = true +151_dso_linker_symbol.test: T1 = ( \ + $(TCC) -shared $(subst 151,151+,$1) -o 151_dso_linker_symbol$(DLLSUF) && \ + $(TCC) $1 ./151_dso_linker_symbol$(DLLSUF) -Wl,-rpath=. \ + -o $(basename $@).exe && \ + ./$(basename $@).exe \ + ) + 112_backtrace.test: FLAGS += -dt -b 112_backtrace.test 113_btdll.test 126_bound_global.test: FILTER += \ -e 's;[0-9A-Fa-fx]\{5,\};........;g' \