brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.1 KiB · 7f2edbf Raw
114 lines · cpp
1//===-- DWARFCompileUnit.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 "DWARFCompileUnit.h"10#include "DWARFDebugAranges.h"11#include "LogChannelDWARF.h"12#include "SymbolFileDWARFDebugMap.h"13 14#include "lldb/Symbol/CompileUnit.h"15#include "lldb/Symbol/LineTable.h"16#include "lldb/Utility/Stream.h"17#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"18 19using namespace lldb;20using namespace lldb_private;21using namespace lldb_private::plugin::dwarf;22 23void DWARFCompileUnit::Dump(Stream *s) const {24  s->Format(25 26      "{0:x16}: Compile Unit: length = {1:x8}, version = {2:x}, "27      "abbr_offset = {3:x8}, addr_size = {4:x2} (next CU at "28      "[{5:x16}])\n",29      GetOffset(), GetLength(), GetVersion(), (uint32_t)GetAbbrevOffset(),30      GetAddressByteSize(), GetNextUnitOffset());31}32 33void DWARFCompileUnit::BuildAddressRangeTable(34    DWARFDebugAranges *debug_aranges) {35  // This function is usually called if there in no .debug_aranges section in36  // order to produce a compile unit level set of address ranges that is37  // accurate.38 39  size_t num_debug_aranges = debug_aranges->GetNumRanges();40 41  // First get the compile unit DIE only and check contains ranges information.42  const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();43 44  const dw_offset_t cu_offset = GetOffset();45  if (die) {46    llvm::Expected<llvm::DWARFAddressRangesVector> ranges =47        die->GetAttributeAddressRanges(this, /*check_hi_lo_pc=*/true);48    if (ranges) {49      for (const llvm::DWARFAddressRange &range : *ranges)50        debug_aranges->AppendRange(cu_offset, range.LowPC, range.HighPC);51      if (!ranges->empty())52        return;53    } else {54      LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),55                     "{1:x}: {0}", cu_offset);56    }57  }58 59  if (debug_aranges->GetNumRanges() == num_debug_aranges) {60    // We got nothing from the debug info, try to build the arange table from61    // the debug map OSO aranges.62    SymbolContext sc;63    sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);64    if (sc.comp_unit) {65      SymbolFileDWARFDebugMap *debug_map_sym_file =66          m_dwarf.GetDebugMapSymfile();67      if (debug_map_sym_file) {68        auto *cu_info =69            debug_map_sym_file->GetCompileUnitInfo(&GetSymbolFileDWARF());70        // If there are extra compile units the OSO entries aren't a reliable71        // source of information.72        if (cu_info->compile_units_sps.empty())73          debug_map_sym_file->AddOSOARanges(&m_dwarf, debug_aranges);74      }75    }76  }77 78  if (debug_aranges->GetNumRanges() == num_debug_aranges) {79    // We got nothing from the functions, maybe we have a line tables only80    // situation. Check the line tables and build the arange table from this.81    SymbolContext sc;82    sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);83    if (sc.comp_unit) {84      if (LineTable *line_table = sc.comp_unit->GetLineTable()) {85        LineTable::FileAddressRanges file_ranges;86        const bool append = true;87        const size_t num_ranges =88            line_table->GetContiguousFileAddressRanges(file_ranges, append);89        for (uint32_t idx = 0; idx < num_ranges; ++idx) {90          const LineTable::FileAddressRanges::Entry &range =91              file_ranges.GetEntryRef(idx);92          debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(),93                                     range.GetRangeEnd());94        }95      }96    }97  }98}99 100DWARFCompileUnit &DWARFCompileUnit::GetNonSkeletonUnit() {101  return llvm::cast<DWARFCompileUnit>(DWARFUnit::GetNonSkeletonUnit());102}103 104DWARFDIE DWARFCompileUnit::LookupAddress(const dw_addr_t address) {105  if (DIE()) {106    const DWARFDebugAranges &func_aranges = GetFunctionAranges();107 108    // Re-check the aranges auto pointer contents in case it was created above109    if (!func_aranges.IsEmpty())110      return GetDIE(func_aranges.FindAddress(address));111  }112  return DWARFDIE();113}114