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