mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-30 00:24:00 +00:00
Relax dwarf line fragments. This fixes a crash in the included testcase.
llvm-svn: 118365
This commit is contained in:
parent
24ba201941
commit
877bb5ba4b
@ -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);
|
||||
|
||||
|
@ -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
11
test/MC/ELF/relax-crash.s
Normal 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
|
Loading…
x
Reference in New Issue
Block a user