diff --git a/llvm/include/llvm/MC/MCELFObjectWriter.h b/llvm/include/llvm/MC/MCELFObjectWriter.h index 3b7a0c8a7025..a61abd58e835 100644 --- a/llvm/include/llvm/MC/MCELFObjectWriter.h +++ b/llvm/include/llvm/MC/MCELFObjectWriter.h @@ -189,6 +189,8 @@ public: bool checkRelocation(MCContext &Ctx, SMLoc Loc, const MCSectionELF *From, const MCSectionELF *To); + void fixSymbolsInTLSFixups(MCAssembler &Asm, const MCExpr *Expr); + unsigned getELFHeaderEFlags() const { return ELFHeaderEFlags; } void setELFHeaderEFlags(unsigned Flags) { ELFHeaderEFlags = Flags; } diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index 8065d17546d2..aa703a06979c 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -159,10 +159,8 @@ public: private: bool isBundleLocked() const; - void emitInstToFragment(const MCInst &Inst, const MCSubtargetInfo &) override; void emitInstToData(const MCInst &Inst, const MCSubtargetInfo &) override; - void fixSymbolsInTLSFixups(const MCExpr *expr); void finalizeCGProfileEntry(const MCSymbolRefExpr *&S, uint64_t Offset); void finalizeCGProfile(); diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 68e7f1785fa2..d0e56162f616 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -1468,6 +1468,9 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm, return; } + if (Fixup.getValue()) + fixSymbolsInTLSFixups(Asm, Fixup.getValue()); + const MCSymbolELF *RenamedSymA = SymA; if (SymA) { if (const MCSymbolELF *R = Renames.lookup(SymA)) @@ -1502,6 +1505,92 @@ bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl( return &SymA.getSection() == FB.getParent(); } +void ELFObjectWriter::fixSymbolsInTLSFixups(MCAssembler &Asm, + const MCExpr *expr) { + switch (expr->getKind()) { + case MCExpr::Target: + cast(expr)->fixELFSymbolsInTLSFixups(Asm); + break; + case MCExpr::Constant: + break; + + case MCExpr::Binary: { + const MCBinaryExpr *be = cast(expr); + fixSymbolsInTLSFixups(Asm, be->getLHS()); + fixSymbolsInTLSFixups(Asm, be->getRHS()); + break; + } + + case MCExpr::SymbolRef: { + const MCSymbolRefExpr &symRef = *cast(expr); + switch (symRef.getKind()) { + default: + return; + case MCSymbolRefExpr::VK_GOTTPOFF: + case MCSymbolRefExpr::VK_INDNTPOFF: + case MCSymbolRefExpr::VK_NTPOFF: + case MCSymbolRefExpr::VK_GOTNTPOFF: + case MCSymbolRefExpr::VK_TLSCALL: + case MCSymbolRefExpr::VK_TLSDESC: + case MCSymbolRefExpr::VK_TLSGD: + case MCSymbolRefExpr::VK_TLSLD: + case MCSymbolRefExpr::VK_TLSLDM: + case MCSymbolRefExpr::VK_TPOFF: + case MCSymbolRefExpr::VK_TPREL: + case MCSymbolRefExpr::VK_DTPOFF: + case MCSymbolRefExpr::VK_DTPREL: + case MCSymbolRefExpr::VK_PPC_DTPMOD: + case MCSymbolRefExpr::VK_PPC_TPREL_LO: + case MCSymbolRefExpr::VK_PPC_TPREL_HI: + case MCSymbolRefExpr::VK_PPC_TPREL_HA: + case MCSymbolRefExpr::VK_PPC_TPREL_HIGH: + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA: + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: + case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: + case MCSymbolRefExpr::VK_PPC_DTPREL_LO: + case MCSymbolRefExpr::VK_PPC_DTPREL_HI: + case MCSymbolRefExpr::VK_PPC_DTPREL_HA: + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH: + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA: + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: + case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: + case MCSymbolRefExpr::VK_PPC_GOT_TPREL: + case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: + case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: + case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: + case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL: + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: + case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: + case MCSymbolRefExpr::VK_PPC_TLS: + case MCSymbolRefExpr::VK_PPC_TLS_PCREL: + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: + case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL: + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: + case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: + break; + } + Asm.registerSymbol(symRef.getSymbol()); + cast(symRef.getSymbol()).setType(ELF::STT_TLS); + break; + } + + case MCExpr::Unary: + fixSymbolsInTLSFixups(Asm, cast(expr)->getSubExpr()); + break; + } +} + uint64_t ELFObjectWriter::writeObject(MCAssembler &Asm) { uint64_t Size = ELFWriter(*this, OS, IsLittleEndian, diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index df559f1f6a16..2668bc1b2920 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -318,7 +318,6 @@ void MCELFStreamer::emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) { if (isBundleLocked()) report_fatal_error("Emitting values inside a locked bundle is forbidden"); - fixSymbolsInTLSFixups(Value); MCObjectStreamer::emitValueImpl(Value, Size, Loc); } @@ -351,91 +350,6 @@ void MCELFStreamer::emitIdent(StringRef IdentString) { popSection(); } -void MCELFStreamer::fixSymbolsInTLSFixups(const MCExpr *expr) { - switch (expr->getKind()) { - case MCExpr::Target: - cast(expr)->fixELFSymbolsInTLSFixups(getAssembler()); - break; - case MCExpr::Constant: - break; - - case MCExpr::Binary: { - const MCBinaryExpr *be = cast(expr); - fixSymbolsInTLSFixups(be->getLHS()); - fixSymbolsInTLSFixups(be->getRHS()); - break; - } - - case MCExpr::SymbolRef: { - const MCSymbolRefExpr &symRef = *cast(expr); - switch (symRef.getKind()) { - default: - return; - case MCSymbolRefExpr::VK_GOTTPOFF: - case MCSymbolRefExpr::VK_INDNTPOFF: - case MCSymbolRefExpr::VK_NTPOFF: - case MCSymbolRefExpr::VK_GOTNTPOFF: - case MCSymbolRefExpr::VK_TLSCALL: - case MCSymbolRefExpr::VK_TLSDESC: - case MCSymbolRefExpr::VK_TLSGD: - case MCSymbolRefExpr::VK_TLSLD: - case MCSymbolRefExpr::VK_TLSLDM: - case MCSymbolRefExpr::VK_TPOFF: - case MCSymbolRefExpr::VK_TPREL: - case MCSymbolRefExpr::VK_DTPOFF: - case MCSymbolRefExpr::VK_DTPREL: - case MCSymbolRefExpr::VK_PPC_DTPMOD: - case MCSymbolRefExpr::VK_PPC_TPREL_LO: - case MCSymbolRefExpr::VK_PPC_TPREL_HI: - case MCSymbolRefExpr::VK_PPC_TPREL_HA: - case MCSymbolRefExpr::VK_PPC_TPREL_HIGH: - case MCSymbolRefExpr::VK_PPC_TPREL_HIGHA: - case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: - case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: - case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: - case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: - case MCSymbolRefExpr::VK_PPC_DTPREL_LO: - case MCSymbolRefExpr::VK_PPC_DTPREL_HI: - case MCSymbolRefExpr::VK_PPC_DTPREL_HA: - case MCSymbolRefExpr::VK_PPC_DTPREL_HIGH: - case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHA: - case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: - case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: - case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: - case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: - case MCSymbolRefExpr::VK_PPC_GOT_TPREL: - case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: - case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: - case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: - case MCSymbolRefExpr::VK_PPC_GOT_TPREL_PCREL: - case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: - case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: - case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: - case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: - case MCSymbolRefExpr::VK_PPC_TLS: - case MCSymbolRefExpr::VK_PPC_TLS_PCREL: - case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: - case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: - case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: - case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: - case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_PCREL: - case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: - case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: - case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: - case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: - break; - } - getAssembler().registerSymbol(symRef.getSymbol()); - cast(symRef.getSymbol()).setType(ELF::STT_TLS); - break; - } - - case MCExpr::Unary: - fixSymbolsInTLSFixups(cast(expr)->getSubExpr()); - break; - } -} - void MCELFStreamer::finalizeCGProfileEntry(const MCSymbolRefExpr *&SRE, uint64_t Offset) { const MCSymbol *S = &SRE->getSymbol(); @@ -478,15 +392,6 @@ void MCELFStreamer::finalizeCGProfile() { popSection(); } -void MCELFStreamer::emitInstToFragment(const MCInst &Inst, - const MCSubtargetInfo &STI) { - this->MCObjectStreamer::emitInstToFragment(Inst, STI); - MCRelaxableFragment &F = *cast(getCurrentFragment()); - - for (auto &Fixup : F.getFixups()) - fixSymbolsInTLSFixups(Fixup.getValue()); -} - // A fragment can only have one Subtarget, and when bundling is enabled we // sometimes need to use the same fragment. We give an error if there // are conflicting Subtargets. @@ -548,10 +453,8 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst, DF->getFixups(), STI); auto Fixups = MutableArrayRef(DF->getFixups()).slice(FixupStartIndex); - for (auto &Fixup : Fixups) { + for (auto &Fixup : Fixups) Fixup.setOffset(Fixup.getOffset() + CodeOffset); - fixSymbolsInTLSFixups(Fixup.getValue()); - } DF->setHasInstructions(STI); if (!Fixups.empty() && Fixups.back().getTargetKind() ==