diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-12-28 05:39:27 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-12-28 05:39:27 +0000 |
commit | 245a1e20419aa5a3c833d7a8e89168e19d5f4d2c (patch) | |
tree | 1a10fd4b3e598e4457f2db8f82f92f4a6b47186e /lib/MC/MCObjectStreamer.cpp | |
parent | 5bba08425374ca36fe5fbc7423ce1a09858e4097 (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.cpp | 49 |
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()); |