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