summaryrefslogtreecommitdiff
path: root/lib/MC/MCAssembler.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/MCAssembler.cpp
parent5bba08425374ca36fe5fbc7423ce1a09858e4097 (diff)
downloadllvm-245a1e20419aa5a3c833d7a8e89168e19d5f4d2c.tar.gz
llvm-245a1e20419aa5a3c833d7a8e89168e19d5f4d2c.tar.bz2
llvm-245a1e20419aa5a3c833d7a8e89168e19d5f4d2c.tar.xz
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/MCAssembler.cpp')
-rw-r--r--lib/MC/MCAssembler.cpp40
1 files changed, 37 insertions, 3 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 030ff98739..5b291490f7 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -323,6 +323,8 @@ uint64_t MCAssembler::ComputeFragmentSize(const MCAsmLayout &Layout,
case MCFragment::FT_Dwarf:
return cast<MCDwarfLineAddrFragment>(F).getContents().size();
+ case MCFragment::FT_DwarfFrame:
+ return cast<MCDwarfCallFrameFragment>(F).getContents().size();
}
assert(0 && "invalid fragment kind");
@@ -453,6 +455,11 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
OW->WriteBytes(OF.getContents().str());
break;
}
+ case MCFragment::FT_DwarfFrame: {
+ const MCDwarfCallFrameFragment &CF = cast<MCDwarfCallFrameFragment>(F);
+ OW->WriteBytes(CF.getContents().str());
+ break;
+ }
}
assert(OW->getStream().tell() - Start == FragmentSize);
@@ -712,6 +719,21 @@ bool MCAssembler::RelaxDwarfLineAddr(MCAsmLayout &Layout,
return OldSize != Data.size();
}
+bool MCAssembler::RelaxDwarfCallFrameFragment(MCAsmLayout &Layout,
+ MCDwarfCallFrameFragment &DF) {
+ int64_t AddrDelta = 0;
+ uint64_t OldSize = DF.getContents().size();
+ bool IsAbs = DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, Layout);
+ (void)IsAbs;
+ assert(IsAbs);
+ SmallString<8> &Data = DF.getContents();
+ Data.clear();
+ raw_svector_ostream OSE(Data);
+ MCDwarfFrameEmitter::EncodeAdvanceLoc(AddrDelta, OSE);
+ OSE.flush();
+ return OldSize != Data.size();
+}
+
bool MCAssembler::LayoutSectionOnce(MCAsmLayout &Layout,
MCSectionData &SD) {
MCFragment *FirstInvalidFragment = NULL;
@@ -730,9 +752,14 @@ bool MCAssembler::LayoutSectionOnce(MCAsmLayout &Layout,
relaxedFrag = RelaxDwarfLineAddr(Layout,
*cast<MCDwarfLineAddrFragment>(it2));
break;
- case MCFragment::FT_LEB:
- relaxedFrag = RelaxLEB(Layout, *cast<MCLEBFragment>(it2));
- break;
+ case MCFragment::FT_DwarfFrame:
+ relaxedFrag =
+ RelaxDwarfCallFrameFragment(Layout,
+ *cast<MCDwarfCallFrameFragment>(it2));
+ break;
+ case MCFragment::FT_LEB:
+ relaxedFrag = RelaxLEB(Layout, *cast<MCLEBFragment>(it2));
+ break;
}
// Update the layout, and remember that we relaxed.
if (relaxedFrag && !FirstInvalidFragment)
@@ -789,6 +816,7 @@ void MCFragment::dump() {
case MCFragment::FT_Inst: OS << "MCInstFragment"; break;
case MCFragment::FT_Org: OS << "MCOrgFragment"; break;
case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break;
+ case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break;
case MCFragment::FT_LEB: OS << "MCLEBFragment"; break;
}
@@ -855,6 +883,12 @@ void MCFragment::dump() {
<< " LineDelta:" << OF->getLineDelta();
break;
}
+ case MCFragment::FT_DwarfFrame: {
+ const MCDwarfCallFrameFragment *CF = cast<MCDwarfCallFrameFragment>(this);
+ OS << "\n ";
+ OS << " AddrDelta:" << CF->getAddrDelta();
+ break;
+ }
case MCFragment::FT_LEB: {
const MCLEBFragment *LF = cast<MCLEBFragment>(this);
OS << "\n ";