1 //===-- LineEntry.cpp -------------------------------------------*- 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 #include "lldb/Symbol/LineEntry.h"
11 #include "lldb/Symbol/CompileUnit.h"
12 #include "lldb/Target/Process.h"
13 #include "lldb/Target/Target.h"
14 
15 using namespace lldb_private;
16 
LineEntry()17 LineEntry::LineEntry() :
18     range(),
19     file(),
20     line(0),
21     column(0),
22     is_start_of_statement(0),
23     is_start_of_basic_block(0),
24     is_prologue_end(0),
25     is_epilogue_begin(0),
26     is_terminal_entry(0)
27 {
28 }
29 
LineEntry(const lldb::SectionSP & section_sp,lldb::addr_t section_offset,lldb::addr_t byte_size,const FileSpec & _file,uint32_t _line,uint16_t _column,bool _is_start_of_statement,bool _is_start_of_basic_block,bool _is_prologue_end,bool _is_epilogue_begin,bool _is_terminal_entry)30 LineEntry::LineEntry
31 (
32     const lldb::SectionSP &section_sp,
33     lldb::addr_t section_offset,
34     lldb::addr_t byte_size,
35     const FileSpec &_file,
36     uint32_t _line,
37     uint16_t _column,
38     bool _is_start_of_statement,
39     bool _is_start_of_basic_block,
40     bool _is_prologue_end,
41     bool _is_epilogue_begin,
42     bool _is_terminal_entry
43 ) :
44     range(section_sp, section_offset, byte_size),
45     file(_file),
46     line(_line),
47     column(_column),
48     is_start_of_statement(_is_start_of_statement),
49     is_start_of_basic_block(_is_start_of_basic_block),
50     is_prologue_end(_is_prologue_end),
51     is_epilogue_begin(_is_epilogue_begin),
52     is_terminal_entry(_is_terminal_entry)
53 {
54 }
55 
56 void
Clear()57 LineEntry::Clear()
58 {
59     range.Clear();
60     file.Clear();
61     line = 0;
62     column = 0;
63     is_start_of_statement = 0;
64     is_start_of_basic_block = 0;
65     is_prologue_end = 0;
66     is_epilogue_begin = 0;
67     is_terminal_entry = 0;
68 }
69 
70 
71 bool
IsValid() const72 LineEntry::IsValid() const
73 {
74     return range.GetBaseAddress().IsValid() && line != 0;
75 }
76 
77 bool
DumpStopContext(Stream * s,bool show_fullpaths) const78 LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const
79 {
80     bool result = false;
81     if (file)
82     {
83         if (show_fullpaths)
84             file.Dump (s);
85         else
86             file.GetFilename().Dump (s);
87 
88         if (line)
89             s->PutChar(':');
90         result = true;
91     }
92     if (line)
93         s->Printf ("%u", line);
94     else
95         result = false;
96 
97     return result;
98 }
99 
100 bool
Dump(Stream * s,Target * target,bool show_file,Address::DumpStyle style,Address::DumpStyle fallback_style,bool show_range) const101 LineEntry::Dump
102 (
103     Stream *s,
104     Target *target,
105     bool show_file,
106     Address::DumpStyle style,
107     Address::DumpStyle fallback_style,
108     bool show_range
109 ) const
110 {
111     if (show_range)
112     {
113         // Show address range
114         if (!range.Dump(s, target, style, fallback_style))
115             return false;
116     }
117     else
118     {
119         // Show address only
120         if (!range.GetBaseAddress().Dump(s,
121                                          target,
122                                          style,
123                                          fallback_style))
124             return false;
125     }
126     if (show_file)
127         *s << ", file = " << file;
128     if (line)
129         s->Printf(", line = %u", line);
130     if (column)
131         s->Printf(", column = %u", column);
132     if (is_start_of_statement)
133         *s << ", is_start_of_statement = TRUE";
134 
135     if (is_start_of_basic_block)
136         *s << ", is_start_of_basic_block = TRUE";
137 
138     if (is_prologue_end)
139         *s << ", is_prologue_end = TRUE";
140 
141     if (is_epilogue_begin)
142         *s << ", is_epilogue_begin = TRUE";
143 
144     if (is_terminal_entry)
145         *s << ", is_terminal_entry = TRUE";
146     return true;
147 }
148 
149 bool
GetDescription(Stream * s,lldb::DescriptionLevel level,CompileUnit * cu,Target * target,bool show_address_only) const150 LineEntry::GetDescription (Stream *s, lldb::DescriptionLevel level, CompileUnit* cu, Target *target, bool show_address_only) const
151 {
152 
153     if (level == lldb::eDescriptionLevelBrief || level == lldb::eDescriptionLevelFull)
154     {
155         if (show_address_only)
156         {
157             range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
158         }
159         else
160         {
161             range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
162         }
163 
164         *s << ": " << file;
165 
166         if (line)
167         {
168             s->Printf(":%u", line);
169             if (column)
170                 s->Printf(":%u", column);
171         }
172 
173 
174         if (level == lldb::eDescriptionLevelFull)
175         {
176             if (is_start_of_statement)
177                 *s << ", is_start_of_statement = TRUE";
178 
179             if (is_start_of_basic_block)
180                 *s << ", is_start_of_basic_block = TRUE";
181 
182             if (is_prologue_end)
183                 *s << ", is_prologue_end = TRUE";
184 
185             if (is_epilogue_begin)
186                 *s << ", is_epilogue_begin = TRUE";
187 
188             if (is_terminal_entry)
189                 *s << ", is_terminal_entry = TRUE";
190         }
191         else
192         {
193             if (is_terminal_entry)
194                 s->EOL();
195         }
196     }
197     else
198     {
199         return Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
200     }
201     return true;
202 }
203 
204 
205 bool
operator <(const LineEntry & a,const LineEntry & b)206 lldb_private::operator< (const LineEntry& a, const LineEntry& b)
207 {
208     return LineEntry::Compare (a, b) < 0;
209 }
210 
211 int
Compare(const LineEntry & a,const LineEntry & b)212 LineEntry::Compare (const LineEntry& a, const LineEntry& b)
213 {
214     int result = Address::CompareFileAddress (a.range.GetBaseAddress(), b.range.GetBaseAddress());
215     if (result != 0)
216         return result;
217 
218     const lldb::addr_t a_byte_size = a.range.GetByteSize();
219     const lldb::addr_t b_byte_size = b.range.GetByteSize();
220 
221     if (a_byte_size < b_byte_size)
222         return -1;
223     if (a_byte_size > b_byte_size)
224         return +1;
225 
226     // Check for an end sequence entry mismatch after we have determined
227     // that the address values are equal. If one of the items is an end
228     // sequence, we don't care about the line, file, or column info.
229     if (a.is_terminal_entry > b.is_terminal_entry)
230         return -1;
231     if (a.is_terminal_entry < b.is_terminal_entry)
232         return +1;
233 
234     if (a.line < b.line)
235         return -1;
236     if (a.line > b.line)
237         return +1;
238 
239     if (a.column < b.column)
240         return -1;
241     if (a.column > b.column)
242         return +1;
243 
244     return FileSpec::Compare (a.file, b.file, true);
245 }
246 
247