Index: llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h @@ -24,10 +24,10 @@ struct Header { /// The total length of the entries for that set, not including the length /// field itself. - uint32_t Length; + uint64_t Length; /// The offset from the beginning of the .debug_info section of the /// compilation unit entry referenced by the table. - uint32_t CuOffset; + uint64_t CuOffset; /// The DWARF version number. uint16_t Version; /// The size in bytes of an address on the target architecture. For segmented @@ -61,7 +61,7 @@ Error extract(DataExtractor data, uint64_t *offset_ptr); void dump(raw_ostream &OS) const; - uint32_t getCompileUnitDIEOffset() const { return HeaderData.CuOffset; } + uint64_t getCompileUnitDIEOffset() const { return HeaderData.CuOffset; } const Header &getHeader() const { return HeaderData; } Index: llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" @@ -35,23 +36,43 @@ ArangeDescriptors.clear(); Offset = *offset_ptr; - // 7.20 Address Range Table - // + // 7.21 Address Range Table (extract) // Each set of entries in the table of address ranges contained in - // the .debug_aranges section begins with a header consisting of: a - // 4-byte length containing the length of the set of entries for this - // compilation unit, not including the length field itself; a 2-byte - // version identifier containing the value 2 for DWARF Version 2; a - // 4-byte offset into the.debug_infosection; a 1-byte unsigned integer - // containing the size in bytes of an address (or the offset portion of - // an address for segmented addressing) on the target system; and a - // 1-byte unsigned integer containing the size in bytes of a segment - // descriptor on the target system. This header is followed by a series - // of tuples. Each tuple consists of an address and a length, each in - // the size appropriate for an address on the target architecture. + // the .debug_aranges section begins with a header containing: + // 1. unit_length (initial length) + // A 4-byte (32-bit DWARF) or 12-byte (64-bit DWARF) length containing + // the length of the set of entries for this compilation unit, + // not including the length field itself. + // 2. version (uhalf) + // The value in this field is 2. + // 3. debug_info_offset (section offset) + // A 4-byte (32-bit DWARF) or 8-byte (64-bit DWARF) offset into the + // .debug_info section of the compilation unit header. + // 4. address_size (ubyte) + // 5. segment_selector_size (ubyte) + // This header is followed by a series of tuples. Each tuple consists of + // a segment, an address and a length. The segment selector size is given by + // the segment_selector_size field of the header; the address and length + // size are each given by the address_size field of the header. Each set of + // tuples is terminated by a 0 for the segment, a 0 for the address and 0 + // for the length. If the segment_selector_size field in the header is zero, + // the segment selectors are omitted from all tuples, including + // the terminating tuple. + + uint8_t OffsetByteSize = 4; HeaderData.Length = data.getU32(offset_ptr); + if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) { + HeaderData.Length = data.getU64(offset_ptr); + OffsetByteSize = 8; + } else if (HeaderData.Length >= dwarf::DW_LENGTH_lo_reserved) { + return createStringError( + errc::invalid_argument, + "address range table at offset 0x%" PRIx64 + " has unsupported reserved unit length of value 0x%8.8" PRIx64, + Offset, HeaderData.Length); + } HeaderData.Version = data.getU16(offset_ptr); - HeaderData.CuOffset = data.getU32(offset_ptr); + HeaderData.CuOffset = data.getUnsigned(offset_ptr, OffsetByteSize); HeaderData.AddrSize = data.getU8(offset_ptr); HeaderData.SegSize = data.getU8(offset_ptr); @@ -98,10 +119,12 @@ } void DWARFDebugArangeSet::dump(raw_ostream &OS) const { - OS << format("Address Range Header: length = 0x%8.8x, version = 0x%4.4x, ", - HeaderData.Length, HeaderData.Version) - << format("cu_offset = 0x%8.8x, addr_size = 0x%2.2x, seg_size = 0x%2.2x\n", - HeaderData.CuOffset, HeaderData.AddrSize, HeaderData.SegSize); + OS << "Address Range Header: " + << format("length = 0x%8.8" PRIx64 ", ", HeaderData.Length) + << format("version = 0x%4.4x, ", HeaderData.Version) + << format("cu_offset = 0x%8.8" PRIx64 ", ", HeaderData.CuOffset) + << format("addr_size = 0x%2.2x, ", HeaderData.AddrSize) + << format("seg_size = 0x%2.2x\n", HeaderData.SegSize); for (const auto &Desc : ArangeDescriptors) { Desc.dump(OS, HeaderData.AddrSize); Index: llvm/test/DebugInfo/X86/dwarfdump-debug-aranges-dwarf64.s =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/dwarfdump-debug-aranges-dwarf64.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \ +# RUN: llvm-dwarfdump -debug-aranges - 2>&1 | \ +# RUN: FileCheck %s + + .section .debug_aranges,"",@progbits + .long 0xffffffff # DWARF64 mark + .quad .AREnd - .ARVersion # Length +.ARVersion: + .short 2 # Version + .quad 0x123456789a # Debug Info Offset + .byte 4 # Address Size + .byte 0 # Segment Selector Size + .balign 0+4+4 # The first tuple alignment +.ARTable: + .long 0, 1 # Address and size + .long 0, 0 # Termination tuple +.AREnd: + +# CHECK: Address Range Header: +# CHECK-SAME: length = 0x0000001c, +# CHECK-SAME: version = 0x0002, +# CHECK-SAME: cu_offset = 0x123456789a, +# CHECK-SAME: addr_size = 0x04, +# CHECK-SAME: seg_size = 0x00 +# CHECK-NEXT: [0x00000000, 0x00000001) +# CHECK-NOT: [0x \ No newline at end of file