summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorJames Y Knight <jyknight@google.com>2019-11-10 16:12:29 -0500
committerJames Y Knight <jyknight@google.com>2019-11-16 09:52:07 -0500
commitbf142fc43347d8a35a71f46f7dda7e2a0a992e0d (patch)
tree637c0d55792d11174365c5ffd6bd2d8f2d392990 /llvm/lib
parent5987cc1bb5d5eb624135e76a6b3ade1aef94caf7 (diff)
downloadbcm5719-llvm-bf142fc43347d8a35a71f46f7dda7e2a0a992e0d.tar.gz
bcm5719-llvm-bf142fc43347d8a35a71f46f7dda7e2a0a992e0d.zip
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
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/MCELFStreamer.cpp5
-rw-r--r--llvm/lib/MC/MCObjectStreamer.cpp20
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp3
3 files changed, 21 insertions, 7 deletions
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<MCSymbolELF>(S);
- MCObjectStreamer::EmitLabel(Symbol, Loc, F);
+ MCObjectStreamer::EmitLabelAtPos(Symbol, Loc, F, Offset);
const MCSectionELF &Section =
static_cast<const MCSectionELF &>(*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<MCDataFragment>(F);
- if (DF)
+ Symbol->setOffset(Offset);
+ if (DF) {
Symbol->setFragment(F);
- else
+ } else {
+ assert(isa<MCDummyFragment>(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<MCSymbolELF>(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 {
OpenPOWER on IntegriCloud