Index: llvm/include/llvm/MC/MCContext.h =================================================================== --- llvm/include/llvm/MC/MCContext.h +++ llvm/include/llvm/MC/MCContext.h @@ -185,6 +185,9 @@ /// The maximum version of dwarf that we should emit. uint16_t DwarfVersion = 4; + /// The format of dwarf that we emit. + dwarf::DwarfFormat DwarfFormat = dwarf::DWARF32; + /// Honor temporary labels, this is useful for debugging semantic /// differences between temporary and non-temporary labels (primarily on /// Darwin). @@ -694,10 +697,8 @@ void setDwarfDebugProducer(StringRef S) { DwarfDebugProducer = S; } StringRef getDwarfDebugProducer() { return DwarfDebugProducer; } - dwarf::DwarfFormat getDwarfFormat() const { - // TODO: Support DWARF64 - return dwarf::DWARF32; - } + void setDwarfFormat(dwarf::DwarfFormat f) { DwarfFormat = f; } + dwarf::DwarfFormat getDwarfFormat() const { return DwarfFormat; } void setDwarfVersion(uint16_t v) { DwarfVersion = v; } uint16_t getDwarfVersion() const { return DwarfVersion; } Index: llvm/include/llvm/MC/MCTargetOptions.h =================================================================== --- llvm/include/llvm/MC/MCTargetOptions.h +++ llvm/include/llvm/MC/MCTargetOptions.h @@ -53,6 +53,7 @@ /// Preserve Comments in Assembly. bool PreserveAsmComments : 1; + bool Dwarf64 : 1; int DwarfVersion = 0; std::string ABIName; Index: llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h =================================================================== --- llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h +++ llvm/include/llvm/MC/MCTargetOptionsCommandFlags.h @@ -30,6 +30,8 @@ int getDwarfVersion(); +bool getDwarf64(); + bool getShowMCInst(); bool getFatalWarnings(); Index: llvm/lib/MC/MCDwarf.cpp =================================================================== --- llvm/lib/MC/MCDwarf.cpp +++ llvm/lib/MC/MCDwarf.cpp @@ -50,8 +50,14 @@ S.getContext().createTempSymbol("debug_list_header_start", true, true); MCSymbol *End = S.getContext().createTempSymbol("debug_list_header_end", true, true); + auto DwarfFormat = S.getContext().getDwarfFormat(); + if (DwarfFormat == dwarf::DWARF64) { + S.AddComment("DWARF64 mark"); + S.emitInt32(dwarf::DW_LENGTH_DWARF64); + } S.AddComment("Length"); - S.emitAbsoluteSymbolDiff(End, Start, 4); + S.emitAbsoluteSymbolDiff(End, Start, + dwarf::getDwarfOffsetByteSize(DwarfFormat)); S.emitLabel(Start); S.AddComment("Version"); S.emitInt16(S.getContext().getDwarfVersion()); @@ -332,7 +338,8 @@ } void MCDwarfLineStr::emitRef(MCStreamer *MCOS, StringRef Path) { - int RefSize = 4; // FIXME: Support DWARF-64 + int RefSize = + dwarf::getDwarfOffsetByteSize(MCOS->getContext().getDwarfFormat()); size_t Offset = LineStrings.add(Path); if (UseRelocs) { MCContext &Ctx = MCOS->getContext(); @@ -472,10 +479,20 @@ // Create a symbol for the end of the section (to be set when we get there). MCSymbol *LineEndSym = context.createTempSymbol(); - // The first 4 bytes is the total length of the information for this - // compilation unit (not including these 4 bytes for the length). - emitAbsValue( - *MCOS, MakeStartMinusEndExpr(context, *LineStartSym, *LineEndSym, 4), 4); + unsigned UnitLengthBytes = + dwarf::getUnitLengthFieldByteSize(context.getDwarfFormat()); + unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat()); + + if (context.getDwarfFormat() == dwarf::DWARF64) + // Emit DWARF64 mark. + MCOS->emitInt32(dwarf::DW_LENGTH_DWARF64); + + // The length field does not include itself and, in case of the 64-bit DWARF + // format, the DWARF64 mark. + emitAbsValue(*MCOS, + MakeStartMinusEndExpr(context, *LineStartSym, *LineEndSym, + UnitLengthBytes), + OffsetSize); // Next 2 bytes is the Version. unsigned LineTableVersion = context.getDwarfVersion(); @@ -483,7 +500,7 @@ // Keep track of the bytes between the very start and where the header length // comes out. - unsigned PreHeaderLengthBytes = 4 + 2; + unsigned PreHeaderLengthBytes = UnitLengthBytes + 2; // In v5, we get address info next. if (LineTableVersion >= 5) { @@ -495,12 +512,12 @@ // Create a symbol for the end of the prologue (to be set when we get there). MCSymbol *ProEndSym = context.createTempSymbol(); // Lprologue_end - // Length of the prologue, is the next 4 bytes. This is actually the length - // from after the length word, to the end of the prologue. + // Length of the prologue, is the next 4 bytes (8 bytes for DWARF64). This is + // actually the length from after the length word, to the end of the prologue. emitAbsValue(*MCOS, MakeStartMinusEndExpr(context, *LineStartSym, *ProEndSym, - (PreHeaderLengthBytes + 4)), - 4); + (PreHeaderLengthBytes + OffsetSize)), + OffsetSize); // Parameters of the state machine, are next. MCOS->emitInt8(context.getAsmInfo()->getMinInstAlignment()); @@ -816,14 +833,15 @@ MCOS->emitULEB128IntValue(1); MCOS->emitULEB128IntValue(dwarf::DW_TAG_compile_unit); MCOS->emitInt8(dwarf::DW_CHILDREN_yes); - EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, context.getDwarfVersion() >= 4 - ? dwarf::DW_FORM_sec_offset - : dwarf::DW_FORM_data4); + dwarf::Form SecOffsetForm = + context.getDwarfVersion() >= 4 + ? dwarf::DW_FORM_sec_offset + : (context.getDwarfFormat() == dwarf::DWARF64 ? dwarf::DW_FORM_data8 + : dwarf::DW_FORM_data4); + EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, SecOffsetForm); if (context.getGenDwarfSectionSyms().size() > 1 && context.getDwarfVersion() >= 3) { - EmitAbbrev(MCOS, dwarf::DW_AT_ranges, context.getDwarfVersion() >= 4 - ? dwarf::DW_FORM_sec_offset - : dwarf::DW_FORM_data4); + EmitAbbrev(MCOS, dwarf::DW_AT_ranges, SecOffsetForm); } else { EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr); EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr); @@ -871,9 +889,13 @@ MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfARangesSection()); + unsigned UnitLengthBytes = + dwarf::getUnitLengthFieldByteSize(context.getDwarfFormat()); + unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat()); + // This will be the length of the .debug_aranges section, first account for // the size of each item in the header (see below where we emit these items). - int Length = 4 + 2 + 4 + 1 + 1; + int Length = UnitLengthBytes + 2 + OffsetSize + 1 + 1; // Figure the padding after the header before the table of address and size // pairs who's values are PointerSize'ed. @@ -891,17 +913,21 @@ Length += 2 * AddrSize; // Emit the header for this section. - // The 4 byte length not including the 4 byte value for the length. - MCOS->emitInt32(Length - 4); + if (context.getDwarfFormat() == dwarf::DWARF64) + // The DWARF64 mark. + MCOS->emitInt32(dwarf::DW_LENGTH_DWARF64); + // The 4 (8 for DWARF64) byte length not including the length of the unit + // length field itself. + MCOS->emitIntValue(Length - UnitLengthBytes, OffsetSize); // The 2 byte version, which is 2. MCOS->emitInt16(2); - // The 4 byte offset to the compile unit in the .debug_info from the start - // of the .debug_info. + // The 4 (8 for DWARF64) 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, OffsetSize, asmInfo->needsDwarfSectionOffsetDirective()); else - MCOS->emitInt32(0); + MCOS->emitIntValue(0, OffsetSize); // The 1 byte size of an address. MCOS->emitInt8(AddrSize); // The 1 byte size of a segment descriptor, we use a value of zero. @@ -950,11 +976,19 @@ // First part: the header. - // The 4 byte total length of the information for this compilation unit, not - // including these 4 bytes. + unsigned UnitLengthBytes = + dwarf::getUnitLengthFieldByteSize(context.getDwarfFormat()); + unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(context.getDwarfFormat()); + + if (context.getDwarfFormat() == dwarf::DWARF64) + // Emit DWARF64 mark. + MCOS->emitInt32(dwarf::DW_LENGTH_DWARF64); + + // The 4 (8 for DWARF64) byte total length of the information for this + // compilation unit, not including the unit length field itself. const MCExpr *Length = - MakeStartMinusEndExpr(context, *InfoStart, *InfoEnd, 4); - emitAbsValue(*MCOS, Length, 4); + MakeStartMinusEndExpr(context, *InfoStart, *InfoEnd, UnitLengthBytes); + emitAbsValue(*MCOS, Length, OffsetSize); // The 2 byte DWARF version. MCOS->emitInt16(context.getDwarfVersion()); @@ -967,12 +1001,12 @@ MCOS->emitInt8(dwarf::DW_UT_compile); MCOS->emitInt8(AddrSize); } - // The 4 byte offset to the debug abbrevs from the start of the .debug_abbrev, - // it is at the start of that section so this is zero. + // The 4 (8 for DWARF64) byte offset to the debug abbrevs from the start of + // the .debug_abbrev, it is at the start of that section so this is zero. if (AbbrevSectionSymbol == nullptr) - MCOS->emitInt32(0); + MCOS->emitIntValue(0, OffsetSize); else - MCOS->emitSymbolValue(AbbrevSectionSymbol, 4, + MCOS->emitSymbolValue(AbbrevSectionSymbol, OffsetSize, AsmInfo.needsDwarfSectionOffsetDirective()); if (context.getDwarfVersion() <= 4) MCOS->emitInt8(AddrSize); @@ -982,19 +1016,19 @@ // The DW_TAG_compile_unit DIE abbrev (1). MCOS->emitULEB128IntValue(1); - // 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. + // DW_AT_stmt_list, a 4 (8 for DWARF64) 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, + MCOS->emitSymbolValue(LineSectionSymbol, OffsetSize, AsmInfo.needsDwarfSectionOffsetDirective()); else - MCOS->emitInt32(0); + MCOS->emitIntValue(0, OffsetSize); if (RangesSymbol) { // There are multiple sections containing code, so we must use - // .debug_ranges/.debug_rnglists. AT_ranges, the 4 byte offset from the + // .debug_ranges/.debug_rnglists. AT_ranges, the 4/8 byte offset from the // start of the .debug_ranges/.debug_rnglists. - MCOS->emitSymbolValue(RangesSymbol, 4); + MCOS->emitSymbolValue(RangesSymbol, OffsetSize); } else { // If we only have one non-empty code section, we can use the simpler // AT_low_pc and AT_high_pc attributes. @@ -1594,14 +1628,25 @@ MCSymbol *sectionEnd = context.createTempSymbol(); + unsigned UnitLengthBytes = + IsEH ? 4 : dwarf::getUnitLengthFieldByteSize(context.getDwarfFormat()); + unsigned OffsetSize = + IsEH ? 4 : dwarf::getDwarfOffsetByteSize(context.getDwarfFormat()); + bool IsDwarf64 = context.getDwarfFormat() == dwarf::DWARF64; + + if (!IsEH && IsDwarf64) + // DWARF64 mark + Streamer.emitInt32(dwarf::DW_LENGTH_DWARF64); + // Length - const MCExpr *Length = - MakeStartMinusEndExpr(context, *sectionStart, *sectionEnd, 4); - emitAbsValue(Streamer, Length, 4); + const MCExpr *Length = MakeStartMinusEndExpr(context, *sectionStart, + *sectionEnd, UnitLengthBytes); + emitAbsValue(Streamer, Length, OffsetSize); // CIE ID - unsigned CIE_ID = IsEH ? 0 : -1; - Streamer.emitInt32(CIE_ID); + uint64_t CIE_ID = + IsEH ? 0 : (IsDwarf64 ? dwarf::DW64_CIE_ID : dwarf::DW_CIE_ID); + Streamer.emitIntValue(CIE_ID, OffsetSize); // Version uint8_t CIEVersion = getCIEVersion(IsEH, context.getDwarfVersion()); @@ -1711,9 +1756,16 @@ CFAOffset = InitialCFAOffset; + unsigned OffsetSize = + IsEH ? 4 : dwarf::getDwarfOffsetByteSize(context.getDwarfFormat()); + + if (!IsEH && context.getDwarfFormat() == dwarf::DWARF64) + // DWARF64 mark + Streamer.emitInt32(dwarf::DW_LENGTH_DWARF64); + // Length const MCExpr *Length = MakeStartMinusEndExpr(context, *fdeStart, *fdeEnd, 0); - emitAbsValue(Streamer, Length, 4); + emitAbsValue(Streamer, Length, OffsetSize); Streamer.emitLabel(fdeStart); @@ -1722,13 +1774,13 @@ if (IsEH) { const MCExpr *offset = MakeStartMinusEndExpr(context, cieStart, *fdeStart, 0); - emitAbsValue(Streamer, offset, 4); + emitAbsValue(Streamer, offset, OffsetSize); } else if (!asmInfo->doesDwarfUseRelocationsAcrossSections()) { const MCExpr *offset = MakeStartMinusEndExpr(context, SectionStart, cieStart, 0); - emitAbsValue(Streamer, offset, 4); + emitAbsValue(Streamer, offset, OffsetSize); } else { - Streamer.emitSymbolValue(&cieStart, 4, + Streamer.emitSymbolValue(&cieStart, OffsetSize, asmInfo->needsDwarfSectionOffsetDirective()); } Index: llvm/lib/MC/MCTargetOptions.cpp =================================================================== --- llvm/lib/MC/MCTargetOptions.cpp +++ llvm/lib/MC/MCTargetOptions.cpp @@ -16,7 +16,7 @@ MCNoWarn(false), MCNoDeprecatedWarn(false), MCSaveTempLabels(false), MCUseDwarfDirectory(false), MCIncrementalLinkerCompatible(false), ShowMCEncoding(false), ShowMCInst(false), AsmVerbose(false), - PreserveAsmComments(true) {} + PreserveAsmComments(true), Dwarf64(false) {} StringRef MCTargetOptions::getABIName() const { return ABIName; Index: llvm/lib/MC/MCTargetOptionsCommandFlags.cpp =================================================================== --- llvm/lib/MC/MCTargetOptionsCommandFlags.cpp +++ llvm/lib/MC/MCTargetOptionsCommandFlags.cpp @@ -38,6 +38,7 @@ MCOPT_EXP(bool, RelaxAll) MCOPT(bool, IncrementalLinkerCompatible) MCOPT(int, DwarfVersion) +MCOPT(bool, Dwarf64) MCOPT(bool, ShowMCInst) MCOPT(bool, FatalWarnings) MCOPT(bool, NoWarn) @@ -66,6 +67,11 @@ cl::init(0)); MCBINDOPT(DwarfVersion); + static cl::opt Dwarf64( + "dwarf64", + cl::desc("Generate debugging info in the 64-bit DWARF format")); + MCBINDOPT(Dwarf64); + static cl::opt ShowMCInst( "asm-show-inst", cl::desc("Emit internal instruction representation to assembly file")); @@ -97,6 +103,7 @@ MCTargetOptions Options; Options.MCRelaxAll = getRelaxAll(); Options.MCIncrementalLinkerCompatible = getIncrementalLinkerCompatible(); + Options.Dwarf64 = getDwarf64(); Options.DwarfVersion = getDwarfVersion(); Options.ShowMCInst = getShowMCInst(); Options.ABIName = getABIName(); Index: llvm/test/MC/COFF/dwarf64-err.s =================================================================== --- /dev/null +++ llvm/test/MC/COFF/dwarf64-err.s @@ -0,0 +1,3 @@ +# RUN: not llvm-mc -dwarf64 -triple x86_64-unknown-windows-gnu %s -o - 2>&1 | FileCheck %s + +# CHECK: the 64-bit DWARF format is not supported for x86_64-unknown-windows-gnu Index: llvm/test/MC/ELF/dwarf64-err.s =================================================================== --- /dev/null +++ llvm/test/MC/ELF/dwarf64-err.s @@ -0,0 +1,5 @@ +# RUN: not llvm-mc -g -dwarf-version 5 -dwarf64 -triple i686 %s -filetype=asm -o - 2>&1 | FileCheck --check-prefix=I686 %s +# RUN: not llvm-mc -g -dwarf-version 2 -dwarf64 -triple x86_64 %s -filetype=asm -o - 2>&1 | FileCheck --check-prefix=DWARF2 %s + +# DWARF2: the 64-bit DWARF format is not supported for DWARF versions prior to 3 +# I686: the 64-bit DWARF format is only supported for 64-bit targets Index: llvm/test/MC/ELF/gen-dwarf64.s =================================================================== --- /dev/null +++ llvm/test/MC/ELF/gen-dwarf64.s @@ -0,0 +1,120 @@ +# RUN: llvm-mc -g -dwarf-version 3 -dwarf64 -triple x86_64 %s -filetype=obj -o %t3.o +# RUN: llvm-mc -g -dwarf-version 5 -dwarf64 -triple x86_64 %s -filetype=obj -o %t5.o + +## This checks that llvm-mc is able to produce 64-bit debug info. + +# RUN: llvm-readobj -r %t3.o | FileCheck --check-prefixes=REL,REL3 %s +# RUN: llvm-readobj -r %t5.o | FileCheck --check-prefixes=REL,REL5 %s + +# RUN: llvm-dwarfdump -v %t3.o | FileCheck --check-prefixes=DUMP,DUMP3 %s +# RUN: llvm-dwarfdump -v %t5.o | FileCheck --check-prefixes=DUMP,DUMP5 %s + +## The references to other debug info sections are 64-bit, as required for DWARF64. +## The references to code sections are 64-bit, because the target is 64-bit. +# REL: Relocations [ +# REL: Section ({{[0-9]+}}) .rela.debug_frame { +# REL-NEXT: R_X86_64_64 .debug_frame 0x0 +# REL-NEXT: R_X86_64_64 .bar 0x0 +# REL-NEXT: } +# REL-NEXT: Section ({{[0-9]+}}) .rela.debug_info { +# REL-NEXT: R_X86_64_64 .debug_abbrev 0x0 +# REL-NEXT: R_X86_64_64 .debug_line 0x0 +# REL3-NEXT: R_X86_64_64 .debug_ranges 0x0 +# REL5-NEXT: R_X86_64_64 .debug_rnglists 0x14 +# REL-NEXT: R_X86_64_64 .foo 0x0 +# REL-NEXT: R_X86_64_64 .bar 0x0 +# REL-NEXT: } +# REL-NEXT: Section ({{[0-9]+}}) .rela.debug_aranges { +# REL-NEXT: R_X86_64_64 .debug_info 0x0 +# REL-NEXT: R_X86_64_64 .foo 0x0 +# REL-NEXT: R_X86_64_64 .bar 0x0 +# REL-NEXT: } +# REL3-NEXT: Section ({{[0-9]+}}) .rela.debug_ranges { +# REL5-NEXT: Section ({{[0-9]+}}) .rela.debug_rnglists { +# REL-NEXT: R_X86_64_64 .foo 0x0 +# REL-NEXT: R_X86_64_64 .bar 0x0 +# REL-NEXT: } +# REL-NEXT: Section ({{[0-9]+}}) .rela.debug_line { +# REL5-NEXT: R_X86_64_64 .debug_line_str 0x0 +# REL5-NEXT: R_X86_64_64 .debug_line_str 0x +# REL-NEXT: R_X86_64_64 .foo 0x0 +# REL-NEXT: R_X86_64_64 .bar 0x0 +# REL-NEXT: } +# REL-NEXT: ] + +## DW_FORM_sec_offset was introduced in DWARFv4. +## For DWARFv3, DW_FORM_data8 is used instead. +# DUMP: .debug_abbrev contents: +# DUMP3: DW_AT_stmt_list DW_FORM_data8 +# DUMP3-NEXT: DW_AT_ranges DW_FORM_data8 +# DUMP5: DW_AT_stmt_list DW_FORM_sec_offset +# DUMP5-NEXT: DW_AT_ranges DW_FORM_sec_offset + +# DUMP: .debug_info contents: +# DUMP-NEXT: 0x00000000: Compile Unit: +# DUMP-SAME: format = DWARF64 +# DUMP: DW_TAG_compile_unit [1] * +# DUMP3-NEXT: DW_AT_stmt_list [DW_FORM_data8] (0x0000000000000000) +# DUMP5-NEXT: DW_AT_stmt_list [DW_FORM_sec_offset] (0x0000000000000000) +# DUMP3-NEXT: DW_AT_ranges [DW_FORM_data8] (0x0000000000000000 +# DUMP5-NEXT: DW_AT_ranges [DW_FORM_sec_offset] (0x0000000000000014 +# DUMP-NEXT: [0x0000000000000000, 0x0000000000000001) ".foo" +# DUMP-NEXT: [0x0000000000000000, 0x0000000000000001) ".bar") + +# DUMP: .debug_frame contents: +# DUMP: 00000000 {{([[:xdigit:]]{16})}} ffffffffffffffff CIE +# DUMP-NEXT: Format: DWARF64 +# DUMP: {{([[:xdigit:]]{8})}} {{([[:xdigit:]]{16})}} 0000000000000000 FDE cie=00000000 pc=00000000...00000001 +# DUMP-NEXT: Format: DWARF64 + +# DUMP: .debug_aranges contents: +# DUMP-NEXT: Address Range Header: +# DUMP-SAME: format = DWARF64 +# DUMP-NEXT: [0x0000000000000000, 0x0000000000000001) +# DUMP-NEXT: [0x0000000000000000, 0x0000000000000001) +# DUMP-EMPTY: + +# DUMP: .debug_line contents: +# DUMP-NEXT: debug_line[0x00000000] +# DUMP-NEXT: Line table prologue: +# DUMP-NEXT: total_length: +# DUMP-NEXT: format: DWARF64 +# DUMP3: include_directories[ 1] = "{{.*}}" +# DUMP3-NEXT: file_names[ 1]: +# DUMP3-NEXT: name: "{{.*}}" +# DUMP3-NEXT: dir_index: 1 +# DUMP5: include_directories[ 0] = .debug_line_str[0x0000000000000000] = "[[DIR:.+]]" +# DUMP5-NEXT: file_names[ 0]: +# DUMP5-NEXT: name: .debug_line_str[0x00000000[[FILEOFF:[[:xdigit:]]{8}]]] = "[[FILE:.+]]" +# DUMP5-NEXT: dir_index: 0 + +# DUMP5: .debug_line_str contents: +# DUMP5-NEXT: 0x00000000: "[[DIR]]" +# DUMP5-NEXT: 0x[[FILEOFF]]: "[[FILE]]" + +# DUMP3: .debug_ranges contents: +# DUMP3-NEXT: 00000000 ffffffffffffffff 0000000000000000 +# DUMP3-NEXT: 00000000 0000000000000000 0000000000000001 +# DUMP3-NEXT: 00000000 ffffffffffffffff 0000000000000000 +# DUMP3-NEXT: 00000000 0000000000000000 0000000000000001 +# DUMP3-NEXT: 00000000 + +# DUMP5: .debug_rnglists contents: +# DUMP5-NEXT: 0x00000000: range list header: +# DUMP5-SAME: format = DWARF64 +# DUMP5-NEXT: ranges: +# DUMP5-NEXT: 0x00000014: [DW_RLE_start_length]: 0x0000000000000000, 0x0000000000000001 => [0x0000000000000000, 0x0000000000000001) +# DUMP5-NEXT: 0x0000001e: [DW_RLE_start_length]: 0x0000000000000000, 0x0000000000000001 => [0x0000000000000000, 0x0000000000000001) +# DUMP5-NEXT: 0x00000028: [DW_RLE_end_of_list ] + + .cfi_sections .debug_frame + + .section .foo, "ax", @progbits +foo: + nop + + .section .bar, "ax", @progbits +bar: + .cfi_startproc + nop + .cfi_endproc Index: llvm/tools/llvm-mc/llvm-mc.cpp =================================================================== --- llvm/tools/llvm-mc/llvm-mc.cpp +++ llvm/tools/llvm-mc/llvm-mc.cpp @@ -387,6 +387,31 @@ return 1; } Ctx.setDwarfVersion(DwarfVersion); + if (MCOptions.Dwarf64) { + // DWARFv3 was the first standard where the 64-bit DWARF was described. + if (DwarfVersion < 3) { + errs() << ProgName + << ": the 64-bit DWARF format is not supported for DWARF versions " + "prior to 3\n"; + return 1; + } + // 32-bit targets don't support DWARF64, which requires 64-bit relocations. + if (MAI->getCodePointerSize() < 8) { + errs() << ProgName + << ": the 64-bit DWARF format is only supported for 64-bit " + "targets\n"; + return 1; + } + // If needsDwarfSectionOffsetDirective is true, we would eventually call + // MCStreamer::emitSymbolValue() with IsSectionRelative = true, but that + // is supported only for 4-byte long references. + if (MAI->needsDwarfSectionOffsetDirective()) { + errs() << ProgName << ": the 64-bit DWARF format is not supported for " + << TheTriple.normalize() << "\n"; + return 1; + } + Ctx.setDwarfFormat(dwarf::DWARF64); + } if (!DwarfDebugFlags.empty()) Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags)); if (!DwarfDebugProducer.empty())