diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 91e879cb92a..32ec969c369 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -765,6 +765,9 @@ static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) { return nullptr; } +// True if the assembler knows nothing about the final value of the symbol. +// This doesn't cover the comdat issues, since in those cases the assembler +// can at least know that all symbols in the section will move together. static bool isWeak(const MCSymbolData &D) { if (MCELF::GetType(D) == ELF::STT_GNU_IFUNC) return true; @@ -775,27 +778,11 @@ static bool isWeak(const MCSymbolData &D) { case ELF::STB_LOCAL: return false; case ELF::STB_GLOBAL: - break; + return false; case ELF::STB_WEAK: case ELF::STB_GNU_UNIQUE: return true; } - - const MCSymbol &Sym = D.getSymbol(); - if (!Sym.isInSection()) - return false; - - const auto &Sec = cast(Sym.getSection()); - if (!Sec.getGroup()) - return false; - - // It is invalid to replace a reference to a global in a comdat - // with a reference to a local since out of comdat references - // to a local are forbidden. - // We could try to return false for more cases, like the reference - // being in the same comdat or Sym being an alias to another global, - // but it is not clear if it is worth the effort. - return true; } void ELFObjectWriter::RecordRelocation(MCAssembler &Asm, @@ -1692,7 +1679,25 @@ bool ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( } bool ELFObjectWriter::isWeak(const MCSymbolData &SD) const { - return ::isWeak(SD); + if (::isWeak(SD)) + return true; + + const MCSymbol &Sym = SD.getSymbol(); + if (!Sym.isInSection()) + return false; + + const auto &Sec = cast(Sym.getSection()); + if (!Sec.getGroup()) + return false; + + // It is invalid to replace a reference to a global in a comdat + // with a reference to a local since out of comdat references + // to a local are forbidden. + // We could try to return false for more cases, like the reference + // being in the same comdat or Sym being an alias to another global, + // but it is not clear if it is worth the effort. + return true; + } MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, diff --git a/test/MC/ELF/relocation.s b/test/MC/ELF/relocation.s index de2b43454ac..cd0cc45fc00 100644 --- a/test/MC/ELF/relocation.s +++ b/test/MC/ELF/relocation.s @@ -2,6 +2,13 @@ // Test that we produce the correct relocation. + + .section .pr23272,"aGw",@progbits,pr23272,comdat + .globl pr23272 +pr23272: +pr23272_2: + + .text bar: movl $bar, %edx # R_X86_64_32 movq $bar, %rdx # R_X86_64_32S @@ -43,6 +50,8 @@ bar: .long foo@gotpcrel .long foo@plt + + .quad pr23272_2 - pr23272 // CHECK: Section { // CHECK: Name: .rela.text // CHECK: Relocations [ @@ -89,5 +98,5 @@ bar: // CHECK-NEXT: Binding: Local // CHECK-NEXT: Type: Section // CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: .text (0x1) +// CHECK-NEXT: Section: .text // CHECK-NEXT: }