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