Relax dwarf line fragments. This fixes a crash in the included testcase.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118365 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2010-11-07 02:07:12 +00:00
parent 689cf3cb62
commit 187d8339db
3 changed files with 40 additions and 14 deletions

View File

@ -388,11 +388,14 @@ class MCDwarfLineAddrFragment : public MCFragment {
/// make up the address delta between two .loc dwarf directives.
const MCExpr *AddrDelta;
/// Size - The current size estimate.
uint64_t Size;
public:
MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
MCSectionData *SD = 0)
: MCFragment(FT_Dwarf, SD),
LineDelta(_LineDelta), AddrDelta(&_AddrDelta) {}
LineDelta(_LineDelta), AddrDelta(&_AddrDelta), Size(1) {}
/// @name Accessors
/// @{
@ -401,6 +404,10 @@ public:
const MCExpr &getAddrDelta() const { return *AddrDelta; }
uint64_t getSize() const { return Size; }
void setSize(uint64_t Size_) { Size = Size_; }
/// @}
static bool classof(const MCFragment *F) {
@ -727,6 +734,9 @@ private:
bool RelaxLEB(const MCObjectWriter &Writer, MCAsmLayout &Layout,
MCLEBFragment &IF);
bool RelaxDwarfLineAddr(const MCObjectWriter &Writer, MCAsmLayout &Layout,
MCDwarfLineAddrFragment &DF);
/// FinishLayout - Finalize a layout, including fragment lowering.
void FinishLayout(MCAsmLayout &Layout);

View File

@ -340,19 +340,8 @@ uint64_t MCAssembler::ComputeFragmentSize(MCAsmLayout &Layout,
case MCFragment::FT_Org:
return cast<MCOrgFragment>(F).getSize();
case MCFragment::FT_Dwarf: {
const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F);
// The AddrDelta is really unsigned and it can only increase.
int64_t AddrDelta;
OF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, &Layout);
int64_t LineDelta;
LineDelta = OF.getLineDelta();
return MCDwarfLineAddr::ComputeSize(LineDelta, AddrDelta);
}
case MCFragment::FT_Dwarf:
return cast<MCDwarfLineAddrFragment>(F).getSize();
}
assert(0 && "invalid fragment kind");
@ -861,6 +850,18 @@ bool MCAssembler::RelaxLEB(const MCObjectWriter &Writer,
return OldSize != LF.getSize();
}
bool MCAssembler::RelaxDwarfLineAddr(const MCObjectWriter &Writer,
MCAsmLayout &Layout,
MCDwarfLineAddrFragment &DF) {
int64_t AddrDelta;
DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, &Layout);
int64_t LineDelta;
LineDelta = DF.getLineDelta();
uint64_t OldSize = DF.getSize();
DF.setSize(MCDwarfLineAddr::ComputeSize(LineDelta, AddrDelta));
return OldSize != DF.getSize();
}
bool MCAssembler::LayoutOnce(const MCObjectWriter &Writer,
MCAsmLayout &Layout) {
++stats::RelaxationSteps;
@ -886,6 +887,10 @@ bool MCAssembler::LayoutOnce(const MCObjectWriter &Writer,
case MCFragment::FT_Org:
WasRelaxed |= RelaxOrg(Writer, Layout, *cast<MCOrgFragment>(it2));
break;
case MCFragment::FT_Dwarf:
WasRelaxed |= RelaxDwarfLineAddr(Writer, Layout,
*cast<MCDwarfLineAddrFragment>(it2));
break;
case MCFragment::FT_LEB:
WasRelaxed |= RelaxLEB(Writer, Layout, *cast<MCLEBFragment>(it2));
break;

11
test/MC/ELF/relax-crash.s Normal file
View File

@ -0,0 +1,11 @@
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t
// This is a test that we don't crash. We used to do so by going in a infinite
// recursion trying to compute the size of a MCDwarfLineAddrFragment.
.section .debug_line,"",@progbits
.text
.file 1 "Disassembler.ii"
.section foo
.loc 1 1 0
ret