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