tccelf: consider DSO symbols for PROVIDE

An input shared object can be the only place where a conventional boundary name is referenced or defined. In that case the regular symbol table has no entry, but native ELF linkers still synthesize the executable definition so that it participates in dynamic symbol resolution.

Consult the input dynamic symbol table before treating a plain boundary name as unreferenced. Exercise the case with a DSO-defined end symbol whose address must be interposed by the executable's final boundary.
This commit is contained in:
Mounir IDRASSI 2026-07-28 18:01:53 +09:00
parent 384614a945
commit 43158eaa71
5 changed files with 37 additions and 5 deletions

View File

@ -1586,9 +1586,13 @@ static void provide_linker_sym(TCCState *s1, const char *name,
{ {
int sym_index = find_elf_sym(symtab_section, name); int sym_index = find_elf_sym(symtab_section, name);
if (!sym_index if (sym_index) {
|| ((ElfW(Sym) *)symtab_section->data)[sym_index].st_shndx != SHN_UNDEF) 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; return;
}
set_linker_sym(s1, name, sec, offs); set_linker_sym(s1, name, sec, offs);
} }

View File

@ -0,0 +1,6 @@
char end = 7;
char *get_dso_end(void)
{
return &end;
}

View File

@ -0,0 +1,12 @@
#include <stdio.h>
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;
}

View File

@ -0,0 +1 @@
DSO linker symbol errors: 0

View File

@ -38,7 +38,7 @@ ifeq ($(CONFIG_bcheck),no)
endif endif
ifeq ($(CONFIG_dll),no) ifeq ($(CONFIG_dll),no)
SKIP += 113_btdll.test 147_def_library.test # no shared lib support yet 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 endif
ifeq (-$(findstring gcc,$(CC))-,--) ifeq (-$(findstring gcc,$(CC))-,--)
SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS)) SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS))
@ -56,7 +56,7 @@ ifeq (-$(CONFIG_WIN32)-,-yes-)
SKIP += 124_atomic_counter.test # No pthread support SKIP += 124_atomic_counter.test # No pthread support
SKIP += 144_tls.test 146_tls_extern.test # TLS runtime not supported 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 += 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 endif
ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS))) ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS)))
SKIP += 106_versym.test # no pthread_condattr_setpshared SKIP += 106_versym.test # no pthread_condattr_setpshared
@ -70,7 +70,7 @@ endif
ifeq ($(CONFIG_OSX),yes) ifeq ($(CONFIG_OSX),yes)
SKIP += 144_tls.test 146_tls_extern.test # TLS runtime not supported on Mach-O 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 += 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 endif
ifeq ($(CONFIG_pie),yes) ifeq ($(CONFIG_pie),yes)
SKIP += 149_end_copy_reloc.test # PIE executables do not use copy relocations SKIP += 149_end_copy_reloc.test # PIE executables do not use copy relocations
@ -183,6 +183,15 @@ GEN-ALWAYS =
./$(basename $@).exe \ ./$(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: FLAGS += -dt -b
112_backtrace.test 113_btdll.test 126_bound_global.test: FILTER += \ 112_backtrace.test 113_btdll.test 126_bound_global.test: FILTER += \
-e 's;[0-9A-Fa-fx]\{5,\};........;g' \ -e 's;[0-9A-Fa-fx]\{5,\};........;g' \