OS << char(dwarf::DW_LNS_const_add_pc);
else {
OS << char(dwarf::DW_LNS_advance_pc);
- SmallString<32> Tmp;
- raw_svector_ostream OSE(Tmp);
- MCObjectWriter::EncodeULEB128(AddrDelta, OSE);
- OS << OSE.str();
+ MCObjectWriter::EncodeULEB128(AddrDelta, OS);
}
OS << char(dwarf::DW_LNS_extended_op);
OS << char(1);
int CIENum;
bool UsingCFI;
bool IsEH;
+ const MCSymbol *SectionStart;
public:
- FrameEmitterImpl(bool usingCFI, bool isEH) : CFAOffset(0), CIENum(0),
- UsingCFI(usingCFI),
- IsEH(isEH) {
+ FrameEmitterImpl(bool usingCFI, bool isEH, const MCSymbol *sectionStart) :
+ CFAOffset(0), CIENum(0), UsingCFI(usingCFI), IsEH(isEH),
+ SectionStart(sectionStart) {
}
+ /// EmitCompactUnwind - Emit the unwind information in a compact way. If
+ /// we're successful, return 'true'. Otherwise, return 'false' and it will
+ /// emit the normal CIE and FDE.
+ bool EmitCompactUnwind(MCStreamer &streamer,
+ const MCDwarfFrameInfo &frame);
+
const MCSymbol &EmitCIE(MCStreamer &streamer,
const MCSymbol *personality,
unsigned personalityEncoding,
// If advancing cfa.
if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
- assert(!Src.isReg() && "Machine move not supported yet.");
-
if (Src.getReg() == MachineLocation::VirtualFP) {
Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);
} else {
}
}
+/// EmitCompactUnwind - Emit the unwind information in a compact way. If we're
+/// successful, return 'true'. Otherwise, return 'false' and it will emit the
+/// normal CIE and FDE.
+bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer,
+ const MCDwarfFrameInfo &Frame) {
+#if 1
+ return false;
+#else
+ MCContext &Context = Streamer.getContext();
+ const TargetAsmInfo &TAI = Context.getTargetAsmInfo();
+ Streamer.SwitchSection(TAI.getCompactUnwindSection());
+
+ unsigned FDEEncoding = TAI.getFDEEncoding(UsingCFI);
+ unsigned Size = getSizeForEncoding(Streamer, FDEEncoding);
+
+ // range-start range-length compact-unwind-enc personality-func lsda
+ // _foo LfooEnd-_foo 0x00000023 0 0
+ // _bar LbarEnd-_bar 0x00000025 __gxx_personality except_tab1
+ //
+ // .section __LD,__compact_unwind,regular,debug
+ //
+ // # compact unwind for _foo
+ // .quad _foo
+ // .set L1,LfooEnd-_foo
+ // .long L1
+ // .long 0x01010001
+ // .quad 0
+ // .quad 0
+ //
+ // # compact unwind for _bar
+ // .quad _bar
+ // .set L2,LbarEnd-_bar
+ // .long L2
+ // .long 0x01020011
+ // .quad __gxx_personality
+ // .quad except_tab1
+
+ // Range Start
+ EmitSymbol(Streamer, *Frame.Begin, FDEEncoding);
+
+ // Range Length
+ const MCExpr *Range = MakeStartMinusEndExpr(Streamer, *Frame.Begin,
+ *Frame.End, 0);
+ Streamer.EmitAbsValue(Range, Size);
+
+ return true;
+#endif
+}
+
const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
const MCSymbol *personality,
unsigned personalityEncoding,
MCContext &context = streamer.getContext();
MCSymbol *fdeStart = context.CreateTempSymbol();
MCSymbol *fdeEnd = context.CreateTempSymbol();
- const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
+ const TargetAsmInfo &TAsmInfo = context.getTargetAsmInfo();
- if (!asmInfo.isFunctionEHFrameSymbolPrivate() && IsEH) {
+ if (!TAsmInfo.isFunctionEHFrameSymbolPrivate() && IsEH) {
MCSymbol *EHSym = context.GetOrCreateSymbol(
frame.Function->getName() + Twine(".eh"));
streamer.EmitEHSymAttributes(frame.Function, EHSym);
streamer.EmitAbsValue(Length, 4);
streamer.EmitLabel(fdeStart);
+
// CIE Pointer
+ const MCAsmInfo &asmInfo = context.getAsmInfo();
if (IsEH) {
const MCExpr *offset = MakeStartMinusEndExpr(streamer, cieStart, *fdeStart,
0);
streamer.EmitAbsValue(offset, 4);
+ } else if (!asmInfo.doesDwarfRequireRelocationForSectionOffset()) {
+ const MCExpr *offset = MakeStartMinusEndExpr(streamer, *SectionStart,
+ cieStart, 0);
+ streamer.EmitAbsValue(offset, 4);
} else {
streamer.EmitSymbolValue(&cieStart, 4);
}
- unsigned fdeEncoding = asmInfo.getFDEEncoding(UsingCFI);
+ unsigned fdeEncoding = TAsmInfo.getFDEEncoding(UsingCFI);
unsigned size = getSizeForEncoding(streamer, fdeEncoding);
// PC Begin
- unsigned PCBeginEncoding = IsEH ? fdeEncoding : dwarf::DW_EH_PE_absptr;
+ unsigned PCBeginEncoding = IsEH ? fdeEncoding :
+ (unsigned)dwarf::DW_EH_PE_absptr;
unsigned PCBeginSize = getSizeForEncoding(streamer, PCBeginEncoding);
EmitSymbol(streamer, *frame.Begin, PCBeginEncoding);
void MCDwarfFrameEmitter::Emit(MCStreamer &streamer,
bool usingCFI,
bool isEH) {
- const MCContext &context = streamer.getContext();
+ MCContext &context = streamer.getContext();
const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
const MCSection §ion = isEH ?
- *asmInfo.getEHFrameSection() : *asmInfo.getDwarfFrameSection();
+ *asmInfo.getEHFrameSection() :
+ *asmInfo.getDwarfFrameSection();
streamer.SwitchSection(§ion);
+ MCSymbol *SectionStart = context.CreateTempSymbol();
+ streamer.EmitLabel(SectionStart);
MCSymbol *fdeEnd = NULL;
DenseMap<CIEKey, const MCSymbol*> CIEStarts;
- FrameEmitterImpl Emitter(usingCFI, isEH);
+ FrameEmitterImpl Emitter(usingCFI, isEH, SectionStart);
const MCSymbol *DummyDebugKey = NULL;
for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) {
CIEKey key(frame.Personality, frame.PersonalityEncoding,
frame.LsdaEncoding);
const MCSymbol *&cieStart = isEH ? CIEStarts[key] : DummyDebugKey;
+ if (isEH && asmInfo.getSupportsCompactUnwindInfo() &&
+ Emitter.EmitCompactUnwind(streamer, frame))
+ continue;
+
if (!cieStart)
cieStart = &Emitter.EmitCIE(streamer, frame.Personality,
frame.PersonalityEncoding, frame.Lsda,
frame.LsdaEncoding);
+
fdeEnd = Emitter.EmitFDE(streamer, *cieStart, frame);
+
if (i != n - 1)
streamer.EmitLabel(fdeEnd);
}