Index: include/llvm/BinaryFormat/Dwarf.h =================================================================== --- include/llvm/BinaryFormat/Dwarf.h +++ include/llvm/BinaryFormat/Dwarf.h @@ -62,6 +62,9 @@ const uint32_t DW_CIE_ID = UINT32_MAX; const uint64_t DW64_CIE_ID = UINT64_MAX; +// TODO: It has to match the offset type (uint32_t or uint64_t) +#define DW_INVALID_OFFSET UINT32_MAX + enum Tag : uint16_t { #define HANDLE_DW_TAG(ID, NAME, VERSION, VENDOR) DW_TAG_##NAME = ID, #include "llvm/BinaryFormat/Dwarf.def" Index: include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h +++ include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h @@ -45,6 +45,14 @@ const RelocAddrMap& Relocs; public: + struct HashData { + uint32_t Offset = DW_INVALID_OFFSET; + uint16_t Tag = 0; + uint32_t TypeFlags = 0; + }; + + struct HashData HshData; + DWARFAcceleratorTable(DataExtractor AccelSection, DataExtractor StringSection, const RelocAddrMap &Relocs) : AccelSection(AccelSection), StringSection(StringSection), Relocs(Relocs) {} @@ -54,6 +62,7 @@ uint32_t getNumHashes(); uint32_t getSizeHdr(); uint32_t getHeaderDataLength(); + uint32_t readHeader(uint32_t Offset); void dump(raw_ostream &OS) const; }; Index: include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h +++ include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h @@ -29,6 +29,8 @@ // VTable anchor. ~DWARFCompileUnit() override; + uint32_t getHeaderSize() const override { return DWARFUnit::getHeaderSize(); } + void dump(raw_ostream &OS, DIDumpOptions DumpOpts); static const DWARFSectionKind Section = DW_SECT_INFO; Index: include/llvm/DebugInfo/DWARF/DWARFContext.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFContext.h +++ include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -276,6 +276,8 @@ std::shared_ptr getDWOContext(StringRef AbsolutePath); + bool containsUnitOffset(uint32_t Offset); + private: /// Return the compile unit that includes an offset (relative to .debug_info). DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset); Index: include/llvm/DebugInfo/DWARF/DWARFFormValue.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -93,7 +93,9 @@ /// getAsFoo functions below return the extracted value as Foo if only /// DWARFFormValue has form class is suitable for representing Foo. Optional getAsReference() const; + uint64_t getAsReference(uint32_t RefBase) const; Optional getAsUnsignedConstant() const; + uint64_t getAsUnsigned() const; Optional getAsSignedConstant() const; Optional getAsCString() const; Optional getAsAddress() const; Index: include/llvm/DebugInfo/DWARF/DWARFUnit.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -298,6 +298,17 @@ DWARFDie getParent(const DWARFDebugInfoEntry *Die); DWARFDie getSibling(const DWARFDebugInfoEntry *Die); + bool containsOffset(uint32_t Offset) { + extractDIEsIfNeeded(false); + if (!DieArray.empty()) { + for (auto it = DieArray.begin(); it != DieArray.end(); ++it) { + if (it->getOffset() == Offset) + return true; + } + } + return false; + } + /// \brief Return the DIE object for a given offset inside the /// unit's DIE vector. /// Index: include/llvm/DebugInfo/DWARF/DWARFVerifier.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFVerifier.h +++ include/llvm/DebugInfo/DWARF/DWARFVerifier.h @@ -21,6 +21,7 @@ class DWARFDie; class DWARFUnit; class DWARFAcceleratorTable; +class DWARFCompileUnit; /// A class that verifies DWARF debug information given a DWARF Context. class DWARFVerifier { Index: include/llvm/Support/DataExtractor.h =================================================================== --- include/llvm/Support/DataExtractor.h +++ include/llvm/Support/DataExtractor.h @@ -58,6 +58,20 @@ /// NULL will be returned. const char *getCStr(uint32_t *offset_ptr) const; + /// Extract a C string from \a Offset. + /// + /// Returns a pointer to a C String from the data at the offset + /// \a Offset. A variable length NULL terminated C + /// string will be extracted. + /// + /// \param[in,out] Offset + /// An offset within the data + /// + /// \return + /// A pointer to the C string value in the data. If the offset + /// is out of bounds NULL will be returned. + const char *peekCStr(uint32_t Offset) const ; + /// Extract a C string from \a *OffsetPtr. /// /// Returns a StringRef for the C String from the data at the offset Index: lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp +++ lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp @@ -62,6 +62,36 @@ return Hdr.HeaderDataLength; } +uint32_t DWARFAcceleratorTable::readHeader(uint32_t Offset) { + if (HdrData.Atoms.size() == 0) + return DW_INVALID_OFFSET; + + for (uint32_t i = 0; i < HdrData.Atoms.size(); ++i) { + DWARFFormValue FormValue(HdrData.Atoms[i].second); + if (!FormValue.extractValue(AccelSection, &Offset, NULL)) + return DW_INVALID_OFFSET; + + switch (HdrData.Atoms[i].first) { + case dwarf::DW_ATOM_die_offset: // DIE offset, check form for encoding + HshData.Offset = + (uint32_t)FormValue.getAsReference(HdrData.DIEOffsetBase); + break; + + case dwarf::DW_ATOM_die_tag: // DW_TAG value for the DIE + HshData.Tag = (uint16_t)FormValue.getAsUnsigned(); + break; + + case dwarf::DW_ATOM_type_flags: // Flags from enum TypeFlags + HshData.TypeFlags = (uint32_t)FormValue.getAsUnsigned(); + break; + + default: + break; + } + } + return Offset; +}; + LLVM_DUMP_METHOD void DWARFAcceleratorTable::dump(raw_ostream &OS) const { // Dump the header. OS << "Magic = " << format("0x%08x", Hdr.Magic) << '\n' Index: lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFContext.cpp +++ lib/DebugInfo/DWARF/DWARFContext.cpp @@ -634,6 +634,13 @@ return getCompileUnitForOffset(CUOffset); } +bool DWARFContext::containsUnitOffset(uint32_t Offset) { + DWARFCompileUnit *CU = this->getCompileUnitForOffset(Offset); + if (CU) + return CU->containsOffset(Offset); + return false; +} + static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, Index: lib/DebugInfo/DWARF/DWARFFormValue.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -356,20 +356,34 @@ IsBlock = true; break; case DW_FORM_data1: + Value.uval = Data.getU8(OffsetPtr); + break; case DW_FORM_ref1: + Value.uval = Data.getU8(OffsetPtr); + break; case DW_FORM_flag: + Value.uval = Data.getU8(OffsetPtr); + break; case DW_FORM_strx1: case DW_FORM_addrx1: Value.uval = Data.getU8(OffsetPtr); break; case DW_FORM_data2: + Value.uval = Data.getU16(OffsetPtr); + break; case DW_FORM_ref2: + Value.uval = Data.getU16(OffsetPtr); + break; case DW_FORM_strx2: case DW_FORM_addrx2: Value.uval = Data.getU16(OffsetPtr); break; case DW_FORM_data4: + Value.uval = Data.getU32(OffsetPtr); + break; case DW_FORM_ref4: + Value.uval = Data.getU32(OffsetPtr); + break; case DW_FORM_ref_sup4: case DW_FORM_strx4: case DW_FORM_addrx4: { @@ -378,7 +392,11 @@ break; } case DW_FORM_data8: + Value.uval = Data.getU64(OffsetPtr); + break; case DW_FORM_ref8: + Value.uval = Data.getU64(OffsetPtr); + break; case DW_FORM_ref_sup8: Value.uval = Data.getU64(OffsetPtr); break; @@ -386,6 +404,8 @@ Value.sval = Data.getSLEB128(OffsetPtr); break; case DW_FORM_udata: + Value.uval = Data.getULEB128(OffsetPtr); + break; case DW_FORM_ref_udata: Value.uval = Data.getULEB128(OffsetPtr); break; @@ -397,7 +417,11 @@ Indirect = true; break; case DW_FORM_strp: + Value.uval = Data.getU32(OffsetPtr); + break; case DW_FORM_sec_offset: + Value.uval = Data.getU32(OffsetPtr); + break; case DW_FORM_GNU_ref_alt: case DW_FORM_GNU_strp_alt: case DW_FORM_line_strp: @@ -670,6 +694,24 @@ } } +uint64_t DWARFFormValue::getAsReference(uint32_t RefBase) const { + uint64_t DIEOffset = Value.uval; + + switch (Form) { + case DW_FORM_ref1: + case DW_FORM_ref2: + case DW_FORM_ref4: + case DW_FORM_ref8: + case DW_FORM_ref_udata: + DIEOffset += RefBase; + break; + + default: + break; + } + return DIEOffset; +} + Optional DWARFFormValue::getAsSectionOffset() const { if (!isFormClass(FC_SectionOffset)) return None; @@ -683,6 +725,10 @@ return Value.uval; } +uint64_t DWARFFormValue::getAsUnsigned() const { + return Value.uval; +} + Optional DWARFFormValue::getAsSignedConstant() const { if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) || (Form == DW_FORM_udata && Index: lib/DebugInfo/DWARF/DWARFVerifier.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -298,6 +298,8 @@ uint32_t BucketsOffset = AppleNames.getSizeHdr() + AppleNames.getHeaderDataLength(); + uint32_t HashesBase = BucketsOffset + NumBuckets * 4; + uint32_t OffsetsBase = HashesBase + NumHashes * 4; for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) { uint32_t HashIdx = AppleNamesSection.getU32(&BucketsOffset); @@ -307,5 +309,50 @@ ++NumAppleNamesErrors; } } + + for (uint32_t HashIdx = 0; HashIdx < NumHashes; ++HashIdx) { + uint32_t HashOffset = HashesBase + 4 * HashIdx; + uint32_t DataOffset = OffsetsBase + 4 * HashIdx; + uint32_t Hash = AppleNamesSection.getU32(&HashOffset); + uint32_t HashDataOffset = AppleNamesSection.getU32(&DataOffset); + if (!AppleNamesSection.isValidOffsetForDataOfSize(HashDataOffset, + sizeof(uint64_t))) { + OS << format("error: Hash[%d] has invalid HashData offset: 0x%08x\n", + HashIdx, HashDataOffset); + ++NumAppleNamesErrors; + } + + uint32_t StrpOffset; + uint32_t StringCount = 0; + while ((StrpOffset = AppleNamesSection.getU32(&HashDataOffset)) != 0) { + const uint32_t NumHashDataObjects = + AppleNamesSection.getU32(&HashDataOffset); + for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects; + ++HashDataIdx) { + const uint32_t HashDataOffsetStart = HashDataOffset; + HashDataOffset = AppleNames.readHeader(HashDataOffset); + if (HashDataOffset == DW_INVALID_OFFSET) { + OS << format("error: failed to read HashData at 0x%08x\n", + HashDataOffsetStart); + ++NumAppleNamesErrors; + } else if (!DCtx.containsUnitOffset(AppleNames.HshData.Offset)) { + const uint32_t BucketIdx = + NumBuckets ? (Hash % NumBuckets) : UINT32_MAX; + const char *Name = StrData.peekCStr(StrpOffset); + if (!Name) + Name = ""; + + OS << format("error: .apple_names Bucket[%d] Hash[%d] = 0x%08x " + "Str[%u] = 0x%08x " + "DIE[%d] = 0x%08x is not a valid DIE offset for %s.\n", + BucketIdx, HashIdx, Hash, StringCount, StrpOffset, + HashDataIdx, AppleNames.HshData.Offset, Name); + + ++NumAppleNamesErrors; + } + } + ++StringCount; + } + } return NumAppleNamesErrors == 0; } Index: lib/Support/DataExtractor.cpp =================================================================== --- lib/Support/DataExtractor.cpp +++ lib/Support/DataExtractor.cpp @@ -128,6 +128,14 @@ return nullptr; } +const char *DataExtractor::peekCStr(uint32_t Offset) const { + StringRef::size_type pos = Data.find('\0', Offset); + if (pos != StringRef::npos) { + return Data.data() + Offset; + } + return nullptr; +} + StringRef DataExtractor::getCStrRef(uint32_t *OffsetPtr) const { uint32_t Start = *OffsetPtr; StringRef::size_type Pos = Data.find('\0', Start); Index: test/tools/llvm-dwarfdump/X86/apple_names_verify_buckets_hashdataoffset.s =================================================================== --- /dev/null +++ test/tools/llvm-dwarfdump/X86/apple_names_verify_buckets_hashdataoffset.s @@ -0,0 +1,194 @@ +# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \ +# RUN: | not llvm-dwarfdump -verify - \ +# RUN: | FileCheck %s + +# CHECK: Verifying .apple_names... +# CHECK-NEXT: error: Bucket[0] has invalid hash index: [-2] +# CHECK-NEXT: error: Hash[0] has invalid HashData offset: 0x000000b2 + +# This test is meant to verify that the -verify option +# in llvm-dwarfdump, correctly identifies +# an invalid hash index for bucket[0] in the .apple_names section, +# as well as an invalid HashData offset for Hash[0] in the same section. + + .section __TEXT,__text,regular,pure_instructions + .file 1 "basic.c" + .comm _i,4,2 ## @i + .section __DWARF,__debug_str,regular,debug +Linfo_string: + .asciz "basic.c" ## string offset=42 + .asciz "i" ## string offset=84 + .asciz "int" ## string offset=86 + .section __DWARF,__debug_loc,regular,debug +Lsection_debug_loc: + .section __DWARF,__debug_abbrev,regular,debug +Lsection_abbrev: + .byte 1 ## Abbreviation Code + .byte 17 ## DW_TAG_compile_unit + .byte 1 ## DW_CHILDREN_yes + .byte 37 ## DW_AT_producer + .byte 14 ## DW_FORM_strp + .byte 19 ## DW_AT_language + .byte 5 ## DW_FORM_data2 + .byte 3 ## DW_AT_name + .byte 14 ## DW_FORM_strp + .byte 16 ## DW_AT_stmt_list + .byte 23 ## DW_FORM_sec_offset + .byte 27 ## DW_AT_comp_dir + .byte 14 ## DW_FORM_strp + .byte 0 ## EOM(1) + .byte 0 ## EOM(2) + .byte 2 ## Abbreviation Code + .byte 52 ## DW_TAG_variable + .byte 0 ## DW_CHILDREN_no + .byte 3 ## DW_AT_name + .byte 14 ## DW_FORM_strp + .byte 73 ## DW_AT_type + .byte 19 ## DW_FORM_ref4 + .byte 63 ## DW_AT_external + .byte 25 ## DW_FORM_flag_present + .byte 58 ## DW_AT_decl_file + .byte 11 ## DW_FORM_data1 + .byte 59 ## DW_AT_decl_line + .byte 11 ## DW_FORM_data1 + .byte 2 ## DW_AT_location + .byte 24 ## DW_FORM_exprloc + .byte 0 ## EOM(1) + .byte 0 ## EOM(2) + .byte 3 ## Abbreviation Code + .byte 36 ## DW_TAG_base_type + .byte 0 ## DW_CHILDREN_no + .byte 3 ## DW_AT_name + .byte 14 ## DW_FORM_strp + .byte 62 ## DW_AT_encoding + .byte 11 ## DW_FORM_data1 + .byte 11 ## DW_AT_byte_size + .byte 11 ## DW_FORM_data1 + .byte 0 ## EOM(1) + .byte 0 ## EOM(2) + .byte 0 ## EOM(3) + .section __DWARF,__debug_info,regular,debug +Lsection_info: +Lcu_begin0: + .long 55 ## Length of Unit + .short 4 ## DWARF version number +Lset0 = Lsection_abbrev-Lsection_abbrev ## Offset Into Abbrev. Section + .long Lset0 + .byte 8 ## Address Size (in bytes) + .byte 1 ## Abbrev [1] 0xb:0x30 DW_TAG_compile_unit + .long 0 ## DW_AT_producer + .short 12 ## DW_AT_language + .long 42 ## DW_AT_name +Lset1 = Lline_table_start0-Lsection_line ## DW_AT_stmt_list + .long Lset1 + .long 50 ## DW_AT_comp_dir + .byte 2 ## Abbrev [2] 0x1e:0x15 DW_TAG_variable + .long 84 ## DW_AT_name + .long 51 ## DW_AT_type + ## DW_AT_external + .byte 1 ## DW_AT_decl_file + .byte 1 ## DW_AT_decl_line + .byte 9 ## DW_AT_location + .byte 3 + .quad _i + .byte 3 ## Abbrev [3] 0x33:0x7 DW_TAG_base_type + .long 86 ## DW_AT_name + .byte 5 ## DW_AT_encoding + .byte 4 ## DW_AT_byte_size + .byte 0 ## End Of Children Mark + .section __DWARF,__debug_ranges,regular,debug +Ldebug_range: + .section __DWARF,__debug_macinfo,regular,debug +Ldebug_macinfo: +Lcu_macro_begin0: + .byte 0 ## End Of Macro List Mark + .section __DWARF,__apple_names,regular,debug +Lnames_begin: + .long 1212240712 ## Header Magic + .short 1 ## Header Version + .short 0 ## Header Hash Function + .long 1 ## Header Bucket Count + .long 1 ## Header Hash Count + .long 12 ## Header Data Length + .long 0 ## HeaderData Die Offset Base + .long 1 ## HeaderData Atom Count + .short 1 ## DW_ATOM_die_offset + .short 6 ## DW_FORM_data4 + .long -2 ## Bucket 0 -- error: Bucket[0] has invalid hash index: [-2] + .long 177678 ## Hash in Bucket 0 + .long Lobjc_begin ## Offset in Bucket 0 -- error: Hash[0] has invalid HashData offset: 0x000000b2 +LNames0: + .long 84 ## i + .long 1 ## Num DIEs + .long 30 + .long 0 + .section __DWARF,__apple_objc,regular,debug +Lobjc_begin: + .long 1212240712 ## Header Magic + .short 1 ## Header Version + .short 0 ## Header Hash Function + .long 1 ## Header Bucket Count + .long 0 ## Header Hash Count + .long 12 ## Header Data Length + .long 0 ## HeaderData Die Offset Base + .long 1 ## HeaderData Atom Count + .short 1 ## DW_ATOM_die_offset + .short 6 ## DW_FORM_data4 + .long -1 ## Bucket 0 + .section __DWARF,__apple_namespac,regular,debug +Lnamespac_begin: + .long 1212240712 ## Header Magic + .short 1 ## Header Version + .short 0 ## Header Hash Function + .long 1 ## Header Bucket Count + .long 0 ## Header Hash Count + .long 12 ## Header Data Length + .long 0 ## HeaderData Die Offset Base + .long 1 ## HeaderData Atom Count + .short 1 ## DW_ATOM_die_offset + .short 6 ## DW_FORM_data4 + .long -1 ## Bucket 0 + .section __DWARF,__apple_types,regular,debug +Ltypes_begin: + .long 1212240712 ## Header Magic + .short 1 ## Header Version + .short 0 ## Header Hash Function + .long 1 ## Header Bucket Count + .long 1 ## Header Hash Count + .long 20 ## Header Data Length + .long 0 ## HeaderData Die Offset Base + .long 3 ## HeaderData Atom Count + .short 1 ## DW_ATOM_die_offset + .short 6 ## DW_FORM_data4 + .short 3 ## DW_ATOM_die_tag + .short 5 ## DW_FORM_data2 + .short 4 ## DW_ATOM_type_flags + .short 11 ## DW_FORM_data1 + .long 0 ## Bucket 0 + .long 193495088 ## Hash in Bucket 0 + .long Ltypes0-Ltypes_begin ## Offset in Bucket 0 +Ltypes0: + .long 86 ## int + .long 1 ## Num DIEs + .long 51 + .short 36 + .byte 0 + .long 0 + .section __DWARF,__apple_exttypes,regular,debug +Lexttypes_begin: + .long 1212240712 ## Header Magic + .short 1 ## Header Version + .short 0 ## Header Hash Function + .long 1 ## Header Bucket Count + .long 0 ## Header Hash Count + .long 12 ## Header Data Length + .long 0 ## HeaderData Die Offset Base + .long 1 ## HeaderData Atom Count + .short 7 ## DW_ATOM_ext_types + .short 6 ## DW_FORM_data4 + .long -1 ## Bucket 0 + +.subsections_via_symbols + .section __DWARF,__debug_line,regular,debug +Lsection_line: +Lline_table_start0: Index: test/tools/llvm-dwarfdump/X86/apple_names_verify_die.s =================================================================== --- /dev/null +++ test/tools/llvm-dwarfdump/X86/apple_names_verify_die.s @@ -0,0 +1,193 @@ +# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \ +# RUN: | not llvm-dwarfdump -verify - \ +# RUN: | FileCheck %s + +# CHECK: Verifying .apple_names... +# CHECK-NEXT: error: .apple_names Bucket[0] Hash[0] = 0x0002b60e Str[0] = 0x00000054 DIE[0] = 0xffffffff is not a valid DIE offset for . + +# This test is meant to verify that the -verify option +# in llvm-dwarfdump, correctly identifies +# that the DIE is not valid since the DW_ATOM_DIE_OFFSET is not the +# one it should be. + + .section __TEXT,__text,regular,pure_instructions + .file 1 "basic.c" + .comm _i,4,2 ## @i + .section __DWARF,__debug_str,regular,debug +Linfo_string: + .asciz "basic.c" ## string offset=42 + .asciz "i" ## string offset=84 + .asciz "int" ## string offset=86 + .section __DWARF,__debug_loc,regular,debug +Lsection_debug_loc: + .section __DWARF,__debug_abbrev,regular,debug +Lsection_abbrev: + .byte 1 ## Abbreviation Code + .byte 17 ## DW_TAG_compile_unit + .byte 1 ## DW_CHILDREN_yes + .byte 37 ## DW_AT_producer + .byte 14 ## DW_FORM_strp + .byte 19 ## DW_AT_language + .byte 5 ## DW_FORM_data2 + .byte 3 ## DW_AT_name + .byte 14 ## DW_FORM_strp + .byte 16 ## DW_AT_stmt_list + .byte 23 ## DW_FORM_sec_offset + .byte 27 ## DW_AT_comp_dir + .byte 14 ## DW_FORM_strp + .byte 0 ## EOM(1) + .byte 0 ## EOM(2) + .byte 2 ## Abbreviation Code + .byte 52 ## DW_TAG_variable + .byte 0 ## DW_CHILDREN_no + .byte 3 ## DW_AT_name + .byte 14 ## DW_FORM_strp + .byte 73 ## DW_AT_type + .byte 19 ## DW_FORM_ref4 + .byte 63 ## DW_AT_external + .byte 25 ## DW_FORM_flag_present + .byte 58 ## DW_AT_decl_file + .byte 11 ## DW_FORM_data1 + .byte 59 ## DW_AT_decl_line + .byte 11 ## DW_FORM_data1 + .byte 2 ## DW_AT_location + .byte 24 ## DW_FORM_exprloc + .byte 0 ## EOM(1) + .byte 0 ## EOM(2) + .byte 3 ## Abbreviation Code + .byte 36 ## DW_TAG_base_type + .byte 0 ## DW_CHILDREN_no + .byte 3 ## DW_AT_name + .byte 14 ## DW_FORM_strp + .byte 62 ## DW_AT_encoding + .byte 11 ## DW_FORM_data1 + .byte 11 ## DW_AT_byte_size + .byte 11 ## DW_FORM_data1 + .byte 0 ## EOM(1) + .byte 0 ## EOM(2) + .byte 0 ## EOM(3) + .section __DWARF,__debug_info,regular,debug +Lsection_info: +Lcu_begin0: + .long 55 ## Length of Unit + .short 4 ## DWARF version number +Lset0 = Lsection_abbrev-Lsection_abbrev ## Offset Into Abbrev. Section + .long Lset0 + .byte 8 ## Address Size (in bytes) + .byte 1 ## Abbrev [1] 0xb:0x30 DW_TAG_compile_unit + .long 0 ## DW_AT_producer + .short 12 ## DW_AT_language + .long 42 ## DW_AT_name +Lset1 = Lline_table_start0-Lsection_line ## DW_AT_stmt_list + .long Lset1 + .long 50 ## DW_AT_comp_dir + .byte 2 ## Abbrev [2] 0x1e:0x15 DW_TAG_variable + .long 84 ## DW_AT_name + .long 51 ## DW_AT_type + ## DW_AT_external + .byte 1 ## DW_AT_decl_file + .byte 1 ## DW_AT_decl_line + .byte 9 ## DW_AT_location + .byte 3 + .quad _i + .byte 3 ## Abbrev [3] 0x33:0x7 DW_TAG_base_type + .long 86 ## DW_AT_name + .byte 5 ## DW_AT_encoding + .byte 4 ## DW_AT_byte_size + .byte 0 ## End Of Children Mark + .section __DWARF,__debug_ranges,regular,debug +Ldebug_range: + .section __DWARF,__debug_macinfo,regular,debug +Ldebug_macinfo: +Lcu_macro_begin0: + .byte 0 ## End Of Macro List Mark + .section __DWARF,__apple_names,regular,debug +Lnames_begin: + .long 1212240712 ## Header Magic + .short 1 ## Header Version + .short 0 ## Header Hash Function + .long 1 ## Header Bucket Count + .long 1 ## Header Hash Count + .long 12 ## Header Data Length + .long 0 ## HeaderData Die Offset Base + .long 1 ## HeaderData Atom Count + .short 400 ## DW_ATOM_die_offset -- error: .apple_names Bucket[0] Hash[0] = 0x0002b60e Str[0] = 0x00000054 DIE[0] = 0xffffffff is not a valid DIE offset for . + .short 6 ## DW_FORM_data4 + .long 0 ## Bucket 0 + .long 177678 ## Hash in Bucket 0 + .long LNames0-Lnames_begin ## Offset in Bucket 0 +LNames0: + .long 84 ## i + .long 1 ## Num DIEs + .long 30 + .long 0 + .section __DWARF,__apple_objc,regular,debug +Lobjc_begin: + .long 1212240712 ## Header Magic + .short 1 ## Header Version + .short 0 ## Header Hash Function + .long 1 ## Header Bucket Count + .long 0 ## Header Hash Count + .long 12 ## Header Data Length + .long 0 ## HeaderData Die Offset Base + .long 1 ## HeaderData Atom Count + .short 1 ## DW_ATOM_die_offset + .short 6 ## DW_FORM_data4 + .long -1 ## Bucket 0 + .section __DWARF,__apple_namespac,regular,debug +Lnamespac_begin: + .long 1212240712 ## Header Magic + .short 1 ## Header Version + .short 0 ## Header Hash Function + .long 1 ## Header Bucket Count + .long 0 ## Header Hash Count + .long 12 ## Header Data Length + .long 0 ## HeaderData Die Offset Base + .long 1 ## HeaderData Atom Count + .short 1 ## DW_ATOM_die_offset + .short 6 ## DW_FORM_data4 + .long -1 ## Bucket 0 + .section __DWARF,__apple_types,regular,debug +Ltypes_begin: + .long 1212240712 ## Header Magic + .short 1 ## Header Version + .short 0 ## Header Hash Function + .long 1 ## Header Bucket Count + .long 1 ## Header Hash Count + .long 20 ## Header Data Length + .long 0 ## HeaderData Die Offset Base + .long 3 ## HeaderData Atom Count + .short 1 ## DW_ATOM_die_offset + .short 6 ## DW_FORM_data4 + .short 3 ## DW_ATOM_die_tag + .short 5 ## DW_FORM_data2 + .short 4 ## DW_ATOM_type_flags + .short 11 ## DW_FORM_data1 + .long 0 ## Bucket 0 + .long 193495088 ## Hash in Bucket 0 + .long Ltypes0-Ltypes_begin ## Offset in Bucket 0 +Ltypes0: + .long 86 ## int + .long 1 ## Num DIEs + .long 51 + .short 36 + .byte 0 + .long 0 + .section __DWARF,__apple_exttypes,regular,debug +Lexttypes_begin: + .long 1212240712 ## Header Magic + .short 1 ## Header Version + .short 0 ## Header Hash Function + .long 1 ## Header Bucket Count + .long 0 ## Header Hash Count + .long 12 ## Header Data Length + .long 0 ## HeaderData Die Offset Base + .long 1 ## HeaderData Atom Count + .short 7 ## DW_ATOM_ext_types + .short 6 ## DW_FORM_data4 + .long -1 ## Bucket 0 + +.subsections_via_symbols + .section __DWARF,__debug_line,regular,debug +Lsection_line: +Lline_table_start0: Index: test/tools/llvm-dwarfdump/X86/apple_names_verify_hashdata_start.s =================================================================== --- test/tools/llvm-dwarfdump/X86/apple_names_verify_hashdata_start.s +++ test/tools/llvm-dwarfdump/X86/apple_names_verify_hashdata_start.s @@ -3,11 +3,11 @@ # RUN: | FileCheck %s # CHECK: Verifying .apple_names... -# CHECK-NEXT: error: Bucket[0] has invalid hash index: [-2] +# CHECK-NEXT: error: failed to read HashData at 0x00000034 # This test is meant to verify that the -verify option # in llvm-dwarfdump, correctly identifies -# an invalid hash index for bucket[0] in the .apple_names section. +# that there's no data to read since number of Atoms is 0. .section __TEXT,__text,regular,pure_instructions .file 1 "basic.c" @@ -109,10 +109,10 @@ .long 1 ## Header Hash Count .long 12 ## Header Data Length .long 0 ## HeaderData Die Offset Base - .long 1 ## HeaderData Atom Count + .long 0 ## HeaderData Atom Count -- error: failed to read HashData at 0x00000034 .short 1 ## DW_ATOM_die_offset .short 6 ## DW_FORM_data4 - .long -2 ## Bucket 0 -- error: Bucket[0] has invalid hash index: [-2] + .long 0 ## Bucket 0 .long 177678 ## Hash in Bucket 0 .long LNames0-Lnames_begin ## Offset in Bucket 0 LNames0: