diff --git a/llvm/test/tools/llvm-dwp/Inputs/simple/notypes/a-v5.dwo b/llvm/test/tools/llvm-dwp/Inputs/simple/notypes/a-v5.dwo new file mode 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@= 5) { + // Unit_length field should not include the length field(4 bytes) it self. + Out.EmitIntValue(Size - 4, 4); + Out.EmitIntValue(5, 2); // Version. + Out.EmitIntValue(0, 2); // Padding. + } + uint64_t Offset = Version >= 5 ? 8 : 0; while (Offset < Size) { auto OldOffset = Data.getU32(&Offset); auto NewOffset = OffsetRemapping[OldOffset]; @@ -117,16 +125,23 @@ }; static Expected -getIndexedString(dwarf::Form Form, DataExtractor InfoData, - uint64_t &InfoOffset, StringRef StrOffsets, StringRef Str) { +getIndexedString(dwarf::Form Form, DataExtractor InfoData, uint64_t &InfoOffset, + StringRef StrOffsets, StringRef Str, uint16_t Version) { + uint64_t StrOffsetsOffset = 0; if (Form == dwarf::DW_FORM_string) return InfoData.getCStr(&InfoOffset); - if (Form != dwarf::DW_FORM_GNU_str_index) + if (Form != dwarf::DW_FORM_strx1 && Form != dwarf::DW_FORM_strx2 && + Form != dwarf::DW_FORM_strx3 && Form != dwarf::DW_FORM_strx4 && + Form != dwarf::DW_FORM_GNU_str_index) return make_error( - "string field encoded without DW_FORM_string or DW_FORM_GNU_str_index"); + "string field encoded without DW_FORM_string or DW_FORM_GNU_str_index \ + or DW_FORM_strx*"); auto StrIndex = InfoData.getULEB128(&InfoOffset); DataExtractor StrOffsetsData(StrOffsets, true, 0); - uint64_t StrOffsetsOffset = 4 * StrIndex; + if (Version >= 5) + StrOffsetsOffset = 4 * StrIndex + 8 /*Header Size*/; + else + StrOffsetsOffset = 4 * StrIndex; uint64_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset); DataExtractor StrData(Str, true, 0); return StrData.getCStr(&StrOffset); @@ -140,6 +155,8 @@ DataExtractor InfoData(Info, true, 0); dwarf::DwarfFormat Format = dwarf::DwarfFormat::DWARF32; uint64_t Length = InfoData.getU32(&Offset); + CompileUnitIdentifiers ID; + Optional Signature = None; // If the length is 0xffffffff, then this indictes that this is a DWARF 64 // stream and the length is actually encoded into a 64 bit value that follows. if (Length == 0xffffffffU) { @@ -147,9 +164,17 @@ Length = InfoData.getU64(&Offset); } uint16_t Version = InfoData.getU16(&Offset); + if (Version >= 5) { + auto UnitType = InfoData.getU8(&Offset); + if (UnitType != dwarf::DW_UT_split_compile) + return make_error( + "unit type DW_UT_split_compile type not found in debug_info header"); + } InfoData.getU32(&Offset); // Abbrev offset (should be zero) uint8_t AddrSize = InfoData.getU8(&Offset); + if (Version >= 5) + Signature = InfoData.getU64(&Offset); uint32_t AbbrCode = InfoData.getULEB128(&Offset); DataExtractor AbbrevData(Abbrev, true, 0); @@ -161,23 +186,22 @@ AbbrevData.getU8(&AbbrevOffset); uint32_t Name; dwarf::Form Form; - CompileUnitIdentifiers ID; - Optional Signature = None; while ((Name = AbbrevData.getULEB128(&AbbrevOffset)) | (Form = static_cast(AbbrevData.getULEB128(&AbbrevOffset))) && (Name != 0 || Form != 0)) { switch (Name) { case dwarf::DW_AT_name: { Expected EName = - getIndexedString(Form, InfoData, Offset, StrOffsets, Str); + getIndexedString(Form, InfoData, Offset, StrOffsets, Str, Version); if (!EName) return EName.takeError(); ID.Name = *EName; break; } - case dwarf::DW_AT_GNU_dwo_name: { + case dwarf::DW_AT_GNU_dwo_name: + case dwarf::DW_AT_dwo_name: { Expected EName = - getIndexedString(Form, InfoData, Offset, StrOffsets, Str); + getIndexedString(Form, InfoData, Offset, StrOffsets, Str, Version); if (!EName) return EName.takeError(); ID.DWOName = *EName; @@ -562,8 +586,19 @@ if (InfoSection.empty()) continue; + /*Here we're extracting Dwarf Version from Info Section to pass it + * for reconstruction of debug_str_offset section based on Dwarf Version. + */ + auto getVersion = [&]() -> uint16_t { + DataExtractor InfoData(InfoSection, true, 0); + // Version field is located just after length field in Info section + // header. For DWARF32 length field is of 4 bytes. + uint64_t Offset = 4; + return InfoData.getU16(&Offset); + }; + auto DwarfVersion = getVersion(); writeStringsAndOffsets(Out, Strings, StrOffsetSection, CurStrSection, - CurStrOffsetSection); + CurStrOffsetSection, DwarfVersion); if (CurCUIndexSection.empty()) { Expected EID = getCUIdentifiers(