1103285Sikob//===-- LineTable.h ---------------------------------------------*- C++ -*-===//
2113584Ssimokawa//
3103285Sikob// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4103285Sikob// See https://llvm.org/LICENSE.txt for license information.
5103285Sikob// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6103285Sikob//
7103285Sikob//===----------------------------------------------------------------------===//
8103285Sikob
9103285Sikob#ifndef liblldb_LineTable_h_
10103285Sikob#define liblldb_LineTable_h_
11103285Sikob
12103285Sikob#include "lldb/Core/ModuleChild.h"
13103285Sikob#include "lldb/Core/Section.h"
14103285Sikob#include "lldb/Symbol/LineEntry.h"
15103285Sikob#include "lldb/Utility/RangeMap.h"
16103285Sikob#include "lldb/lldb-private.h"
17106802Ssimokawa#include <vector>
18103285Sikob
19103285Sikobnamespace lldb_private {
20103285Sikob
21103285Sikob/// \class LineSequence LineTable.h "lldb/Symbol/LineTable.h" An abstract base
22103285Sikob/// class used during symbol table creation.
23103285Sikobclass LineSequence {
24103285Sikobpublic:
25103285Sikob  LineSequence();
26103285Sikob
27103285Sikob  virtual ~LineSequence() = default;
28103285Sikob
29103285Sikob  virtual void Clear() = 0;
30103285Sikob
31103285Sikobprivate:
32103285Sikob  DISALLOW_COPY_AND_ASSIGN(LineSequence);
33103285Sikob};
34103285Sikob
35103285Sikob/// \class LineTable LineTable.h "lldb/Symbol/LineTable.h"
36103285Sikob/// A line table class.
37106802Ssimokawaclass LineTable {
38103285Sikobpublic:
39103285Sikob  /// Construct with compile unit.
40103285Sikob  ///
41103285Sikob  /// \param[in] comp_unit
42103285Sikob  ///     The compile unit to which this line table belongs.
43103285Sikob  LineTable(CompileUnit *comp_unit);
44103285Sikob
45103285Sikob  /// Destructor.
46103285Sikob  ~LineTable();
47103285Sikob
48103285Sikob  /// Adds a new line entry to this line table.
49103285Sikob  ///
50103285Sikob  /// All line entries are maintained in file address order.
51103285Sikob  ///
52103285Sikob  /// \param[in] line_entry
53113584Ssimokawa  ///     A const reference to a new line_entry to add to this line
54103285Sikob  ///     table.
55103285Sikob  ///
56103285Sikob  /// \see Address::DumpStyle
57117067Ssimokawa  //  void
58117067Ssimokawa  //  AddLineEntry (const LineEntry& line_entry);
59117067Ssimokawa
60117067Ssimokawa  // Called when you can't guarantee the addresses are in increasing order
61103285Sikob  void InsertLineEntry(lldb::addr_t file_addr, uint32_t line, uint16_t column,
62103285Sikob                       uint16_t file_idx, bool is_start_of_statement,
63113584Ssimokawa                       bool is_start_of_basic_block, bool is_prologue_end,
64103285Sikob                       bool is_epilogue_begin, bool is_terminal_entry);
65103285Sikob
66103285Sikob  // Used to instantiate the LineSequence helper class
67103285Sikob  LineSequence *CreateLineSequenceContainer();
68103285Sikob
69106802Ssimokawa  // Append an entry to a caller-provided collection that will later be
70103285Sikob  // inserted in this line table.
71103285Sikob  void AppendLineEntryToSequence(LineSequence *sequence, lldb::addr_t file_addr,
72113584Ssimokawa                                 uint32_t line, uint16_t column,
73103285Sikob                                 uint16_t file_idx, bool is_start_of_statement,
74103285Sikob                                 bool is_start_of_basic_block,
75113584Ssimokawa                                 bool is_prologue_end, bool is_epilogue_begin,
76103285Sikob                                 bool is_terminal_entry);
77103285Sikob
78103285Sikob  // Insert a sequence of entries into this line table.
79103285Sikob  void InsertSequence(LineSequence *sequence);
80103285Sikob
81103285Sikob  /// Dump all line entries in this line table to the stream \a s.
82103285Sikob  ///
83103285Sikob  /// \param[in] s
84103285Sikob  ///     The stream to which to dump the object description.
85113584Ssimokawa  ///
86116376Ssimokawa  /// \param[in] style
87116376Ssimokawa  ///     The display style for the address.
88103285Sikob  ///
89103285Sikob  /// \see Address::DumpStyle
90103285Sikob  void Dump(Stream *s, Target *target, Address::DumpStyle style,
91103285Sikob            Address::DumpStyle fallback_style, bool show_line_ranges);
92103285Sikob
93103285Sikob  void GetDescription(Stream *s, Target *target, lldb::DescriptionLevel level);
94103285Sikob
95103285Sikob  /// Find a line entry that contains the section offset address \a so_addr.
96103285Sikob  ///
97103285Sikob  /// \param[in] so_addr
98103285Sikob  ///     A section offset address object containing the address we
99103285Sikob  ///     are searching for.
100103285Sikob  ///
101103285Sikob  /// \param[out] line_entry
102103285Sikob  ///     A copy of the line entry that was found if \b true is
103103285Sikob  ///     returned, otherwise \a entry is left unmodified.
104103285Sikob  ///
105103285Sikob  /// \param[out] index_ptr
106103285Sikob  ///     A pointer to a 32 bit integer that will get the actual line
107103285Sikob  ///     entry index if it is not nullptr.
108103285Sikob  ///
109103285Sikob  /// \return
110103285Sikob  ///     Returns \b true if \a so_addr is contained in a line entry
111103285Sikob  ///     in this line table, \b false otherwise.
112103285Sikob  bool FindLineEntryByAddress(const Address &so_addr, LineEntry &line_entry,
113103285Sikob                              uint32_t *index_ptr = nullptr);
114103285Sikob
115103285Sikob  /// Find a line entry index that has a matching file index and source line
116103285Sikob  /// number.
117113584Ssimokawa  ///
118103285Sikob  /// Finds the next line entry that has a matching \a file_idx and source
119106789Ssimokawa  /// line number \a line starting at the \a start_idx entries into the line
120103285Sikob  /// entry collection.
121103285Sikob  ///
122103285Sikob  /// \param[in] start_idx
123103285Sikob  ///     The number of entries to skip when starting the search.
124103285Sikob  ///
125103285Sikob  /// \param[out] file_idx
126103285Sikob  ///     The file index to search for that should be found prior
127103285Sikob  ///     to calling this function using the following functions:
128103285Sikob  ///     CompileUnit::GetSupportFiles()
129103285Sikob  ///     FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const
130113584Ssimokawa  ///
131103285Sikob  /// \param[in] line
132113584Ssimokawa  ///     The source line to match.
133103285Sikob  ///
134103285Sikob  /// \param[in] exact
135103285Sikob  ///     If true, match only if you find a line entry exactly matching \a line.
136103285Sikob  ///     If false, return the closest line entry greater than \a line.
137113584Ssimokawa  ///
138113584Ssimokawa  /// \param[out] line_entry_ptr
139113584Ssimokawa  ///     A pointer to a line entry object that will get a copy of
140103285Sikob  ///     the line entry if \b true is returned, otherwise \a
141113584Ssimokawa  ///     line_entry is left untouched.
142103285Sikob  ///
143103285Sikob  /// \return
144103285Sikob  ///     Returns \b true if a matching line entry is found in this
145103285Sikob  ///     line table, \b false otherwise.
146103285Sikob  ///
147113584Ssimokawa  /// \see CompileUnit::GetSupportFiles()
148113584Ssimokawa  /// \see FileSpecList::FindFileIndex (uint32_t, const FileSpec &) const
149113584Ssimokawa  uint32_t FindLineEntryIndexByFileIndex(uint32_t start_idx, uint32_t file_idx,
150103285Sikob                                         uint32_t line, bool exact,
151103285Sikob                                         LineEntry *line_entry_ptr);
152103285Sikob
153103285Sikob  uint32_t FindLineEntryIndexByFileIndex(
154103285Sikob      uint32_t start_idx, const std::vector<uint32_t> &file_indexes,
155103285Sikob      uint32_t line, bool exact, LineEntry *line_entry_ptr);
156103285Sikob
157103285Sikob  size_t FineLineEntriesForFileIndex(uint32_t file_idx, bool append,
158103285Sikob                                     SymbolContextList &sc_list);
159103285Sikob
160103285Sikob  /// Get the line entry from the line table at index \a idx.
161112523Ssimokawa  ///
162103285Sikob  /// \param[in] idx
163103285Sikob  ///     An index into the line table entry collection.
164103285Sikob  ///
165103285Sikob  /// \return
166103285Sikob  ///     A valid line entry if \a idx is a valid index, or an invalid
167103285Sikob  ///     line entry if \a idx is not valid.
168103285Sikob  ///
169103285Sikob  /// \see LineTable::GetSize()
170103285Sikob  /// \see LineEntry::IsValid() const
171103285Sikob  bool GetLineEntryAtIndex(uint32_t idx, LineEntry &line_entry);
172103285Sikob
173103285Sikob  /// Gets the size of the line table in number of line table entries.
174103285Sikob  ///
175103285Sikob  /// \return
176103285Sikob  ///     The number of line table entries in this line table.
177103285Sikob  uint32_t GetSize() const;
178103285Sikob
179103285Sikob  typedef lldb_private::RangeArray<lldb::addr_t, lldb::addr_t, 32>
180103285Sikob      FileAddressRanges;
181103285Sikob
182103285Sikob  /// Gets all contiguous file address ranges for the entire line table.
183103285Sikob  ///
184103285Sikob  /// \param[out] file_ranges
185103285Sikob  ///     A collection of file address ranges that will be filled in
186103285Sikob  ///     by this function.
187103285Sikob  ///
188103285Sikob  /// \param[out] append
189103285Sikob  ///     If \b true, then append to \a file_ranges, otherwise clear
190113584Ssimokawa  ///     \a file_ranges prior to adding any ranges.
191103285Sikob  ///
192103285Sikob  /// \return
193103285Sikob  ///     The number of address ranges added to \a file_ranges
194103285Sikob  size_t GetContiguousFileAddressRanges(FileAddressRanges &file_ranges,
195103285Sikob                                        bool append);
196103285Sikob
197103285Sikob  typedef RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t>
198103285Sikob      FileRangeMap;
199103285Sikob
200103285Sikob  LineTable *LinkLineTable(const FileRangeMap &file_range_map);
201103285Sikob
202103285Sikobprotected:
203103285Sikob  struct Entry {
204103285Sikob    Entry()
205103285Sikob        : file_addr(LLDB_INVALID_ADDRESS), line(0),
206103285Sikob          is_start_of_statement(false), is_start_of_basic_block(false),
207103285Sikob          is_prologue_end(false), is_epilogue_begin(false),
208103285Sikob          is_terminal_entry(false), column(0), file_idx(0) {}
209103285Sikob
210103285Sikob    Entry(lldb::addr_t _file_addr, uint32_t _line, uint16_t _column,
211103285Sikob          uint16_t _file_idx, bool _is_start_of_statement,
212103285Sikob          bool _is_start_of_basic_block, bool _is_prologue_end,
213103285Sikob          bool _is_epilogue_begin, bool _is_terminal_entry)
214103285Sikob        : file_addr(_file_addr), line(_line),
215103285Sikob          is_start_of_statement(_is_start_of_statement),
216103285Sikob          is_start_of_basic_block(_is_start_of_basic_block),
217103285Sikob          is_prologue_end(_is_prologue_end),
218103285Sikob          is_epilogue_begin(_is_epilogue_begin),
219103285Sikob          is_terminal_entry(_is_terminal_entry), column(_column),
220103285Sikob          file_idx(_file_idx) {}
221103285Sikob
222103285Sikob    int bsearch_compare(const void *key, const void *arrmem);
223103285Sikob
224103285Sikob    void Clear() {
225103285Sikob      file_addr = LLDB_INVALID_ADDRESS;
226103285Sikob      line = 0;
227103285Sikob      column = 0;
228103285Sikob      file_idx = 0;
229103285Sikob      is_start_of_statement = false;
230103285Sikob      is_start_of_basic_block = false;
231103285Sikob      is_prologue_end = false;
232103285Sikob      is_epilogue_begin = false;
233103285Sikob      is_terminal_entry = false;
234103285Sikob    }
235103285Sikob
236103285Sikob    static int Compare(const Entry &lhs, const Entry &rhs) {
237103285Sikob// Compare the sections before calling
238103285Sikob#define SCALAR_COMPARE(a, b)                                                   \
239103285Sikob  if (a < b)                                                                   \
240103285Sikob    return -1;                                                                 \
241103285Sikob  if (a > b)                                                                   \
242103285Sikob  return +1
243103285Sikob      SCALAR_COMPARE(lhs.file_addr, rhs.file_addr);
244103285Sikob      SCALAR_COMPARE(lhs.line, rhs.line);
245103285Sikob      SCALAR_COMPARE(lhs.column, rhs.column);
246103285Sikob      SCALAR_COMPARE(lhs.is_start_of_statement, rhs.is_start_of_statement);
247103285Sikob      SCALAR_COMPARE(lhs.is_start_of_basic_block, rhs.is_start_of_basic_block);
248103285Sikob      // rhs and lhs reversed on purpose below.
249103285Sikob      SCALAR_COMPARE(rhs.is_prologue_end, lhs.is_prologue_end);
250103285Sikob      SCALAR_COMPARE(lhs.is_epilogue_begin, rhs.is_epilogue_begin);
251103285Sikob      // rhs and lhs reversed on purpose below.
252103285Sikob      SCALAR_COMPARE(rhs.is_terminal_entry, lhs.is_terminal_entry);
253103285Sikob      SCALAR_COMPARE(lhs.file_idx, rhs.file_idx);
254106790Ssimokawa#undef SCALAR_COMPARE
255106790Ssimokawa      return 0;
256103285Sikob    }
257103285Sikob
258103285Sikob    class LessThanBinaryPredicate {
259103285Sikob    public:
260103285Sikob      LessThanBinaryPredicate(LineTable *line_table);
261103285Sikob      bool operator()(const LineTable::Entry &, const LineTable::Entry &) const;
262103285Sikob
263103285Sikob    protected:
264103285Sikob      LineTable *m_line_table;
265103285Sikob    };
266103285Sikob
267103285Sikob    static bool EntryAddressLessThan(const Entry &lhs, const Entry &rhs) {
268103285Sikob      return lhs.file_addr < rhs.file_addr;
269103285Sikob    }
270103285Sikob
271103285Sikob    // Member variables.
272103285Sikob    /// The file address for this line entry.
273103285Sikob    lldb::addr_t file_addr;
274103285Sikob    /// The source line number, or zero if there is no line number
275103285Sikob    /// information.
276103285Sikob    uint32_t line : 27;
277103285Sikob    /// Indicates this entry is the beginning of a statement.
278103285Sikob    uint32_t is_start_of_statement : 1;
279103285Sikob    /// Indicates this entry is the beginning of a basic block.
280103285Sikob    uint32_t is_start_of_basic_block : 1;
281103285Sikob    /// Indicates this entry is one (of possibly many) where execution
282103285Sikob    /// should be suspended for an entry breakpoint of a function.
283103285Sikob    uint32_t is_prologue_end : 1;
284103285Sikob    /// Indicates this entry is one (of possibly many) where execution
285109280Ssimokawa    /// should be suspended for an exit breakpoint of a function.
286103285Sikob    uint32_t is_epilogue_begin : 1;
287107653Ssimokawa    /// Indicates this entry is that of the first byte after the end
288103285Sikob    /// of a sequence of target machine instructions.
289107653Ssimokawa    uint32_t is_terminal_entry : 1;
290107653Ssimokawa    /// The column number of the source line, or zero if there is no
291107653Ssimokawa    /// column information.
292103285Sikob    uint16_t column;
293103285Sikob    /// The file index into CompileUnit's file table, or zero if there
294103285Sikob    /// is no file information.
295103285Sikob    uint16_t file_idx;
296106790Ssimokawa  };
297106790Ssimokawa
298103285Sikob  struct EntrySearchInfo {
299108500Ssimokawa    LineTable *line_table;
300108500Ssimokawa    lldb_private::Section *a_section;
301103285Sikob    Entry *a_entry;
302103285Sikob  };
303108500Ssimokawa
304108500Ssimokawa  // Types
305108500Ssimokawa  typedef std::vector<lldb_private::Section *>
306103285Sikob      section_collection; ///< The collection type for the sections.
307103285Sikob  typedef std::vector<Entry>
308108500Ssimokawa      entry_collection; ///< The collection type for the line entries.
309103285Sikob  // Member variables.
310103285Sikob  CompileUnit
311103285Sikob      *m_comp_unit; ///< The compile unit that this line table belongs to.
312109280Ssimokawa  entry_collection
313103285Sikob      m_entries; ///< The collection of line entries in this line table.
314108500Ssimokawa
315109280Ssimokawa  // Helper class
316109280Ssimokawa  class LineSequenceImpl : public LineSequence {
317108527Ssimokawa  public:
318109280Ssimokawa    LineSequenceImpl() = default;
319108527Ssimokawa
320108527Ssimokawa    ~LineSequenceImpl() override = default;
321108500Ssimokawa
322108500Ssimokawa    void Clear() override;
323108500Ssimokawa
324108500Ssimokawa    entry_collection
325108500Ssimokawa        m_entries; ///< The collection of line entries in this sequence.
326109280Ssimokawa  };
327109280Ssimokawa
328108500Ssimokawa  bool ConvertEntryAtIndexToLineEntry(uint32_t idx, LineEntry &line_entry);
329109280Ssimokawa
330108500Ssimokawaprivate:
331108500Ssimokawa  DISALLOW_COPY_AND_ASSIGN(LineTable);
332108500Ssimokawa};
333108500Ssimokawa
334108500Ssimokawa} // namespace lldb_private
335108500Ssimokawa
336108500Ssimokawa#endif // liblldb_LineTable_h_
337103285Sikob