diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -438,11 +438,12 @@ // 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 . + // See the comment in maybeReportUndefined for PPC32 .got2 and PPC64 .toc auto *d = dyn_cast(&sym); if (!d) { if (!isDebugSection(*sec) && sec->name != ".eh_frame" && - sec->name != ".gcc_except_table" && sec->name != ".toc") { + sec->name != ".gcc_except_table" && sec->name != ".got2" && + sec->name != ".toc") { uint32_t secIdx = cast(sym).discardedSecIdx; Elf_Shdr_Impl sec = CHECK(file->getObj().sections(), file)[secIdx]; diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -946,8 +946,12 @@ // .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") + // + // PPC32 .got2 is similar but cannot be fixed. Multiple .got2 is infeasible + // because .LC0-.LTOC is not representable if the two labels are in different + // .got2 + if (cast(sym).discardedSecIdx != 0 && + (sec.name == ".got2" || sec.name == ".toc")) return false; bool isWarning = diff --git a/lld/test/ELF/comdat-discarded-ppc32.s b/lld/test/ELF/comdat-discarded-ppc32.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/comdat-discarded-ppc32.s @@ -0,0 +1,21 @@ +# REQUIRES: ppc +# RUN: llvm-mc -filetype=obj -triple=powerpc %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 + +## Similar to PPC64, clang/gcc PPC32 may emit a .rela.got2 which references a local symbol +## defined in a discarded .rodata section. Unfortunately, .got2 cannot be placed in a comdat +## because for lwz 3, .LC0-.LTOC(30), we cannot define .LC0 in a different .got2 section. + +## Don't error "relocation refers to a discarded section". + +.section .text.foo,"axG",@progbits,foo,comdat +.globl foo +foo: + lwz 3, .LC0-.LTOC(30) +.L0: + +.section .got2,"aw",@progbits +.set .LTOC, .got2+32768 +.LC0: +.long .L0