10b57cec5SDimitry Andric //===- DWARFDataExtractor.h -------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 9fe6060f1SDimitry Andric #ifndef LLVM_DEBUGINFO_DWARF_DWARFDATAEXTRACTOR_H 10fe6060f1SDimitry Andric #define LLVM_DEBUGINFO_DWARF_DWARFDATAEXTRACTOR_H 110b57cec5SDimitry Andric 125ffd83dbSDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 130b57cec5SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFSection.h" 140b57cec5SDimitry Andric #include "llvm/Support/DataExtractor.h" 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric namespace llvm { 170b57cec5SDimitry Andric class DWARFObject; 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric /// A DataExtractor (typically for an in-memory copy of an object-file section) 200b57cec5SDimitry Andric /// plus a relocation map for that section, if there is one. 210b57cec5SDimitry Andric class DWARFDataExtractor : public DataExtractor { 220b57cec5SDimitry Andric const DWARFObject *Obj = nullptr; 230b57cec5SDimitry Andric const DWARFSection *Section = nullptr; 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric public: 260b57cec5SDimitry Andric /// Constructor for the normal case of extracting data from a DWARF section. 270b57cec5SDimitry Andric /// The DWARFSection's lifetime must be at least as long as the extractor's. DWARFDataExtractor(const DWARFObject & Obj,const DWARFSection & Section,bool IsLittleEndian,uint8_t AddressSize)280b57cec5SDimitry Andric DWARFDataExtractor(const DWARFObject &Obj, const DWARFSection &Section, 290b57cec5SDimitry Andric bool IsLittleEndian, uint8_t AddressSize) 300b57cec5SDimitry Andric : DataExtractor(Section.Data, IsLittleEndian, AddressSize), Obj(&Obj), 310b57cec5SDimitry Andric Section(&Section) {} 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric /// Constructor for cases when there are no relocations. DWARFDataExtractor(StringRef Data,bool IsLittleEndian,uint8_t AddressSize)340b57cec5SDimitry Andric DWARFDataExtractor(StringRef Data, bool IsLittleEndian, uint8_t AddressSize) 350b57cec5SDimitry Andric : DataExtractor(Data, IsLittleEndian, AddressSize) {} DWARFDataExtractor(ArrayRef<uint8_t> Data,bool IsLittleEndian,uint8_t AddressSize)365ffd83dbSDimitry Andric DWARFDataExtractor(ArrayRef<uint8_t> Data, bool IsLittleEndian, 375ffd83dbSDimitry Andric uint8_t AddressSize) 385ffd83dbSDimitry Andric : DataExtractor( 395ffd83dbSDimitry Andric StringRef(reinterpret_cast<const char *>(Data.data()), Data.size()), 405ffd83dbSDimitry Andric IsLittleEndian, AddressSize) {} 415ffd83dbSDimitry Andric 425ffd83dbSDimitry Andric /// Truncating constructor DWARFDataExtractor(const DWARFDataExtractor & Other,size_t Length)435ffd83dbSDimitry Andric DWARFDataExtractor(const DWARFDataExtractor &Other, size_t Length) 445ffd83dbSDimitry Andric : DataExtractor(Other.getData().substr(0, Length), Other.isLittleEndian(), 455ffd83dbSDimitry Andric Other.getAddressSize()), 465ffd83dbSDimitry Andric Obj(Other.Obj), Section(Other.Section) {} 475ffd83dbSDimitry Andric 485ffd83dbSDimitry Andric /// Extracts the DWARF "initial length" field, which can either be a 32-bit 495ffd83dbSDimitry Andric /// value smaller than 0xfffffff0, or the value 0xffffffff followed by a 505ffd83dbSDimitry Andric /// 64-bit length. Returns the actual length, and the DWARF format which is 515ffd83dbSDimitry Andric /// encoded in the field. In case of errors, it returns {0, DWARF32} and 525ffd83dbSDimitry Andric /// leaves the offset unchanged. 535ffd83dbSDimitry Andric std::pair<uint64_t, dwarf::DwarfFormat> 545ffd83dbSDimitry Andric getInitialLength(uint64_t *Off, Error *Err = nullptr) const; 555ffd83dbSDimitry Andric getInitialLength(Cursor & C)565ffd83dbSDimitry Andric std::pair<uint64_t, dwarf::DwarfFormat> getInitialLength(Cursor &C) const { 575ffd83dbSDimitry Andric return getInitialLength(&getOffset(C), &getError(C)); 585ffd83dbSDimitry Andric } 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric /// Extracts a value and applies a relocation to the result if 610b57cec5SDimitry Andric /// one exists for the given offset. 628bcb0991SDimitry Andric uint64_t getRelocatedValue(uint32_t Size, uint64_t *Off, 638bcb0991SDimitry Andric uint64_t *SectionIndex = nullptr, 648bcb0991SDimitry Andric Error *Err = nullptr) const; 655ffd83dbSDimitry Andric uint64_t getRelocatedValue(Cursor &C, uint32_t Size, 665ffd83dbSDimitry Andric uint64_t *SectionIndex = nullptr) const { 675ffd83dbSDimitry Andric return getRelocatedValue(Size, &getOffset(C), SectionIndex, &getError(C)); 685ffd83dbSDimitry Andric } 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric /// Extracts an address-sized value and applies a relocation to the result if 710b57cec5SDimitry Andric /// one exists for the given offset. 728bcb0991SDimitry Andric uint64_t getRelocatedAddress(uint64_t *Off, uint64_t *SecIx = nullptr) const { 730b57cec5SDimitry Andric return getRelocatedValue(getAddressSize(), Off, SecIx); 740b57cec5SDimitry Andric } 758bcb0991SDimitry Andric uint64_t getRelocatedAddress(Cursor &C, uint64_t *SecIx = nullptr) const { 768bcb0991SDimitry Andric return getRelocatedValue(getAddressSize(), &getOffset(C), SecIx, 778bcb0991SDimitry Andric &getError(C)); 788bcb0991SDimitry Andric } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric /// Extracts a DWARF-encoded pointer in \p Offset using \p Encoding. 810b57cec5SDimitry Andric /// There is a DWARF encoding that uses a PC-relative adjustment. 820b57cec5SDimitry Andric /// For these values, \p AbsPosOffset is used to fix them, which should 830b57cec5SDimitry Andric /// reflect the absolute address of this pointer. 84*bdd1243dSDimitry Andric std::optional<uint64_t> getEncodedPointer(uint64_t *Offset, uint8_t Encoding, 850b57cec5SDimitry Andric uint64_t AbsPosOffset = 0) const; 860b57cec5SDimitry Andric }; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric } // end namespace llvm 890b57cec5SDimitry Andric 90fe6060f1SDimitry Andric #endif // LLVM_DEBUGINFO_DWARF_DWARFDATAEXTRACTOR_H 91