1 //===-- LineTable.h ---------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef liblldb_LineTable_h_
10 #define liblldb_LineTable_h_
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"
19 namespace lldb_private {
21 /// \class LineSequence LineTable.h "lldb/Symbol/LineTable.h" An abstract base
22 /// class used during symbol table creation.
27 virtual ~LineSequence() = default;
29 virtual void Clear() = 0;
32 DISALLOW_COPY_AND_ASSIGN(LineSequence);
35 /// \class LineTable LineTable.h "lldb/Symbol/LineTable.h"
36 /// A line table class.
39 /// Construct with compile unit.
41 /// \param[in] comp_unit
42 /// The compile unit to which this line table belongs.
43 LineTable(CompileUnit *comp_unit);
48 /// Adds a new line entry to this line table.
50 /// All line entries are maintained in file address order.
52 /// \param[in] line_entry
53 /// A const reference to a new line_entry to add to this line
56 /// \see Address::DumpStyle
58 // AddLineEntry (const LineEntry& line_entry);
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);
66 // Used to instantiate the LineSequence helper class
67 LineSequence *CreateLineSequenceContainer();
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);
78 // Insert a sequence of entries into this line table.
79 void InsertSequence(LineSequence *sequence);
81 /// Dump all line entries in this line table to the stream \a s.
84 /// The stream to which to dump the object description.
87 /// The display style for the address.
89 /// \see Address::DumpStyle
90 void Dump(Stream *s, Target *target, Address::DumpStyle style,
91 Address::DumpStyle fallback_style, bool show_line_ranges);
93 void GetDescription(Stream *s, Target *target, lldb::DescriptionLevel level);
95 /// Find a line entry that contains the section offset address \a so_addr.
97 /// \param[in] so_addr
98 /// A section offset address object containing the address we
99 /// are searching for.
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.
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.
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);
115 /// Find a line entry index that has a matching file index and source line
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.
122 /// \param[in] start_idx
123 /// The number of entries to skip when starting the search.
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
132 /// The source line to match.
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.
138 /// \param[out] line_entry
139 /// A reference 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.
144 /// Returns \b true if a matching line entry is found in this
145 /// line table, \b false otherwise.
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);
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);
157 size_t FineLineEntriesForFileIndex(uint32_t file_idx, bool append,
158 SymbolContextList &sc_list);
160 /// Get the line entry from the line table at index \a idx.
163 /// An index into the line table entry collection.
166 /// A valid line entry if \a idx is a valid index, or an invalid
167 /// line entry if \a idx is not valid.
169 /// \see LineTable::GetSize()
170 /// \see LineEntry::IsValid() const
171 bool GetLineEntryAtIndex(uint32_t idx, LineEntry &line_entry);
173 /// Gets the size of the line table in number of line table entries.
176 /// The number of line table entries in this line table.
177 uint32_t GetSize() const;
179 typedef lldb_private::RangeArray<lldb::addr_t, lldb::addr_t, 32>
182 /// Gets all contiguous file address ranges for the entire line table.
184 /// \param[out] file_ranges
185 /// A collection of file address ranges that will be filled in
186 /// by this function.
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.
193 /// The number of address ranges added to \a file_ranges
194 size_t GetContiguousFileAddressRanges(FileAddressRanges &file_ranges,
197 /// Given a file range link map, relink the current line table and return a
198 /// fixed up line table.
200 /// \param[out] file_range_map
201 /// A collection of file ranges that maps to new file ranges
202 /// that will be used when linking the line table.
205 /// A new line table if at least one line table entry was able
207 typedef RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t>
210 LineTable *LinkLineTable(const FileRangeMap &file_range_map);
215 : file_addr(LLDB_INVALID_ADDRESS), line(0),
216 is_start_of_statement(false), is_start_of_basic_block(false),
217 is_prologue_end(false), is_epilogue_begin(false),
218 is_terminal_entry(false), column(0), file_idx(0) {}
220 Entry(lldb::addr_t _file_addr, uint32_t _line, uint16_t _column,
221 uint16_t _file_idx, bool _is_start_of_statement,
222 bool _is_start_of_basic_block, bool _is_prologue_end,
223 bool _is_epilogue_begin, bool _is_terminal_entry)
224 : file_addr(_file_addr), line(_line),
225 is_start_of_statement(_is_start_of_statement),
226 is_start_of_basic_block(_is_start_of_basic_block),
227 is_prologue_end(_is_prologue_end),
228 is_epilogue_begin(_is_epilogue_begin),
229 is_terminal_entry(_is_terminal_entry), column(_column),
230 file_idx(_file_idx) {}
232 int bsearch_compare(const void *key, const void *arrmem);
235 file_addr = LLDB_INVALID_ADDRESS;
239 is_start_of_statement = false;
240 is_start_of_basic_block = false;
241 is_prologue_end = false;
242 is_epilogue_begin = false;
243 is_terminal_entry = false;
246 static int Compare(const Entry &lhs, const Entry &rhs) {
247 // Compare the sections before calling
248 #define SCALAR_COMPARE(a, b) \
253 SCALAR_COMPARE(lhs.file_addr, rhs.file_addr);
254 SCALAR_COMPARE(lhs.line, rhs.line);
255 SCALAR_COMPARE(lhs.column, rhs.column);
256 SCALAR_COMPARE(lhs.is_start_of_statement, rhs.is_start_of_statement);
257 SCALAR_COMPARE(lhs.is_start_of_basic_block, rhs.is_start_of_basic_block);
258 // rhs and lhs reversed on purpose below.
259 SCALAR_COMPARE(rhs.is_prologue_end, lhs.is_prologue_end);
260 SCALAR_COMPARE(lhs.is_epilogue_begin, rhs.is_epilogue_begin);
261 // rhs and lhs reversed on purpose below.
262 SCALAR_COMPARE(rhs.is_terminal_entry, lhs.is_terminal_entry);
263 SCALAR_COMPARE(lhs.file_idx, rhs.file_idx);
264 #undef SCALAR_COMPARE
268 class LessThanBinaryPredicate {
270 LessThanBinaryPredicate(LineTable *line_table);
271 bool operator()(const LineTable::Entry &, const LineTable::Entry &) const;
274 LineTable *m_line_table;
277 static bool EntryAddressLessThan(const Entry &lhs, const Entry &rhs) {
278 return lhs.file_addr < rhs.file_addr;
282 /// The file address for this line entry.
283 lldb::addr_t file_addr;
284 /// The source line number, or zero if there is no line number
287 /// Indicates this entry is the beginning of a statement.
288 uint32_t is_start_of_statement : 1;
289 /// Indicates this entry is the beginning of a basic block.
290 uint32_t is_start_of_basic_block : 1;
291 /// Indicates this entry is one (of possibly many) where execution
292 /// should be suspended for an entry breakpoint of a function.
293 uint32_t is_prologue_end : 1;
294 /// Indicates this entry is one (of possibly many) where execution
295 /// should be suspended for an exit breakpoint of a function.
296 uint32_t is_epilogue_begin : 1;
297 /// Indicates this entry is that of the first byte after the end
298 /// of a sequence of target machine instructions.
299 uint32_t is_terminal_entry : 1;
300 /// The column number of the source line, or zero if there is no
301 /// column information.
303 /// The file index into CompileUnit's file table, or zero if there
304 /// is no file information.
308 struct EntrySearchInfo {
309 LineTable *line_table;
310 lldb_private::Section *a_section;
315 typedef std::vector<lldb_private::Section *>
316 section_collection; ///< The collection type for the sections.
317 typedef std::vector<Entry>
318 entry_collection; ///< The collection type for the line entries.
321 *m_comp_unit; ///< The compile unit that this line table belongs to.
323 m_entries; ///< The collection of line entries in this line table.
326 class LineSequenceImpl : public LineSequence {
328 LineSequenceImpl() = default;
330 ~LineSequenceImpl() override = default;
332 void Clear() override;
335 m_entries; ///< The collection of line entries in this sequence.
338 bool ConvertEntryAtIndexToLineEntry(uint32_t idx, LineEntry &line_entry);
341 DISALLOW_COPY_AND_ASSIGN(LineTable);
344 } // namespace lldb_private
346 #endif // liblldb_LineTable_h_