unsigned Column = 0;
unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
unsigned Isa = 0;
+ unsigned Discriminator = 0;
MCSymbol *LastLabel = NULL;
// Loop through each MCLineEntry and encode the dwarf line number table.
MCOS->EmitIntValue(dwarf::DW_LNS_set_column, 1);
MCOS->EmitULEB128IntValue(Column);
}
+ if (Discriminator != it->getDiscriminator()) {
+ Discriminator = it->getDiscriminator();
+ unsigned Size = getULEB128Size(Discriminator);
+ MCOS->EmitIntValue(dwarf::DW_LNS_extended_op, 1);
+ MCOS->EmitULEB128IntValue(Size + 1);
+ MCOS->EmitIntValue(dwarf::DW_LNE_set_discriminator, 1);
+ MCOS->EmitULEB128IntValue(Discriminator);
+ }
if (Isa != it->getIsa()) {
Isa = it->getIsa();
MCOS->EmitIntValue(dwarf::DW_LNS_set_isa, 1);
EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
- EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
+ if (!context.getCompilationDir().empty())
+ EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
if (!DwarfDebugFlags.empty())
EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
// AT_comp_dir, the working directory the assembly was done in.
- MCOS->EmitBytes(context.getCompilationDir());
- MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
+ if (!context.getCompilationDir().empty()) {
+ MCOS->EmitBytes(context.getCompilationDir());
+ MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string.
+ }
// AT_APPLE_flags, the command line arguments of the assembler tool.
StringRef DwarfDebugFlags = context.getDwarfDebugFlags();
}
}
-static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol,
- unsigned symbolEncoding, const char *comment = 0) {
+static void EmitFDESymbol(MCStreamer &streamer, const MCSymbol &symbol,
+ unsigned symbolEncoding, bool isEH,
+ const char *comment = 0) {
MCContext &context = streamer.getContext();
const MCAsmInfo *asmInfo = context.getAsmInfo();
const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol,
streamer);
unsigned size = getSizeForEncoding(streamer, symbolEncoding);
if (streamer.isVerboseAsm() && comment) streamer.AddComment(comment);
- streamer.EmitAbsValue(v, size);
+ if (asmInfo->doDwarfFDESymbolsUseAbsDiff() && isEH)
+ streamer.EmitAbsValue(v, size);
+ else
+ streamer.EmitValue(v, size);
}
static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol,
unsigned personalityEncoding,
const MCSymbol *lsda,
bool IsSignalFrame,
- unsigned lsdaEncoding);
+ unsigned lsdaEncoding,
+ bool IsSimple);
MCSymbol *EmitFDE(MCStreamer &streamer,
const MCSymbol &cieStart,
const MCDwarfFrameInfo &frame);
Streamer.EmitULEB128IntValue(Reg2);
return;
}
+ case MCCFIInstruction::OpWindowSave: {
+ Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1);
+ return;
+ }
case MCCFIInstruction::OpUndefined: {
unsigned Reg = Instr.getRegister();
if (VerboseAsm) {
unsigned personalityEncoding,
const MCSymbol *lsda,
bool IsSignalFrame,
- unsigned lsdaEncoding) {
+ unsigned lsdaEncoding,
+ bool IsSimple) {
MCContext &context = streamer.getContext();
const MCRegisterInfo *MRI = context.getRegisterInfo();
const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
// Initial Instructions
const MCAsmInfo *MAI = context.getAsmInfo();
- const std::vector<MCCFIInstruction> &Instructions =
- MAI->getInitialFrameState();
- EmitCFIInstructions(streamer, Instructions, NULL);
+ if (!IsSimple) {
+ const std::vector<MCCFIInstruction> &Instructions =
+ MAI->getInitialFrameState();
+ EmitCFIInstructions(streamer, Instructions, NULL);
+ }
// Padding
streamer.EmitValueToAlignment(IsEH ? 4 : MAI->getPointerSize());
unsigned PCEncoding = IsEH ? MOFI->getFDEEncoding(UsingCFI)
: (unsigned)dwarf::DW_EH_PE_absptr;
unsigned PCSize = getSizeForEncoding(streamer, PCEncoding);
- EmitSymbol(streamer, *frame.Begin, PCEncoding, "FDE initial location");
+ EmitFDESymbol(streamer, *frame.Begin, PCEncoding, IsEH, "FDE initial location");
// PC Range
const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin,
// Augmentation Data
if (frame.Lsda)
- EmitSymbol(streamer, *frame.Lsda, frame.LsdaEncoding,
- "Language Specific Data Area");
+ EmitFDESymbol(streamer, *frame.Lsda, frame.LsdaEncoding, true,
+ "Language Specific Data Area");
}
// Call Frame Instructions
namespace {
struct CIEKey {
- static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1, false); }
- static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0, false); }
+ static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1, false, false); }
+ static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0, false, false); }
CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_,
- unsigned LsdaEncoding_, bool IsSignalFrame_) :
+ unsigned LsdaEncoding_, bool IsSignalFrame_, bool IsSimple_) :
Personality(Personality_), PersonalityEncoding(PersonalityEncoding_),
- LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_) {
+ LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_),
+ IsSimple(IsSimple_) {
}
const MCSymbol* Personality;
unsigned PersonalityEncoding;
unsigned LsdaEncoding;
bool IsSignalFrame;
+ bool IsSimple;
};
}
return static_cast<unsigned>(hash_combine(Key.Personality,
Key.PersonalityEncoding,
Key.LsdaEncoding,
- Key.IsSignalFrame));
+ Key.IsSignalFrame,
+ Key.IsSimple));
}
static bool isEqual(const CIEKey &LHS,
const CIEKey &RHS) {
return LHS.Personality == RHS.Personality &&
LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
LHS.LsdaEncoding == RHS.LsdaEncoding &&
- LHS.IsSignalFrame == RHS.IsSignalFrame;
+ LHS.IsSignalFrame == RHS.IsSignalFrame &&
+ LHS.IsSimple == RHS.IsSimple;
}
};
}
for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
const MCDwarfFrameInfo &Frame = FrameArray[i];
CIEKey Key(Frame.Personality, Frame.PersonalityEncoding,
- Frame.LsdaEncoding, Frame.IsSignalFrame);
+ Frame.LsdaEncoding, Frame.IsSignalFrame, Frame.IsSimple);
const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
if (!CIEStart)
CIEStart = &Emitter.EmitCIE(Streamer, Frame.Personality,
Frame.PersonalityEncoding, Frame.Lsda,
Frame.IsSignalFrame,
- Frame.LsdaEncoding);
+ Frame.LsdaEncoding,
+ Frame.IsSimple);
FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame);