brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.1 KiB · c941a69 Raw
254 lines · cpp
1//===-- LineEntry.cpp -----------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Symbol/LineEntry.h"10#include "lldb/Symbol/CompileUnit.h"11#include "lldb/Target/Process.h"12#include "lldb/Target/Target.h"13 14using namespace lldb_private;15 16LineEntry::LineEntry()17    : range(), file_sp(std::make_shared<SupportFile>()),18      original_file_sp(std::make_shared<SupportFile>()),19      is_start_of_statement(0), is_start_of_basic_block(0), is_prologue_end(0),20      is_epilogue_begin(0), is_terminal_entry(0) {}21 22void LineEntry::Clear() {23  range.Clear();24  file_sp = std::make_shared<SupportFile>();25  original_file_sp = std::make_shared<SupportFile>();26  line = LLDB_INVALID_LINE_NUMBER;27  column = 0;28  is_start_of_statement = 0;29  is_start_of_basic_block = 0;30  is_prologue_end = 0;31  is_epilogue_begin = 0;32  is_terminal_entry = 0;33}34 35bool LineEntry::IsValid() const {36  return range.GetBaseAddress().IsValid() && line != LLDB_INVALID_LINE_NUMBER;37}38 39bool LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const {40  const FileSpec &file = file_sp->GetSpecOnly();41  if (file) {42    if (show_fullpaths)43      file.Dump(s->AsRawOstream());44    else45      file.GetFilename().Dump(s);46 47    if (line)48      s->PutChar(':');49  }50  if (line) {51    s->Printf("%u", line);52    if (column) {53      s->PutChar(':');54      s->Printf("%u", column);55    }56  }57  return file || line;58}59 60bool LineEntry::Dump(Stream *s, Target *target, bool show_file,61                     Address::DumpStyle style,62                     Address::DumpStyle fallback_style, bool show_range) const {63  if (show_range) {64    // Show address range65    if (!range.Dump(s, target, style, fallback_style))66      return false;67  } else {68    // Show address only69    if (!range.GetBaseAddress().Dump(s, target, style, fallback_style))70      return false;71  }72  if (show_file)73    *s << ", file = " << GetFile();74  if (line)75    s->Printf(", line = %u", line);76  if (column)77    s->Printf(", column = %u", column);78  if (is_start_of_statement)79    *s << ", is_start_of_statement = TRUE";80 81  if (is_start_of_basic_block)82    *s << ", is_start_of_basic_block = TRUE";83 84  if (is_prologue_end)85    *s << ", is_prologue_end = TRUE";86 87  if (is_epilogue_begin)88    *s << ", is_epilogue_begin = TRUE";89 90  if (is_terminal_entry)91    *s << ", is_terminal_entry = TRUE";92  return true;93}94 95bool LineEntry::GetDescription(Stream *s, lldb::DescriptionLevel level,96                               CompileUnit *cu, Target *target,97                               bool show_address_only) const {98 99  if (level == lldb::eDescriptionLevelBrief ||100      level == lldb::eDescriptionLevelFull) {101    if (show_address_only) {102      range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress,103                                  Address::DumpStyleFileAddress);104    } else {105      range.Dump(s, target, Address::DumpStyleLoadAddress,106                 Address::DumpStyleFileAddress);107    }108 109    *s << ": " << GetFile();110 111    if (line) {112      s->Printf(":%u", line);113      if (column)114        s->Printf(":%u", column);115    }116 117    if (level == lldb::eDescriptionLevelFull) {118      if (is_start_of_statement)119        *s << ", is_start_of_statement = TRUE";120 121      if (is_start_of_basic_block)122        *s << ", is_start_of_basic_block = TRUE";123 124      if (is_prologue_end)125        *s << ", is_prologue_end = TRUE";126 127      if (is_epilogue_begin)128        *s << ", is_epilogue_begin = TRUE";129 130      if (is_terminal_entry)131        *s << ", is_terminal_entry = TRUE";132    } else {133      if (is_terminal_entry)134        s->EOL();135    }136  } else {137    return Dump(s, target, true, Address::DumpStyleLoadAddress,138                Address::DumpStyleModuleWithFileAddress, true);139  }140  return true;141}142 143bool lldb_private::operator<(const LineEntry &a, const LineEntry &b) {144  return LineEntry::Compare(a, b) < 0;145}146 147int LineEntry::Compare(const LineEntry &a, const LineEntry &b) {148  int result = Address::CompareFileAddress(a.range.GetBaseAddress(),149                                           b.range.GetBaseAddress());150  if (result != 0)151    return result;152 153  const lldb::addr_t a_byte_size = a.range.GetByteSize();154  const lldb::addr_t b_byte_size = b.range.GetByteSize();155 156  if (a_byte_size < b_byte_size)157    return -1;158  if (a_byte_size > b_byte_size)159    return +1;160 161  // Check for an end sequence entry mismatch after we have determined that the162  // address values are equal. If one of the items is an end sequence, we don't163  // care about the line, file, or column info.164  if (a.is_terminal_entry > b.is_terminal_entry)165    return -1;166  if (a.is_terminal_entry < b.is_terminal_entry)167    return +1;168 169  if (a.line < b.line)170    return -1;171  if (a.line > b.line)172    return +1;173 174  if (a.column < b.column)175    return -1;176  if (a.column > b.column)177    return +1;178 179  return FileSpec::Compare(a.GetFile(), b.GetFile(), true);180}181 182AddressRange LineEntry::GetSameLineContiguousAddressRange(183    bool include_inlined_functions) const {184  // Add each LineEntry's range to complete_line_range until we find a185  // different file / line number.186  AddressRange complete_line_range = range;187  auto symbol_context_scope = lldb::eSymbolContextLineEntry;188  Declaration start_call_site(original_file_sp->GetSpecOnly(), line);189  if (include_inlined_functions)190    symbol_context_scope |= lldb::eSymbolContextBlock;191 192  while (true) {193    SymbolContext next_line_sc;194    Address range_end(complete_line_range.GetBaseAddress());195    range_end.Slide(complete_line_range.GetByteSize());196    range_end.CalculateSymbolContext(&next_line_sc, symbol_context_scope);197 198    if (!next_line_sc.line_entry.IsValid() ||199        next_line_sc.line_entry.range.GetByteSize() == 0)200      break;201 202    if (original_file_sp->Equal(*next_line_sc.line_entry.original_file_sp,203                                SupportFile::eEqualFileSpecAndChecksumIfSet) &&204        (next_line_sc.line_entry.line == 0 ||205         line == next_line_sc.line_entry.line)) {206      // Include any line 0 entries - they indicate that this is compiler-207      // generated code that does not correspond to user source code.208      // next_line_sc is the same file & line as this LineEntry, so extend209      // our AddressRange by its size and continue to see if there are more210      // LineEntries that we can combine. However, if there was nothing to211      // extend we're done.212      if (!complete_line_range.Extend(next_line_sc.line_entry.range))213        break;214      continue;215    }216 217    if (include_inlined_functions && next_line_sc.block &&218        next_line_sc.block->GetContainingInlinedBlock() != nullptr) {219      // The next_line_sc might be in a different file if it's an inlined220      // function. If this is the case then we still want to expand our line221      // range to include them if the inlined function is at the same call site222      // as this line entry. The current block could represent a nested inline223      // function call so we need to need to check up the block tree to see if224      // we find one.225      auto inlined_parent_block =226          next_line_sc.block->GetContainingInlinedBlockWithCallSite(227              start_call_site);228      if (!inlined_parent_block)229        // We didn't find any parent inlined block with a call site at this line230        // entry so this inlined function is probably at another line.231        break;232      // Extend our AddressRange by the size of the inlined block, but if there233      // was nothing to add then we're done.234      if (!complete_line_range.Extend(next_line_sc.line_entry.range))235        break;236      continue;237    }238 239    break;240  }241  return complete_line_range;242}243 244void LineEntry::ApplyFileMappings(lldb::TargetSP target_sp) {245  if (target_sp) {246    // Apply any file remappings to our file.247    if (auto new_file_spec = target_sp->GetSourcePathMap().FindFile(248            original_file_sp->GetSpecOnly())) {249      file_sp = std::make_shared<SupportFile>(*new_file_spec,250                                              original_file_sp->GetChecksum());251    }252  }253}254