//===-- DWARFCompileUnit.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "DWARFCompileUnit.h"
#include "DWARFDebugAranges.h"
#include "LogChannelDWARF.h"
#include "SymbolFileDWARFDebugMap.h"

#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Utility/Stream.h"
#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::plugin::dwarf;

void DWARFCompileUnit::Dump(Stream *s) const {
  s->Format(

      "{0:x16}: Compile Unit: length = {1:x8}, version = {2:x}, "
      "abbr_offset = {3:x8}, addr_size = {4:x2} (next CU at "
      "[{5:x16}])\n",
      GetOffset(), GetLength(), GetVersion(), (uint32_t)GetAbbrevOffset(),
      GetAddressByteSize(), GetNextUnitOffset());
}

void DWARFCompileUnit::BuildAddressRangeTable(
    DWARFDebugAranges *debug_aranges) {
  // This function is usually called if there in no .debug_aranges section in
  // order to produce a compile unit level set of address ranges that is
  // accurate.

  size_t num_debug_aranges = debug_aranges->GetNumRanges();

  // First get the compile unit DIE only and check contains ranges information.
  const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();

  const dw_offset_t cu_offset = GetOffset();
  if (die) {
    llvm::Expected<llvm::DWARFAddressRangesVector> ranges =
        die->GetAttributeAddressRanges(this, /*check_hi_lo_pc=*/true);
    if (ranges) {
      for (const llvm::DWARFAddressRange &range : *ranges)
        debug_aranges->AppendRange(cu_offset, range.LowPC, range.HighPC);
      if (!ranges->empty())
        return;
    } else {
      LLDB_LOG_ERROR(GetLog(DWARFLog::DebugInfo), ranges.takeError(),
                     "DIE({1:x}): {0}", cu_offset);
    }
  }

  if (debug_aranges->GetNumRanges() == num_debug_aranges) {
    // We got nothing from the debug info, try to build the arange table from
    // the debug map OSO aranges.
    SymbolContext sc;
    sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
    if (sc.comp_unit) {
      SymbolFileDWARFDebugMap *debug_map_sym_file =
          m_dwarf.GetDebugMapSymfile();
      if (debug_map_sym_file) {
        auto *cu_info =
            debug_map_sym_file->GetCompileUnitInfo(&GetSymbolFileDWARF());
        // If there are extra compile units the OSO entries aren't a reliable
        // source of information.
        if (cu_info->compile_units_sps.empty())
          debug_map_sym_file->AddOSOARanges(&m_dwarf, debug_aranges);
      }
    }
  }

  if (debug_aranges->GetNumRanges() == num_debug_aranges) {
    // We got nothing from the functions, maybe we have a line tables only
    // situation. Check the line tables and build the arange table from this.
    SymbolContext sc;
    sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
    if (sc.comp_unit) {
      if (LineTable *line_table = sc.comp_unit->GetLineTable()) {
        LineTable::FileAddressRanges file_ranges;
        const bool append = true;
        const size_t num_ranges =
            line_table->GetContiguousFileAddressRanges(file_ranges, append);
        for (uint32_t idx = 0; idx < num_ranges; ++idx) {
          const LineTable::FileAddressRanges::Entry &range =
              file_ranges.GetEntryRef(idx);
          debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(),
                                     range.GetRangeEnd());
        }
      }
    }
  }
}

DWARFCompileUnit &DWARFCompileUnit::GetNonSkeletonUnit() {
  return llvm::cast<DWARFCompileUnit>(DWARFUnit::GetNonSkeletonUnit());
}

DWARFDIE DWARFCompileUnit::LookupAddress(const dw_addr_t address) {
  if (DIE()) {
    const DWARFDebugAranges &func_aranges = GetFunctionAranges();

    // Re-check the aranges auto pointer contents in case it was created above
    if (!func_aranges.IsEmpty())
      return GetDIE(func_aranges.FindAddress(address));
  }
  return DWARFDIE();
}
