Path: blob/main/contrib/llvm-project/lldb/source/Symbol/LineEntry.cpp
39587 views
//===-- LineEntry.cpp -----------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "lldb/Symbol/LineEntry.h"9#include "lldb/Symbol/CompileUnit.h"10#include "lldb/Target/Process.h"11#include "lldb/Target/Target.h"1213using namespace lldb_private;1415LineEntry::LineEntry()16: range(), file_sp(std::make_shared<SupportFile>()),17original_file_sp(std::make_shared<SupportFile>()),18is_start_of_statement(0), is_start_of_basic_block(0), is_prologue_end(0),19is_epilogue_begin(0), is_terminal_entry(0) {}2021void LineEntry::Clear() {22range.Clear();23file_sp = std::make_shared<SupportFile>();24original_file_sp = std::make_shared<SupportFile>();25line = LLDB_INVALID_LINE_NUMBER;26column = 0;27is_start_of_statement = 0;28is_start_of_basic_block = 0;29is_prologue_end = 0;30is_epilogue_begin = 0;31is_terminal_entry = 0;32}3334bool LineEntry::IsValid() const {35return range.GetBaseAddress().IsValid() && line != LLDB_INVALID_LINE_NUMBER;36}3738bool LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const {39const FileSpec &file = file_sp->GetSpecOnly();40if (file) {41if (show_fullpaths)42file.Dump(s->AsRawOstream());43else44file.GetFilename().Dump(s);4546if (line)47s->PutChar(':');48}49if (line) {50s->Printf("%u", line);51if (column) {52s->PutChar(':');53s->Printf("%u", column);54}55}56return file || line;57}5859bool LineEntry::Dump(Stream *s, Target *target, bool show_file,60Address::DumpStyle style,61Address::DumpStyle fallback_style, bool show_range) const {62if (show_range) {63// Show address range64if (!range.Dump(s, target, style, fallback_style))65return false;66} else {67// Show address only68if (!range.GetBaseAddress().Dump(s, target, style, fallback_style))69return false;70}71if (show_file)72*s << ", file = " << GetFile();73if (line)74s->Printf(", line = %u", line);75if (column)76s->Printf(", column = %u", column);77if (is_start_of_statement)78*s << ", is_start_of_statement = TRUE";7980if (is_start_of_basic_block)81*s << ", is_start_of_basic_block = TRUE";8283if (is_prologue_end)84*s << ", is_prologue_end = TRUE";8586if (is_epilogue_begin)87*s << ", is_epilogue_begin = TRUE";8889if (is_terminal_entry)90*s << ", is_terminal_entry = TRUE";91return true;92}9394bool LineEntry::GetDescription(Stream *s, lldb::DescriptionLevel level,95CompileUnit *cu, Target *target,96bool show_address_only) const {9798if (level == lldb::eDescriptionLevelBrief ||99level == lldb::eDescriptionLevelFull) {100if (show_address_only) {101range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress,102Address::DumpStyleFileAddress);103} else {104range.Dump(s, target, Address::DumpStyleLoadAddress,105Address::DumpStyleFileAddress);106}107108*s << ": " << GetFile();109110if (line) {111s->Printf(":%u", line);112if (column)113s->Printf(":%u", column);114}115116if (level == lldb::eDescriptionLevelFull) {117if (is_start_of_statement)118*s << ", is_start_of_statement = TRUE";119120if (is_start_of_basic_block)121*s << ", is_start_of_basic_block = TRUE";122123if (is_prologue_end)124*s << ", is_prologue_end = TRUE";125126if (is_epilogue_begin)127*s << ", is_epilogue_begin = TRUE";128129if (is_terminal_entry)130*s << ", is_terminal_entry = TRUE";131} else {132if (is_terminal_entry)133s->EOL();134}135} else {136return Dump(s, target, true, Address::DumpStyleLoadAddress,137Address::DumpStyleModuleWithFileAddress, true);138}139return true;140}141142bool lldb_private::operator<(const LineEntry &a, const LineEntry &b) {143return LineEntry::Compare(a, b) < 0;144}145146int LineEntry::Compare(const LineEntry &a, const LineEntry &b) {147int result = Address::CompareFileAddress(a.range.GetBaseAddress(),148b.range.GetBaseAddress());149if (result != 0)150return result;151152const lldb::addr_t a_byte_size = a.range.GetByteSize();153const lldb::addr_t b_byte_size = b.range.GetByteSize();154155if (a_byte_size < b_byte_size)156return -1;157if (a_byte_size > b_byte_size)158return +1;159160// Check for an end sequence entry mismatch after we have determined that the161// address values are equal. If one of the items is an end sequence, we don't162// care about the line, file, or column info.163if (a.is_terminal_entry > b.is_terminal_entry)164return -1;165if (a.is_terminal_entry < b.is_terminal_entry)166return +1;167168if (a.line < b.line)169return -1;170if (a.line > b.line)171return +1;172173if (a.column < b.column)174return -1;175if (a.column > b.column)176return +1;177178return FileSpec::Compare(a.GetFile(), b.GetFile(), true);179}180181AddressRange LineEntry::GetSameLineContiguousAddressRange(182bool include_inlined_functions) const {183// Add each LineEntry's range to complete_line_range until we find a184// different file / line number.185AddressRange complete_line_range = range;186auto symbol_context_scope = lldb::eSymbolContextLineEntry;187Declaration start_call_site(original_file_sp->GetSpecOnly(), line);188if (include_inlined_functions)189symbol_context_scope |= lldb::eSymbolContextBlock;190191while (true) {192SymbolContext next_line_sc;193Address range_end(complete_line_range.GetBaseAddress());194range_end.Slide(complete_line_range.GetByteSize());195range_end.CalculateSymbolContext(&next_line_sc, symbol_context_scope);196197if (!next_line_sc.line_entry.IsValid() ||198next_line_sc.line_entry.range.GetByteSize() == 0)199break;200201if (original_file_sp->Equal(*next_line_sc.line_entry.original_file_sp,202SupportFile::eEqualFileSpecAndChecksumIfSet) &&203(next_line_sc.line_entry.line == 0 ||204line == next_line_sc.line_entry.line)) {205// Include any line 0 entries - they indicate that this is compiler-206// generated code that does not correspond to user source code.207// next_line_sc is the same file & line as this LineEntry, so extend208// our AddressRange by its size and continue to see if there are more209// LineEntries that we can combine. However, if there was nothing to210// extend we're done.211if (!complete_line_range.Extend(next_line_sc.line_entry.range))212break;213continue;214}215216if (include_inlined_functions && next_line_sc.block &&217next_line_sc.block->GetContainingInlinedBlock() != nullptr) {218// The next_line_sc might be in a different file if it's an inlined219// function. If this is the case then we still want to expand our line220// range to include them if the inlined function is at the same call site221// as this line entry. The current block could represent a nested inline222// function call so we need to need to check up the block tree to see if223// we find one.224auto inlined_parent_block =225next_line_sc.block->GetContainingInlinedBlockWithCallSite(226start_call_site);227if (!inlined_parent_block)228// We didn't find any parent inlined block with a call site at this line229// entry so this inlined function is probably at another line.230break;231// Extend our AddressRange by the size of the inlined block, but if there232// was nothing to add then we're done.233if (!complete_line_range.Extend(next_line_sc.line_entry.range))234break;235continue;236}237238break;239}240return complete_line_range;241}242243void LineEntry::ApplyFileMappings(lldb::TargetSP target_sp) {244if (target_sp) {245// Apply any file remappings to our file.246if (auto new_file_spec = target_sp->GetSourcePathMap().FindFile(247original_file_sp->GetSpecOnly())) {248file_sp = std::make_shared<SupportFile>(*new_file_spec,249original_file_sp->GetChecksum());250}251}252}253254255