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