1c2dfd502SJames Henderson //===- DWARFDebugRnglists.cpp ---------------------------------------------===// 2c2dfd502SJames Henderson // 3c2dfd502SJames Henderson // The LLVM Compiler Infrastructure 4c2dfd502SJames Henderson // 5c2dfd502SJames Henderson // This file is distributed under the University of Illinois Open Source 6c2dfd502SJames Henderson // License. See LICENSE.TXT for details. 7c2dfd502SJames Henderson // 8c2dfd502SJames Henderson //===----------------------------------------------------------------------===// 9c2dfd502SJames Henderson 10c2dfd502SJames Henderson #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h" 11c2dfd502SJames Henderson #include "llvm/BinaryFormat/Dwarf.h" 12*ad60559bSWolfgang Pieb #include "llvm/DebugInfo/DWARF/DWARFUnit.h" 13c2dfd502SJames Henderson #include "llvm/Support/Error.h" 14c2dfd502SJames Henderson #include "llvm/Support/Format.h" 15c2dfd502SJames Henderson #include "llvm/Support/raw_ostream.h" 16c2dfd502SJames Henderson 17c2dfd502SJames Henderson using namespace llvm; 18c2dfd502SJames Henderson 193fb9e3f3SWolfgang Pieb void DWARFDebugRnglistTable::clear() { 20c2dfd502SJames Henderson HeaderData = {}; 21c2dfd502SJames Henderson Offsets.clear(); 22c2dfd502SJames Henderson Ranges.clear(); 23c2dfd502SJames Henderson } 24c2dfd502SJames Henderson 25c2dfd502SJames Henderson template <typename... Ts> 26c2dfd502SJames Henderson static Error createError(char const *Fmt, const Ts &... Vals) { 27c2dfd502SJames Henderson std::string Buffer; 28c2dfd502SJames Henderson raw_string_ostream Stream(Buffer); 29c2dfd502SJames Henderson Stream << format(Fmt, Vals...); 30c2dfd502SJames Henderson return make_error<StringError>(Stream.str(), inconvertibleErrorCode()); 31c2dfd502SJames Henderson } 32c2dfd502SJames Henderson 333fb9e3f3SWolfgang Pieb Error DWARFDebugRnglistTable::extractHeaderAndOffsets(DWARFDataExtractor Data, 34c2dfd502SJames Henderson uint32_t *OffsetPtr) { 35a0729d41SWolfgang Pieb HeaderOffset = *OffsetPtr; 36c2dfd502SJames Henderson // Read and verify the length field. 37c2dfd502SJames Henderson if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t))) 38c2dfd502SJames Henderson return createError("section is not large enough to contain a " 39c2dfd502SJames Henderson ".debug_rnglists table length at offset 0x%" PRIx32, 40c2dfd502SJames Henderson *OffsetPtr); 41c2dfd502SJames Henderson // TODO: Add support for DWARF64. 42c2dfd502SJames Henderson HeaderData.Length = Data.getU32(OffsetPtr); 43a0729d41SWolfgang Pieb if (HeaderData.Length == 0xffffffffu) 44a0729d41SWolfgang Pieb return createError( 45a0729d41SWolfgang Pieb "DWARF64 is not supported in .debug_rnglists at offset 0x%" PRIx32, 46a0729d41SWolfgang Pieb HeaderOffset); 47*ad60559bSWolfgang Pieb Format = dwarf::DwarfFormat::DWARF32; 48c2dfd502SJames Henderson if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header)) 49c2dfd502SJames Henderson return createError(".debug_rnglists table at offset 0x%" PRIx32 50c2dfd502SJames Henderson " has too small length (0x%" PRIx32 51c2dfd502SJames Henderson ") to contain a complete header", 52a0729d41SWolfgang Pieb HeaderOffset, length()); 53a0729d41SWolfgang Pieb uint32_t End = HeaderOffset + length(); 54a0729d41SWolfgang Pieb if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset)) 55c2dfd502SJames Henderson return createError( 56c2dfd502SJames Henderson "section is not large enough to contain a .debug_rnglists table " 57c2dfd502SJames Henderson "of length 0x%" PRIx32 " at offset 0x%" PRIx32, 58a0729d41SWolfgang Pieb length(), HeaderOffset); 59c2dfd502SJames Henderson 60c2dfd502SJames Henderson HeaderData.Version = Data.getU16(OffsetPtr); 61c2dfd502SJames Henderson HeaderData.AddrSize = Data.getU8(OffsetPtr); 62c2dfd502SJames Henderson HeaderData.SegSize = Data.getU8(OffsetPtr); 63c2dfd502SJames Henderson HeaderData.OffsetEntryCount = Data.getU32(OffsetPtr); 64c2dfd502SJames Henderson 65c2dfd502SJames Henderson // Perform basic validation of the remaining header fields. 66c2dfd502SJames Henderson if (HeaderData.Version != 5) 67c2dfd502SJames Henderson return createError("unrecognised .debug_rnglists table version %" PRIu16 68c2dfd502SJames Henderson " in table at offset 0x%" PRIx32, 69a0729d41SWolfgang Pieb HeaderData.Version, HeaderOffset); 70c2dfd502SJames Henderson if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8) 71c2dfd502SJames Henderson return createError(".debug_rnglists table at offset 0x%" PRIx32 72c2dfd502SJames Henderson " has unsupported address size %hhu", 73a0729d41SWolfgang Pieb HeaderOffset, HeaderData.AddrSize); 74c2dfd502SJames Henderson if (HeaderData.SegSize != 0) 75c2dfd502SJames Henderson return createError(".debug_rnglists table at offset 0x%" PRIx32 76c2dfd502SJames Henderson " has unsupported segment selector size %" PRIu8, 77a0729d41SWolfgang Pieb HeaderOffset, HeaderData.SegSize); 78a0729d41SWolfgang Pieb if (End < HeaderOffset + sizeof(HeaderData) + 79c2dfd502SJames Henderson HeaderData.OffsetEntryCount * sizeof(uint32_t)) 80c2dfd502SJames Henderson return createError(".debug_rnglists table at offset 0x%" PRIx32 81c2dfd502SJames Henderson " has more offset entries (%" PRIu32 82c2dfd502SJames Henderson ") than there is space for", 83a0729d41SWolfgang Pieb HeaderOffset, HeaderData.OffsetEntryCount); 84c2dfd502SJames Henderson Data.setAddressSize(HeaderData.AddrSize); 85c2dfd502SJames Henderson for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I) 86c2dfd502SJames Henderson Offsets.push_back(Data.getU32(OffsetPtr)); 873fb9e3f3SWolfgang Pieb return Error::success(); 883fb9e3f3SWolfgang Pieb } 89c2dfd502SJames Henderson 903fb9e3f3SWolfgang Pieb Error DWARFDebugRnglist::RangeListEntry::extract(DWARFDataExtractor Data, 913fb9e3f3SWolfgang Pieb uint32_t End, 923fb9e3f3SWolfgang Pieb uint32_t *OffsetPtr) { 933fb9e3f3SWolfgang Pieb Offset = *OffsetPtr; 94*ad60559bSWolfgang Pieb SectionIndex = -1ULL; 953fb9e3f3SWolfgang Pieb // The caller should guarantee that we have at least 1 byte available, so 963fb9e3f3SWolfgang Pieb // we just assert instead of revalidate. 973fb9e3f3SWolfgang Pieb assert(*OffsetPtr < End && 983fb9e3f3SWolfgang Pieb "not enough space to extract a rangelist encoding"); 99c2dfd502SJames Henderson uint8_t Encoding = Data.getU8(OffsetPtr); 1003fb9e3f3SWolfgang Pieb 101c2dfd502SJames Henderson switch (Encoding) { 102c2dfd502SJames Henderson case dwarf::DW_RLE_end_of_list: 1033fb9e3f3SWolfgang Pieb Value0 = Value1 = 0; 104c2dfd502SJames Henderson break; 105c2dfd502SJames Henderson // TODO: Support other encodings. 106c2dfd502SJames Henderson case dwarf::DW_RLE_base_addressx: 107c2dfd502SJames Henderson return createError("unsupported rnglists encoding DW_RLE_base_addressx " 108c2dfd502SJames Henderson "at offset 0x%" PRIx32, 109c2dfd502SJames Henderson *OffsetPtr - 1); 110c2dfd502SJames Henderson case dwarf::DW_RLE_startx_endx: 111c2dfd502SJames Henderson return createError("unsupported rnglists encoding DW_RLE_startx_endx at " 112c2dfd502SJames Henderson "offset 0x%" PRIx32, 113c2dfd502SJames Henderson *OffsetPtr - 1); 114c2dfd502SJames Henderson case dwarf::DW_RLE_startx_length: 115c2dfd502SJames Henderson return createError("unsupported rnglists encoding DW_RLE_startx_length " 116c2dfd502SJames Henderson "at offset 0x%" PRIx32, 117c2dfd502SJames Henderson *OffsetPtr - 1); 118ab068eaaSWolfgang Pieb case dwarf::DW_RLE_offset_pair: { 119ab068eaaSWolfgang Pieb uint32_t PreviousOffset = *OffsetPtr - 1; 1203fb9e3f3SWolfgang Pieb Value0 = Data.getULEB128(OffsetPtr); 1213fb9e3f3SWolfgang Pieb Value1 = Data.getULEB128(OffsetPtr); 122ab068eaaSWolfgang Pieb if (End < *OffsetPtr) 123ab068eaaSWolfgang Pieb return createError("read past end of table when reading " 124ab068eaaSWolfgang Pieb "DW_RLE_offset_pair encoding at offset 0x%" PRIx32, 125ab068eaaSWolfgang Pieb PreviousOffset); 126ab068eaaSWolfgang Pieb break; 127ab068eaaSWolfgang Pieb } 128ab068eaaSWolfgang Pieb case dwarf::DW_RLE_base_address: { 1293fb9e3f3SWolfgang Pieb if ((End - *OffsetPtr) < Data.getAddressSize()) 130ab068eaaSWolfgang Pieb return createError("insufficient space remaining in table for " 131ab068eaaSWolfgang Pieb "DW_RLE_base_address encoding at offset 0x%" PRIx32, 132c2dfd502SJames Henderson *OffsetPtr - 1); 133*ad60559bSWolfgang Pieb Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex); 134ab068eaaSWolfgang Pieb break; 135ab068eaaSWolfgang Pieb } 136c2dfd502SJames Henderson case dwarf::DW_RLE_start_end: { 1373fb9e3f3SWolfgang Pieb if ((End - *OffsetPtr) < unsigned(Data.getAddressSize() * 2)) 138c2dfd502SJames Henderson return createError("insufficient space remaining in table for " 139c2dfd502SJames Henderson "DW_RLE_start_end encoding " 140c2dfd502SJames Henderson "at offset 0x%" PRIx32, 141c2dfd502SJames Henderson *OffsetPtr - 1); 142*ad60559bSWolfgang Pieb Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex); 143*ad60559bSWolfgang Pieb Value1 = Data.getRelocatedAddress(OffsetPtr); 144c2dfd502SJames Henderson break; 145c2dfd502SJames Henderson } 146c2dfd502SJames Henderson case dwarf::DW_RLE_start_length: { 147c2dfd502SJames Henderson uint32_t PreviousOffset = *OffsetPtr - 1; 148*ad60559bSWolfgang Pieb Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex); 1493fb9e3f3SWolfgang Pieb Value1 = Data.getULEB128(OffsetPtr); 150c2dfd502SJames Henderson if (End < *OffsetPtr) 151c2dfd502SJames Henderson return createError("read past end of table when reading " 152c2dfd502SJames Henderson "DW_RLE_start_length encoding at offset 0x%" PRIx32, 153c2dfd502SJames Henderson PreviousOffset); 154c2dfd502SJames Henderson break; 155c2dfd502SJames Henderson } 156c2dfd502SJames Henderson default: 157c2dfd502SJames Henderson return createError("unknown rnglists encoding 0x%" PRIx32 158c2dfd502SJames Henderson " at offset 0x%" PRIx32, 159c2dfd502SJames Henderson uint32_t(Encoding), *OffsetPtr - 1); 160c2dfd502SJames Henderson } 1613fb9e3f3SWolfgang Pieb 1623fb9e3f3SWolfgang Pieb EntryKind = Encoding; 1633fb9e3f3SWolfgang Pieb return Error::success(); 164c2dfd502SJames Henderson } 165c2dfd502SJames Henderson 166*ad60559bSWolfgang Pieb DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges( 167*ad60559bSWolfgang Pieb llvm::Optional<BaseAddress> BaseAddr) const { 168*ad60559bSWolfgang Pieb DWARFAddressRangesVector Res; 169*ad60559bSWolfgang Pieb for (const RangeListEntry &RLE : Entries) { 170*ad60559bSWolfgang Pieb if (RLE.EntryKind == dwarf::DW_RLE_end_of_list) 171*ad60559bSWolfgang Pieb break; 172*ad60559bSWolfgang Pieb if (RLE.EntryKind == dwarf::DW_RLE_base_address) { 173*ad60559bSWolfgang Pieb BaseAddr = {RLE.Value0, RLE.SectionIndex}; 174*ad60559bSWolfgang Pieb continue; 175*ad60559bSWolfgang Pieb } 176*ad60559bSWolfgang Pieb 177*ad60559bSWolfgang Pieb DWARFAddressRange E; 178*ad60559bSWolfgang Pieb E.SectionIndex = RLE.SectionIndex; 179*ad60559bSWolfgang Pieb if (BaseAddr && E.SectionIndex == -1ULL) 180*ad60559bSWolfgang Pieb E.SectionIndex = BaseAddr->SectionIndex; 181*ad60559bSWolfgang Pieb 182*ad60559bSWolfgang Pieb switch (RLE.EntryKind) { 183*ad60559bSWolfgang Pieb case dwarf::DW_RLE_offset_pair: 184*ad60559bSWolfgang Pieb E.LowPC = RLE.Value0; 185*ad60559bSWolfgang Pieb E.HighPC = RLE.Value1; 186*ad60559bSWolfgang Pieb if (BaseAddr) { 187*ad60559bSWolfgang Pieb E.LowPC += BaseAddr->Address; 188*ad60559bSWolfgang Pieb E.HighPC += BaseAddr->Address; 189*ad60559bSWolfgang Pieb } 190*ad60559bSWolfgang Pieb break; 191*ad60559bSWolfgang Pieb case dwarf::DW_RLE_start_end: 192*ad60559bSWolfgang Pieb E.LowPC = RLE.Value0; 193*ad60559bSWolfgang Pieb E.HighPC = RLE.Value1; 194*ad60559bSWolfgang Pieb break; 195*ad60559bSWolfgang Pieb case dwarf::DW_RLE_start_length: 196*ad60559bSWolfgang Pieb E.LowPC = RLE.Value0; 197*ad60559bSWolfgang Pieb E.HighPC = E.LowPC + RLE.Value1; 198*ad60559bSWolfgang Pieb break; 199*ad60559bSWolfgang Pieb default: 200*ad60559bSWolfgang Pieb // Unsupported encodings should have been reported during extraction, 201*ad60559bSWolfgang Pieb // so we should not run into any here. 202*ad60559bSWolfgang Pieb llvm_unreachable("Unsupported range list encoding"); 203*ad60559bSWolfgang Pieb } 204*ad60559bSWolfgang Pieb Res.push_back(E); 205*ad60559bSWolfgang Pieb } 206*ad60559bSWolfgang Pieb return Res; 207*ad60559bSWolfgang Pieb } 208*ad60559bSWolfgang Pieb 2093fb9e3f3SWolfgang Pieb Error DWARFDebugRnglist::extract(DWARFDataExtractor Data, uint32_t HeaderOffset, 2103fb9e3f3SWolfgang Pieb uint32_t End, uint32_t *OffsetPtr) { 2113fb9e3f3SWolfgang Pieb Entries.clear(); 2123fb9e3f3SWolfgang Pieb while (*OffsetPtr < End) { 2133fb9e3f3SWolfgang Pieb RangeListEntry Entry{0, 0, 0, 0}; 2143fb9e3f3SWolfgang Pieb if (Error E = Entry.extract(Data, End, OffsetPtr)) 2153fb9e3f3SWolfgang Pieb return E; 2163fb9e3f3SWolfgang Pieb Entries.push_back(Entry); 2173fb9e3f3SWolfgang Pieb if (Entry.EntryKind == dwarf::DW_RLE_end_of_list) 2183fb9e3f3SWolfgang Pieb return Error::success(); 2193fb9e3f3SWolfgang Pieb } 220c2dfd502SJames Henderson return createError( 221c2dfd502SJames Henderson "no end of list marker detected at end of .debug_rnglists table " 222c2dfd502SJames Henderson "starting at offset 0x%" PRIx32, 223a0729d41SWolfgang Pieb HeaderOffset); 2243fb9e3f3SWolfgang Pieb } 2253fb9e3f3SWolfgang Pieb 2263fb9e3f3SWolfgang Pieb Error DWARFDebugRnglistTable::extract(DWARFDataExtractor Data, 2273fb9e3f3SWolfgang Pieb uint32_t *OffsetPtr) { 2283fb9e3f3SWolfgang Pieb clear(); 2293fb9e3f3SWolfgang Pieb if (Error E = extractHeaderAndOffsets(Data, OffsetPtr)) 2303fb9e3f3SWolfgang Pieb return E; 2313fb9e3f3SWolfgang Pieb 2323fb9e3f3SWolfgang Pieb Data.setAddressSize(HeaderData.AddrSize); 2333fb9e3f3SWolfgang Pieb uint32_t End = HeaderOffset + length(); 2343fb9e3f3SWolfgang Pieb while (*OffsetPtr < End) { 2353fb9e3f3SWolfgang Pieb DWARFDebugRnglist CurrentRangeList; 2363fb9e3f3SWolfgang Pieb uint32_t Off = *OffsetPtr; 2373fb9e3f3SWolfgang Pieb if (Error E = CurrentRangeList.extract(Data, HeaderOffset, End, OffsetPtr)) 2383fb9e3f3SWolfgang Pieb return E; 2393fb9e3f3SWolfgang Pieb Ranges[Off] = CurrentRangeList; 2403fb9e3f3SWolfgang Pieb } 2413fb9e3f3SWolfgang Pieb 2423fb9e3f3SWolfgang Pieb assert(*OffsetPtr == End && 2433fb9e3f3SWolfgang Pieb "mismatch between expected length of .debug_rnglists table and length " 2443fb9e3f3SWolfgang Pieb "of extracted data"); 245c2dfd502SJames Henderson return Error::success(); 246c2dfd502SJames Henderson } 247c2dfd502SJames Henderson 248a0729d41SWolfgang Pieb static void dumpRangeEntry(raw_ostream &OS, 2493fb9e3f3SWolfgang Pieb DWARFDebugRnglist::RangeListEntry Entry, 250a0729d41SWolfgang Pieb uint8_t AddrSize, uint8_t MaxEncodingStringLength, 251ab068eaaSWolfgang Pieb uint64_t &CurrentBase, DIDumpOptions DumpOpts) { 252ab068eaaSWolfgang Pieb auto PrintRawEntry = [](raw_ostream &OS, 2533fb9e3f3SWolfgang Pieb DWARFDebugRnglist::RangeListEntry Entry, 254ab068eaaSWolfgang Pieb uint8_t AddrSize, DIDumpOptions DumpOpts) { 255ab068eaaSWolfgang Pieb if (DumpOpts.Verbose) { 256ab068eaaSWolfgang Pieb DumpOpts.DisplayRawContents = true; 257ab068eaaSWolfgang Pieb DWARFAddressRange(Entry.Value0, Entry.Value1) 258ab068eaaSWolfgang Pieb .dump(OS, AddrSize, DumpOpts); 259ab068eaaSWolfgang Pieb OS << " => "; 260ab068eaaSWolfgang Pieb } 261ab068eaaSWolfgang Pieb }; 262ab068eaaSWolfgang Pieb 263a0729d41SWolfgang Pieb if (DumpOpts.Verbose) { 264a0729d41SWolfgang Pieb // Print the section offset in verbose mode. 265a0729d41SWolfgang Pieb OS << format("0x%8.8" PRIx32 ":", Entry.Offset); 266a0729d41SWolfgang Pieb auto EncodingString = dwarf::RangeListEncodingString(Entry.EntryKind); 267a0729d41SWolfgang Pieb // Unsupported encodings should have been reported during parsing. 268a0729d41SWolfgang Pieb assert(!EncodingString.empty() && "Unknown range entry encoding"); 269a0729d41SWolfgang Pieb OS << format(" [%s%*c", EncodingString.data(), 270a0729d41SWolfgang Pieb MaxEncodingStringLength - EncodingString.size() + 1, ']'); 271a0729d41SWolfgang Pieb if (Entry.EntryKind != dwarf::DW_RLE_end_of_list) 272a0729d41SWolfgang Pieb OS << ": "; 273a0729d41SWolfgang Pieb } 274a0729d41SWolfgang Pieb 275a0729d41SWolfgang Pieb switch (Entry.EntryKind) { 276a0729d41SWolfgang Pieb case dwarf::DW_RLE_end_of_list: 277a0729d41SWolfgang Pieb OS << (DumpOpts.Verbose ? "" : "<End of list>"); 278a0729d41SWolfgang Pieb break; 279ab068eaaSWolfgang Pieb case dwarf::DW_RLE_base_address: 280ab068eaaSWolfgang Pieb // In non-verbose mode we do not print anything for this entry. 281ab068eaaSWolfgang Pieb CurrentBase = Entry.Value0; 282ab068eaaSWolfgang Pieb if (!DumpOpts.Verbose) 283ab068eaaSWolfgang Pieb return; 284ab068eaaSWolfgang Pieb OS << format(" 0x%*.*" PRIx64, AddrSize * 2, AddrSize * 2, Entry.Value0); 285ab068eaaSWolfgang Pieb break; 286a0729d41SWolfgang Pieb case dwarf::DW_RLE_start_length: 287ab068eaaSWolfgang Pieb PrintRawEntry(OS, Entry, AddrSize, DumpOpts); 288a0729d41SWolfgang Pieb DWARFAddressRange(Entry.Value0, Entry.Value0 + Entry.Value1) 289a0729d41SWolfgang Pieb .dump(OS, AddrSize, DumpOpts); 290a0729d41SWolfgang Pieb break; 291ab068eaaSWolfgang Pieb case dwarf::DW_RLE_offset_pair: 292ab068eaaSWolfgang Pieb PrintRawEntry(OS, Entry, AddrSize, DumpOpts); 293ab068eaaSWolfgang Pieb DWARFAddressRange(Entry.Value0 + CurrentBase, Entry.Value1 + CurrentBase) 294ab068eaaSWolfgang Pieb .dump(OS, AddrSize, DumpOpts); 295ab068eaaSWolfgang Pieb break; 296a0729d41SWolfgang Pieb case dwarf::DW_RLE_start_end: 297a0729d41SWolfgang Pieb DWARFAddressRange(Entry.Value0, Entry.Value1).dump(OS, AddrSize, DumpOpts); 298a0729d41SWolfgang Pieb break; 299a0729d41SWolfgang Pieb default: 300a0729d41SWolfgang Pieb llvm_unreachable("Unsupported range list encoding"); 301a0729d41SWolfgang Pieb } 302a0729d41SWolfgang Pieb OS << "\n"; 303a0729d41SWolfgang Pieb } 304a0729d41SWolfgang Pieb 3053fb9e3f3SWolfgang Pieb void DWARFDebugRnglistTable::dump(raw_ostream &OS, 3063fb9e3f3SWolfgang Pieb DIDumpOptions DumpOpts) const { 307a0729d41SWolfgang Pieb if (DumpOpts.Verbose) 308a0729d41SWolfgang Pieb OS << format("0x%8.8" PRIx32 ": ", HeaderOffset); 30910392cdbSJames Henderson OS << format("Range List Header: length = 0x%8.8" PRIx32 31010392cdbSJames Henderson ", version = 0x%4.4" PRIx16 ", " 31110392cdbSJames Henderson "addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8 31210392cdbSJames Henderson ", offset_entry_count = " 31310392cdbSJames Henderson "0x%8.8" PRIx32 "\n", 314c2dfd502SJames Henderson HeaderData.Length, HeaderData.Version, HeaderData.AddrSize, 315c2dfd502SJames Henderson HeaderData.SegSize, HeaderData.OffsetEntryCount); 316c2dfd502SJames Henderson 317c2dfd502SJames Henderson if (HeaderData.OffsetEntryCount > 0) { 318c2dfd502SJames Henderson OS << "Offsets: ["; 319a0729d41SWolfgang Pieb for (const auto &Off : Offsets) { 32010392cdbSJames Henderson OS << format("\n0x%8.8" PRIx32, Off); 321a0729d41SWolfgang Pieb if (DumpOpts.Verbose) 322a0729d41SWolfgang Pieb OS << format(" => 0x%8.8" PRIx32, 323a0729d41SWolfgang Pieb Off + HeaderOffset + sizeof(HeaderData)); 324a0729d41SWolfgang Pieb } 325c2dfd502SJames Henderson OS << "\n]\n"; 326c2dfd502SJames Henderson } 327c2dfd502SJames Henderson OS << "Ranges:\n"; 328c2dfd502SJames Henderson 3293fb9e3f3SWolfgang Pieb // Determine the length of the longest encoding string we have in the table, 3303fb9e3f3SWolfgang Pieb // so we can align the output properly. We only need this in verbose mode. 3313fb9e3f3SWolfgang Pieb size_t MaxEncodingStringLength = 0; 3323fb9e3f3SWolfgang Pieb if (DumpOpts.Verbose) { 3333fb9e3f3SWolfgang Pieb for (const auto &List : Ranges) 3343fb9e3f3SWolfgang Pieb for (const auto &Entry : List.second.getEntries()) 3353fb9e3f3SWolfgang Pieb MaxEncodingStringLength = 3363fb9e3f3SWolfgang Pieb std::max(MaxEncodingStringLength, 3373fb9e3f3SWolfgang Pieb dwarf::RangeListEncodingString(Entry.EntryKind).size()); 3383fb9e3f3SWolfgang Pieb } 3393fb9e3f3SWolfgang Pieb 340ab068eaaSWolfgang Pieb uint64_t CurrentBase = 0; 341a0729d41SWolfgang Pieb for (const auto &List : Ranges) 3423fb9e3f3SWolfgang Pieb for (const auto &Entry : List.second.getEntries()) 343a0729d41SWolfgang Pieb dumpRangeEntry(OS, Entry, HeaderData.AddrSize, MaxEncodingStringLength, 344ab068eaaSWolfgang Pieb CurrentBase, DumpOpts); 345c2dfd502SJames Henderson } 346c2dfd502SJames Henderson 3473fb9e3f3SWolfgang Pieb uint32_t DWARFDebugRnglistTable::length() const { 348c2dfd502SJames Henderson if (HeaderData.Length == 0) 349c2dfd502SJames Henderson return 0; 350c2dfd502SJames Henderson // TODO: DWARF64 support. 351c2dfd502SJames Henderson return HeaderData.Length + sizeof(uint32_t); 352c2dfd502SJames Henderson } 353*ad60559bSWolfgang Pieb 354*ad60559bSWolfgang Pieb Optional<DWARFDebugRnglist> 355*ad60559bSWolfgang Pieb DWARFDebugRnglistTable::findRangeList(DWARFDataExtractor Data, 356*ad60559bSWolfgang Pieb uint32_t Offset) { 357*ad60559bSWolfgang Pieb auto Entry = Ranges.find(Offset); 358*ad60559bSWolfgang Pieb if (Entry != Ranges.end()) 359*ad60559bSWolfgang Pieb return Entry->second; 360*ad60559bSWolfgang Pieb 361*ad60559bSWolfgang Pieb // Extract the rangelist from the section and enter it into the ranges map. 362*ad60559bSWolfgang Pieb DWARFDebugRnglist RngList; 363*ad60559bSWolfgang Pieb uint32_t End = HeaderOffset + length(); 364*ad60559bSWolfgang Pieb uint32_t StartingOffset = Offset; 365*ad60559bSWolfgang Pieb if (Error E = RngList.extract(Data, HeaderOffset, End, &Offset)) { 366*ad60559bSWolfgang Pieb llvm::consumeError(std::move(E)); 367*ad60559bSWolfgang Pieb return None; 368*ad60559bSWolfgang Pieb } 369*ad60559bSWolfgang Pieb Ranges[StartingOffset] = RngList; 370*ad60559bSWolfgang Pieb return RngList; 371*ad60559bSWolfgang Pieb } 372