diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -1614,14 +1614,24 @@ MCSymbol *sectionEnd = context.createTempSymbol(); + dwarf::DwarfFormat Format = IsEH ? dwarf::DWARF32 : context.getDwarfFormat(); + unsigned UnitLengthBytes = dwarf::getUnitLengthFieldByteSize(Format); + unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(Format); + bool IsDwarf64 = Format == dwarf::DWARF64; + + if (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()); @@ -1731,9 +1741,16 @@ CFAOffset = InitialCFAOffset; + dwarf::DwarfFormat Format = IsEH ? dwarf::DWARF32 : context.getDwarfFormat(); + unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(Format); + + if (Format == 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); @@ -1742,13 +1759,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()); } diff --git a/llvm/test/MC/ELF/gen-dwarf64.s b/llvm/test/MC/ELF/gen-dwarf64.s --- a/llvm/test/MC/ELF/gen-dwarf64.s +++ b/llvm/test/MC/ELF/gen-dwarf64.s @@ -9,6 +9,8 @@ # 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. +# REL: Section ({{[0-9]+}}) .rela.debug_frame { +# REL-NEXT: R_X86_64_64 .debug_frame 0x0 # REL: Section ({{[0-9]+}}) .rela.debug_info { # REL-NEXT: R_X86_64_64 .debug_abbrev 0x0 # REL-NEXT: R_X86_64_64 .debug_line 0x0 @@ -42,6 +44,20 @@ # DUMP: DW_TAG_label [2] # DUMP-NEXT: DW_AT_name [DW_FORM_string] ("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 + +## Even though the debug info sections are in the 64-bit format, +## .eh_frame is still generated as 32-bit. +# DUMP: .eh_frame contents: +# DUMP: 00000000 {{([[:xdigit:]]{8})}} 00000000 CIE +# DUMP-NEXT: Format: DWARF32 +# DUMP: {{([[:xdigit:]]{8})}} {{([[:xdigit:]]{8})}} {{([[:xdigit:]]{8})}} FDE cie=00000000 pc=00000000...00000001 +# DUMP-NEXT: Format: DWARF32 + # DUMP: .debug_aranges contents: # DUMP-NEXT: Address Range Header: length = 0x0000000000000044, format = DWARF64, version = 0x0002, cu_offset = 0x0000000000000000, addr_size = 0x08, seg_size = 0x00 # DUMP-NEXT: [0x0000000000000000, 0x0000000000000001) @@ -76,10 +92,14 @@ # DUMP5-NEXT: 0x0000001e: [DW_RLE_start_length]: 0x0000000000000000, 0x0000000000000001 => [0x0000000000000000, 0x0000000000000001) # DUMP5-NEXT: 0x00000028: [DW_RLE_end_of_list ] + .cfi_sections .eh_frame, .debug_frame + .section .foo, "ax", @progbits foo: nop .section .bar, "ax", @progbits bar: + .cfi_startproc nop + .cfi_endproc diff --git a/llvm/test/MC/MachO/gen-dwarf64.s b/llvm/test/MC/MachO/gen-dwarf64.s --- a/llvm/test/MC/MachO/gen-dwarf64.s +++ b/llvm/test/MC/MachO/gen-dwarf64.s @@ -10,10 +10,20 @@ // CHECK: DW_TAG_label [2] // CHECK-NEXT: DW_AT_name [DW_FORM_string] ("foo") +// CHECK: .debug_frame contents: +// CHECK: 00000000 {{([[:xdigit:]]{16})}} ffffffffffffffff CIE +// CHECK-NEXT: Format: DWARF64 +// CHECK: {{([[:xdigit:]]{8})}} {{([[:xdigit:]]{16})}} 0000000000000000 FDE cie=00000000 pc=00000000...00000001 +// CHECK-NEXT: Format: DWARF64 + // CHECK: .debug_aranges contents: // CHECK-NEXT: Address Range Header: length = 0x0000000000000034, format = DWARF64, version = 0x0002, cu_offset = 0x0000000000000000, addr_size = 0x08, seg_size = 0x00 // CHECK-NEXT: [0x0000000000000000, 0x0000000000000001) // CHECK-EMPTY: + .cfi_sections .debug_frame + _foo: + .cfi_startproc nop + .cfi_endproc