diff --git a/passes.cc b/passes.cc index 00b11e39..37db486b 100644 --- a/passes.cc +++ b/passes.cc @@ -303,8 +303,8 @@ void check_duplicate_symbols(Context &ctx) { const ElfSym &esym = file->elf_syms[i]; Symbol &sym = *file->symbols[i]; - if (sym.file == file || esym.is_undef() || esym.is_common() || - (esym.st_bind == STB_WEAK)) + if (sym.file == file || sym.file == ctx.internal_obj || + esym.is_undef() || esym.is_common() || (esym.st_bind == STB_WEAK)) continue; if (!esym.is_abs() && !file->get_section(esym)->is_alive) diff --git a/test/synthetic-symbols.sh b/test/synthetic-symbols.sh new file mode 100755 index 00000000..dae10011 --- /dev/null +++ b/test/synthetic-symbols.sh @@ -0,0 +1,63 @@ +#!/bin/bash +set -e +cd $(dirname $0) +echo -n "Testing $(basename -s .sh $0) ... " +t=$(pwd)/tmp/$(basename -s .sh $0) +mkdir -p $t + +cat < +#include + +extern char __ehdr_start[]; +extern char __executable_start[]; +extern char __start_foo[]; +extern char __stop_foo[]; + +int main() { + printf("__ehdr_start=%p\n", &__ehdr_start); + printf("__executable_start=%p\n", &__executable_start); + printf("%.*s\n", (int)(__stop_foo - __start_foo), __start_foo); +} +EOF + +clang -fuse-ld=`pwd`/../mold -Wl,--image-base=0x40000 -o $t/exe $t/a.o $t/b.o +$t/exe > $t/log + +grep -q '^__ehdr_start=0x40000$' $t/log +grep -q '^__executable_start=0x40000$' $t/log +grep -q '^section foo$' $t/log + +# Make sure that synthetic symbols overwrite existing ones + +cat < +#include + +char __ehdr_start[] = "foo"; +char __executable_start[] = "foo"; +char __start_foo[] = "foo"; +char __stop_foo[] = "foo"; + +int main() { + printf("__ehdr_start=%p\n", &__ehdr_start); + printf("__executable_start=%p\n", &__executable_start); + printf("%.*s\n", (int)(__stop_foo - __start_foo), __start_foo); +} +EOF + +clang -fuse-ld=`pwd`/../mold -Wl,--image-base=0x40000 -o $t/exe $t/a.o $t/c.o +$t/exe > $t/log + +grep -q '^__ehdr_start=0x40000$' $t/log +grep -q '^__executable_start=0x40000$' $t/log +grep -q '^section foo$' $t/log + +echo OK