180814287SRaphael Isemann //===-- LineEntry.cpp -----------------------------------------------------===//
230fdc8d8SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
630fdc8d8SChris Lattner //
730fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
830fdc8d8SChris Lattner
930fdc8d8SChris Lattner #include "lldb/Symbol/LineEntry.h"
1030fdc8d8SChris Lattner #include "lldb/Symbol/CompileUnit.h"
1130fdc8d8SChris Lattner #include "lldb/Target/Process.h"
12f5e56de0SGreg Clayton #include "lldb/Target/Target.h"
1330fdc8d8SChris Lattner
1430fdc8d8SChris Lattner using namespace lldb_private;
1530fdc8d8SChris Lattner
LineEntry()16b9c1b51eSKate Stone LineEntry::LineEntry()
179494c510SJonas Devlieghere : range(), file(), is_start_of_statement(0), is_start_of_basic_block(0),
189494c510SJonas Devlieghere is_prologue_end(0), is_epilogue_begin(0), is_terminal_entry(0) {}
1930fdc8d8SChris Lattner
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)20b9c1b51eSKate Stone LineEntry::LineEntry(const lldb::SectionSP §ion_sp,
21b9c1b51eSKate Stone lldb::addr_t section_offset, lldb::addr_t byte_size,
22b9c1b51eSKate Stone const FileSpec &_file, uint32_t _line, uint16_t _column,
23b9c1b51eSKate Stone bool _is_start_of_statement, bool _is_start_of_basic_block,
24b9c1b51eSKate Stone bool _is_prologue_end, bool _is_epilogue_begin,
25b9c1b51eSKate Stone bool _is_terminal_entry)
26b9c1b51eSKate Stone : range(section_sp, section_offset, byte_size), file(_file),
27b9c1b51eSKate Stone original_file(_file), line(_line), column(_column),
2830fdc8d8SChris Lattner is_start_of_statement(_is_start_of_statement),
2930fdc8d8SChris Lattner is_start_of_basic_block(_is_start_of_basic_block),
30b9c1b51eSKate Stone is_prologue_end(_is_prologue_end), is_epilogue_begin(_is_epilogue_begin),
31b9c1b51eSKate Stone is_terminal_entry(_is_terminal_entry) {}
3230fdc8d8SChris Lattner
Clear()33b9c1b51eSKate Stone void LineEntry::Clear() {
3430fdc8d8SChris Lattner range.Clear();
3530fdc8d8SChris Lattner file.Clear();
36911d5784STed Woodward original_file.Clear();
372b89a531SJim Ingham line = LLDB_INVALID_LINE_NUMBER;
3830fdc8d8SChris Lattner column = 0;
3930fdc8d8SChris Lattner is_start_of_statement = 0;
4030fdc8d8SChris Lattner is_start_of_basic_block = 0;
4130fdc8d8SChris Lattner is_prologue_end = 0;
4230fdc8d8SChris Lattner is_epilogue_begin = 0;
4330fdc8d8SChris Lattner is_terminal_entry = 0;
4430fdc8d8SChris Lattner }
4530fdc8d8SChris Lattner
IsValid() const46b9c1b51eSKate Stone bool LineEntry::IsValid() const {
472b89a531SJim Ingham return range.GetBaseAddress().IsValid() && line != LLDB_INVALID_LINE_NUMBER;
4830fdc8d8SChris Lattner }
4930fdc8d8SChris Lattner
DumpStopContext(Stream * s,bool show_fullpaths) const50b9c1b51eSKate Stone bool LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const {
51b9c1b51eSKate Stone if (file) {
526dadd508SGreg Clayton if (show_fullpaths)
534dac97ebSRaphael Isemann file.Dump(s->AsRawOstream());
546dadd508SGreg Clayton else
556dadd508SGreg Clayton file.GetFilename().Dump(s);
566dadd508SGreg Clayton
5730fdc8d8SChris Lattner if (line)
5830fdc8d8SChris Lattner s->PutChar(':');
5930fdc8d8SChris Lattner }
60431b1584SAdrian Prantl if (line) {
6130fdc8d8SChris Lattner s->Printf("%u", line);
62431b1584SAdrian Prantl if (column) {
63431b1584SAdrian Prantl s->PutChar(':');
64431b1584SAdrian Prantl s->Printf("%u", column);
65431b1584SAdrian Prantl }
66431b1584SAdrian Prantl }
67431b1584SAdrian Prantl return file || line;
6830fdc8d8SChris Lattner }
6930fdc8d8SChris Lattner
Dump(Stream * s,Target * target,bool show_file,Address::DumpStyle style,Address::DumpStyle fallback_style,bool show_range) const70b9c1b51eSKate Stone bool LineEntry::Dump(Stream *s, Target *target, bool show_file,
7130fdc8d8SChris Lattner Address::DumpStyle style,
72b9c1b51eSKate Stone Address::DumpStyle fallback_style, bool show_range) const {
73b9c1b51eSKate Stone if (show_range) {
7430fdc8d8SChris Lattner // Show address range
75f5e56de0SGreg Clayton if (!range.Dump(s, target, style, fallback_style))
7630fdc8d8SChris Lattner return false;
77b9c1b51eSKate Stone } else {
7830fdc8d8SChris Lattner // Show address only
79b9c1b51eSKate Stone if (!range.GetBaseAddress().Dump(s, target, style, fallback_style))
8030fdc8d8SChris Lattner return false;
8130fdc8d8SChris Lattner }
820c5cd90dSGreg Clayton if (show_file)
830c5cd90dSGreg Clayton *s << ", file = " << file;
8430fdc8d8SChris Lattner if (line)
8530fdc8d8SChris Lattner s->Printf(", line = %u", line);
8630fdc8d8SChris Lattner if (column)
8730fdc8d8SChris Lattner s->Printf(", column = %u", column);
8830fdc8d8SChris Lattner if (is_start_of_statement)
8930fdc8d8SChris Lattner *s << ", is_start_of_statement = TRUE";
9030fdc8d8SChris Lattner
9130fdc8d8SChris Lattner if (is_start_of_basic_block)
9230fdc8d8SChris Lattner *s << ", is_start_of_basic_block = TRUE";
9330fdc8d8SChris Lattner
9430fdc8d8SChris Lattner if (is_prologue_end)
9530fdc8d8SChris Lattner *s << ", is_prologue_end = TRUE";
9630fdc8d8SChris Lattner
9730fdc8d8SChris Lattner if (is_epilogue_begin)
9830fdc8d8SChris Lattner *s << ", is_epilogue_begin = TRUE";
9930fdc8d8SChris Lattner
10030fdc8d8SChris Lattner if (is_terminal_entry)
10130fdc8d8SChris Lattner *s << ", is_terminal_entry = TRUE";
10230fdc8d8SChris Lattner return true;
10330fdc8d8SChris Lattner }
10430fdc8d8SChris Lattner
GetDescription(Stream * s,lldb::DescriptionLevel level,CompileUnit * cu,Target * target,bool show_address_only) const105b9c1b51eSKate Stone bool LineEntry::GetDescription(Stream *s, lldb::DescriptionLevel level,
106b9c1b51eSKate Stone CompileUnit *cu, Target *target,
107b9c1b51eSKate Stone bool show_address_only) const {
10830fdc8d8SChris Lattner
109b9c1b51eSKate Stone if (level == lldb::eDescriptionLevelBrief ||
110b9c1b51eSKate Stone level == lldb::eDescriptionLevelFull) {
111b9c1b51eSKate Stone if (show_address_only) {
112b9c1b51eSKate Stone range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress,
113b9c1b51eSKate Stone Address::DumpStyleFileAddress);
114b9c1b51eSKate Stone } else {
115b9c1b51eSKate Stone range.Dump(s, target, Address::DumpStyleLoadAddress,
116b9c1b51eSKate Stone Address::DumpStyleFileAddress);
1170c5cd90dSGreg Clayton }
11830fdc8d8SChris Lattner
119c9800667SGreg Clayton *s << ": " << file;
12030fdc8d8SChris Lattner
121b9c1b51eSKate Stone if (line) {
12230fdc8d8SChris Lattner s->Printf(":%u", line);
12330fdc8d8SChris Lattner if (column)
12430fdc8d8SChris Lattner s->Printf(":%u", column);
12530fdc8d8SChris Lattner }
12630fdc8d8SChris Lattner
127b9c1b51eSKate Stone if (level == lldb::eDescriptionLevelFull) {
12830fdc8d8SChris Lattner if (is_start_of_statement)
12930fdc8d8SChris Lattner *s << ", is_start_of_statement = TRUE";
13030fdc8d8SChris Lattner
13130fdc8d8SChris Lattner if (is_start_of_basic_block)
13230fdc8d8SChris Lattner *s << ", is_start_of_basic_block = TRUE";
13330fdc8d8SChris Lattner
13430fdc8d8SChris Lattner if (is_prologue_end)
13530fdc8d8SChris Lattner *s << ", is_prologue_end = TRUE";
13630fdc8d8SChris Lattner
13730fdc8d8SChris Lattner if (is_epilogue_begin)
13830fdc8d8SChris Lattner *s << ", is_epilogue_begin = TRUE";
13930fdc8d8SChris Lattner
14030fdc8d8SChris Lattner if (is_terminal_entry)
14130fdc8d8SChris Lattner *s << ", is_terminal_entry = TRUE";
142b9c1b51eSKate Stone } else {
14330fdc8d8SChris Lattner if (is_terminal_entry)
14430fdc8d8SChris Lattner s->EOL();
14530fdc8d8SChris Lattner }
146b9c1b51eSKate Stone } else {
147b9c1b51eSKate Stone return Dump(s, target, true, Address::DumpStyleLoadAddress,
148b9c1b51eSKate Stone Address::DumpStyleModuleWithFileAddress, true);
14930fdc8d8SChris Lattner }
15030fdc8d8SChris Lattner return true;
15130fdc8d8SChris Lattner }
15230fdc8d8SChris Lattner
operator <(const LineEntry & a,const LineEntry & b)153b9c1b51eSKate Stone bool lldb_private::operator<(const LineEntry &a, const LineEntry &b) {
15430fdc8d8SChris Lattner return LineEntry::Compare(a, b) < 0;
15530fdc8d8SChris Lattner }
15630fdc8d8SChris Lattner
Compare(const LineEntry & a,const LineEntry & b)157b9c1b51eSKate Stone int LineEntry::Compare(const LineEntry &a, const LineEntry &b) {
158b9c1b51eSKate Stone int result = Address::CompareFileAddress(a.range.GetBaseAddress(),
159b9c1b51eSKate Stone b.range.GetBaseAddress());
16030fdc8d8SChris Lattner if (result != 0)
16130fdc8d8SChris Lattner return result;
16230fdc8d8SChris Lattner
16330fdc8d8SChris Lattner const lldb::addr_t a_byte_size = a.range.GetByteSize();
16430fdc8d8SChris Lattner const lldb::addr_t b_byte_size = b.range.GetByteSize();
16530fdc8d8SChris Lattner
16630fdc8d8SChris Lattner if (a_byte_size < b_byte_size)
16730fdc8d8SChris Lattner return -1;
16830fdc8d8SChris Lattner if (a_byte_size > b_byte_size)
16930fdc8d8SChris Lattner return +1;
17030fdc8d8SChris Lattner
17105097246SAdrian Prantl // Check for an end sequence entry mismatch after we have determined that the
17205097246SAdrian Prantl // address values are equal. If one of the items is an end sequence, we don't
17305097246SAdrian Prantl // care about the line, file, or column info.
17430fdc8d8SChris Lattner if (a.is_terminal_entry > b.is_terminal_entry)
17530fdc8d8SChris Lattner return -1;
17630fdc8d8SChris Lattner if (a.is_terminal_entry < b.is_terminal_entry)
17730fdc8d8SChris Lattner return +1;
17830fdc8d8SChris Lattner
17930fdc8d8SChris Lattner if (a.line < b.line)
18030fdc8d8SChris Lattner return -1;
18130fdc8d8SChris Lattner if (a.line > b.line)
18230fdc8d8SChris Lattner return +1;
18330fdc8d8SChris Lattner
18430fdc8d8SChris Lattner if (a.column < b.column)
18530fdc8d8SChris Lattner return -1;
18630fdc8d8SChris Lattner if (a.column > b.column)
18730fdc8d8SChris Lattner return +1;
18830fdc8d8SChris Lattner
18930fdc8d8SChris Lattner return FileSpec::Compare(a.file, b.file, true);
19030fdc8d8SChris Lattner }
19130fdc8d8SChris Lattner
GetSameLineContiguousAddressRange(bool include_inlined_functions) const1928a777920SGreg Clayton AddressRange LineEntry::GetSameLineContiguousAddressRange(
1938a777920SGreg Clayton bool include_inlined_functions) const {
19405097246SAdrian Prantl // Add each LineEntry's range to complete_line_range until we find a
19505097246SAdrian Prantl // different file / line number.
19625d5b10bSJason Molenda AddressRange complete_line_range = range;
1978a777920SGreg Clayton auto symbol_context_scope = lldb::eSymbolContextLineEntry;
1988a777920SGreg Clayton Declaration start_call_site(original_file, line);
1998a777920SGreg Clayton if (include_inlined_functions)
2008a777920SGreg Clayton symbol_context_scope |= lldb::eSymbolContextBlock;
20125d5b10bSJason Molenda
202b9c1b51eSKate Stone while (true) {
20325d5b10bSJason Molenda SymbolContext next_line_sc;
20425d5b10bSJason Molenda Address range_end(complete_line_range.GetBaseAddress());
20525d5b10bSJason Molenda range_end.Slide(complete_line_range.GetByteSize());
2068a777920SGreg Clayton range_end.CalculateSymbolContext(&next_line_sc, symbol_context_scope);
20725d5b10bSJason Molenda
2088a777920SGreg Clayton if (!next_line_sc.line_entry.IsValid() ||
2098a777920SGreg Clayton next_line_sc.line_entry.range.GetByteSize() == 0)
2108a777920SGreg Clayton break;
2118a777920SGreg Clayton
2128a777920SGreg Clayton if (original_file == next_line_sc.line_entry.original_file &&
2138a777920SGreg Clayton (next_line_sc.line_entry.line == 0 ||
2148a777920SGreg Clayton line == next_line_sc.line_entry.line)) {
21505097246SAdrian Prantl // Include any line 0 entries - they indicate that this is compiler-
21605097246SAdrian Prantl // generated code that does not correspond to user source code.
2178a777920SGreg Clayton // next_line_sc is the same file & line as this LineEntry, so extend
2188a777920SGreg Clayton // our AddressRange by its size and continue to see if there are more
2198a777920SGreg Clayton // LineEntries that we can combine. However, if there was nothing to
2208a777920SGreg Clayton // extend we're done.
2218a777920SGreg Clayton if (!complete_line_range.Extend(next_line_sc.line_entry.range))
2228a777920SGreg Clayton break;
22325d5b10bSJason Molenda continue;
22425d5b10bSJason Molenda }
22525d5b10bSJason Molenda
2268a777920SGreg Clayton if (include_inlined_functions && next_line_sc.block &&
2278a777920SGreg Clayton next_line_sc.block->GetContainingInlinedBlock() != nullptr) {
2288a777920SGreg Clayton // The next_line_sc might be in a different file if it's an inlined
2298a777920SGreg Clayton // function. If this is the case then we still want to expand our line
2308a777920SGreg Clayton // range to include them if the inlined function is at the same call site
2318a777920SGreg Clayton // as this line entry. The current block could represent a nested inline
2328a777920SGreg Clayton // function call so we need to need to check up the block tree to see if
2338a777920SGreg Clayton // we find one.
2348a777920SGreg Clayton auto inlined_parent_block =
2358a777920SGreg Clayton next_line_sc.block->GetContainingInlinedBlockWithCallSite(
2368a777920SGreg Clayton start_call_site);
2378a777920SGreg Clayton if (!inlined_parent_block)
2388a777920SGreg Clayton // We didn't find any parent inlined block with a call site at this line
2398a777920SGreg Clayton // entry so this inlined function is probably at another line.
2408a777920SGreg Clayton break;
2418a777920SGreg Clayton // Extend our AddressRange by the size of the inlined block, but if there
2428a777920SGreg Clayton // was nothing to add then we're done.
2438a777920SGreg Clayton if (!complete_line_range.Extend(next_line_sc.line_entry.range))
2448a777920SGreg Clayton break;
24525d5b10bSJason Molenda continue;
24625d5b10bSJason Molenda }
2478a777920SGreg Clayton
24825d5b10bSJason Molenda break;
24925d5b10bSJason Molenda }
25025d5b10bSJason Molenda return complete_line_range;
25125d5b10bSJason Molenda }
252911d5784STed Woodward
ApplyFileMappings(lldb::TargetSP target_sp)253b9c1b51eSKate Stone void LineEntry::ApplyFileMappings(lldb::TargetSP target_sp) {
254b9c1b51eSKate Stone if (target_sp) {
255*a3463722SAdrian Prantl // Apply any file remappings to our file.
256*a3463722SAdrian Prantl if (auto new_file_spec =
257*a3463722SAdrian Prantl target_sp->GetSourcePathMap().FindFile(original_file))
258*a3463722SAdrian Prantl file = *new_file_spec;
259911d5784STed Woodward }
260911d5784STed Woodward }
261