1 //===- DWARFDataExtractor.h -------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_DEBUGINFO_DWARF_DWARFDATAEXTRACTOR_H 10 #define LLVM_DEBUGINFO_DWARF_DWARFDATAEXTRACTOR_H 11 12 #include "llvm/BinaryFormat/Dwarf.h" 13 #include "llvm/DebugInfo/DWARF/DWARFObject.h" 14 #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" 15 #include "llvm/DebugInfo/DWARF/DWARFSection.h" 16 #include "llvm/DebugInfo/DWARF/LowLevel/DWARFDataExtractorSimple.h" 17 #include "llvm/Support/Compiler.h" 18 19 namespace llvm { 20 21 /// A DWARFDataExtractor (typically for an in-memory copy of an object-file 22 /// section) plus a relocation map for that section, if there is one. 23 class DWARFDataExtractor : public DWARFDataExtractorBase<DWARFDataExtractor> { 24 const DWARFObject *Obj = nullptr; 25 const DWARFSection *Section = nullptr; 26 27 public: 28 using DWARFDataExtractorBase::DWARFDataExtractorBase; 29 30 /// Constructor for the normal case of extracting data from a DWARF section. 31 /// 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)32 DWARFDataExtractor(const DWARFObject &Obj, const DWARFSection &Section, 33 bool IsLittleEndian, uint8_t AddressSize) 34 : DWARFDataExtractorBase(Section.Data, IsLittleEndian, AddressSize), 35 Obj(&Obj), Section(&Section) {} 36 37 /// Truncating constructor DWARFDataExtractor(const DWARFDataExtractor & Other,size_t Length)38 DWARFDataExtractor(const DWARFDataExtractor &Other, size_t Length) 39 : DWARFDataExtractorBase(Other.getData().substr(0, Length), 40 Other.isLittleEndian(), Other.getAddressSize()), 41 Obj(Other.Obj), Section(Other.Section) {} 42 43 /// Extracts a value and applies a relocation to the result if 44 /// one exists for the given offset. getRelocatedValueImpl(uint32_t Size,uint64_t * Off,uint64_t * SecNdx,Error * Err)45 uint64_t getRelocatedValueImpl(uint32_t Size, uint64_t *Off, uint64_t *SecNdx, 46 Error *Err) const { 47 if (SecNdx) 48 *SecNdx = object::SectionedAddress::UndefSection; 49 if (!Section) 50 return getUnsigned(Off, Size, Err); 51 ErrorAsOutParameter ErrAsOut(Err); 52 std::optional<RelocAddrEntry> E = Obj->find(*Section, *Off); 53 uint64_t LocData = getUnsigned(Off, Size, Err); 54 if (!E || (Err && *Err)) 55 return LocData; 56 if (SecNdx) 57 *SecNdx = E->SectionIndex; 58 59 uint64_t R = object::resolveRelocation(E->Resolver, E->Reloc, 60 E->SymbolValue, LocData); 61 if (E->Reloc2) 62 R = object::resolveRelocation(E->Resolver, *E->Reloc2, E->SymbolValue2, 63 R); 64 return R; 65 } 66 }; 67 68 } // end namespace llvm 69 70 #endif // LLVM_DEBUGINFO_DWARF_DWARFDATAEXTRACTOR_H 71