aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
blob: 3b141304f85f4959cdd4669fe1daa612a99b36b9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//===- DWARFDebugLoc.h ------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H
#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H

#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include <cstdint>

namespace llvm {
class DWARFUnit;
class MCRegisterInfo;
class raw_ostream;

/// A single location within a location list. Entries are stored in the DWARF5
/// form even if they originally come from a DWARF<=4 location list.
struct DWARFLocationEntry {
  /// The entry kind (DW_LLE_***).
  uint8_t Kind;

  /// The first value of the location entry (if applicable).
  uint64_t Value0;

  /// The second value of the location entry (if applicable).
  uint64_t Value1;

  /// The index of the section this entry is relative to (if applicable).
  uint64_t SectionIndex;

  /// The location expression itself (if applicable).
  SmallVector<uint8_t, 4> Loc;
};

/// An abstract base class for various kinds of location tables (.debug_loc,
/// .debug_loclists, and their dwo variants).
class DWARFLocationTable {
public:
  DWARFLocationTable(DWARFDataExtractor Data) : Data(std::move(Data)) {}
  virtual ~DWARFLocationTable() = default;

  /// Call the user-provided callback for each entry (including the end-of-list
  /// entry) in the location list starting at \p Offset. The callback can return
  /// false to terminate the iteration early. Returns an error if it was unable
  /// to parse the entire location list correctly. Upon successful termination
  /// \p Offset will be updated point past the end of the list.
  virtual Error visitLocationList(
      uint64_t *Offset,
      function_ref<bool(const DWARFLocationEntry &)> Callback) const = 0;

  /// Dump the location list at the given \p Offset. The function returns true
  /// iff it has successfully reched the end of the list. This means that one
  /// can attempt to parse another list after the current one (\p Offset will be
  /// updated to point past the end of the current list).
  bool dumpLocationList(uint64_t *Offset, raw_ostream &OS,
                        Optional<object::SectionedAddress> BaseAddr,
                        const MCRegisterInfo *MRI, const DWARFObject &Obj,
                        DWARFUnit *U, DIDumpOptions DumpOpts,
                        unsigned Indent) const;

  Error visitAbsoluteLocationList(
      uint64_t Offset, Optional<object::SectionedAddress> BaseAddr,
      std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr,
      function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const;

protected:
  DWARFDataExtractor Data;

  virtual void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS,
                            unsigned Indent, DIDumpOptions DumpOpts,
                            const DWARFObject &Obj) const = 0;
};

class DWARFDebugLoc final : public DWARFLocationTable {
public:
  /// A list of locations that contain one variable.
  struct LocationList {
    /// The beginning offset where this location list is stored in the debug_loc
    /// section.
    uint64_t Offset;
    /// All the locations in which the variable is stored.
    SmallVector<DWARFLocationEntry, 2> Entries;
  };

private:
  using LocationLists = SmallVector<LocationList, 4>;

  /// A list of all the variables in the debug_loc section, each one describing
  /// the locations in which the variable is stored.
  LocationLists Locations;

public:
  DWARFDebugLoc(DWARFDataExtractor Data)
      : DWARFLocationTable(std::move(Data)) {}

  /// Print the location lists found within the debug_loc section.
  void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo,
            const DWARFObject &Obj, DIDumpOptions DumpOpts,
            Optional<uint64_t> Offset) const;

  Error visitLocationList(
      uint64_t *Offset,
      function_ref<bool(const DWARFLocationEntry &)> Callback) const override;

protected:
  void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS,
                    unsigned Indent, DIDumpOptions DumpOpts,
                    const DWARFObject &Obj) const override;
};

class DWARFDebugLoclists final : public DWARFLocationTable {
public:
  DWARFDebugLoclists(DWARFDataExtractor Data, uint16_t Version)
      : DWARFLocationTable(std::move(Data)), Version(Version) {}

  Error visitLocationList(
      uint64_t *Offset,
      function_ref<bool(const DWARFLocationEntry &)> Callback) const override;

  /// Dump all location lists within the given range.
  void dumpRange(uint64_t StartOffset, uint64_t Size, raw_ostream &OS,
                 const MCRegisterInfo *MRI, const DWARFObject &Obj,
                 DIDumpOptions DumpOpts);

protected:
  void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS,
                    unsigned Indent, DIDumpOptions DumpOpts,
                    const DWARFObject &Obj) const override;

private:
  uint16_t Version;
};

} // end namespace llvm

#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGLOC_H