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