From bf142fc43347d8a35a71f46f7dda7e2a0a992e0d Mon Sep 17 00:00:00 2001 From: James Y Knight Date: Sun, 10 Nov 2019 16:12:29 -0500 Subject: MCObjectStreamer: assign MCSymbols in the dummy fragment to offset 0. In MCObjectStreamer, when there is no current fragment, initially symbols are created in a "pending" state and assigned to a dummy empty fragment. Previously, they were not being assigned an offset, and thus evaluateAbsolute would fail if trying to evaluate an expression 'a - b', where both 'a' and 'b' were in this pending state. Also slightly refactored the EmitLabel overload which takes an MCFragment for clarity. Fixes: https://llvm.org/PR41825 Differential Revision: https://reviews.llvm.org/D70062 --- llvm/lib/MC/MCELFStreamer.cpp | 5 +++-- llvm/lib/MC/MCObjectStreamer.cpp | 20 +++++++++++++++++--- llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp | 3 +-- 3 files changed, 21 insertions(+), 7 deletions(-) (limited to 'llvm/lib') diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index fa2133078bf..c2e2beb23cb 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -106,9 +106,10 @@ void MCELFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc) { Symbol->setType(ELF::STT_TLS); } -void MCELFStreamer::EmitLabel(MCSymbol *S, SMLoc Loc, MCFragment *F) { +void MCELFStreamer::EmitLabelAtPos(MCSymbol *S, SMLoc Loc, MCFragment *F, + uint64_t Offset) { auto *Symbol = cast(S); - MCObjectStreamer::EmitLabel(Symbol, Loc, F); + MCObjectStreamer::EmitLabelAtPos(Symbol, Loc, F, Offset); const MCSectionELF &Section = static_cast(*getCurrentSectionOnly()); diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 83f6ab8fe33..cc33810c7ec 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -243,18 +243,32 @@ void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) { Symbol->setFragment(F); Symbol->setOffset(F->getContents().size()); } else { + // Assign all pending labels to offset 0 within the dummy "pending" + // fragment. (They will all be reassigned to a real fragment in + // flushPendingLabels()) + Symbol->setOffset(0); PendingLabels.push_back(Symbol); } } -void MCObjectStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc, MCFragment *F) { +// Emit a label at a previously emitted fragment/offset position. This must be +// within the currently-active section. +void MCObjectStreamer::EmitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, + MCFragment *F, uint64_t Offset) { + assert(F->getParent() == getCurrentSectionOnly()); + MCStreamer::EmitLabel(Symbol, Loc); getAssembler().registerSymbol(*Symbol); auto *DF = dyn_cast_or_null(F); - if (DF) + Symbol->setOffset(Offset); + if (DF) { Symbol->setFragment(F); - else + } else { + assert(isa(F) && + "F must either be an MCDataFragment or the pending MCDummyFragment"); + assert(Offset == 0); PendingLabels.push_back(Symbol); + } } void MCObjectStreamer::EmitULEB128Value(const MCExpr *Value) { diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp index 01b98ccf897..f558ca8d2d9 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp @@ -659,11 +659,10 @@ private: uint64_t Offset) { auto *Symbol = cast(getContext().getOrCreateSymbol( Name + "." + Twine(MappingSymbolCounter++))); - EmitLabel(Symbol, Loc, F); + EmitLabelAtPos(Symbol, Loc, F, Offset); Symbol->setType(ELF::STT_NOTYPE); Symbol->setBinding(ELF::STB_LOCAL); Symbol->setExternal(false); - Symbol->setOffset(Offset); } void EmitThumbFunc(MCSymbol *Func) override { -- cgit v1.2.3