aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/MCObjectStreamer.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2010-12-28 05:39:27 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2010-12-28 05:39:27 +0000
commit245a1e20419aa5a3c833d7a8e89168e19d5f4d2c (patch)
tree1a10fd4b3e598e4457f2db8f82f92f4a6b47186e /lib/MC/MCObjectStreamer.cpp
parent5bba08425374ca36fe5fbc7423ce1a09858e4097 (diff)
Relax address updates in the eh_frame section.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122591 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCObjectStreamer.cpp')
-rw-r--r--lib/MC/MCObjectStreamer.cpp49
1 files changed, 36 insertions, 13 deletions
diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp
index af102ecf78..b428e8747b 100644
--- a/lib/MC/MCObjectStreamer.cpp
+++ b/lib/MC/MCObjectStreamer.cpp
@@ -190,6 +190,28 @@ void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups());
}
+static const MCExpr *BuildSymbolDiff(MCContext &Context,
+ const MCSymbol *A, const MCSymbol *B) {
+ MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
+ const MCExpr *ARef =
+ MCSymbolRefExpr::Create(A, Variant, Context);
+ const MCExpr *BRef =
+ MCSymbolRefExpr::Create(B, Variant, Context);
+ const MCExpr *AddrDelta =
+ MCBinaryExpr::Create(MCBinaryExpr::Sub, ARef, BRef, Context);
+ return AddrDelta;
+}
+
+static const MCExpr *ForceExpAbs(MCObjectStreamer *Streamer,
+ MCContext &Context, const MCExpr* Expr) {
+ if (Context.getAsmInfo().hasAggressiveSymbolFolding())
+ return Expr;
+
+ MCSymbol *ABS = Context.CreateTempSymbol();
+ Streamer->EmitAssignment(ABS, Expr);
+ return MCSymbolRefExpr::Create(ABS, Context);
+}
+
void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
const MCSymbol *LastLabel,
const MCSymbol *Label) {
@@ -198,27 +220,28 @@ void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
EmitDwarfSetLineAddr(LineDelta, Label, PointerSize);
return;
}
- MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
- const MCExpr *LabelRef =
- MCSymbolRefExpr::Create(Label, Variant, getContext());
- const MCExpr *LastLabelRef =
- MCSymbolRefExpr::Create(LastLabel, Variant, getContext());
- const MCExpr *AddrDelta =
- MCBinaryExpr::Create(MCBinaryExpr::Sub, LabelRef, LastLabelRef,
- getContext());
+ const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
int64_t Res;
if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
MCDwarfLineAddr::Emit(this, LineDelta, Res);
return;
}
- if (!getContext().getAsmInfo().hasAggressiveSymbolFolding()) {
- MCSymbol *ABS = getContext().CreateTempSymbol();
- EmitAssignment(ABS, AddrDelta);
- AddrDelta = MCSymbolRefExpr::Create(ABS, getContext());
- }
+ AddrDelta = ForceExpAbs(this, getContext(), AddrDelta);
new MCDwarfLineAddrFragment(LineDelta, *AddrDelta, getCurrentSectionData());
}
+void MCObjectStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel,
+ const MCSymbol *Label) {
+ const MCExpr *AddrDelta = BuildSymbolDiff(getContext(), Label, LastLabel);
+ int64_t Res;
+ if (AddrDelta->EvaluateAsAbsolute(Res, getAssembler())) {
+ MCDwarfFrameEmitter::EmitAdvanceLoc(*this, Res);
+ return;
+ }
+ AddrDelta = ForceExpAbs(this, getContext(), AddrDelta);
+ new MCDwarfCallFrameFragment(*AddrDelta, getCurrentSectionData());
+}
+
void MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset,
unsigned char Value) {
new MCOrgFragment(*Offset, Value, getCurrentSectionData());