LineTable.h revision 360784
1//===-- LineTable.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 liblldb_LineTable_h_
10#define liblldb_LineTable_h_
11
12#include "lldb/Core/ModuleChild.h"
13#include "lldb/Core/Section.h"
14#include "lldb/Symbol/LineEntry.h"
15#include "lldb/Utility/RangeMap.h"
16#include "lldb/lldb-private.h"
17#include <vector>
18
19namespace lldb_private {
20
21/// \class LineSequence LineTable.h "lldb/Symbol/LineTable.h" An abstract base
22/// class used during symbol table creation.
23class LineSequence {
24public:
25  LineSequence();
26
27  virtual ~LineSequence() = default;
28
29  virtual void Clear() = 0;
30
31private:
32  DISALLOW_COPY_AND_ASSIGN(LineSequence);
33};
34
35/// \class LineTable LineTable.h "lldb/Symbol/LineTable.h"
36/// A line table class.
37class LineTable {
38public:
39  /// Construct with compile unit.
40  ///
41  /// \param[in] comp_unit
42  ///     The compile unit to which this line table belongs.
43  LineTable(CompileUnit *comp_unit);
44
45  /// Destructor.
46  ~LineTable();
47
48  /// Adds a new line entry to this line table.
49  ///
50  /// All line entries are maintained in file address order.
51  ///
52  /// \param[in] line_entry
53  ///     A const reference to a new line_entry to add to this line
54  ///     table.
55  ///
56  /// \see Address::DumpStyle
57  //  void
58  //  AddLineEntry (const LineEntry& line_entry);
59
60  // Called when you can't guarantee the addresses are in increasing order
61  void InsertLineEntry(lldb::addr_t file_addr, uint32_t line, uint16_t column,
62                       uint16_t file_idx, bool is_start_of_statement,
63                       bool is_start_of_basic_block, bool is_prologue_end,
64                       bool is_epilogue_begin, bool is_terminal_entry);
65
66  // Used to instantiate the LineSequence helper class
67  LineSequence *CreateLineSequenceContainer();
68
69  // Append an entry to a caller-provided collection that will later be
70  // inserted in this line table.
71  void AppendLineEntryToSequence(LineSequence *sequence, lldb::addr_t file_addr,
72                                 uint32_t line, uint16_t column,
73                                 uint16_t file_idx, bool is_start_of_statement,
74                                 bool is_start_of_basic_block,
75                                 bool is_prologue_end, bool is_epilogue_begin,
76                                 bool is_terminal_entry);
77
78  // Insert a sequence of entries into this line table.
79  void InsertSequence(LineSequence *sequence);
80
81  /// Dump all line entries in this line table to the stream \a s.
82  ///
83  /// \param[in] s
84  ///     The stream to which to dump the object description.
85  ///
86  /// \param[in] style
87  ///     The display style for the address.
88  ///
89  /// \see Address::DumpStyle
90  void Dump(Stream *s, Target *target, Address::DumpStyle style,
91            Address::DumpStyle fallback_style, bool show_line_ranges);
92
93  void GetDescription(Stream *s, Target *target, lldb::DescriptionLevel level);
94
95  /// Find a line entry that contains the section offset address \a so_addr.
96  ///
97  /// \param[in] so_addr
98  ///     A section offset address object containing the address we
99  ///     are searching for.
100  ///
101  /// \param[out] line_entry
102  ///     A copy of the line entry that was found if \b true is
103  ///     returned, otherwise \a entry is left unmodified.
104  ///
105  /// \param[out] index_ptr
106  ///     A pointer to a 32 bit integer that will get the actual line
107  ///     entry index if it is not nullptr.
108  ///
109  /// \return
110  ///     Returns \b true if \a so_addr is contained in a line entry
111  ///     in this line table, \b false otherwise.
112  bool FindLineEntryByAddress(const Address &so_addr, LineEntry &line_entry,
113                              uint32_t *index_ptr = nullptr);
114
115  /// Find a line entry index that has a matching file index and source line
116  /// number.
117  ///
118  /// Finds the next line entry that has a matching \a file_idx and source
119  /// line number \a line starting at the \a start_idx entries into the line
120  /// entry collection.
121  ///
122  /// \param[in] start_idx
123  ///     The number of entries to skip when starting the search.
124  ///
125  /// \param[out] file_idx
126  ///     The file index to search for that should be found prior
127  ///     to calling this function using the following functions:
128  ///     CompileUnit::GetSupportFiles()
129  ///     FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const
130  ///
131  /// \param[in] line
132  ///     The source line to match.
133  ///
134  /// \param[in] exact
135  ///     If true, match only if you find a line entry exactly matching \a line.
136  ///     If false, return the closest line entry greater than \a line.
137  ///
138  /// \param[out] line_entry_ptr
139  ///     A pointer to a line entry object that will get a copy of
140  ///     the line entry if \b true is returned, otherwise \a
141  ///     line_entry is left untouched.
142  ///
143  /// \return
144  ///     Returns \b true if a matching line entry is found in this
145  ///     line table, \b false otherwise.
146  ///
147  /// \see CompileUnit::GetSupportFiles()
148  /// \see FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const
149  uint32_t FindLineEntryIndexByFileIndex(uint32_t start_idx, uint32_t file_idx,
150                                         uint32_t line, bool exact,
151                                         LineEntry *line_entry_ptr);
152
153  uint32_t FindLineEntryIndexByFileIndex(
154      uint32_t start_idx, const std::vector<uint32_t> &file_indexes,
155      uint32_t line, bool exact, LineEntry *line_entry_ptr);
156
157  size_t FineLineEntriesForFileIndex(uint32_t file_idx, bool append,
158                                     SymbolContextList &sc_list);
159
160  /// Get the line entry from the line table at index \a idx.
161  ///
162  /// \param[in] idx
163  ///     An index into the line table entry collection.
164  ///
165  /// \return
166  ///     A valid line entry if \a idx is a valid index, or an invalid
167  ///     line entry if \a idx is not valid.
168  ///
169  /// \see LineTable::GetSize()
170  /// \see LineEntry::IsValid() const
171  bool GetLineEntryAtIndex(uint32_t idx, LineEntry &line_entry);
172
173  /// Gets the size of the line table in number of line table entries.
174  ///
175  /// \return
176  ///     The number of line table entries in this line table.
177  uint32_t GetSize() const;
178
179  typedef lldb_private::RangeArray<lldb::addr_t, lldb::addr_t, 32>
180      FileAddressRanges;
181
182  /// Gets all contiguous file address ranges for the entire line table.
183  ///
184  /// \param[out] file_ranges
185  ///     A collection of file address ranges that will be filled in
186  ///     by this function.
187  ///
188  /// \param[out] append
189  ///     If \b true, then append to \a file_ranges, otherwise clear
190  ///     \a file_ranges prior to adding any ranges.
191  ///
192  /// \return
193  ///     The number of address ranges added to \a file_ranges
194  size_t GetContiguousFileAddressRanges(FileAddressRanges &file_ranges,
195                                        bool append);
196
197  typedef RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t>
198      FileRangeMap;
199
200  LineTable *LinkLineTable(const FileRangeMap &file_range_map);
201
202protected:
203  struct Entry {
204    Entry()
205        : file_addr(LLDB_INVALID_ADDRESS), line(0),
206          is_start_of_statement(false), is_start_of_basic_block(false),
207          is_prologue_end(false), is_epilogue_begin(false),
208          is_terminal_entry(false), column(0), file_idx(0) {}
209
210    Entry(lldb::addr_t _file_addr, uint32_t _line, uint16_t _column,
211          uint16_t _file_idx, bool _is_start_of_statement,
212          bool _is_start_of_basic_block, bool _is_prologue_end,
213          bool _is_epilogue_begin, bool _is_terminal_entry)
214        : file_addr(_file_addr), line(_line),
215          is_start_of_statement(_is_start_of_statement),
216          is_start_of_basic_block(_is_start_of_basic_block),
217          is_prologue_end(_is_prologue_end),
218          is_epilogue_begin(_is_epilogue_begin),
219          is_terminal_entry(_is_terminal_entry), column(_column),
220          file_idx(_file_idx) {}
221
222    int bsearch_compare(const void *key, const void *arrmem);
223
224    void Clear() {
225      file_addr = LLDB_INVALID_ADDRESS;
226      line = 0;
227      column = 0;
228      file_idx = 0;
229      is_start_of_statement = false;
230      is_start_of_basic_block = false;
231      is_prologue_end = false;
232      is_epilogue_begin = false;
233      is_terminal_entry = false;
234    }
235
236    static int Compare(const Entry &lhs, const Entry &rhs) {
237// Compare the sections before calling
238#define SCALAR_COMPARE(a, b)                                                   \
239  if (a < b)                                                                   \
240    return -1;                                                                 \
241  if (a > b)                                                                   \
242  return +1
243      SCALAR_COMPARE(lhs.file_addr, rhs.file_addr);
244      SCALAR_COMPARE(lhs.line, rhs.line);
245      SCALAR_COMPARE(lhs.column, rhs.column);
246      SCALAR_COMPARE(lhs.is_start_of_statement, rhs.is_start_of_statement);
247      SCALAR_COMPARE(lhs.is_start_of_basic_block, rhs.is_start_of_basic_block);
248      // rhs and lhs reversed on purpose below.
249      SCALAR_COMPARE(rhs.is_prologue_end, lhs.is_prologue_end);
250      SCALAR_COMPARE(lhs.is_epilogue_begin, rhs.is_epilogue_begin);
251      // rhs and lhs reversed on purpose below.
252      SCALAR_COMPARE(rhs.is_terminal_entry, lhs.is_terminal_entry);
253      SCALAR_COMPARE(lhs.file_idx, rhs.file_idx);
254#undef SCALAR_COMPARE
255      return 0;
256    }
257
258    class LessThanBinaryPredicate {
259    public:
260      LessThanBinaryPredicate(LineTable *line_table);
261      bool operator()(const LineTable::Entry &, const LineTable::Entry &) const;
262
263    protected:
264      LineTable *m_line_table;
265    };
266
267    static bool EntryAddressLessThan(const Entry &lhs, const Entry &rhs) {
268      return lhs.file_addr < rhs.file_addr;
269    }
270
271    // Member variables.
272    /// The file address for this line entry.
273    lldb::addr_t file_addr;
274    /// The source line number, or zero if there is no line number
275    /// information.
276    uint32_t line : 27;
277    /// Indicates this entry is the beginning of a statement.
278    uint32_t is_start_of_statement : 1;
279    /// Indicates this entry is the beginning of a basic block.
280    uint32_t is_start_of_basic_block : 1;
281    /// Indicates this entry is one (of possibly many) where execution
282    /// should be suspended for an entry breakpoint of a function.
283    uint32_t is_prologue_end : 1;
284    /// Indicates this entry is one (of possibly many) where execution
285    /// should be suspended for an exit breakpoint of a function.
286    uint32_t is_epilogue_begin : 1;
287    /// Indicates this entry is that of the first byte after the end
288    /// of a sequence of target machine instructions.
289    uint32_t is_terminal_entry : 1;
290    /// The column number of the source line, or zero if there is no
291    /// column information.
292    uint16_t column;
293    /// The file index into CompileUnit's file table, or zero if there
294    /// is no file information.
295    uint16_t file_idx;
296  };
297
298  struct EntrySearchInfo {
299    LineTable *line_table;
300    lldb_private::Section *a_section;
301    Entry *a_entry;
302  };
303
304  // Types
305  typedef std::vector<lldb_private::Section *>
306      section_collection; ///< The collection type for the sections.
307  typedef std::vector<Entry>
308      entry_collection; ///< The collection type for the line entries.
309  // Member variables.
310  CompileUnit
311      *m_comp_unit; ///< The compile unit that this line table belongs to.
312  entry_collection
313      m_entries; ///< The collection of line entries in this line table.
314
315  // Helper class
316  class LineSequenceImpl : public LineSequence {
317  public:
318    LineSequenceImpl() = default;
319
320    ~LineSequenceImpl() override = default;
321
322    void Clear() override;
323
324    entry_collection
325        m_entries; ///< The collection of line entries in this sequence.
326  };
327
328  bool ConvertEntryAtIndexToLineEntry(uint32_t idx, LineEntry &line_entry);
329
330private:
331  DISALLOW_COPY_AND_ASSIGN(LineTable);
332};
333
334} // namespace lldb_private
335
336#endif // liblldb_LineTable_h_
337