0, // length of DW_LNS_set_epilogue_begin
1 // DW_LNS_set_isa
};
- assert(array_lengthof(StandardOpcodeLengths) == (DWARF2_LINE_OPCODE_BASE - 1));
+ assert(array_lengthof(StandardOpcodeLengths) ==
+ (DWARF2_LINE_OPCODE_BASE - 1));
return Emit(MCOS, StandardOpcodeLengths);
}
for (const auto &LineSec : MCLineSections.getMCLineEntries())
EmitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
- if (MCOS->getContext().getAsmInfo()->getLinkerRequiresNonEmptyDwarfLines() &&
- MCLineSections.getMCLineEntries().empty()) {
- // The darwin9 linker has a bug (see PR8715). For for 32-bit architectures
- // it requires:
- // total_length >= prologue_length + 10
- // We are 4 bytes short, since we have total_length = 51 and
- // prologue_length = 45
-
- // The regular end_sequence should be sufficient.
- MCDwarfLineAddr::Emit(MCOS, INT64_MAX, 0);
- }
-
// This is the end of the section, so set the value of the symbol at the end
// of this section (that was used in a previous expression).
MCOS->EmitLabel(LineEndSym);
FileNumber = SourceIdMap.size() + 1;
assert((MCDwarfFiles.empty() || FileNumber == MCDwarfFiles.size()) &&
"Don't mix autonumbered and explicit numbered line table usage");
- StringMapEntry<unsigned> &Ent = SourceIdMap.GetOrCreateValue(
- (Directory + Twine('\0') + FileName).str(), FileNumber);
- if (Ent.getValue() != FileNumber)
- return Ent.getValue();
+ auto IterBool = SourceIdMap.insert(
+ std::make_pair((Directory + Twine('\0') + FileName).str(), FileNumber));
+ if (!IterBool.second)
+ return IterBool.first->second;
}
// Make space for this FileNumber in the MCDwarfFiles vector if needed.
MCDwarfFiles.resize(FileNumber + 1);
if (LineDelta == INT64_MAX) {
if (AddrDelta == MAX_SPECIAL_ADDR_DELTA)
OS << char(dwarf::DW_LNS_const_add_pc);
- else {
+ else if (AddrDelta) {
OS << char(dwarf::DW_LNS_advance_pc);
encodeULEB128(AddrDelta, OS);
}
MCOS->EmitULEB128IntValue(dwarf::DW_TAG_compile_unit);
MCOS->EmitIntValue(dwarf::DW_CHILDREN_yes, 1);
EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4);
- if (MCOS->getContext().getGenDwarfSectionSyms().size() > 1) {
+ if (MCOS->getContext().getGenDwarfSectionSyms().size() > 1 &&
+ MCOS->getContext().getDwarfVersion() >= 3) {
EmitAbbrev(MCOS, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4);
} else {
EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
// The 4 byte offset to the compile unit in the .debug_info from the start
// of the .debug_info.
if (InfoSectionSymbol)
- MCOS->EmitSymbolValue(InfoSectionSymbol, 4);
+ MCOS->EmitSymbolValue(InfoSectionSymbol, 4,
+ asmInfo->needsDwarfSectionOffsetDirective());
else
MCOS->EmitIntValue(0, 4);
// The 1 byte size of an address.
// DW_AT_stmt_list, a 4 byte offset from the start of the .debug_line section,
// which is at the start of that section so this is zero.
- if (LineSectionSymbol) {
- MCOS->EmitSymbolValue(LineSectionSymbol, 4);
- } else {
+ if (LineSectionSymbol)
+ MCOS->EmitSymbolValue(LineSectionSymbol, 4,
+ AsmInfo.needsDwarfSectionOffsetDirective());
+ else
MCOS->EmitIntValue(0, 4);
- }
if (RangesSectionSymbol) {
// There are multiple sections containing code, so we must use the
if (MCOS->getContext().getGenDwarfSectionSyms().empty())
return;
- // We only need to use the .debug_ranges section if we have multiple
- // code sections.
+ // We only use the .debug_ranges section if we have multiple code sections,
+ // and we are emitting a DWARF version which supports it.
const bool UseRangesSection =
- MCOS->getContext().getGenDwarfSectionSyms().size() > 1;
+ MCOS->getContext().getGenDwarfSectionSyms().size() > 1 &&
+ MCOS->getContext().getDwarfVersion() >= 3;
CreateDwarfSectionSymbols |= UseRangesSection;
MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection());
namespace {
class FrameEmitterImpl {
int CFAOffset;
- int CIENum;
bool IsEH;
const MCSymbol *SectionStart;
public:
FrameEmitterImpl(bool isEH)
- : CFAOffset(0), CIENum(0), IsEH(isEH), SectionStart(nullptr) {}
+ : CFAOffset(0), IsEH(isEH), SectionStart(nullptr) {}
void setSectionStart(const MCSymbol *Label) { SectionStart = Label; }
void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer,
const MCCFIInstruction &Instr) {
int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
+ auto *MRI = Streamer.getContext().getRegisterInfo();
switch (Instr.getOperation()) {
case MCCFIInstruction::OpRegister: {
unsigned Reg1 = Instr.getRegister();
unsigned Reg2 = Instr.getRegister2();
+ if (!IsEH) {
+ Reg1 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg1, true), false);
+ Reg2 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg2, true), false);
+ }
Streamer.EmitIntValue(dwarf::DW_CFA_register, 1);
Streamer.EmitULEB128IntValue(Reg1);
Streamer.EmitULEB128IntValue(Reg2);
return;
}
case MCCFIInstruction::OpDefCfa: {
+ unsigned Reg = Instr.getRegister();
+ if (!IsEH)
+ Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false);
Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
- Streamer.EmitULEB128IntValue(Instr.getRegister());
+ Streamer.EmitULEB128IntValue(Reg);
CFAOffset = -Instr.getOffset();
Streamer.EmitULEB128IntValue(CFAOffset);
}
case MCCFIInstruction::OpDefCfaRegister: {
+ unsigned Reg = Instr.getRegister();
+ if (!IsEH)
+ Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false);
Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);
- Streamer.EmitULEB128IntValue(Instr.getRegister());
+ Streamer.EmitULEB128IntValue(Reg);
return;
}
Instr.getOperation() == MCCFIInstruction::OpRelOffset;
unsigned Reg = Instr.getRegister();
+ if (!IsEH)
+ Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false);
+
int Offset = Instr.getOffset();
if (IsRelative)
Offset -= CFAOffset;
}
case MCCFIInstruction::OpRestore: {
unsigned Reg = Instr.getRegister();
+ if (!IsEH)
+ Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false);
Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1);
return;
}
MCSymbol *sectionStart = context.CreateTempSymbol();
streamer.EmitLabel(sectionStart);
- CIENum++;
MCSymbol *sectionEnd = context.CreateTempSymbol();
Augmentation += "R";
if (IsSignalFrame)
Augmentation += "S";
- streamer.EmitBytes(Augmentation.str());
+ streamer.EmitBytes(Augmentation);
}
streamer.EmitIntValue(0, 1);
if (CIEVersion == 1) {
assert(MRI->getRARegister() <= 255 &&
"DWARF 2 encodes return_address_register in one byte");
- streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), true), 1);
+ streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), IsEH), 1);
} else {
streamer.EmitULEB128IntValue(
- MRI->getDwarfRegNum(MRI->getRARegister(), true));
+ MRI->getDwarfRegNum(MRI->getRARegister(), IsEH));
}
// Augmentation Data Length (optional)