}
// Emit a DW_LNE_end_sequence for the end of the section.
- // Using the pointer Section create a temporary label at the end of the
- // section and use that and the LastLabel to compute the address delta
- // and use INT64_MAX as the line delta which is the signal that this is
- // actually a DW_LNE_end_sequence.
+ // Use the section end label to compute the address delta and use INT64_MAX
+ // as the line delta which is the signal that this is actually a
+ // DW_LNE_end_sequence.
+ MCSymbol *SectionEnd = MCOS->endSection(Section);
- // Switch to the section to be able to create a symbol at its end.
- // TODO: keep track of the last subsection so that this symbol appears in the
- // correct place.
- MCOS->SwitchSection(Section);
+ // Switch back the dwarf line section, in case endSection had to switch the
+ // section.
+ MCContext &Ctx = MCOS->getContext();
+ MCOS->SwitchSection(Ctx.getObjectFileInfo()->getDwarfLineSection());
- MCContext &context = MCOS->getContext();
- // Create a symbol at the end of the section.
- MCSymbol *SectionEnd = context.CreateTempSymbol();
- // Set the value of the symbol, as we are at the end of the section.
- MCOS->EmitLabel(SectionEnd);
-
- // Switch back the dwarf line section.
- MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection());
-
- const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo();
+ const MCAsmInfo *AsmInfo = Ctx.getAsmInfo();
MCOS->EmitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd,
- asmInfo->getPointerSize());
+ AsmInfo->getPointerSize());
}
//
0, // length of DW_LNS_set_epilogue_begin
1 // DW_LNS_set_isa
};
- static_assert(array_lengthof(StandardOpcodeLengths) ==
- (DWARF2_LINE_OPCODE_BASE - 1),
- "");
+ assert(array_lengthof(StandardOpcodeLengths) ==
+ (DWARF2_LINE_OPCODE_BASE - 1));
return Emit(MCOS, StandardOpcodeLengths);
}
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection());
- for (const auto sec : Sections) {
+ for (const auto &sec : Sections) {
MCSymbol *StartSymbol = sec.second.first;
MCSymbol *EndSymbol = sec.second.second;
namespace {
class FrameEmitterImpl {
int CFAOffset;
+ int InitialCFAOffset;
bool IsEH;
const MCSymbol *SectionStart;
public:
FrameEmitterImpl(bool isEH)
- : CFAOffset(0), IsEH(isEH), SectionStart(nullptr) {}
+ : CFAOffset(0), InitialCFAOffset(0), IsEH(isEH), SectionStart(nullptr) {
+ }
void setSectionStart(const MCSymbol *Label) { SectionStart = Label; }
Streamer.EmitIntValue(0, Size); // No LSDA
}
+static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion) {
+ if (IsEH)
+ return 1;
+ switch (DwarfVersion) {
+ case 2:
+ return 1;
+ case 3:
+ return 3;
+ case 4:
+ return 4;
+ }
+ llvm_unreachable("Unknown version");
+}
+
const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer,
const MCSymbol *personality,
unsigned personalityEncoding,
streamer.EmitIntValue(CIE_ID, 4);
// Version
- // For DWARF2, we use CIE version 1
- // For DWARF3+, we use CIE version 3
- uint8_t CIEVersion = context.getDwarfVersion() <= 2 ? 1 : 3;
+ uint8_t CIEVersion = getCIEVersion(IsEH, context.getDwarfVersion());
streamer.EmitIntValue(CIEVersion, 1);
// Augmentation String
Augmentation += "R";
if (IsSignalFrame)
Augmentation += "S";
- streamer.EmitBytes(Augmentation.str());
+ streamer.EmitBytes(Augmentation);
}
streamer.EmitIntValue(0, 1);
+ if (CIEVersion >= 4) {
+ // Address Size
+ streamer.EmitIntValue(context.getAsmInfo()->getPointerSize(), 1);
+
+ // Segment Descriptor Size
+ streamer.EmitIntValue(0, 1);
+ }
+
// Code Alignment Factor
streamer.EmitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment());
EmitCFIInstructions(streamer, Instructions, nullptr);
}
+ InitialCFAOffset = CFAOffset;
+
// Padding
streamer.EmitValueToAlignment(IsEH ? 4 : MAI->getPointerSize());
MCSymbol *fdeEnd = context.CreateTempSymbol();
const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
+ CFAOffset = InitialCFAOffset;
+
// Length
const MCExpr *Length = MakeStartMinusEndExpr(streamer, *fdeStart, *fdeEnd, 0);
emitAbsValue(streamer, Length, 4);