Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | //===- DWARFDebugLoc.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_DWARFDEBUGLOC_H |
||
| 10 | #define LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H |
||
| 11 | |||
| 12 | #include "llvm/ADT/SmallVector.h" |
||
| 13 | #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" |
||
| 14 | #include "llvm/Support/Errc.h" |
||
| 15 | #include <cstdint> |
||
| 16 | |||
| 17 | namespace llvm { |
||
| 18 | class DWARFUnit; |
||
| 19 | class MCRegisterInfo; |
||
| 20 | class raw_ostream; |
||
| 21 | class DWARFObject; |
||
| 22 | struct DIDumpOptions; |
||
| 23 | struct DWARFLocationExpression; |
||
| 24 | namespace object { |
||
| 25 | struct SectionedAddress; |
||
| 26 | } |
||
| 27 | |||
| 28 | /// A single location within a location list. Entries are stored in the DWARF5 |
||
| 29 | /// form even if they originally come from a DWARF<=4 location list. |
||
| 30 | struct DWARFLocationEntry { |
||
| 31 | /// The entry kind (DW_LLE_***). |
||
| 32 | uint8_t Kind; |
||
| 33 | |||
| 34 | /// The first value of the location entry (if applicable). |
||
| 35 | uint64_t Value0; |
||
| 36 | |||
| 37 | /// The second value of the location entry (if applicable). |
||
| 38 | uint64_t Value1; |
||
| 39 | |||
| 40 | /// The index of the section this entry is relative to (if applicable). |
||
| 41 | uint64_t SectionIndex; |
||
| 42 | |||
| 43 | /// The location expression itself (if applicable). |
||
| 44 | SmallVector<uint8_t, 4> Loc; |
||
| 45 | }; |
||
| 46 | |||
| 47 | /// An abstract base class for various kinds of location tables (.debug_loc, |
||
| 48 | /// .debug_loclists, and their dwo variants). |
||
| 49 | class DWARFLocationTable { |
||
| 50 | public: |
||
| 51 | DWARFLocationTable(DWARFDataExtractor Data) : Data(std::move(Data)) {} |
||
| 52 | virtual ~DWARFLocationTable() = default; |
||
| 53 | |||
| 54 | /// Call the user-provided callback for each entry (including the end-of-list |
||
| 55 | /// entry) in the location list starting at \p Offset. The callback can return |
||
| 56 | /// false to terminate the iteration early. Returns an error if it was unable |
||
| 57 | /// to parse the entire location list correctly. Upon successful termination |
||
| 58 | /// \p Offset will be updated point past the end of the list. |
||
| 59 | virtual Error visitLocationList( |
||
| 60 | uint64_t *Offset, |
||
| 61 | function_ref<bool(const DWARFLocationEntry &)> Callback) const = 0; |
||
| 62 | |||
| 63 | /// Dump the location list at the given \p Offset. The function returns true |
||
| 64 | /// iff it has successfully reched the end of the list. This means that one |
||
| 65 | /// can attempt to parse another list after the current one (\p Offset will be |
||
| 66 | /// updated to point past the end of the current list). |
||
| 67 | bool dumpLocationList(uint64_t *Offset, raw_ostream &OS, |
||
| 68 | std::optional<object::SectionedAddress> BaseAddr, |
||
| 69 | const DWARFObject &Obj, DWARFUnit *U, |
||
| 70 | DIDumpOptions DumpOpts, unsigned Indent) const; |
||
| 71 | |||
| 72 | Error visitAbsoluteLocationList( |
||
| 73 | uint64_t Offset, std::optional<object::SectionedAddress> BaseAddr, |
||
| 74 | std::function<std::optional<object::SectionedAddress>(uint32_t)> |
||
| 75 | LookupAddr, |
||
| 76 | function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const; |
||
| 77 | |||
| 78 | const DWARFDataExtractor &getData() { return Data; } |
||
| 79 | |||
| 80 | protected: |
||
| 81 | DWARFDataExtractor Data; |
||
| 82 | |||
| 83 | virtual void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS, |
||
| 84 | unsigned Indent, DIDumpOptions DumpOpts, |
||
| 85 | const DWARFObject &Obj) const = 0; |
||
| 86 | }; |
||
| 87 | |||
| 88 | class DWARFDebugLoc final : public DWARFLocationTable { |
||
| 89 | public: |
||
| 90 | /// A list of locations that contain one variable. |
||
| 91 | struct LocationList { |
||
| 92 | /// The beginning offset where this location list is stored in the debug_loc |
||
| 93 | /// section. |
||
| 94 | uint64_t Offset; |
||
| 95 | /// All the locations in which the variable is stored. |
||
| 96 | SmallVector<DWARFLocationEntry, 2> Entries; |
||
| 97 | }; |
||
| 98 | |||
| 99 | private: |
||
| 100 | using LocationLists = SmallVector<LocationList, 4>; |
||
| 101 | |||
| 102 | /// A list of all the variables in the debug_loc section, each one describing |
||
| 103 | /// the locations in which the variable is stored. |
||
| 104 | LocationLists Locations; |
||
| 105 | |||
| 106 | public: |
||
| 107 | DWARFDebugLoc(DWARFDataExtractor Data) |
||
| 108 | : DWARFLocationTable(std::move(Data)) {} |
||
| 109 | |||
| 110 | /// Print the location lists found within the debug_loc section. |
||
| 111 | void dump(raw_ostream &OS, const DWARFObject &Obj, DIDumpOptions DumpOpts, |
||
| 112 | std::optional<uint64_t> Offset) const; |
||
| 113 | |||
| 114 | Error visitLocationList( |
||
| 115 | uint64_t *Offset, |
||
| 116 | function_ref<bool(const DWARFLocationEntry &)> Callback) const override; |
||
| 117 | |||
| 118 | protected: |
||
| 119 | void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS, |
||
| 120 | unsigned Indent, DIDumpOptions DumpOpts, |
||
| 121 | const DWARFObject &Obj) const override; |
||
| 122 | }; |
||
| 123 | |||
| 124 | class DWARFDebugLoclists final : public DWARFLocationTable { |
||
| 125 | public: |
||
| 126 | DWARFDebugLoclists(DWARFDataExtractor Data, uint16_t Version) |
||
| 127 | : DWARFLocationTable(std::move(Data)), Version(Version) {} |
||
| 128 | |||
| 129 | Error visitLocationList( |
||
| 130 | uint64_t *Offset, |
||
| 131 | function_ref<bool(const DWARFLocationEntry &)> Callback) const override; |
||
| 132 | |||
| 133 | /// Dump all location lists within the given range. |
||
| 134 | void dumpRange(uint64_t StartOffset, uint64_t Size, raw_ostream &OS, |
||
| 135 | const DWARFObject &Obj, DIDumpOptions DumpOpts); |
||
| 136 | |||
| 137 | protected: |
||
| 138 | void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS, |
||
| 139 | unsigned Indent, DIDumpOptions DumpOpts, |
||
| 140 | const DWARFObject &Obj) const override; |
||
| 141 | |||
| 142 | private: |
||
| 143 | uint16_t Version; |
||
| 144 | }; |
||
| 145 | |||
| 146 | class ResolverError : public ErrorInfo<ResolverError> { |
||
| 147 | public: |
||
| 148 | static char ID; |
||
| 149 | |||
| 150 | ResolverError(uint32_t Index, dwarf::LoclistEntries Kind) : Index(Index), Kind(Kind) {} |
||
| 151 | |||
| 152 | void log(raw_ostream &OS) const override; |
||
| 153 | std::error_code convertToErrorCode() const override { |
||
| 154 | return llvm::errc::invalid_argument; |
||
| 155 | } |
||
| 156 | |||
| 157 | private: |
||
| 158 | uint32_t Index; |
||
| 159 | dwarf::LoclistEntries Kind; |
||
| 160 | }; |
||
| 161 | |||
| 162 | } // end namespace llvm |
||
| 163 | |||
| 164 | #endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H |