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
This commit is contained in:
Rafael Espindola
2010-12-28 05:39:27 +00:00
parent 5bba084253
commit 245a1e2041
8 changed files with 145 additions and 29 deletions

View File

@@ -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());