Index: include/llvm/MC/MCAsmBackend.h =================================================================== --- include/llvm/MC/MCAsmBackend.h +++ include/llvm/MC/MCAsmBackend.h @@ -60,6 +60,8 @@ /// Get information on a fixup kind. virtual const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const; + virtual MCFixupKind getPCRelKind(MCFixupKind Kind) const; + /// Hook to check if a relocation is needed for some target specific reason. virtual bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, @@ -71,9 +73,8 @@ /// the offset specified by the fixup and following the fixup kind as /// appropriate. Errors (such as an out of range fixup value) should be /// reported via \p Ctx. - virtual void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t Value, bool IsResolved) const = 0; + virtual void applyFixup(const MCAssembler &Asm, const MCReloc &Reloc, + MutableArrayRef Data, bool IsResolved) const = 0; /// @} @@ -87,13 +88,12 @@ /// Target specific predicate for whether a given fixup requires the /// associated instruction to be relaxed. - virtual bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved, - uint64_t Value, + virtual bool fixupNeedsRelaxationAdvanced(const MCReloc &Reloc, bool Resolved, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const; /// Simple predicate for targets where !Resolved implies requiring relaxation - virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, + virtual bool fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const = 0; Index: include/llvm/MC/MCAssembler.h =================================================================== --- include/llvm/MC/MCAssembler.h +++ include/llvm/MC/MCAssembler.h @@ -162,7 +162,7 @@ /// relocation. bool evaluateFixup(const MCAsmLayout &Layout, const MCFixup &Fixup, const MCFragment *DF, MCValue &Target, - uint64_t &Value) const; + MCReloc &Reloc) const; /// Check whether a fixup can be satisfied, or whether it needs to be relaxed /// (increased in size, in order to hold its value correctly). @@ -195,8 +195,8 @@ /// finishLayout - Finalize a layout, including fragment lowering. void finishLayout(MCAsmLayout &Layout); - std::tuple - handleFixup(const MCAsmLayout &Layout, MCFragment &F, const MCFixup &Fixup); + std::pair handleFixup(const MCAsmLayout &Layout, MCFragment &F, + const MCFixup &Fixup); public: /// Construct a new assembler instance. Index: include/llvm/MC/MCELFObjectWriter.h =================================================================== --- include/llvm/MC/MCELFObjectWriter.h +++ include/llvm/MC/MCELFObjectWriter.h @@ -26,6 +26,7 @@ class MCSymbol; class MCSymbolELF; class MCValue; +class MCReloc; struct ELFRelocationEntry { uint64_t Offset; // Where is the relocation. @@ -75,9 +76,8 @@ return ELF::ELFOSABI_NONE; } } - - virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const = 0; + virtual unsigned getRelocType(MCAssembler &Asm, + const MCReloc &Reloc) const = 0; virtual bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const; Index: include/llvm/MC/MCFixup.h =================================================================== --- include/llvm/MC/MCFixup.h +++ include/llvm/MC/MCFixup.h @@ -112,6 +112,67 @@ SMLoc getLoc() const { return Loc; } }; +// This is what a MCFixup evaluates to. MCRelocs are short lived. They +// are only created to communicate with the targets. +class MCReloc { + /// The target dependent kind of fixup item this is. + MCFixupKind Kind; + + /// The source location which gave rise to the fixup, if any. + SMLoc Loc; + + /// The byte index of start of the relocation inside the MCFragment. + uint32_t Offset; + + /// The computed value: A - B + C, modified by RefKind. Since no + /// object format supports something like 'foo - bar@got', we store + /// just a MCSymbol for B. + const MCSymbolRefExpr *RefA; + const MCSymbol *SymB; + uint64_t Constant; + uint32_t RefKind; + + // FIXME: We shouldn't need the expression at this late stage. + const MCExpr *Value; + +public: + MCReloc() + : Kind(FK_Data_1), Offset(0), RefA(nullptr), SymB(nullptr), Constant(0), + RefKind(0), Value(nullptr) {} + + MCFixupKind getKind() const { return Kind; } + void setKind(MCFixupKind Val) { Kind = Val; } + + SMLoc getLoc() const { return Loc; } + void setLoc(SMLoc Val) { Loc = Val; } + + uint32_t getOffset() const { return Offset; } + void setOffset(uint32_t Val) { Offset = Val; } + + const MCSymbolRefExpr *getSymA() const { return RefA; } + void setSymA(const MCSymbolRefExpr *Val) { RefA = Val; } + + const MCSymbol *getSymB() const { return SymB; } + void setSymB(const MCSymbol *Val) { SymB = Val; } + + uint64_t getConstant() const { return Constant; } + uint64_t &getConstant() { return Constant; } + void setConstant(uint64_t Val) { Constant = Val; } + + uint32_t getRefKind() const { return RefKind; } + void setRefKind(uint32_t Val) { RefKind = Val; } + + const MCExpr *getValue() const { return Value; } + void setValue(const MCExpr *Val) { Value = Val; } + + bool isAbsolute() const { return !RefA && !SymB; } + MCSymbolRefExpr::VariantKind getAccessVariant() const { + if (RefA && RefA->getKind() != MCSymbolRefExpr::VK_WEAKREF) + return RefA->getKind(); + return MCSymbolRefExpr::VK_None; + } +}; + } // End llvm namespace #endif Index: include/llvm/MC/MCMachObjectWriter.h =================================================================== --- include/llvm/MC/MCMachObjectWriter.h +++ include/llvm/MC/MCMachObjectWriter.h @@ -67,9 +67,7 @@ virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) = 0; + const MCFragment *Fragment, MCReloc &Reloc) = 0; /// @} }; @@ -232,8 +230,7 @@ MCValue Target, uint64_t &FixedValue); void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCFixup &Fixup, - MCValue Target, uint64_t &FixedValue) override; + const MCFragment *Fragment, MCReloc &Reloc) override; void bindIndirectSymbols(MCAssembler &Asm); Index: include/llvm/MC/MCObjectWriter.h =================================================================== --- include/llvm/MC/MCObjectWriter.h +++ include/llvm/MC/MCObjectWriter.h @@ -27,6 +27,7 @@ class MCSymbol; class MCSymbolRefExpr; class MCValue; +class MCReloc; /// Defines the object file and target independent interfaces used by the /// assembler backend to write native file format object files. @@ -84,9 +85,7 @@ /// information about the relocation so that it can be emitted during /// writeObject(). virtual void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) = 0; + const MCFragment *Fragment, MCReloc &Reloc) = 0; /// Check whether the difference (A - B) between two symbol references is /// fully resolved. Index: include/llvm/MC/MCWasmObjectWriter.h =================================================================== --- include/llvm/MC/MCWasmObjectWriter.h +++ include/llvm/MC/MCWasmObjectWriter.h @@ -30,8 +30,7 @@ public: virtual ~MCWasmObjectTargetWriter(); - virtual unsigned getRelocType(const MCValue &Target, - const MCFixup &Fixup) const = 0; + virtual unsigned getRelocType(const MCReloc &Reloc) const = 0; /// \name Accessors /// @{ Index: include/llvm/MC/MCWinCOFFObjectWriter.h =================================================================== --- include/llvm/MC/MCWinCOFFObjectWriter.h +++ include/llvm/MC/MCWinCOFFObjectWriter.h @@ -31,10 +31,10 @@ virtual ~MCWinCOFFObjectTargetWriter() = default; unsigned getMachine() const { return Machine; } - virtual unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsCrossSection, + virtual unsigned getRelocType(MCContext &Ctx, const MCReloc &Reloc, + bool IsCrossSection, const MCAsmBackend &MAB) const = 0; - virtual bool recordRelocation(const MCFixup &) const { return true; } + virtual bool recordRelocation(const MCReloc &) const { return true; } }; /// \brief Construct a new Win COFF writer instance. Index: lib/MC/ELFObjectWriter.cpp =================================================================== --- lib/MC/ELFObjectWriter.cpp +++ lib/MC/ELFObjectWriter.cpp @@ -150,9 +150,8 @@ bool hasRelocationAddend() const { return TargetObjectWriter->hasRelocationAddend(); } - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const { - return TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel); + unsigned getRelocType(MCAssembler &Asm, const MCReloc &Reloc) const { + return TargetObjectWriter->getRelocType(Asm, Reloc); } void align(unsigned Alignment); @@ -205,8 +204,7 @@ unsigned Type) const; void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCFixup &Fixup, - MCValue Target, uint64_t &FixedValue) override; + const MCFragment *Fragment, MCReloc &Reloc) override; // Map from a signature symbol to the group section index using RevGroupMapTy = DenseMap; @@ -626,17 +624,17 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) { - MCAsmBackend &Backend = Asm.getBackend(); - bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags & + MCReloc &Fixup) { + bool IsPCRel = Asm.getBackend().getFixupKindInfo(Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; + MCReloc &Target = Fixup; + uint64_t &FixedValue = Fixup.getConstant(); const MCSectionELF &FixupSection = cast(*Fragment->getParent()); uint64_t C = Target.getConstant(); uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); MCContext &Ctx = Asm.getContext(); - if (const MCSymbolRefExpr *RefB = Target.getSymB()) { + if (const MCSymbol *SymBP = Target.getSymB()) { // Let A, B and C being the components of Target and R be the location of // the fixup. If the fixup is not pcrel, we want to compute (A - B + C). // If it is pcrel, we want to compute (A - B + C - R). @@ -651,7 +649,7 @@ return; } - const auto &SymB = cast(RefB->getSymbol()); + const MCSymbol &SymB = *SymBP; if (SymB.isUndefined()) { Ctx.reportError(Fixup.getLoc(), @@ -668,6 +666,7 @@ return; } + Fixup.setKind(Asm.getBackend().getPCRelKind(Fixup.getKind())); uint64_t SymBOffset = Layout.getSymbolOffset(SymB); uint64_t K = SymBOffset - FixupOffset; IsPCRel = true; @@ -689,7 +688,7 @@ } } - unsigned Type = getRelocType(Ctx, Target, Fixup, IsPCRel); + unsigned Type = getRelocType(Asm, Fixup); uint64_t OriginalC = C; bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type); if (!RelocateWithSymbol && SymA && !SymA->isUndefined()) Index: lib/MC/MCAsmBackend.cpp =================================================================== --- lib/MC/MCAsmBackend.cpp +++ lib/MC/MCAsmBackend.cpp @@ -52,10 +52,25 @@ return Builtins[Kind]; } +MCFixupKind MCAsmBackend::getPCRelKind(MCFixupKind Kind) const { + switch (Kind) { + case FK_Data_1: + return FK_PCRel_1; + case FK_Data_2: + return FK_PCRel_2; + case FK_Data_4: + return FK_PCRel_4; + case FK_Data_8: + return FK_PCRel_8; + default: + llvm_unreachable("cannot convert to pcrel"); + } +} + bool MCAsmBackend::fixupNeedsRelaxationAdvanced( - const MCFixup &Fixup, bool Resolved, uint64_t Value, - const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const { + const MCReloc &Reloc, bool Resolved, const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const { if (!Resolved) return true; - return fixupNeedsRelaxation(Fixup, Value, DF, Layout); + return fixupNeedsRelaxation(Reloc, DF, Layout); } Index: lib/MC/MCAssembler.cpp =================================================================== --- lib/MC/MCAssembler.cpp +++ lib/MC/MCAssembler.cpp @@ -185,9 +185,9 @@ return S.getFragment()->getAtom(); } -bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, - const MCFixup &Fixup, const MCFragment *DF, - MCValue &Target, uint64_t &Value) const { +bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, const MCFixup &Fixup, + const MCFragment *DF, MCValue &Target, + MCReloc &Reloc) const { ++stats::evaluateFixup; // FIXME: This code has some duplication with recordRelocation. We should @@ -198,17 +198,27 @@ // further processing from being done. const MCExpr *Expr = Fixup.getValue(); MCContext &Ctx = getContext(); + uint64_t &Value = Reloc.getConstant(); Value = 0; if (!Expr->evaluateAsRelocatable(Target, &Layout, &Fixup)) { Ctx.reportError(Fixup.getLoc(), "expected relocatable expression"); return true; } + + Reloc.setKind(Fixup.getKind()); + Reloc.setLoc(Fixup.getLoc()); + Reloc.setOffset(Fixup.getOffset()); + Reloc.setValue(Fixup.getValue()); + Reloc.setSymA(Target.getSymA()); + Reloc.setRefKind(Target.getRefKind()); + if (const MCSymbolRefExpr *RefB = Target.getSymB()) { if (RefB->getKind() != MCSymbolRefExpr::VK_None) { Ctx.reportError(Fixup.getLoc(), "unsupported subtraction of qualified symbol"); return true; } + Reloc.setSymB(&RefB->getSymbol()); } bool IsPCRel = Backend.getFixupKindInfo( @@ -236,6 +246,16 @@ Value = Target.getConstant(); + // Let the backend force a relocation if needed. + if (IsResolved && Backend.shouldForceRelocation(*this, Fixup, Target)) + IsResolved = false; + + // If we need a relocation, return now. recordRelocation will take + // care of the rest. + if (!IsResolved) + return false; + + // Since we don't need a relocation we can compute the final value. if (const MCSymbolRefExpr *A = Target.getSymA()) { const MCSymbol &Sym = A->getSymbol(); if (Sym.isDefined()) @@ -261,10 +281,6 @@ Value -= Offset; } - // Let the backend force a relocation if needed. - if (IsResolved && Backend.shouldForceRelocation(*this, Fixup, Target)) - IsResolved = false; - return IsResolved; } @@ -647,20 +663,19 @@ Layout.getSectionAddressSize(Sec)); } -std::tuple -MCAssembler::handleFixup(const MCAsmLayout &Layout, MCFragment &F, - const MCFixup &Fixup) { +std::pair MCAssembler::handleFixup(const MCAsmLayout &Layout, MCFragment &F, + const MCFixup &Fixup) { // Evaluate the fixup. MCValue Target; - uint64_t FixedValue; - bool IsResolved = evaluateFixup(Layout, Fixup, &F, Target, FixedValue); + MCReloc Reloc; + bool IsResolved = evaluateFixup(Layout, Fixup, &F, Target, Reloc); if (!IsResolved) { // The fixup was unresolved, we need a relocation. Inform the object // writer of the relocation, and give it an opportunity to adjust the // fixup value if need be. - getWriter().recordRelocation(*this, Layout, &F, Fixup, Target, FixedValue); + getWriter().recordRelocation(*this, Layout, &F, Reloc); } - return std::make_tuple(Target, FixedValue, IsResolved); + return {Reloc, IsResolved}; } void MCAssembler::layout(MCAsmLayout &Layout) { @@ -735,13 +750,10 @@ } else llvm_unreachable("Unknown fragment with fixups!"); for (const MCFixup &Fixup : Fixups) { - uint64_t FixedValue; + MCReloc Reloc; bool IsResolved; - MCValue Target; - std::tie(Target, FixedValue, IsResolved) = - handleFixup(Layout, Frag, Fixup); - getBackend().applyFixup(*this, Fixup, Target, Contents, FixedValue, - IsResolved); + std::tie(Reloc, IsResolved) = handleFixup(Layout, Frag, Fixup); + Backend.applyFixup(*this, Reloc, Contents, IsResolved); } } } @@ -765,14 +777,13 @@ const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const { MCValue Target; - uint64_t Value; - bool Resolved = evaluateFixup(Layout, Fixup, DF, Target, Value); + MCReloc Reloc; + bool Resolved = evaluateFixup(Layout, Fixup, DF, Target, Reloc); if (Target.getSymA() && Target.getSymA()->getKind() == MCSymbolRefExpr::VK_X86_ABS8 && Fixup.getKind() == FK_Data_1) return false; - return getBackend().fixupNeedsRelaxationAdvanced(Fixup, Resolved, Value, DF, - Layout); + return getBackend().fixupNeedsRelaxationAdvanced(Reloc, Resolved, DF, Layout); } bool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F, Index: lib/MC/MachObjectWriter.cpp =================================================================== --- lib/MC/MachObjectWriter.cpp +++ lib/MC/MachObjectWriter.cpp @@ -448,10 +448,8 @@ void MachObjectWriter::recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) { - TargetObjectWriter->recordRelocation(this, Asm, Layout, Fragment, Fixup, - Target, FixedValue); + MCReloc &Reloc) { + TargetObjectWriter->recordRelocation(this, Asm, Layout, Fragment, Reloc); } void MachObjectWriter::bindIndirectSymbols(MCAssembler &Asm) { Index: lib/MC/WasmObjectWriter.cpp =================================================================== --- lib/MC/WasmObjectWriter.cpp +++ lib/MC/WasmObjectWriter.cpp @@ -202,8 +202,8 @@ // TargetObjectWriter wrappers. bool is64Bit() const { return TargetObjectWriter->is64Bit(); } - unsigned getRelocType(const MCValue &Target, const MCFixup &Fixup) const { - return TargetObjectWriter->getRelocType(Target, Fixup); + unsigned getRelocType(const MCReloc &Reloc) const { + return TargetObjectWriter->getRelocType(Reloc); } void startSection(SectionBookkeeping &Section, unsigned SectionId, @@ -231,8 +231,7 @@ void writeHeader(const MCAssembler &Asm); void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCFixup &Fixup, - MCValue Target, uint64_t &FixedValue) override; + const MCFragment *Fragment, MCReloc &Reloc) override; void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) override; @@ -351,20 +350,17 @@ void WasmObjectWriter::recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) { - MCAsmBackend &Backend = Asm.getBackend(); - bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags & - MCFixupKindInfo::FKF_IsPCRel; + MCReloc &Fixup) { const auto &FixupSection = cast(*Fragment->getParent()); + MCReloc &Target = Fixup; + uint64_t &FixedValue = Fixup.getConstant(); uint64_t C = Target.getConstant(); uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); MCContext &Ctx = Asm.getContext(); + bool IsPCRel = Asm.getBackend().getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; - if (const MCSymbolRefExpr *RefB = Target.getSymB()) { - assert(RefB->getKind() == MCSymbolRefExpr::VK_None && - "Should not have constructed this"); - + if (const MCSymbol *SymBP = Fixup.getSymB()) { // Let A, B and C being the components of Target and R be the location of // the fixup. If the fixup is not pcrel, we want to compute (A - B + C). // If it is pcrel, we want to compute (A - B + C - R). @@ -379,7 +375,7 @@ return; } - const auto &SymB = cast(RefB->getSymbol()); + const MCSymbol &SymB = *SymBP; if (SymB.isUndefined()) { Ctx.reportError(Fixup.getLoc(), @@ -424,7 +420,7 @@ assert(!IsPCRel); assert(SymA); - unsigned Type = getRelocType(Target, Fixup); + unsigned Type = getRelocType(Fixup); WasmRelocationEntry Rec(FixupOffset, SymA, C, Type, &FixupSection); DEBUG(dbgs() << "WasmReloc: " << Rec << "\n"); Index: lib/MC/WinCOFFObjectWriter.cpp =================================================================== --- lib/MC/WinCOFFObjectWriter.cpp +++ lib/MC/WinCOFFObjectWriter.cpp @@ -196,8 +196,7 @@ bool IsPCRel) const override; void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCFixup &Fixup, - MCValue Target, uint64_t &FixedValue) override; + const MCFragment *Fragment, MCReloc &Reloc) override; void createFileSymbols(MCAssembler &Asm); void assignSectionNumbers(); @@ -710,8 +709,9 @@ void WinCOFFObjectWriter::recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) { + MCReloc &Fixup) { + MCReloc &Target = Fixup; + uint64_t &FixedValue = Fixup.getConstant(); assert(Target.getSymA() && "Relocation must reference a symbol!"); const MCSymbol &A = Target.getSymA()->getSymbol(); @@ -735,10 +735,9 @@ "Section must already have been defined in executePostLayoutBinding!"); COFFSection *Sec = SectionMap[MCSec]; - const MCSymbolRefExpr *SymB = Target.getSymB(); + const MCSymbol *B = Target.getSymB(); - if (SymB) { - const MCSymbol *B = &SymB->getSymbol(); + if (B) { if (!B->getFragment()) { Asm.getContext().reportError( Fixup.getLoc(), @@ -783,7 +782,7 @@ Reloc.Data.VirtualAddress += Fixup.getOffset(); Reloc.Data.Type = TargetObjectWriter->getRelocType( - Asm.getContext(), Target, Fixup, SymB, Asm.getBackend()); + Asm.getContext(), Fixup, B, Asm.getBackend()); // FIXME: Can anyone explain what this does other than adjust for the size // of the offset? Index: lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -52,10 +52,12 @@ {"fixup_aarch64_pcrel_adr_imm21", 0, 32, PCRelFlagVal}, {"fixup_aarch64_pcrel_adrp_imm21", 0, 32, PCRelFlagVal}, {"fixup_aarch64_add_imm12", 10, 12, 0}, + {"fixup_aarch64_add_imm12_pc", 10, 12, PCRelFlagVal}, {"fixup_aarch64_ldst_imm12_scale1", 10, 12, 0}, {"fixup_aarch64_ldst_imm12_scale2", 10, 12, 0}, {"fixup_aarch64_ldst_imm12_scale4", 10, 12, 0}, {"fixup_aarch64_ldst_imm12_scale8", 10, 12, 0}, + {"fixup_aarch64_ldst_imm12_scale8_pc", 10, 12, PCRelFlagVal}, {"fixup_aarch64_ldst_imm12_scale16", 10, 12, 0}, {"fixup_aarch64_ldr_pcrel_imm19", 5, 19, PCRelFlagVal}, {"fixup_aarch64_movw", 5, 16, 0}, @@ -73,13 +75,22 @@ return Infos[Kind - FirstTargetFixupKind]; } - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t Value, bool IsResolved) const override; + MCFixupKind getPCRelKind(MCFixupKind Kind) const override { + switch ((unsigned)Kind) { + case AArch64::fixup_aarch64_ldst_imm12_scale8: + return (MCFixupKind)AArch64::fixup_aarch64_ldst_imm12_scale8_pc; + case AArch64::fixup_aarch64_add_imm12: + return (MCFixupKind)AArch64::fixup_aarch64_add_imm12_pc; + default: + return MCAsmBackend::getPCRelKind(Kind); + } + } + + void applyFixup(const MCAssembler &Asm, const MCReloc &Reloc, + MutableArrayRef Data, bool IsResolved) const override; bool mayNeedRelaxation(const MCInst &Inst) const override; - bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, - const MCRelaxableFragment *DF, + bool fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override; void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, MCInst &Res) const override; @@ -106,20 +117,24 @@ case AArch64::fixup_aarch64_tlsdesc_call: return 0; + case FK_PCRel_1: case FK_Data_1: return 1; case AArch64::fixup_aarch64_movw: + case FK_PCRel_2: case FK_Data_2: case FK_SecRel_2: return 2; case AArch64::fixup_aarch64_pcrel_branch14: case AArch64::fixup_aarch64_add_imm12: + case AArch64::fixup_aarch64_add_imm12_pc: case AArch64::fixup_aarch64_ldst_imm12_scale1: case AArch64::fixup_aarch64_ldst_imm12_scale2: case AArch64::fixup_aarch64_ldst_imm12_scale4: case AArch64::fixup_aarch64_ldst_imm12_scale8: + case AArch64::fixup_aarch64_ldst_imm12_scale8_pc: case AArch64::fixup_aarch64_ldst_imm12_scale16: case AArch64::fixup_aarch64_ldr_pcrel_imm19: case AArch64::fixup_aarch64_pcrel_branch19: @@ -129,10 +144,12 @@ case AArch64::fixup_aarch64_pcrel_adrp_imm21: case AArch64::fixup_aarch64_pcrel_branch26: case AArch64::fixup_aarch64_pcrel_call26: + case FK_PCRel_4: case FK_Data_4: case FK_SecRel_4: return 4; + case FK_PCRel_8: case FK_Data_8: return 8; } @@ -144,7 +161,7 @@ return (hi19 << 5) | (lo2 << 29); } -static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, +static uint64_t adjustFixupValue(const MCReloc &Fixup, uint64_t Value, MCContext &Ctx, const Triple &TheTriple, bool IsResolved) { unsigned Kind = Fixup.getKind(); @@ -171,6 +188,7 @@ // Low two bits are not encoded. return (Value >> 2) & 0x7ffff; case AArch64::fixup_aarch64_add_imm12: + case AArch64::fixup_aarch64_add_imm12_pc: case AArch64::fixup_aarch64_ldst_imm12_scale1: if (TheTriple.isOSBinFormatCOFF() && !IsResolved) Value &= 0xfff; @@ -197,6 +215,7 @@ Ctx.reportError(Fixup.getLoc(), "fixup must be 4-byte aligned"); return Value >> 2; case AArch64::fixup_aarch64_ldst_imm12_scale8: + case AArch64::fixup_aarch64_ldst_imm12_scale8_pc: if (TheTriple.isOSBinFormatCOFF() && !IsResolved) Value &= 0xfff; // Unsigned 12-bit immediate which gets multiplied by 8 @@ -268,10 +287,12 @@ case AArch64::fixup_aarch64_movw: case AArch64::fixup_aarch64_pcrel_branch14: case AArch64::fixup_aarch64_add_imm12: + case AArch64::fixup_aarch64_add_imm12_pc: case AArch64::fixup_aarch64_ldst_imm12_scale1: case AArch64::fixup_aarch64_ldst_imm12_scale2: case AArch64::fixup_aarch64_ldst_imm12_scale4: case AArch64::fixup_aarch64_ldst_imm12_scale8: + case AArch64::fixup_aarch64_ldst_imm12_scale8_pc: case AArch64::fixup_aarch64_ldst_imm12_scale16: case AArch64::fixup_aarch64_ldr_pcrel_imm19: case AArch64::fixup_aarch64_pcrel_branch19: @@ -284,11 +305,10 @@ } } -void AArch64AsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, - MutableArrayRef Data, uint64_t Value, - bool IsResolved) const { +void AArch64AsmBackend::applyFixup(const MCAssembler &Asm, const MCReloc &Fixup, + MutableArrayRef Data, bool IsResolved) const { unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind()); + uint64_t Value = Fixup.getConstant(); if (!Value) return; // Doesn't change encoding. MCFixupKindInfo Info = getFixupKindInfo(Fixup.getKind()); @@ -327,10 +347,10 @@ return false; } -bool AArch64AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, - uint64_t Value, +bool AArch64AsmBackend::fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const { + uint64_t Value = Reloc.getConstant(); // FIXME: This isn't correct for AArch64. Just moving the "generic" logic // into the targets for now. // Index: lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64ELFObjectWriter.cpp @@ -16,9 +16,12 @@ #include "MCTargetDesc/AArch64MCExpr.h" #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" #include @@ -35,8 +38,7 @@ ~AArch64ELFObjectWriter() override = default; protected: - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const override; + unsigned getRelocType(MCAssembler &Asm, const MCReloc &Reloc) const override; bool IsILP32; }; @@ -56,9 +58,8 @@ "supported (LP64 eqv: " #lp64rtype ")" // assumes IsILP32 is true -static bool isNonILP32reloc(const MCFixup &Fixup, - AArch64MCExpr::VariantKind RefKind, - MCContext &Ctx) { +static bool isNonILP32reloc(const MCReloc &Fixup, MCContext &Ctx) { + auto RefKind = (AArch64MCExpr::VariantKind)Fixup.getRefKind(); if ((unsigned)Fixup.getKind() != AArch64::fixup_aarch64_movw) return false; switch (RefKind) { @@ -104,32 +105,34 @@ return false; } -unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx, - const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { +unsigned AArch64ELFObjectWriter::getRelocType(MCAssembler &Asm, + const MCReloc &Fixup) const { + MCContext &Ctx = Asm.getContext(); + const MCReloc &Target = Fixup; AArch64MCExpr::VariantKind RefKind = static_cast(Target.getRefKind()); AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind); bool IsNC = AArch64MCExpr::isNotChecked(RefKind); + bool IsPCRel = Asm.getBackend().getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; assert((!Target.getSymA() || Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) && "Should only be expression-level modifiers here"); - assert((!Target.getSymB() || - Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) && - "Should only be expression-level modifiers here"); - if (IsPCRel) { switch ((unsigned)Fixup.getKind()) { + case FK_PCRel_1: case FK_Data_1: Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); return ELF::R_AARCH64_NONE; + case FK_PCRel_2: case FK_Data_2: return R_CLS(PREL16); + case FK_PCRel_4: case FK_Data_4: return R_CLS(PREL32); + case FK_PCRel_8: case FK_Data_8: if (IsILP32) { Ctx.reportError(Fixup.getLoc(), @@ -180,7 +183,7 @@ return ELF::R_AARCH64_NONE; } } else { - if (IsILP32 && isNonILP32reloc(Fixup, RefKind, Ctx)) + if (IsILP32 && isNonILP32reloc(Fixup, Ctx)) return ELF::R_AARCH64_NONE; switch ((unsigned)Fixup.getKind()) { case FK_Data_1: Index: lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h +++ lib/Target/AArch64/MCTargetDesc/AArch64FixupKinds.h @@ -25,12 +25,14 @@ // 12-bit fixup for add/sub instructions. No alignment adjustment. All value // bits are encoded. fixup_aarch64_add_imm12, + fixup_aarch64_add_imm12_pc, // unsigned 12-bit fixups for load and store instructions. fixup_aarch64_ldst_imm12_scale1, fixup_aarch64_ldst_imm12_scale2, fixup_aarch64_ldst_imm12_scale4, fixup_aarch64_ldst_imm12_scale8, + fixup_aarch64_ldst_imm12_scale8_pc, fixup_aarch64_ldst_imm12_scale16, // The high 19 bits of a 21-bit pc-relative immediate. Same encoding as Index: lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64MachObjectWriter.cpp @@ -33,9 +33,9 @@ namespace { class AArch64MachObjectWriter : public MCMachObjectTargetWriter { - bool getAArch64FixupKindMachOInfo(const MCFixup &Fixup, unsigned &RelocType, - const MCSymbolRefExpr *Sym, - unsigned &Log2Size, const MCAssembler &Asm); + bool getAArch64FixupKindMachOInfo(const MCReloc &Fixup, unsigned &RelocType, + const MCSymbolRefExpr *Sym, + unsigned &Log2Size, const MCAssembler &Asm); public: AArch64MachObjectWriter(uint32_t CPUType, uint32_t CPUSubtype) @@ -43,14 +43,13 @@ void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) override; + MCReloc &Fixup) override; }; } // end anonymous namespace bool AArch64MachObjectWriter::getAArch64FixupKindMachOInfo( - const MCFixup &Fixup, unsigned &RelocType, const MCSymbolRefExpr *Sym, + const MCReloc &Fixup, unsigned &RelocType, const MCSymbolRefExpr *Sym, unsigned &Log2Size, const MCAssembler &Asm) { RelocType = unsigned(MachO::ARM64_RELOC_UNSIGNED); Log2Size = ~0U; @@ -149,16 +148,19 @@ return false; } -void AArch64MachObjectWriter::recordRelocation( - MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) { +void AArch64MachObjectWriter::recordRelocation(MachObjectWriter *Writer, + MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + MCReloc &Fixup) { unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind()); + uint64_t &FixedValue = Fixup.getConstant(); + MCReloc &Target = Fixup; // See . uint32_t FixupOffset = Layout.getFragmentOffset(Fragment); unsigned Log2Size = 0; - int64_t Value = 0; + int64_t Value = FixedValue; unsigned Index = 0; unsigned Type = 0; unsigned Kind = Fixup.getKind(); @@ -202,8 +204,6 @@ return; } - Value = Target.getConstant(); - if (Target.isAbsolute()) { // constant // FIXME: Should this always be extern? // SymbolNum of 0 indicates the absolute section. @@ -221,14 +221,13 @@ const MCSymbol *A = &Target.getSymA()->getSymbol(); const MCSymbol *A_Base = Asm.getAtom(*A); - const MCSymbol *B = &Target.getSymB()->getSymbol(); + const MCSymbol *B = Target.getSymB(); const MCSymbol *B_Base = Asm.getAtom(*B); // Check for "_foo@got - .", which comes through here as: // Ltmp0: // ... _foo@got - Ltmp0 if (Target.getSymA()->getKind() == MCSymbolRefExpr::VK_GOT && - Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None && Layout.getSymbolOffset(*B) == Layout.getFragmentOffset(Fragment) + Fixup.getOffset()) { // SymB is the PC, so use a PC-rel pointer-to-GOT relocation. @@ -239,8 +238,7 @@ MRE.r_word1 = (IsPCRel << 24) | (Log2Size << 25) | (Type << 28); Writer->addRelocation(A_Base, Fragment->getParent(), MRE); return; - } else if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None || - Target.getSymB()->getKind() != MCSymbolRefExpr::VK_None) { + } else if (Target.getSymA()->getKind() != MCSymbolRefExpr::VK_None) { // Otherwise, neither symbol can be modified. Asm.getContext().reportError(Fixup.getLoc(), "unsupported relocation of modified symbol"); @@ -329,15 +327,18 @@ // FIXME: Will the Target we already have ever have any data in it // we need to preserve and merge with the new Target? How about // the FixedValue? - if (!Symbol->getVariableValue()->evaluateAsRelocatable(Target, &Layout, - &Fixup)) { + MCValue NewTarget; + if (!Symbol->getVariableValue()->evaluateAsRelocatable(NewTarget, &Layout, + nullptr)) { Asm.getContext().reportError(Fixup.getLoc(), "unable to resolve variable '" + Symbol->getName() + "'"); return; } - return recordRelocation(Writer, Asm, Layout, Fragment, Fixup, Target, - FixedValue); + Fixup.setSymA(NewTarget.getSymA()); + Fixup.setSymB(&NewTarget.getSymB()->getSymbol()); + Fixup.setConstant(NewTarget.getConstant()); + return recordRelocation(Writer, Asm, Layout, Fragment, Fixup); } // Relocations inside debug sections always use local relocations when Index: lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64WinCOFFObjectWriter.cpp @@ -31,18 +31,20 @@ ~AArch64WinCOFFObjectWriter() override = default; - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsCrossSection, + unsigned getRelocType(MCContext &Ctx, const MCReloc &Fixup, + bool IsCrossSection, const MCAsmBackend &MAB) const override; - bool recordRelocation(const MCFixup &) const override; + bool recordRelocation(const MCReloc &) const override; }; } // end anonymous namespace -unsigned AArch64WinCOFFObjectWriter::getRelocType( - MCContext &Ctx, const MCValue &Target, const MCFixup &Fixup, - bool IsCrossSection, const MCAsmBackend &MAB) const { +unsigned +AArch64WinCOFFObjectWriter::getRelocType(MCContext &Ctx, const MCReloc &Fixup, + bool IsCrossSection, + const MCAsmBackend &MAB) const { + const MCReloc &Target = Fixup; auto Modifier = Target.isAbsolute() ? MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); @@ -90,7 +92,7 @@ } } -bool AArch64WinCOFFObjectWriter::recordRelocation(const MCFixup &Fixup) const { +bool AArch64WinCOFFObjectWriter::recordRelocation(const MCReloc &Reloc) const { return true; } Index: lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp =================================================================== --- lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp +++ lib/Target/AMDGPU/MCTargetDesc/AMDGPUAsmBackend.cpp @@ -30,11 +30,9 @@ unsigned getNumFixupKinds() const override { return AMDGPU::NumTargetFixupKinds; }; - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t Value, bool IsResolved) const override; - bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, - const MCRelaxableFragment *DF, + void applyFixup(const MCAssembler &Asm, const MCReloc &Reloc, + MutableArrayRef Data, bool IsResolved) const override; + bool fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override { return false; } @@ -72,8 +70,8 @@ } } -static uint64_t adjustFixupValue(const MCFixup &Fixup, uint64_t Value, - MCContext *Ctx) { +static uint64_t adjustFixupValue(const MCReloc &Fixup, MCContext *Ctx) { + uint64_t Value = Fixup.getConstant(); int64_t SignedValue = static_cast(Value); switch (Fixup.getKind()) { @@ -97,11 +95,9 @@ } } -void AMDGPUAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, - MutableArrayRef Data, uint64_t Value, - bool IsResolved) const { - Value = adjustFixupValue(Fixup, Value, &Asm.getContext()); +void AMDGPUAsmBackend::applyFixup(const MCAssembler &Asm, const MCReloc &Fixup, + MutableArrayRef Data, bool IsResolved) const { + uint64_t Value = adjustFixupValue(Fixup, &Asm.getContext()); if (!Value) return; // Doesn't change encoding. Index: lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp =================================================================== --- lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp +++ lib/Target/AMDGPU/MCTargetDesc/AMDGPUELFObjectWriter.cpp @@ -25,8 +25,7 @@ AMDGPUELFObjectWriter(bool Is64Bit, bool HasRelocationAddend); protected: - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const override; + unsigned getRelocType(MCAssembler &Asm, const MCReloc &Reloc) const override; }; @@ -39,10 +38,9 @@ ELF::EM_AMDGPU, HasRelocationAddend) {} -unsigned AMDGPUELFObjectWriter::getRelocType(MCContext &Ctx, - const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { +unsigned AMDGPUELFObjectWriter::getRelocType(MCAssembler &Asm, + const MCReloc &Fixup) const { + const MCReloc &Target = Fixup; if (const auto *SymA = Target.getSymA()) { // SCRATCH_RSRC_DWORD[01] is a special global variable that represents // the scratch buffer. Index: lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h +++ lib/Target/ARM/MCTargetDesc/ARMAsmBackend.h @@ -37,28 +37,26 @@ bool hasNOP() const { return STI->getFeatureBits()[ARM::HasV6T2Ops]; } const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; + MCFixupKind getPCRelKind(MCFixupKind Kind) const override; bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup, const MCValue &Target) override; - unsigned adjustFixupValue(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, uint64_t Value, - bool IsResolved, MCContext &Ctx, - bool IsLittleEndian) const; + unsigned adjustFixupValue(const MCAssembler &Asm, const MCReloc &Reloc, + MCContext &Ctx, bool IsLittleEndian, + bool IsResolved) const; - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t Value, bool IsResolved) const override; + void applyFixup(const MCAssembler &Asm, const MCReloc &Reloc, + MutableArrayRef Data, bool IsResolved) const override; unsigned getRelaxedOpcode(unsigned Op) const; bool mayNeedRelaxation(const MCInst &Inst) const override; - const char *reasonForFixupRelaxation(const MCFixup &Fixup, + const char *reasonForFixupRelaxation(const MCReloc &Reloc, uint64_t Value) const; - bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, - const MCRelaxableFragment *DF, + bool fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override; void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, Index: lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -94,9 +94,13 @@ // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16 // - 19. {"fixup_arm_movt_hi16", 0, 20, 0}, + {"fixup_arm_movt_hi16_pc", 0, 20, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_arm_movw_lo16", 0, 20, 0}, + {"fixup_arm_movw_lo16_pc", 0, 20, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_t2_movt_hi16", 0, 20, 0}, + {"fixup_t2_movt_hi16_pc", 0, 20, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_t2_movw_lo16", 0, 20, 0}, + {"fixup_t2_movw_lo16_pc", 0, 20, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_arm_mod_imm", 0, 12, 0}, {"fixup_t2_so_imm", 0, 26, 0}, }; @@ -145,9 +149,13 @@ // movw / movt: 16-bits immediate but scattered into two chunks 0 - 12, 16 // - 19. {"fixup_arm_movt_hi16", 12, 20, 0}, + {"fixup_arm_movt_hi16_pc", 12, 20, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_arm_movw_lo16", 12, 20, 0}, + {"fixup_arm_movw_lo16_pc", 12, 20, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_t2_movt_hi16", 12, 20, 0}, + {"fixup_t2_movt_hi16_pc", 12, 20, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_t2_movw_lo16", 12, 20, 0}, + {"fixup_t2_movw_lo16_pc", 12, 20, MCFixupKindInfo::FKF_IsPCRel}, {"fixup_arm_mod_imm", 20, 12, 0}, {"fixup_t2_so_imm", 26, 6, 0}, }; @@ -160,6 +168,21 @@ return (IsLittleEndian ? InfosLE : InfosBE)[Kind - FirstTargetFixupKind]; } +MCFixupKind ARMAsmBackend::getPCRelKind(MCFixupKind Kind) const { + switch ((unsigned)Kind) { + case ARM::fixup_arm_movw_lo16: + return (MCFixupKind)ARM::fixup_arm_movw_lo16_pc; + case ARM::fixup_arm_movt_hi16: + return (MCFixupKind)ARM::fixup_arm_movt_hi16_pc; + case ARM::fixup_t2_movw_lo16: + return (MCFixupKind)ARM::fixup_t2_movw_lo16_pc; + case ARM::fixup_t2_movt_hi16: + return (MCFixupKind)ARM::fixup_t2_movt_hi16_pc; + default: + return MCAsmBackend::getPCRelKind(Kind); + } +} + void ARMAsmBackend::handleAssemblerFlag(MCAssemblerFlag Flag) { switch (Flag) { default: @@ -201,7 +224,7 @@ return false; } -const char *ARMAsmBackend::reasonForFixupRelaxation(const MCFixup &Fixup, +const char *ARMAsmBackend::reasonForFixupRelaxation(const MCReloc &Fixup, uint64_t Value) const { switch ((unsigned)Fixup.getKind()) { case ARM::fixup_arm_thumb_br: { @@ -254,10 +277,10 @@ return nullptr; } -bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, +bool ARMAsmBackend::fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const { - return reasonForFixupRelaxation(Fixup, Value); + return reasonForFixupRelaxation(Reloc, Reloc.getConstant()); } void ARMAsmBackend::relaxInstruction(const MCInst &Inst, @@ -359,10 +382,11 @@ } unsigned ARMAsmBackend::adjustFixupValue(const MCAssembler &Asm, - const MCFixup &Fixup, - const MCValue &Target, uint64_t Value, - bool IsResolved, MCContext &Ctx, - bool IsLittleEndian) const { + const MCReloc &Fixup, MCContext &Ctx, + bool IsLittleEndian, + bool IsResolved) const { + const MCReloc &Target = Fixup; + uint64_t Value = Fixup.getConstant(); unsigned Kind = Fixup.getKind(); // MachO tries to make .o files that look vaguely pre-linked, so for MOVW/MOVT @@ -385,16 +409,19 @@ case FK_Data_1: case FK_Data_2: case FK_Data_4: + case FK_PCRel_4: return Value; case FK_SecRel_2: return Value; case FK_SecRel_4: return Value; case ARM::fixup_arm_movt_hi16: + case ARM::fixup_arm_movt_hi16_pc: if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF()) Value >>= 16; LLVM_FALLTHROUGH; - case ARM::fixup_arm_movw_lo16: { + case ARM::fixup_arm_movw_lo16: + case ARM::fixup_arm_movw_lo16_pc: { unsigned Hi4 = (Value & 0xF000) >> 12; unsigned Lo12 = Value & 0x0FFF; // inst{19-16} = Hi4; @@ -403,10 +430,12 @@ return Value; } case ARM::fixup_t2_movt_hi16: + case ARM::fixup_t2_movt_hi16_pc: if (IsResolved || !STI->getTargetTriple().isOSBinFormatELF()) Value >>= 16; LLVM_FALLTHROUGH; - case ARM::fixup_t2_movw_lo16: { + case ARM::fixup_t2_movw_lo16: + case ARM::fixup_t2_movw_lo16_pc: { unsigned Hi4 = (Value & 0xF000) >> 12; unsigned i = (Value & 0x800) >> 11; unsigned Mid3 = (Value & 0x700) >> 8; @@ -810,6 +839,7 @@ return 3; case FK_Data_4: + case FK_PCRel_4: case ARM::fixup_t2_ldst_pcrel_12: case ARM::fixup_t2_condbranch: case ARM::fixup_t2_uncondbranch: @@ -819,9 +849,13 @@ case ARM::fixup_arm_thumb_bl: case ARM::fixup_arm_thumb_blx: case ARM::fixup_arm_movt_hi16: + case ARM::fixup_arm_movt_hi16_pc: case ARM::fixup_arm_movw_lo16: + case ARM::fixup_arm_movw_lo16_pc: case ARM::fixup_t2_movt_hi16: + case ARM::fixup_t2_movt_hi16_pc: case ARM::fixup_t2_movw_lo16: + case ARM::fixup_t2_movw_lo16_pc: case ARM::fixup_t2_so_imm: return 4; @@ -871,9 +905,13 @@ case ARM::fixup_arm_thumb_bl: case ARM::fixup_arm_thumb_blx: case ARM::fixup_arm_movt_hi16: + case ARM::fixup_arm_movt_hi16_pc: case ARM::fixup_arm_movw_lo16: + case ARM::fixup_arm_movw_lo16_pc: case ARM::fixup_t2_movt_hi16: + case ARM::fixup_t2_movt_hi16_pc: case ARM::fixup_t2_movw_lo16: + case ARM::fixup_t2_movw_lo16_pc: case ARM::fixup_arm_mod_imm: case ARM::fixup_t2_so_imm: // Instruction size is 4 bytes. @@ -881,14 +919,11 @@ } } -void ARMAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, - MutableArrayRef Data, uint64_t Value, - bool IsResolved) const { +void ARMAsmBackend::applyFixup(const MCAssembler &Asm, const MCReloc &Fixup, + MutableArrayRef Data, bool IsResolved) const { unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind()); MCContext &Ctx = Asm.getContext(); - Value = adjustFixupValue(Asm, Fixup, Target, Value, IsResolved, Ctx, - IsLittleEndian); + uint64_t Value = adjustFixupValue(Asm, Fixup, Ctx, IsLittleEndian, IsResolved); if (!Value) return; // Doesn't change encoding. Index: lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -10,10 +10,13 @@ #include "MCTargetDesc/ARMFixupKinds.h" #include "MCTargetDesc/ARMMCTargetDesc.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" @@ -26,16 +29,16 @@ class ARMELFObjectWriter : public MCELFObjectTargetWriter { enum { DefaultEABIVersion = 0x05000000U }; - unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup, - bool IsPCRel, MCContext &Ctx) const; + unsigned GetRelocTypeInner(const MCReloc &Reloc, bool IsPCRel, + MCContext &Ctx) const; public: ARMELFObjectWriter(uint8_t OSABI); ~ARMELFObjectWriter() override = default; - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const override; + unsigned getRelocType(MCAssembler &Asm, + const MCReloc &Reloc) const override; bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const override; @@ -66,16 +69,18 @@ // Need to examine the Fixup when determining whether to // emit the relocation as an explicit symbol or as a section relative // offset -unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { - return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx); +unsigned ARMELFObjectWriter::getRelocType(MCAssembler &Asm, + const MCReloc &Reloc) const { + MCContext &Ctx = Asm.getContext(); + bool IsPCRel = Asm.getBackend().getFixupKindInfo(Reloc.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; + return GetRelocTypeInner(Reloc, IsPCRel, Ctx); } -unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, - const MCFixup &Fixup, +unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCReloc &Fixup, bool IsPCRel, MCContext &Ctx) const { + const MCReloc &Target = Fixup; MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); if (IsPCRel) { @@ -83,6 +88,7 @@ default: Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol"); return ELF::R_ARM_NONE; + case FK_PCRel_4: case FK_Data_4: switch (Modifier) { default: @@ -115,12 +121,16 @@ case ARM::fixup_t2_uncondbranch: return ELF::R_ARM_THM_JUMP24; case ARM::fixup_arm_movt_hi16: + case ARM::fixup_arm_movt_hi16_pc: return ELF::R_ARM_MOVT_PREL; case ARM::fixup_arm_movw_lo16: + case ARM::fixup_arm_movw_lo16_pc: return ELF::R_ARM_MOVW_PREL_NC; case ARM::fixup_t2_movt_hi16: + case ARM::fixup_t2_movt_hi16_pc: return ELF::R_ARM_THM_MOVT_PREL; case ARM::fixup_t2_movw_lo16: + case ARM::fixup_t2_movw_lo16_pc: return ELF::R_ARM_THM_MOVW_PREL_NC; case ARM::fixup_arm_thumb_br: return ELF::R_ARM_THM_JUMP11; @@ -206,6 +216,7 @@ return ELF::R_ARM_MOVT_BREL; } case ARM::fixup_arm_movw_lo16: + case ARM::fixup_arm_movw_lo16_pc: switch (Modifier) { default: llvm_unreachable("Unsupported Modifier"); @@ -224,6 +235,7 @@ return ELF::R_ARM_THM_MOVT_BREL; } case ARM::fixup_t2_movw_lo16: + case ARM::fixup_t2_movw_lo16_pc: switch (Modifier) { default: llvm_unreachable("Unsupported Modifier"); Index: lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h +++ lib/Target/ARM/MCTargetDesc/ARMFixupKinds.h @@ -94,9 +94,16 @@ // The next two are for the movt/movw pair // the 16bit imm field are split into imm{15-12} and imm{11-0} fixup_arm_movt_hi16, // :upper16: + fixup_arm_movt_hi16_pc, + fixup_arm_movw_lo16, // :lower16: - fixup_t2_movt_hi16, // :upper16: - fixup_t2_movw_lo16, // :lower16: + fixup_arm_movw_lo16_pc, + + fixup_t2_movt_hi16, // :upper16: + fixup_t2_movt_hi16_pc, + + fixup_t2_movw_lo16, // :lower16: + fixup_t2_movw_lo16_pc, // Fixup for mod_imm fixup_arm_mod_imm, Index: lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp +++ lib/Target/ARM/MCTargetDesc/ARMMachObjectWriter.cpp @@ -12,6 +12,7 @@ #include "MCTargetDesc/ARMMCTargetDesc.h" #include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/MachO.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" @@ -29,18 +30,13 @@ void RecordARMScatteredRelocation(MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, - MCValue Target, - unsigned Type, - unsigned Log2Size, - uint64_t &FixedValue); + const MCFragment *Fragment, MCReloc &Reloc, + unsigned Type, unsigned Log2Size); void RecordARMScatteredHalfRelocation(MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue); + MCReloc &Reloc); bool requiresExternRelocation(MachObjectWriter *Writer, const MCAssembler &Asm, @@ -53,8 +49,7 @@ void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) override; + MCReloc &Reloc) override; }; } @@ -135,14 +130,11 @@ } } -void ARMMachObjectWriter:: -RecordARMScatteredHalfRelocation(MachObjectWriter *Writer, - const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, - MCValue Target, - uint64_t &FixedValue) { +void ARMMachObjectWriter::RecordARMScatteredHalfRelocation( + MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment *Fragment, MCReloc &Fixup) { + MCReloc &Target = Fixup; + uint64_t &FixedValue = Fixup.getConstant(); uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind()); unsigned Type = MachO::ARM_RELOC_HALF; @@ -161,21 +153,21 @@ uint32_t Value2 = 0; uint64_t SecAddr = Writer->getSectionAddress(A->getFragment()->getParent()); FixedValue += SecAddr; + FixedValue += Layout.getSymbolOffset(*A); - if (const MCSymbolRefExpr *B = Target.getSymB()) { - const MCSymbol *SB = &B->getSymbol(); - + if (const MCSymbol *SB = Target.getSymB()) { if (!SB->getFragment()) { Asm.getContext().reportError(Fixup.getLoc(), - "symbol '" + B->getSymbol().getName() + + "symbol '" + SB->getName() + "' can not be undefined in a subtraction expression"); return; } // Select the appropriate difference relocation type. Type = MachO::ARM_RELOC_HALF_SECTDIFF; - Value2 = Writer->getSymbolAddress(B->getSymbol(), Layout); + Value2 = Writer->getSymbolAddress(*SB, Layout); FixedValue -= Writer->getSectionAddress(SB->getFragment()->getParent()); + FixedValue -= Layout.getSymbolOffset(*SB); } // Relocations are written out in reverse order, so the PAIR comes first. @@ -240,15 +232,12 @@ Writer->addRelocation(nullptr, Fragment->getParent(), MRE); } -void ARMMachObjectWriter::RecordARMScatteredRelocation(MachObjectWriter *Writer, - const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, - MCValue Target, - unsigned Type, - unsigned Log2Size, - uint64_t &FixedValue) { +void ARMMachObjectWriter::RecordARMScatteredRelocation( + MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment *Fragment, MCReloc &Fixup, unsigned Type, + unsigned Log2Size) { + MCReloc &Target = Fixup; + uint64_t &FixedValue = Fixup.getConstant(); uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind()); @@ -267,20 +256,18 @@ FixedValue += SecAddr; uint32_t Value2 = 0; - if (const MCSymbolRefExpr *B = Target.getSymB()) { + if (const MCSymbol *SB = Target.getSymB()) { assert(Type == MachO::ARM_RELOC_VANILLA && "invalid reloc for 2 symbols"); - const MCSymbol *SB = &B->getSymbol(); - if (!SB->getFragment()) { Asm.getContext().reportError(Fixup.getLoc(), - "symbol '" + B->getSymbol().getName() + + "symbol '" + SB->getName() + "' can not be undefined in a subtraction expression"); return; } // Select the appropriate difference relocation type. Type = MachO::ARM_RELOC_SECTDIFF; - Value2 = Writer->getSymbolAddress(B->getSymbol(), Layout); + Value2 = Writer->getSymbolAddress(*SB, Layout); FixedValue -= Writer->getSectionAddress(SB->getFragment()->getParent()); } @@ -349,8 +336,9 @@ MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) { + MCReloc &Fixup) { + MCReloc &Target = Fixup; + uint64_t &FixedValue = Fixup.getConstant(); unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind()); unsigned Log2Size; unsigned RelocType = MachO::ARM_RELOC_VANILLA; @@ -370,10 +358,9 @@ if (Target.getSymB()) { if (RelocType == MachO::ARM_RELOC_HALF) return RecordARMScatteredHalfRelocation(Writer, Asm, Layout, Fragment, - Fixup, Target, FixedValue); + Fixup); return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup, - Target, RelocType, Log2Size, - FixedValue); + RelocType, Log2Size); } // Get the symbol data, if any. @@ -392,8 +379,7 @@ if (Offset && A && !Writer->doesSymbolRequireExternRelocation(*A) && RelocType != MachO::ARM_RELOC_HALF) return RecordARMScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup, - Target, RelocType, Log2Size, - FixedValue); + RelocType, Log2Size); // See . uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); @@ -431,9 +417,15 @@ const MCSection &Sec = A->getSection(); Index = Sec.getOrdinal() + 1; FixedValue += Writer->getSectionAddress(&Sec); + FixedValue += Layout.getSymbolOffset(*A); + } + if (IsPCRel) { + uint32_t Offset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); + if (Asm.getBackend().getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits) + Offset &= ~0x3; + FixedValue -= Writer->getSectionAddress(Fragment->getParent()) + Offset; } - if (IsPCRel) - FixedValue -= Writer->getSectionAddress(Fragment->getParent()); // The type is determined by the fixup kind. Type = RelocType; Index: lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp +++ lib/Target/ARM/MCTargetDesc/ARMWinCOFFObjectWriter.cpp @@ -33,20 +33,20 @@ ~ARMWinCOFFObjectWriter() override = default; - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsCrossSection, + unsigned getRelocType(MCContext &Ctx, const MCReloc &Reloc, + bool IsCrossSection, const MCAsmBackend &MAB) const override; - bool recordRelocation(const MCFixup &) const override; + bool recordRelocation(const MCReloc &) const override; }; } // end anonymous namespace -unsigned ARMWinCOFFObjectWriter::getRelocType(MCContext &Ctx, - const MCValue &Target, - const MCFixup &Fixup, +unsigned ARMWinCOFFObjectWriter::getRelocType(MCContext &Context, + const MCReloc &Fixup, bool IsCrossSection, const MCAsmBackend &MAB) const { + const MCReloc &Target = Fixup; assert(getMachine() == COFF::IMAGE_FILE_MACHINE_ARMNT && "AArch64 support not yet implemented"); @@ -84,7 +84,7 @@ } } -bool ARMWinCOFFObjectWriter::recordRelocation(const MCFixup &Fixup) const { +bool ARMWinCOFFObjectWriter::recordRelocation(const MCReloc &Fixup) const { return static_cast(Fixup.getKind()) != ARM::fixup_t2_movt_hi16; } Index: lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp =================================================================== --- lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp +++ lib/Target/BPF/MCTargetDesc/BPFAsmBackend.cpp @@ -27,15 +27,13 @@ : MCAsmBackend(), IsLittleEndian(IsLittleEndian) {} ~BPFAsmBackend() override = default; - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t Value, bool IsResolved) const override; + void applyFixup(const MCAssembler &Asm, const MCReloc &Reloc, + MutableArrayRef Data, bool IsResolved) const override; MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override; // No instruction requires relaxation - bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, - const MCRelaxableFragment *DF, + bool fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override { return false; } @@ -62,10 +60,9 @@ return true; } -void BPFAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, - MutableArrayRef Data, uint64_t Value, - bool IsResolved) const { +void BPFAsmBackend::applyFixup(const MCAssembler &Asm, const MCReloc &Fixup, + MutableArrayRef Data, bool IsResolved) const { + uint64_t Value = Fixup.getConstant(); if (Fixup.getKind() == FK_SecRel_4 || Fixup.getKind() == FK_SecRel_8) { assert(Value == 0); } else if (Fixup.getKind() == FK_Data_4 || Fixup.getKind() == FK_Data_8) { Index: lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp =================================================================== --- lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp +++ lib/Target/BPF/MCTargetDesc/BPFELFObjectWriter.cpp @@ -24,8 +24,7 @@ ~BPFELFObjectWriter() override = default; protected: - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const override; + unsigned getRelocType(MCAssembler &Asm, const MCReloc &Reloc) const override; }; } // end anonymous namespace @@ -34,9 +33,8 @@ : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_BPF, /*HasRelocationAddend*/ false) {} -unsigned BPFELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { +unsigned BPFELFObjectWriter::getRelocType(MCAssembler &Asm, + const MCReloc &Fixup) const { // determine the type of the relocation switch ((unsigned)Fixup.getKind()) { default: Index: lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp =================================================================== --- lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp +++ lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp @@ -410,10 +410,9 @@ /// ApplyFixup - Apply the \arg Value for given \arg Fixup into the provided /// data fragment, at the offset specified by the fixup and following the /// fixup kind as appropriate. - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t FixupValue, bool IsResolved) const override { - + void applyFixup(const MCAssembler &Asm, const MCReloc &Fixup, + MutableArrayRef Data, bool IsResolved) const override { + uint64_t FixupValue = Fixup.getConstant(); // When FixupValue is 0 the relocation is external and there // is nothing for us to do. if (!FixupValue) return; @@ -567,10 +566,10 @@ /// fixupNeedsRelaxation - Target specific predicate for whether a given /// fixup requires the associated instruction to be relaxed. - bool fixupNeedsRelaxationAdvanced(const MCFixup &Fixup, bool Resolved, - uint64_t Value, + bool fixupNeedsRelaxationAdvanced(const MCReloc &Fixup, bool Resolved, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override { + uint64_t Value = Fixup.getConstant(); MCInst const &MCB = DF->getInst(); assert(HexagonMCInstrInfo::isBundle(MCB)); @@ -643,8 +642,7 @@ } /// Simple predicate for targets where !Resolved implies requiring relaxation - bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, - const MCRelaxableFragment *DF, + bool fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override { llvm_unreachable("Handled by fixupNeedsRelaxationAdvanced"); } Index: lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp =================================================================== --- lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp +++ lib/Target/Hexagon/MCTargetDesc/HexagonELFObjectWriter.cpp @@ -9,8 +9,10 @@ #include "Hexagon.h" #include "MCTargetDesc/HexagonFixupKinds.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCELFObjectWriter.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -29,8 +31,7 @@ public: HexagonELFObjectWriter(uint8_t OSABI, StringRef C); - unsigned getRelocType(MCContext &Ctx, MCValue const &Target, - MCFixup const &Fixup, bool IsPCRel) const override; + unsigned getRelocType(MCAssembler &Asm, const MCReloc &Reloc) const override; }; } @@ -39,10 +40,11 @@ /*HasRelocationAddend*/ true), CPU(C) {} -unsigned HexagonELFObjectWriter::getRelocType(MCContext &Ctx, - MCValue const &Target, - MCFixup const &Fixup, - bool IsPCRel) const { +unsigned HexagonELFObjectWriter::getRelocType(MCAssembler &Asm, + const MCReloc &Fixup) const { + const MCReloc &Target = Fixup; + bool IsPCRel = Asm.getBackend().getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; MCSymbolRefExpr::VariantKind Variant = Target.getAccessVariant(); switch ((unsigned)Fixup.getKind()) { default: Index: lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp =================================================================== --- lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp +++ lib/Target/Lanai/MCTargetDesc/LanaiAsmBackend.cpp @@ -49,14 +49,13 @@ LanaiAsmBackend(const Target &T, Triple::OSType OST) : MCAsmBackend(), OSType(OST) {} - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t Value, bool IsResolved) const override; + void applyFixup(const MCAssembler &Asm, const MCReloc &Reloc, + MutableArrayRef Data, bool IsResolved) const override; MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override; // No instruction requires relaxation - bool fixupNeedsRelaxation(const MCFixup & /*Fixup*/, uint64_t /*Value*/, + bool fixupNeedsRelaxation(const MCReloc & /*Reloc*/, const MCRelaxableFragment * /*DF*/, const MCAsmLayout & /*Layout*/) const override { return false; @@ -89,11 +88,10 @@ return true; } -void LanaiAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, - MutableArrayRef Data, uint64_t Value, - bool /*IsResolved*/) const { +void LanaiAsmBackend::applyFixup(const MCAssembler &Asm, const MCReloc &Fixup, + MutableArrayRef Data, bool IsResolved) const { MCFixupKind Kind = Fixup.getKind(); + uint64_t Value = Fixup.getConstant(); Value = adjustFixupValue(static_cast(Kind), Value); if (!Value) Index: lib/Target/Lanai/MCTargetDesc/LanaiELFObjectWriter.cpp =================================================================== --- lib/Target/Lanai/MCTargetDesc/LanaiELFObjectWriter.cpp +++ lib/Target/Lanai/MCTargetDesc/LanaiELFObjectWriter.cpp @@ -24,8 +24,7 @@ ~LanaiELFObjectWriter() override = default; protected: - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const override; + unsigned getRelocType(MCAssembler &Asm, const MCReloc &Reloc) const override; bool needsRelocateWithSymbol(const MCSymbol &SD, unsigned Type) const override; }; @@ -36,10 +35,8 @@ : MCELFObjectTargetWriter(/*Is64Bit_=*/false, OSABI, ELF::EM_LANAI, /*HasRelocationAddend=*/true) {} -unsigned LanaiELFObjectWriter::getRelocType(MCContext & /*Ctx*/, - const MCValue & /*Target*/, - const MCFixup &Fixup, - bool /*IsPCRel*/) const { +unsigned LanaiELFObjectWriter::getRelocType(MCAssembler & /*Asm*/, + const MCReloc &Fixup) const { unsigned Type; unsigned Kind = static_cast(Fixup.getKind()); switch (Kind) { Index: lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h +++ lib/Target/Mips/MCTargetDesc/MipsAsmBackend.h @@ -38,9 +38,8 @@ MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override; - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t Value, bool IsResolved) const override; + void applyFixup(const MCAssembler &Asm, const MCReloc &Reloc, + MutableArrayRef Data, bool IsResolved) const override; Optional getFixupKind(StringRef Name) const override; const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; @@ -62,9 +61,8 @@ /// fixupNeedsRelaxation - Target specific predicate for whether a given /// fixup requires the associated instruction to be relaxed. - bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, - const MCRelaxableFragment *DF, - const MCAsmLayout &Layout) const override { + bool fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, + const MCAsmLayout &Layout) const override { // FIXME. llvm_unreachable("RelaxInstruction() unimplemented"); return false; Index: lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp +++ lib/Target/Mips/MCTargetDesc/MipsAsmBackend.cpp @@ -33,9 +33,8 @@ using namespace llvm; // Prepare value for the target space for it -static unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value, +static unsigned adjustFixupValue(const MCReloc &Fixup, uint64_t Value, MCContext &Ctx) { - unsigned Kind = Fixup.getKind(); // Add/subtract and shift @@ -64,6 +63,7 @@ case FK_TPRel_4: case FK_TPRel_8: case FK_GPRel_4: + case FK_PCRel_4: case FK_Data_4: case FK_Data_8: case Mips::fixup_Mips_SUB: @@ -235,12 +235,11 @@ /// ApplyFixup - Apply the \p Value for given \p Fixup into the provided /// data fragment, at the offset specified by the fixup and following the /// fixup kind as appropriate. -void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, - MutableArrayRef Data, uint64_t Value, - bool IsResolved) const { +void MipsAsmBackend::applyFixup(const MCAssembler &Asm, const MCReloc &Fixup, + MutableArrayRef Data, bool IsResolved) const { MCFixupKind Kind = Fixup.getKind(); MCContext &Ctx = Asm.getContext(); + uint64_t Value = Fixup.getConstant(); Value = adjustFixupValue(Fixup, Value, Ctx); if (!Value) Index: lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp +++ lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp @@ -11,8 +11,11 @@ #include "MCTargetDesc/MipsMCTargetDesc.h" #include "llvm/ADT/STLExtras.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCSymbolELF.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" @@ -60,8 +63,7 @@ ~MipsELFObjectWriter() override = default; - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const override; + unsigned getRelocType(MCAssembler &Asm, const MCReloc &Reloc) const override; bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const override; void sortRelocs(const MCAssembler &Asm, @@ -215,10 +217,11 @@ /*HasRelocationAddend*/ _isN64, /*IsN64*/ _isN64) {} -unsigned MipsELFObjectWriter::getRelocType(MCContext &Ctx, - const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { +unsigned MipsELFObjectWriter::getRelocType(MCAssembler &Asm, + const MCReloc &Fixup) const { + bool IsPCRel = Asm.getBackend().getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; + // Determine the type of the relocation. unsigned Kind = (unsigned)Fixup.getKind(); @@ -226,9 +229,11 @@ case Mips::fixup_Mips_NONE: return ELF::R_MIPS_NONE; case Mips::fixup_Mips_16: + case FK_PCRel_2: case FK_Data_2: return IsPCRel ? ELF::R_MIPS_PC16 : ELF::R_MIPS_16; case Mips::fixup_Mips_32: + case FK_PCRel_4: case FK_Data_4: return IsPCRel ? ELF::R_MIPS_PC32 : ELF::R_MIPS_32; } Index: lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp =================================================================== --- lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp +++ lib/Target/PowerPC/MCTargetDesc/PPCAsmBackend.cpp @@ -31,6 +31,7 @@ case FK_Data_1: case FK_Data_2: case FK_Data_4: + case FK_PCRel_4: case FK_Data_8: case PPC::fixup_ppc_nofixup: return Value; @@ -41,6 +42,7 @@ case PPC::fixup_ppc_br24abs: return Value & 0x3fffffc; case PPC::fixup_ppc_half16: + case PPC::fixup_ppc_half16_pc: return Value & 0xffff; case PPC::fixup_ppc_half16ds: return Value & 0xfffc; @@ -91,6 +93,7 @@ { "fixup_ppc_br24abs", 6, 24, 0 }, { "fixup_ppc_brcond14abs", 16, 14, 0 }, { "fixup_ppc_half16", 0, 16, 0 }, + { "fixup_ppc_half16_pc", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_ppc_half16ds", 0, 14, 0 }, { "fixup_ppc_nofixup", 0, 0, 0 } }; @@ -101,6 +104,7 @@ { "fixup_ppc_br24abs", 2, 24, 0 }, { "fixup_ppc_brcond14abs", 2, 14, 0 }, { "fixup_ppc_half16", 0, 16, 0 }, + { "fixup_ppc_half16_pc", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, { "fixup_ppc_half16ds", 2, 14, 0 }, { "fixup_ppc_nofixup", 0, 0, 0 } }; @@ -113,9 +117,20 @@ return (IsLittleEndian? InfosLE : InfosBE)[Kind - FirstTargetFixupKind]; } - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t Value, bool IsResolved) const override { + MCFixupKind getPCRelKind(MCFixupKind Kind) const override { + switch ((unsigned)Kind) { + case PPC::fixup_ppc_half16ds: + report_fatal_error("Invalid PC-relative half16ds relocation"); + case PPC::fixup_ppc_half16: + return (MCFixupKind)PPC::fixup_ppc_half16_pc; + default: + return MCAsmBackend::getPCRelKind(Kind); + } + } + + void applyFixup(const MCAssembler &Asm, const MCReloc &Fixup, + MutableArrayRef Data, bool IsResolved) const override { + uint64_t Value = Fixup.getConstant(); Value = adjustFixupValue(Fixup.getKind(), Value); if (!Value) return; // Doesn't change encoding. @@ -160,9 +175,7 @@ return false; } - bool fixupNeedsRelaxation(const MCFixup &Fixup, - uint64_t Value, - const MCRelaxableFragment *DF, + bool fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override { // FIXME. llvm_unreachable("relaxInstruction() unimplemented"); Index: lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp =================================================================== --- lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp +++ lib/Target/PowerPC/MCTargetDesc/PPCELFObjectWriter.cpp @@ -11,8 +11,11 @@ #include "MCTargetDesc/PPCMCExpr.h" #include "MCTargetDesc/PPCMCTargetDesc.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCSymbolELF.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" @@ -25,8 +28,8 @@ PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI); protected: - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const override; + unsigned getRelocType(MCAssembler &Asm, + const MCReloc &Reloc) const override; bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const override; @@ -38,8 +41,8 @@ Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC, /*HasRelocationAddend*/ true) {} -static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target, - const MCFixup &Fixup) { +static MCSymbolRefExpr::VariantKind getAccessVariant(const MCReloc &Fixup) { + const MCReloc &Target = Fixup; const MCExpr *Expr = Fixup.getValue(); if (Expr->getKind() != MCExpr::Target) @@ -66,10 +69,11 @@ llvm_unreachable("unknown PPCMCExpr kind"); } -unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { - MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup); +unsigned PPCELFObjectWriter::getRelocType(MCAssembler &Asm, + const MCReloc &Fixup) const { + MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Fixup); + bool IsPCRel = Asm.getBackend().getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; // determine the type of the relocation unsigned Type; @@ -97,6 +101,7 @@ Type = ELF::R_PPC_REL14; break; case PPC::fixup_ppc_half16: + case PPC::fixup_ppc_half16_pc: switch (Modifier) { default: llvm_unreachable("Unsupported Modifier"); case MCSymbolRefExpr::VK_None: @@ -113,10 +118,6 @@ break; } break; - case PPC::fixup_ppc_half16ds: - Target.print(errs()); - errs() << '\n'; - report_fatal_error("Invalid PC-relative half16ds relocation"); case FK_Data_4: case FK_PCRel_4: Type = ELF::R_PPC_REL32; Index: lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h =================================================================== --- lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h +++ lib/Target/PowerPC/MCTargetDesc/PPCFixupKinds.h @@ -33,6 +33,8 @@ /// 'li' or 'addis'. fixup_ppc_half16, + fixup_ppc_half16_pc, + /// A 14-bit fixup corresponding to lo16(_foo) with implied 2 zero bits for /// instrs like 'std'. fixup_ppc_half16ds, Index: lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp =================================================================== --- lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp +++ lib/Target/PowerPC/MCTargetDesc/PPCMachObjectWriter.cpp @@ -27,14 +27,12 @@ bool recordScatteredRelocation(MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - unsigned Log2Size, uint64_t &FixedValue); + const MCFragment *Fragment, MCReloc &Reloc, + unsigned Log2Size); void RecordPPCRelocation(MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCFixup &Fixup, - MCValue Target, uint64_t &FixedValue); + const MCFragment *Fragment, MCReloc &Reloc); public: PPCMachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype) @@ -42,13 +40,11 @@ void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) override { + MCReloc &Reloc) override { if (Writer->is64Bit()) { report_fatal_error("Relocation emission for MachO/PPC64 unimplemented."); } else - RecordPPCRelocation(Writer, Asm, Layout, Fragment, Fixup, Target, - FixedValue); + RecordPPCRelocation(Writer, Asm, Layout, Fragment, Reloc); } }; } @@ -80,10 +76,10 @@ /// Translates generic PPC fixup kind to Mach-O/PPC relocation type enum. /// Outline based on PPCELFObjectWriter::getRelocType(). -static unsigned getRelocType(const MCValue &Target, - const MCFixupKind FixupKind, // from - // Fixup.getKind() +static unsigned getRelocType(const MCReloc &Reloc, const bool IsPCRel) { + const MCFixupKind FixupKind = Reloc.getKind(); + const MCReloc &Target = Reloc; const MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); @@ -175,7 +171,7 @@ /// Compute fixup offset (address). static uint32_t getFixupOffset(const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup) { + const MCReloc &Fixup) { uint32_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); // On Mach-O, ppc_fixup_half16 relocations must refer to the // start of the instruction, not the second halfword, as ELF does @@ -190,13 +186,14 @@ /// and ARMMachObjectWriter::recordScatteredRelocation bool PPCMachObjectWriter::recordScatteredRelocation( MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, - unsigned Log2Size, uint64_t &FixedValue) { + const MCFragment *Fragment, MCReloc &Fixup, unsigned Log2Size) { // caller already computes these, can we just pass and reuse? + const MCReloc &Target = Fixup; + uint64_t &FixedValue = Fixup.getConstant(); const uint32_t FixupOffset = getFixupOffset(Layout, Fragment, Fixup); const MCFixupKind FK = Fixup.getKind(); const unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, FK); - const unsigned Type = getRelocType(Target, FK, IsPCRel); + const unsigned Type = getRelocType(Fixup, IsPCRel); // Is this a local or SECTDIFF relocation entry? // SECTDIFF relocation entries have symbol subtractions, @@ -213,11 +210,10 @@ uint32_t Value = Writer->getSymbolAddress(*A, Layout); uint64_t SecAddr = Writer->getSectionAddress(A->getFragment()->getParent()); FixedValue += SecAddr; + FixedValue += Layout.getSymbolOffset(*A); uint32_t Value2 = 0; - if (const MCSymbolRefExpr *B = Target.getSymB()) { - const MCSymbol *SB = &B->getSymbol(); - + if (const MCSymbol *SB = Target.getSymB()) { if (!SB->getFragment()) report_fatal_error("symbol '" + SB->getName() + "' can not be undefined in a subtraction expression"); @@ -225,6 +221,7 @@ // FIXME: is Type correct? see include/llvm/BinaryFormat/MachO.h Value2 = Writer->getSymbolAddress(*SB, Layout); FixedValue -= Writer->getSectionAddress(SB->getFragment()->getParent()); + FixedValue -= Layout.getSymbolOffset(*SB); } // FIXME: does FixedValue get used?? @@ -298,14 +295,17 @@ } // see PPCELFObjectWriter for a general outline of cases -void PPCMachObjectWriter::RecordPPCRelocation( - MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) { +void PPCMachObjectWriter::RecordPPCRelocation(MachObjectWriter *Writer, + const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + MCReloc &Fixup) { + const MCReloc &Target = Fixup; + uint64_t &FixedValue = Fixup.getConstant(); const MCFixupKind FK = Fixup.getKind(); // unsigned const unsigned Log2Size = getFixupKindLog2Size(FK); const bool IsPCRel = Writer->isFixupKindPCRel(Asm, FK); - const unsigned RelocType = getRelocType(Target, FK, IsPCRel); + const unsigned RelocType = getRelocType(Fixup, IsPCRel); // If this is a difference or a defined symbol plus an offset, then we need a // scattered relocation entry. Differences always require scattered @@ -314,8 +314,7 @@ // Q: are branch targets ever scattered? RelocType != MachO::PPC_RELOC_BR24 && RelocType != MachO::PPC_RELOC_BR14) { - recordScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup, Target, - Log2Size, FixedValue); + recordScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup, Log2Size); return; } Index: lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp @@ -32,14 +32,12 @@ : MCAsmBackend(), OSABI(OSABI), Is64Bit(Is64Bit) {} ~RISCVAsmBackend() override {} - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t Value, bool IsResolved) const override; + void applyFixup(const MCAssembler &Asm, const MCReloc &Reloc, + MutableArrayRef Data, bool IsResolved) const override; MCObjectWriter *createObjectWriter(raw_pwrite_stream &OS) const override; - bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, - const MCRelaxableFragment *DF, + bool fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override { return false; } @@ -70,10 +68,8 @@ return true; } -void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, - MutableArrayRef Data, uint64_t Value, - bool IsResolved) const { +void RISCVAsmBackend::applyFixup(const MCAssembler &Asm, const MCReloc &Reloc, + MutableArrayRef Data, bool IsResolved) const { return; } Index: lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp =================================================================== --- lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp +++ lib/Target/RISCV/MCTargetDesc/RISCVELFObjectWriter.cpp @@ -22,8 +22,7 @@ ~RISCVELFObjectWriter() override; protected: - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const override; + unsigned getRelocType(MCAssembler &Asm, const MCReloc &Reloc) const override; }; } @@ -33,10 +32,8 @@ RISCVELFObjectWriter::~RISCVELFObjectWriter() {} -unsigned RISCVELFObjectWriter::getRelocType(MCContext &Ctx, - const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { +unsigned RISCVELFObjectWriter::getRelocType(MCAssembler &Asm, + const MCReloc &Reloc) const { llvm_unreachable("invalid fixup kind!"); } Index: lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp =================================================================== --- lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp +++ lib/Target/Sparc/MCTargetDesc/SparcAsmBackend.cpp @@ -240,8 +240,7 @@ /// fixupNeedsRelaxation - Target specific predicate for whether a given /// fixup requires the associated instruction to be relaxed. - bool fixupNeedsRelaxation(const MCFixup &Fixup, - uint64_t Value, + bool fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override { // FIXME. @@ -273,10 +272,9 @@ ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) : SparcAsmBackend(T), OSType(OSType) { } - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t Value, bool IsResolved) const override { - + void applyFixup(const MCAssembler &Asm, const MCReloc &Fixup, + MutableArrayRef Data, bool IsResolved) const override { + uint64_t Value = Fixup.getConstant(); Value = adjustFixupValue(Fixup.getKind(), Value); if (!Value) return; // Doesn't change encoding. Index: lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp =================================================================== --- lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp +++ lib/Target/Sparc/MCTargetDesc/SparcELFObjectWriter.cpp @@ -11,8 +11,11 @@ #include "MCTargetDesc/SparcMCExpr.h" #include "MCTargetDesc/SparcMCTargetDesc.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" @@ -29,8 +32,8 @@ ~SparcELFObjectWriter() override {} protected: - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const override; + unsigned getRelocType(MCAssembler &Asm, + const MCReloc &Reloc) const override; bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const override; @@ -38,10 +41,10 @@ }; } -unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx, - const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { +unsigned SparcELFObjectWriter::getRelocType(MCAssembler &Asm, + const MCReloc &Fixup) const { + bool IsPCRel = Asm.getBackend().getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; if (const SparcMCExpr *SExpr = dyn_cast(Fixup.getValue())) { if (SExpr->getKind() == SparcMCExpr::VK_Sparc_R_DISP32) Index: lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp =================================================================== --- lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp +++ lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp @@ -50,13 +50,12 @@ return SystemZ::NumTargetFixupKinds; } const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override; - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t Value, bool IsResolved) const override; + void applyFixup(const MCAssembler &Asm, const MCReloc &Reloc, + MutableArrayRef Data, bool IsResolved) const override; bool mayNeedRelaxation(const MCInst &Inst) const override { return false; } - bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, + bool fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *Fragment, const MCAsmLayout &Layout) const override { return false; @@ -91,10 +90,9 @@ } void SystemZMCAsmBackend::applyFixup(const MCAssembler &Asm, - const MCFixup &Fixup, - const MCValue &Target, - MutableArrayRef Data, uint64_t Value, - bool IsResolved) const { + const MCReloc &Fixup, + MutableArrayRef Data, bool IsResolved) const { + uint64_t Value = Fixup.getConstant(); MCFixupKind Kind = Fixup.getKind(); unsigned Offset = Fixup.getOffset(); unsigned BitSize = getFixupKindInfo(Kind).TargetSize; Index: lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp =================================================================== --- lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp +++ lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp @@ -10,9 +10,12 @@ #include "MCTargetDesc/SystemZMCFixups.h" #include "MCTargetDesc/SystemZMCTargetDesc.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCAsmBackend.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" #include @@ -29,8 +32,7 @@ protected: // Override MCELFObjectTargetWriter. - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const override; + unsigned getRelocType(MCAssembler &Asm, const MCReloc &Reloc) const override; }; } // end anonymous namespace @@ -54,8 +56,10 @@ static unsigned getPCRelReloc(unsigned Kind) { switch (Kind) { case FK_Data_2: return ELF::R_390_PC16; + case FK_PCRel_4: return ELF::R_390_PC32; case FK_Data_4: return ELF::R_390_PC32; case FK_Data_8: return ELF::R_390_PC64; + case FK_PCRel_8: return ELF::R_390_PC64; case SystemZ::FK_390_PC12DBL: return ELF::R_390_PC12DBL; case SystemZ::FK_390_PC16DBL: return ELF::R_390_PC16DBL; case SystemZ::FK_390_PC24DBL: return ELF::R_390_PC24DBL; @@ -113,10 +117,11 @@ llvm_unreachable("Unsupported absolute address"); } -unsigned SystemZObjectWriter::getRelocType(MCContext &Ctx, - const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { +unsigned SystemZObjectWriter::getRelocType(MCAssembler &Asm, + const MCReloc &Fixup) const { + const MCReloc &Target = Fixup; + bool IsPCRel = Asm.getBackend().getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); unsigned Kind = Fixup.getKind(); switch (Modifier) { Index: lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -108,9 +108,26 @@ return Infos[Kind - FirstTargetFixupKind]; } - void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup, - const MCValue &Target, MutableArrayRef Data, - uint64_t Value, bool IsResolved) const override { + MCFixupKind getPCRelKind(MCFixupKind Kind) const override { + switch ((unsigned)Kind) { + case X86::reloc_signed_4byte: + return FK_PCRel_4; + + // The handling of reloc_global_offset_table is a hack. We accept + // things like "subl _GLOBAL_OFFSET_TABLE_-bar2", so this + // makes the expression always pcrel. + case X86::reloc_global_offset_table: + return (MCFixupKind)X86::reloc_global_offset_table; + case X86::reloc_global_offset_table8: + return (MCFixupKind)X86::reloc_global_offset_table8; + default: + return MCAsmBackend::getPCRelKind(Kind); + } + } + + void applyFixup(const MCAssembler &Asm, const MCReloc &Fixup, + MutableArrayRef Data, bool IsResolved) const override { + uint64_t Value = Fixup.getConstant(); unsigned Size = 1 << getFixupKindLog2Size(Fixup.getKind()); assert(Fixup.getOffset() + Size <= Data.size() && "Invalid fixup offset!"); @@ -128,8 +145,7 @@ bool mayNeedRelaxation(const MCInst &Inst) const override; - bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value, - const MCRelaxableFragment *DF, + bool fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const override; void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI, @@ -292,10 +308,10 @@ return false; } -bool X86AsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, - uint64_t Value, +bool X86AsmBackend::fixupNeedsRelaxation(const MCReloc &Reloc, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const { + uint64_t Value = Reloc.getConstant(); // Relax if the value is too big for a (signed) i8. return int64_t(Value) != int64_t(int8_t(Value)); } Index: lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp +++ lib/Target/X86/MCTargetDesc/X86ELFObjectWriter.cpp @@ -10,11 +10,14 @@ #include "MCTargetDesc/X86FixupKinds.h" #include "MCTargetDesc/X86MCTargetDesc.h" #include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" #include @@ -30,8 +33,7 @@ ~X86ELFObjectWriter() override = default; protected: - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsPCRel) const override; + unsigned getRelocType(MCAssembler &Asm, const MCReloc &Reloc) const override; }; } // end anonymous namespace @@ -56,6 +58,7 @@ Modifier = MCSymbolRefExpr::VK_GOT; IsPCRel = true; return RT64_64; + case FK_PCRel_8: case FK_Data_8: return RT64_64; case X86::reloc_signed_4byte: @@ -283,12 +286,15 @@ } } -unsigned X86ELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, - bool IsPCRel) const { +unsigned X86ELFObjectWriter::getRelocType(MCAssembler &Asm, + const MCReloc &Fixup) const { + const MCReloc &Target = Fixup; MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); unsigned Kind = Fixup.getKind(); + bool IsPCRel = Asm.getBackend().getFixupKindInfo((MCFixupKind)Kind).Flags & + MCFixupKindInfo::FKF_IsPCRel; X86_64RelType Type = getType64(Kind, Modifier, IsPCRel); + MCContext &Ctx = Asm.getContext(); if (getEMachine() == ELF::EM_X86_64) return getRelocType64(Ctx, Fixup.getLoc(), Modifier, Type, IsPCRel, Kind); Index: lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp +++ lib/Target/X86/MCTargetDesc/X86MachObjectWriter.cpp @@ -28,30 +28,18 @@ bool recordScatteredRelocation(MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, - MCValue Target, - unsigned Log2Size, - uint64_t &FixedValue); - void recordTLVPRelocation(MachObjectWriter *Writer, - const MCAssembler &Asm, + const MCFragment *Fragment, MCReloc &Reloc, + unsigned Log2Size); + void recordTLVPRelocation(MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, - MCValue Target, - uint64_t &FixedValue); + const MCFragment *Fragment, MCReloc &Reloc); - void RecordX86Relocation(MachObjectWriter *Writer, - const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, - MCValue Target, - uint64_t &FixedValue); + void RecordX86Relocation(MachObjectWriter *Writer, const MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, MCReloc &Reloc); void RecordX86_64Relocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCFixup &Fixup, - MCValue Target, uint64_t &FixedValue); + const MCFragment *Fragment, MCReloc &Reloc); public: X86MachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype) @@ -59,14 +47,11 @@ void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) override { + MCReloc &Reloc) override { if (Writer->is64Bit()) - RecordX86_64Relocation(Writer, Asm, Layout, Fragment, Fixup, Target, - FixedValue); + RecordX86_64Relocation(Writer, Asm, Layout, Fragment, Reloc); else - RecordX86Relocation(Writer, Asm, Layout, Fragment, Fixup, Target, - FixedValue); + RecordX86Relocation(Writer, Asm, Layout, Fragment, Reloc); } }; } @@ -99,10 +84,13 @@ } } -void X86MachObjectWriter::RecordX86_64Relocation( - MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, - const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, - uint64_t &FixedValue) { +void X86MachObjectWriter::RecordX86_64Relocation(MachObjectWriter *Writer, + MCAssembler &Asm, + const MCAsmLayout &Layout, + const MCFragment *Fragment, + MCReloc &Fixup) { + const MCReloc &Target = Fixup; + uint64_t &FixedValue = Fixup.getConstant(); unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind()); unsigned IsRIPRel = isFixupKindRIPRel(Fixup.getKind()); unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); @@ -147,7 +135,7 @@ A = &Writer->findAliasedSymbol(*A); const MCSymbol *A_Base = Asm.getAtom(*A); - const MCSymbol *B = &Target.getSymB()->getSymbol(); + const MCSymbol *B = Target.getSymB(); if (B->isTemporary()) B = &Writer->findAliasedSymbol(*B); const MCSymbol *B_Base = Asm.getAtom(*B); @@ -361,14 +349,11 @@ Writer->addRelocation(RelSymbol, Fragment->getParent(), MRE); } -bool X86MachObjectWriter::recordScatteredRelocation(MachObjectWriter *Writer, - const MCAssembler &Asm, - const MCAsmLayout &Layout, - const MCFragment *Fragment, - const MCFixup &Fixup, - MCValue Target, - unsigned Log2Size, - uint64_t &FixedValue) { +bool X86MachObjectWriter::recordScatteredRelocation( + MachObjectWriter *Writer, const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment *Fragment, MCReloc &Fixup, unsigned Log2Size) { + MCReloc &Target = Fixup; + uint64_t &FixedValue = Fixup.getConstant(); uint64_t OriginalFixedValue = FixedValue; uint32_t FixupOffset = Layout.getFragmentOffset(Fragment)+Fixup.getOffset(); unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind()); @@ -388,11 +373,10 @@ uint32_t Value = Writer->getSymbolAddress(*A, Layout); uint64_t SecAddr = Writer->getSectionAddress(A->getFragment()->getParent()); FixedValue += SecAddr; + FixedValue += Layout.getSymbolOffset(*A); uint32_t Value2 = 0; - if (const MCSymbolRefExpr *B = Target.getSymB()) { - const MCSymbol *SB = &B->getSymbol(); - + if (const MCSymbol *SB = Target.getSymB()) { if (!SB->getFragment()) { Asm.getContext().reportError( Fixup.getLoc(), @@ -410,6 +394,7 @@ : (unsigned)MachO::GENERIC_RELOC_LOCAL_SECTDIFF; Value2 = Writer->getSymbolAddress(*SB, Layout); FixedValue -= Writer->getSectionAddress(SB->getFragment()->getParent()); + FixedValue -= Layout.getSymbolOffset(*SB); } // Relocations are written out in reverse order, so the PAIR comes first. @@ -465,9 +450,9 @@ const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, - MCValue Target, - uint64_t &FixedValue) { + MCReloc &Fixup) { + MCReloc &Target = Fixup; + uint64_t &FixedValue = Fixup.getConstant(); const MCSymbolRefExpr *SymA = Target.getSymA(); assert(SymA->getKind() == MCSymbolRefExpr::VK_TLVP && !is64Bit() && "Should only be called with a 32-bit TLVP relocation!"); @@ -485,8 +470,7 @@ uint32_t FixupAddress = Writer->getFragmentAddress(Fragment, Layout) + Fixup.getOffset(); IsPCRel = 1; - FixedValue = FixupAddress - - Writer->getSymbolAddress(SymB->getSymbol(), Layout) + + FixedValue = FixupAddress - Writer->getSymbolAddress(*SymB, Layout) + Target.getConstant(); FixedValue += 1ULL << Log2Size; } else { @@ -505,17 +489,16 @@ const MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, - const MCFixup &Fixup, - MCValue Target, - uint64_t &FixedValue) { + MCReloc &Fixup) { + const MCReloc &Target = Fixup; + uint64_t &FixedValue = Fixup.getConstant(); unsigned IsPCRel = Writer->isFixupKindPCRel(Asm, Fixup.getKind()); unsigned Log2Size = getFixupKindLog2Size(Fixup.getKind()); // If this is a 32-bit TLVP reloc it's handled a bit differently. if (Target.getSymA() && Target.getSymA()->getKind() == MCSymbolRefExpr::VK_TLVP) { - recordTLVPRelocation(Writer, Asm, Layout, Fragment, Fixup, Target, - FixedValue); + recordTLVPRelocation(Writer, Asm, Layout, Fragment, Fixup); return; } @@ -523,8 +506,7 @@ // scattered relocation entry. Differences always require scattered // relocations. if (Target.getSymB()) { - recordScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup, - Target, Log2Size, FixedValue); + recordScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup, Log2Size); return; } @@ -542,8 +524,7 @@ // scattered if necessary (see comments in recordScatteredRelocation() // for details). if (Offset && A && !Writer->doesSymbolRequireExternRelocation(*A) && - recordScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup, Target, - Log2Size, FixedValue)) + recordScatteredRelocation(Writer, Asm, Layout, Fragment, Fixup, Log2Size)) return; // See . @@ -582,9 +563,11 @@ const MCSection &Sec = A->getSection(); Index = Sec.getOrdinal() + 1; FixedValue += Writer->getSectionAddress(&Sec); + FixedValue += Layout.getSymbolOffset(*A); } if (IsPCRel) - FixedValue -= Writer->getSectionAddress(Fragment->getParent()); + FixedValue -= Writer->getSectionAddress(Fragment->getParent()) + + Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); Type = MachO::GENERIC_RELOC_VANILLA; } Index: lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp =================================================================== --- lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp +++ lib/Target/X86/MCTargetDesc/X86WinCOFFObjectWriter.cpp @@ -26,8 +26,8 @@ X86WinCOFFObjectWriter(bool Is64Bit); ~X86WinCOFFObjectWriter() override = default; - unsigned getRelocType(MCContext &Ctx, const MCValue &Target, - const MCFixup &Fixup, bool IsCrossSection, + unsigned getRelocType(MCContext &Ctx, const MCReloc &Reloc, + bool IsCrossSection, const MCAsmBackend &MAB) const override; }; @@ -38,10 +38,10 @@ : COFF::IMAGE_FILE_MACHINE_I386) {} unsigned X86WinCOFFObjectWriter::getRelocType(MCContext &Ctx, - const MCValue &Target, - const MCFixup &Fixup, + const MCReloc &Fixup, bool IsCrossSection, const MCAsmBackend &MAB) const { + const MCReloc &Target = Fixup; unsigned FixupKind = Fixup.getKind(); if (IsCrossSection) { if (FixupKind != FK_Data_4 && FixupKind != llvm::X86::reloc_signed_4byte) {