1321369Sdim//===- DWARFDebugRangesList.cpp -------------------------------------------===// 2283625Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6283625Sdim// 7283625Sdim//===----------------------------------------------------------------------===// 8283625Sdim 9283625Sdim#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" 10321369Sdim#include "llvm/DebugInfo/DWARF/DWARFContext.h" 11344779Sdim#include "llvm/Support/Errc.h" 12283625Sdim#include "llvm/Support/Format.h" 13283625Sdim#include "llvm/Support/raw_ostream.h" 14321369Sdim#include <cinttypes> 15321369Sdim#include <cstdint> 16283625Sdim 17283625Sdimusing namespace llvm; 18283625Sdim 19283625Sdimvoid DWARFDebugRangeList::clear() { 20360784Sdim Offset = -1ULL; 21283625Sdim AddressSize = 0; 22283625Sdim Entries.clear(); 23283625Sdim} 24283625Sdim 25341825SdimError DWARFDebugRangeList::extract(const DWARFDataExtractor &data, 26360784Sdim uint64_t *offset_ptr) { 27283625Sdim clear(); 28283625Sdim if (!data.isValidOffset(*offset_ptr)) 29344779Sdim return createStringError(errc::invalid_argument, 30360784Sdim "invalid range list offset 0x%" PRIx64, *offset_ptr); 31341825Sdim 32283625Sdim AddressSize = data.getAddressSize(); 33283625Sdim if (AddressSize != 4 && AddressSize != 8) 34344779Sdim return createStringError(errc::invalid_argument, 35344779Sdim "invalid address size: %" PRIu8, AddressSize); 36283625Sdim Offset = *offset_ptr; 37283625Sdim while (true) { 38327952Sdim RangeListEntry Entry; 39327952Sdim Entry.SectionIndex = -1ULL; 40327952Sdim 41360784Sdim uint64_t prev_offset = *offset_ptr; 42327952Sdim Entry.StartAddress = data.getRelocatedAddress(offset_ptr); 43327952Sdim Entry.EndAddress = 44327952Sdim data.getRelocatedAddress(offset_ptr, &Entry.SectionIndex); 45321369Sdim 46283625Sdim // Check that both values were extracted correctly. 47283625Sdim if (*offset_ptr != prev_offset + 2 * AddressSize) { 48283625Sdim clear(); 49344779Sdim return createStringError(errc::invalid_argument, 50360784Sdim "invalid range list entry at offset 0x%" PRIx64, 51341825Sdim prev_offset); 52283625Sdim } 53327952Sdim if (Entry.isEndOfListEntry()) 54283625Sdim break; 55327952Sdim Entries.push_back(Entry); 56283625Sdim } 57341825Sdim return Error::success(); 58283625Sdim} 59283625Sdim 60283625Sdimvoid DWARFDebugRangeList::dump(raw_ostream &OS) const { 61283625Sdim for (const RangeListEntry &RLE : Entries) { 62360784Sdim const char *format_str = 63360784Sdim (AddressSize == 4 ? "%08" PRIx64 " %08" PRIx64 " %08" PRIx64 "\n" 64360784Sdim : "%08" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n"); 65283625Sdim OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress); 66283625Sdim } 67360784Sdim OS << format("%08" PRIx64 " <End of list>\n", Offset); 68283625Sdim} 69283625Sdim 70327952SdimDWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges( 71353358Sdim llvm::Optional<object::SectionedAddress> BaseAddr) const { 72283625Sdim DWARFAddressRangesVector Res; 73283625Sdim for (const RangeListEntry &RLE : Entries) { 74283625Sdim if (RLE.isBaseAddressSelectionEntry(AddressSize)) { 75327952Sdim BaseAddr = {RLE.EndAddress, RLE.SectionIndex}; 76327952Sdim continue; 77283625Sdim } 78327952Sdim 79327952Sdim DWARFAddressRange E; 80327952Sdim E.LowPC = RLE.StartAddress; 81327952Sdim E.HighPC = RLE.EndAddress; 82327952Sdim E.SectionIndex = RLE.SectionIndex; 83327952Sdim // Base address of a range list entry is determined by the closest preceding 84327952Sdim // base address selection entry in the same range list. It defaults to the 85327952Sdim // base address of the compilation unit if there is no such entry. 86327952Sdim if (BaseAddr) { 87327952Sdim E.LowPC += BaseAddr->Address; 88327952Sdim E.HighPC += BaseAddr->Address; 89327952Sdim if (E.SectionIndex == -1ULL) 90327952Sdim E.SectionIndex = BaseAddr->SectionIndex; 91327952Sdim } 92327952Sdim Res.push_back(E); 93283625Sdim } 94283625Sdim return Res; 95283625Sdim} 96