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 | 736a35d9ab34dd6090db6437389c5b810f0ed83b (patch) | |
| tree | 48343fcbca8aa3f542135a6c5d1bc89a2badef6d /llvm/lib/MC/MCObjectStreamer.cpp | |
| parent | a75b87b55adc2f9e39f2cbdf792c05405b7038d5 (diff) | |
| download | bcm5719-llvm-736a35d9ab34dd6090db6437389c5b810f0ed83b.tar.gz bcm5719-llvm-736a35d9ab34dd6090db6437389c5b810f0ed83b.zip | |
Relax address updates in the eh_frame section.
llvm-svn: 122591
Diffstat (limited to 'llvm/lib/MC/MCObjectStreamer.cpp')
| -rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index af102ecf78a..b428e8747b6 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/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()); |

