Index: include/llvm/MC/MCELFStreamer.h =================================================================== --- include/llvm/MC/MCELFStreamer.h +++ include/llvm/MC/MCELFStreamer.h @@ -62,8 +62,8 @@ SMLoc L = SMLoc()) override; void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment = 0) override; - void EmitValueImpl(const MCExpr *Value, unsigned Size, - SMLoc Loc = SMLoc()) override; + void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc = SMLoc(), + bool Fixed = false) override; void EmitIdent(StringRef IdentString) override; Index: include/llvm/MC/MCFixup.h =================================================================== --- include/llvm/MC/MCFixup.h +++ include/llvm/MC/MCFixup.h @@ -88,15 +88,20 @@ /// The source location which gave rise to the fixup, if any. SMLoc Loc; + + /// Require the MCAssembler to evaluate the fixup. + bool Fixed; + public: - static MCFixup create(uint32_t Offset, const MCExpr *Value, - MCFixupKind Kind, SMLoc Loc = SMLoc()) { + static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, + SMLoc Loc = SMLoc(), bool Fixed = false) { assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!"); MCFixup FI; FI.Value = Value; FI.Offset = Offset; FI.Kind = unsigned(Kind); FI.Loc = Loc; + FI.Fixed = Fixed; return FI; } @@ -129,6 +134,8 @@ const MCExpr *getValue() const { return Value; } + bool isFixed() const { return Fixed; } + /// Return the generic fixup kind for a value with the given size. It /// is an error to pass an unsupported size. static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) { Index: include/llvm/MC/MCObjectStreamer.h =================================================================== --- include/llvm/MC/MCObjectStreamer.h +++ include/llvm/MC/MCObjectStreamer.h @@ -109,8 +109,8 @@ void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override; virtual void EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F); void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) override; - void EmitValueImpl(const MCExpr *Value, unsigned Size, - SMLoc Loc = SMLoc()) override; + void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc = SMLoc(), + bool Fixed = false) override; void EmitULEB128Value(const MCExpr *Value) override; void EmitSLEB128Value(const MCExpr *Value) override; void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) override; Index: include/llvm/MC/MCStreamer.h =================================================================== --- include/llvm/MC/MCStreamer.h +++ include/llvm/MC/MCStreamer.h @@ -617,10 +617,12 @@ /// \param Size - The size of the integer (in bytes) to emit. This must /// match a native machine width. /// \param Loc - The location of the expression for error reporting. + /// \param Fixed - To evaluate \p Value to absolute value by MCAssembler. virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, - SMLoc Loc = SMLoc()); + SMLoc Loc = SMLoc(), bool Fixed = false); - void EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc = SMLoc()); + void EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc = SMLoc(), + bool Fixed = false); /// Special case of EmitValue that avoids the client having /// to pass in a MCExpr for constant integers. Index: include/llvm/MC/MCWasmStreamer.h =================================================================== --- include/llvm/MC/MCWasmStreamer.h +++ include/llvm/MC/MCWasmStreamer.h @@ -63,8 +63,8 @@ SMLoc Loc = SMLoc()) override; void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment = 0) override; - void EmitValueImpl(const MCExpr *Value, unsigned Size, - SMLoc Loc = SMLoc()) override; + void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc = SMLoc(), + bool Fixed = false) override; void EmitIdent(StringRef IdentString) override; Index: lib/MC/MCAsmStreamer.cpp =================================================================== --- lib/MC/MCAsmStreamer.cpp +++ lib/MC/MCAsmStreamer.cpp @@ -185,8 +185,8 @@ void EmitBytes(StringRef Data) override; - void EmitValueImpl(const MCExpr *Value, unsigned Size, - SMLoc Loc = SMLoc()) override; + void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc = SMLoc(), + bool Fixed = false) override; void EmitIntValue(uint64_t Value, unsigned Size) override; void EmitULEB128Value(const MCExpr *Value) override; @@ -922,8 +922,8 @@ EmitValue(MCConstantExpr::create(Value, getContext()), Size); } -void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, - SMLoc Loc) { +void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc, + bool Fixed) { assert(Size <= 8 && "Invalid size"); assert(getCurrentSectionOnly() && "Cannot emit contents before setting section!"); Index: lib/MC/MCDwarf.cpp =================================================================== --- lib/MC/MCDwarf.cpp +++ lib/MC/MCDwarf.cpp @@ -302,9 +302,10 @@ return MCSymbolRefExpr::create(ABS, Context); } -static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size) { +static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size, + bool Fixed = false) { const MCExpr *ABS = forceExpAbs(OS, Value); - OS.EmitValue(ABS, Size); + OS.EmitValue(ABS, Size, SMLoc(), Fixed); } void MCDwarfLineStr::emitSection(MCStreamer *MCOS) { @@ -463,7 +464,8 @@ // The first 4 bytes is the total length of the information for this // compilation unit (not including these 4 bytes for the length). emitAbsValue(*MCOS, - MakeStartMinusEndExpr(*MCOS, *LineStartSym, *LineEndSym, 4), 4); + MakeStartMinusEndExpr(*MCOS, *LineStartSym, *LineEndSym, 4), 4, + true); // Next 2 bytes is the Version. unsigned LineTableVersion = context.getDwarfVersion(); @@ -488,7 +490,7 @@ emitAbsValue(*MCOS, MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym, (PreHeaderLengthBytes + 4)), - 4); + 4, true); // Parameters of the state machine, are next. MCOS->EmitIntValue(context.getAsmInfo()->getMinInstAlignment(), 1); @@ -941,7 +943,7 @@ // The 4 byte total length of the information for this compilation unit, not // including these 4 bytes. const MCExpr *Length = MakeStartMinusEndExpr(*MCOS, *InfoStart, *InfoEnd, 4); - emitAbsValue(*MCOS, Length, 4); + emitAbsValue(*MCOS, Length, 4, true); // The 2 byte DWARF version. MCOS->EmitIntValue(context.getDwarfVersion(), 2); @@ -1570,7 +1572,7 @@ // Length const MCExpr *Length = MakeStartMinusEndExpr(Streamer, *sectionStart, *sectionEnd, 4); - emitAbsValue(Streamer, Length, 4); + emitAbsValue(Streamer, Length, 4, true); // CIE ID unsigned CIE_ID = IsEH ? 0 : -1; @@ -1686,7 +1688,7 @@ // Length const MCExpr *Length = MakeStartMinusEndExpr(Streamer, *fdeStart, *fdeEnd, 0); - emitAbsValue(Streamer, Length, 4); + emitAbsValue(Streamer, Length, 4, true); Streamer.EmitLabel(fdeStart); @@ -1695,11 +1697,11 @@ if (IsEH) { const MCExpr *offset = MakeStartMinusEndExpr(Streamer, cieStart, *fdeStart, 0); - emitAbsValue(Streamer, offset, 4); + emitAbsValue(Streamer, offset, 4, true); } else if (!asmInfo->doesDwarfUseRelocationsAcrossSections()) { const MCExpr *offset = MakeStartMinusEndExpr(Streamer, SectionStart, cieStart, 0); - emitAbsValue(Streamer, offset, 4); + emitAbsValue(Streamer, offset, 4, true); } else { Streamer.EmitSymbolValue(&cieStart, 4); } Index: lib/MC/MCELFStreamer.cpp =================================================================== --- lib/MC/MCELFStreamer.cpp +++ lib/MC/MCELFStreamer.cpp @@ -338,12 +338,12 @@ EmitCommonSymbol(Symbol, Size, ByteAlignment); } -void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, - SMLoc Loc) { +void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc, + bool Fixed) { if (isBundleLocked()) report_fatal_error("Emitting values inside a locked bundle is forbidden"); fixSymbolsInTLSFixups(Value); - MCObjectStreamer::EmitValueImpl(Value, Size, Loc); + MCObjectStreamer::EmitValueImpl(Value, Size, Loc, Fixed); } void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, Index: lib/MC/MCExpr.cpp =================================================================== --- lib/MC/MCExpr.cpp +++ lib/MC/MCExpr.cpp @@ -645,8 +645,9 @@ const MCAsmLayout *Layout, const MCFixup *Fixup) const { MCAssembler *Assembler = Layout ? &Layout->getAssembler() : nullptr; + bool Fixed = Fixup ? Fixup->isFixed() : false; return evaluateAsRelocatableImpl(Res, Assembler, Layout, Fixup, nullptr, - false); + Fixed); } bool MCExpr::evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const { Index: lib/MC/MCObjectStreamer.cpp =================================================================== --- lib/MC/MCObjectStreamer.cpp +++ lib/MC/MCObjectStreamer.cpp @@ -188,8 +188,8 @@ } void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, - SMLoc Loc) { - MCStreamer::EmitValueImpl(Value, Size, Loc); + SMLoc Loc, bool Fixed) { + MCStreamer::EmitValueImpl(Value, Size, Loc, Fixed); MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); @@ -208,7 +208,7 @@ } DF->getFixups().push_back( MCFixup::create(DF->getContents().size(), Value, - MCFixup::getKindForSize(Size, false), Loc)); + MCFixup::getKindForSize(Size, false), Loc, Fixed)); DF->getContents().resize(DF->getContents().size() + Size, 0); } Index: lib/MC/MCStreamer.cpp =================================================================== --- lib/MC/MCStreamer.cpp +++ lib/MC/MCStreamer.cpp @@ -156,8 +156,9 @@ EmitBytes(OSE.str()); } -void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) { - EmitValueImpl(Value, Size, Loc); +void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc, + bool Fixed) { + EmitValueImpl(Value, Size, Loc, Fixed); } void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, @@ -1020,7 +1021,8 @@ void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {} void MCStreamer::EmitBytes(StringRef Data) {} void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); } -void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) { +void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc, + bool Fixed) { visitUsedExpr(*Value); } void MCStreamer::EmitULEB128Value(const MCExpr *Value) {} Index: lib/MC/MCWasmStreamer.cpp =================================================================== --- lib/MC/MCWasmStreamer.cpp +++ lib/MC/MCWasmStreamer.cpp @@ -149,8 +149,8 @@ } void MCWasmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, - SMLoc Loc) { - MCObjectStreamer::EmitValueImpl(Value, Size, Loc); + SMLoc Loc, bool Fixed) { + MCObjectStreamer::EmitValueImpl(Value, Size, Loc, Fixed); } void MCWasmStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, Index: lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp =================================================================== --- lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp +++ lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp @@ -136,9 +136,10 @@ /// This is one of the functions used to emit data into an ELF section, so the /// AArch64 streamer overrides it to add the appropriate mapping symbol ($d) /// if necessary. - void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override { + void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc, + bool Fixed) override { EmitDataMappingSymbol(); - MCELFStreamer::EmitValueImpl(Value, Size, Loc); + MCELFStreamer::EmitValueImpl(Value, Size, Loc, Fixed); } void emitFill(const MCExpr &NumBytes, uint64_t FillValue, Index: lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp =================================================================== --- lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -553,7 +553,8 @@ /// This is one of the functions used to emit data into an ELF section, so the /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if /// necessary. - void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override { + void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc, + bool Fixed) override { if (const MCSymbolRefExpr *SRE = dyn_cast_or_null(Value)) { if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) { getContext().reportError(Loc, "relocated expression must be 32-bit"); @@ -563,7 +564,7 @@ } EmitDataMappingSymbol(); - MCELFStreamer::EmitValueImpl(Value, Size, Loc); + MCELFStreamer::EmitValueImpl(Value, Size, Loc, Fixed); } void EmitAssemblerFlag(MCAssemblerFlag Flag) override { Index: lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h +++ lib/Target/Mips/MCTargetDesc/MipsELFStreamer.h @@ -56,7 +56,8 @@ /// Overriding these functions allows us to dismiss all labels that are /// candidates for marking as microMIPS when .word/.long/.4byte etc /// directives are emitted. - void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override; + void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc, + bool Fixed) override; void EmitIntValue(uint64_t Value, unsigned Size) override; // Overriding these functions allows us to avoid recording of these labels Index: lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp =================================================================== --- lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp +++ lib/Target/Mips/MCTargetDesc/MipsELFStreamer.cpp @@ -97,8 +97,8 @@ } void MipsELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, - SMLoc Loc) { - MCELFStreamer::EmitValueImpl(Value, Size, Loc); + SMLoc Loc, bool Fixed) { + MCELFStreamer::EmitValueImpl(Value, Size, Loc, Fixed); Labels.clear(); } Index: test/DebugInfo/RISCV/relax-debug-frame.ll =================================================================== --- test/DebugInfo/RISCV/relax-debug-frame.ll +++ test/DebugInfo/RISCV/relax-debug-frame.ll @@ -2,10 +2,12 @@ ; RUN: | llvm-readobj -r | FileCheck -check-prefix=RELAX %s ; ; RELAX: .rela.{{eh|debug}}_frame { -; RELAX: R_RISCV_ADD32 -; RELAX: R_RISCV_SUB32 -; RELAX: R_RISCV_SET6 -; RELAX: R_RISCV_SUB6 +; RELAX-NOT: 0x0 R_RISCV_ADD32 +; RELAX-NOT: 0x0 R_RISCV_SUB32 +; RELAX: 0x20 R_RISCV_ADD32 +; RELAX: 0x20 R_RISCV_SUB32 +; RELAX: 0x25 R_RISCV_SET6 +; RELAX: 0x25 R_RISCV_SUB6 source_filename = "frame.c" ; Function Attrs: noinline nounwind optnone