180814287SRaphael Isemann //===-- DWARFCompileUnit.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 "DWARFCompileUnit.h"
1032439646SPavel Labath #include "DWARFDebugAranges.h"
1132439646SPavel Labath #include "SymbolFileDWARFDebugMap.h"
1230fdc8d8SChris Lattner 
1332439646SPavel Labath #include "lldb/Symbol/CompileUnit.h"
1432439646SPavel Labath #include "lldb/Symbol/LineTable.h"
15b13f0338SPavel Labath #include "lldb/Utility/Stream.h"
1630fdc8d8SChris Lattner 
1721f2a491SGreg Clayton using namespace lldb;
1830fdc8d8SChris Lattner using namespace lldb_private;
1930fdc8d8SChris Lattner 
Dump(Stream * s) const20b9c1b51eSKate Stone void DWARFCompileUnit::Dump(Stream *s) const {
21b9c1b51eSKate Stone   s->Printf("0x%8.8x: Compile Unit: length = 0x%8.8x, version = 0x%4.4x, "
22b9c1b51eSKate Stone             "abbr_offset = 0x%8.8x, addr_size = 0x%2.2x (next CU at "
23b9c1b51eSKate Stone             "{0x%8.8x})\n",
2403c4bf73SPavel Labath             GetOffset(), GetLength(), GetVersion(), GetAbbrevOffset(),
2503c4bf73SPavel Labath             GetAddressByteSize(), GetNextUnitOffset());
26f56c30d1SGreg Clayton }
2732439646SPavel Labath 
BuildAddressRangeTable(DWARFDebugAranges * debug_aranges)2832439646SPavel Labath void DWARFCompileUnit::BuildAddressRangeTable(
2932439646SPavel Labath     DWARFDebugAranges *debug_aranges) {
3032439646SPavel Labath   // This function is usually called if there in no .debug_aranges section in
3132439646SPavel Labath   // order to produce a compile unit level set of address ranges that is
3232439646SPavel Labath   // accurate.
3332439646SPavel Labath 
3432439646SPavel Labath   size_t num_debug_aranges = debug_aranges->GetNumRanges();
3532439646SPavel Labath 
367cfa74fcSPavel Labath   // First get the compile unit DIE only and check contains ranges information.
3732439646SPavel Labath   const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
3832439646SPavel Labath 
3932439646SPavel Labath   const dw_offset_t cu_offset = GetOffset();
4032439646SPavel Labath   if (die) {
4132439646SPavel Labath     DWARFRangeList ranges;
4232439646SPavel Labath     const size_t num_ranges =
437cfa74fcSPavel Labath         die->GetAttributeAddressRanges(this, ranges, /*check_hi_lo_pc=*/true);
4432439646SPavel Labath     if (num_ranges > 0) {
4532439646SPavel Labath       for (size_t i = 0; i < num_ranges; ++i) {
4632439646SPavel Labath         const DWARFRangeList::Entry &range = ranges.GetEntryRef(i);
4732439646SPavel Labath         debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
4832439646SPavel Labath                                    range.GetRangeEnd());
4932439646SPavel Labath       }
5032439646SPavel Labath 
517cfa74fcSPavel Labath       return;
5232439646SPavel Labath     }
5332439646SPavel Labath   }
5432439646SPavel Labath 
5532439646SPavel Labath   if (debug_aranges->GetNumRanges() == num_debug_aranges) {
567cfa74fcSPavel Labath     // We got nothing from the debug info, maybe we have a line tables only
5732439646SPavel Labath     // situation. Check the line tables and build the arange table from this.
5832439646SPavel Labath     SymbolContext sc;
596a2eb367SPavel Labath     sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
6032439646SPavel Labath     if (sc.comp_unit) {
6132439646SPavel Labath       SymbolFileDWARFDebugMap *debug_map_sym_file =
626a2eb367SPavel Labath           m_dwarf.GetDebugMapSymfile();
6332439646SPavel Labath       if (debug_map_sym_file == nullptr) {
6432439646SPavel Labath         if (LineTable *line_table = sc.comp_unit->GetLineTable()) {
6532439646SPavel Labath           LineTable::FileAddressRanges file_ranges;
6632439646SPavel Labath           const bool append = true;
6732439646SPavel Labath           const size_t num_ranges =
6832439646SPavel Labath               line_table->GetContiguousFileAddressRanges(file_ranges, append);
6932439646SPavel Labath           for (uint32_t idx = 0; idx < num_ranges; ++idx) {
7032439646SPavel Labath             const LineTable::FileAddressRanges::Entry &range =
7132439646SPavel Labath                 file_ranges.GetEntryRef(idx);
7232439646SPavel Labath             debug_aranges->AppendRange(cu_offset, range.GetRangeBase(),
7332439646SPavel Labath                                        range.GetRangeEnd());
7432439646SPavel Labath           }
7532439646SPavel Labath         }
7632439646SPavel Labath       } else
776a2eb367SPavel Labath         debug_map_sym_file->AddOSOARanges(&m_dwarf, debug_aranges);
7832439646SPavel Labath     }
7932439646SPavel Labath   }
8032439646SPavel Labath 
8132439646SPavel Labath   if (debug_aranges->GetNumRanges() == num_debug_aranges) {
8232439646SPavel Labath     // We got nothing from the functions, maybe we have a line tables only
8332439646SPavel Labath     // situation. Check the line tables and build the arange table from this.
8432439646SPavel Labath     SymbolContext sc;
856a2eb367SPavel Labath     sc.comp_unit = m_dwarf.GetCompUnitForDWARFCompUnit(*this);
8632439646SPavel Labath     if (sc.comp_unit) {
8732439646SPavel Labath       if (LineTable *line_table = sc.comp_unit->GetLineTable()) {
8832439646SPavel Labath         LineTable::FileAddressRanges file_ranges;
8932439646SPavel Labath         const bool append = true;
9032439646SPavel Labath         const size_t num_ranges =
9132439646SPavel Labath             line_table->GetContiguousFileAddressRanges(file_ranges, append);
9232439646SPavel Labath         for (uint32_t idx = 0; idx < num_ranges; ++idx) {
9332439646SPavel Labath           const LineTable::FileAddressRanges::Entry &range =
9432439646SPavel Labath               file_ranges.GetEntryRef(idx);
9532439646SPavel Labath           debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(),
9632439646SPavel Labath                                      range.GetRangeEnd());
9732439646SPavel Labath         }
9832439646SPavel Labath       }
9932439646SPavel Labath     }
10032439646SPavel Labath   }
10132439646SPavel Labath }
102*0e5248beSJan Kratochvil 
GetNonSkeletonUnit()103*0e5248beSJan Kratochvil DWARFCompileUnit &DWARFCompileUnit::GetNonSkeletonUnit() {
104*0e5248beSJan Kratochvil   return llvm::cast<DWARFCompileUnit>(DWARFUnit::GetNonSkeletonUnit());
105*0e5248beSJan Kratochvil }
106*0e5248beSJan Kratochvil 
LookupAddress(const dw_addr_t address)107*0e5248beSJan Kratochvil DWARFDIE DWARFCompileUnit::LookupAddress(const dw_addr_t address) {
108*0e5248beSJan Kratochvil   if (DIE()) {
109*0e5248beSJan Kratochvil     const DWARFDebugAranges &func_aranges = GetFunctionAranges();
110*0e5248beSJan Kratochvil 
111*0e5248beSJan Kratochvil     // Re-check the aranges auto pointer contents in case it was created above
112*0e5248beSJan Kratochvil     if (!func_aranges.IsEmpty())
113*0e5248beSJan Kratochvil       return GetDIE(func_aranges.FindAddress(address));
114*0e5248beSJan Kratochvil   }
115*0e5248beSJan Kratochvil   return DWARFDIE();
116*0e5248beSJan Kratochvil }
117