Index: lld/trunk/ELF/InputSection.cpp =================================================================== --- lld/trunk/ELF/InputSection.cpp +++ lld/trunk/ELF/InputSection.cpp @@ -438,11 +438,13 @@ // relocation in it pointing to discarded sections with R_*_NONE, which // hopefully creates a frame that is ignored at runtime. Also, don't warn // on .gcc_except_table and debug sections. + // + // See the comment in maybeReportUndefined for PPC64 .toc . auto *D = dyn_cast(&Sym); if (!D) { if (!Sec->Name.startswith(".debug") && !Sec->Name.startswith(".zdebug") && Sec->Name != ".eh_frame" && - Sec->Name != ".gcc_except_table") { + Sec->Name != ".gcc_except_table" && Sec->Name != ".toc") { uint32_t SecIdx = cast(Sym).DiscardedSecIdx; Elf_Shdr_Impl Sec = CHECK(File->getObj().sections(), File)[SecIdx]; Index: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -718,6 +718,15 @@ if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore && CanBeExternal) return false; + // clang (as of 2019-06-12) / gcc (as of 8.2.1) PPC64 may emit a .rela.toc + // which references a switch table in a discarded .rodata/.text section. The + // .toc and the .rela.toc are incorrectly not placed in the comdat. The ELF + // spec says references from outside the group to a STB_LOCAL symbol are not + // allowed. Work around the bug. + if (Config->EMachine == EM_PPC64 && + cast(Sym).DiscardedSecIdx != 0 && Sec.Name == ".toc") + return false; + auto Visibility = [&]() -> std::string { switch (Sym.Visibility) { case STV_INTERNAL: Index: lld/trunk/test/ELF/comdat-discarded-ppc64.s =================================================================== --- lld/trunk/test/ELF/comdat-discarded-ppc64.s +++ lld/trunk/test/ELF/comdat-discarded-ppc64.s @@ -0,0 +1,17 @@ +# REQUIRES: ppc +# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o +# RUN: ld.lld %t.o %t.o -o /dev/null +# RUN: ld.lld -r --fatal-warnings %t.o %t.o -o /dev/null + +## clang/gcc PPC64 may emit a .rela.toc which references a switch table in a +## discarded .rodata/.text section. The .toc and the .rela.toc are incorrectly +## not placed in the comdat. +## Don't error "relocation refers to a discarded section". + +.section .text.foo,"axG",@progbits,foo,comdat +.globl foo +foo: +.L0: + +.section .toc,"aw" +.quad .L0