124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-- DWARFDebugAranges.cpp -----------------------------------*- C++ -*-===//
224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                     The LLVM Compiler Infrastructure
424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file is distributed under the University of Illinois Open Source
624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// License. See LICENSE.TXT for details.
724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===//
924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DWARFDebugAranges.h"
1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <assert.h>
13ec2d9787bed36e9eda6eac1996c7bed76c8d3da4Stephen Wilson#include <stdio.h>
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <algorithm>
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17144188bc458a35997d2f2e52206ab69747439073Greg Clayton#include "lldb/Core/Log.h"
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Stream.h"
19388c057309b7692628450f988b6fa676230ec7cfJohnny Chen#include "lldb/Core/Timer.h"
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
21144188bc458a35997d2f2e52206ab69747439073Greg Clayton#include "LogChannelDWARF.h"
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "SymbolFileDWARF.h"
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DWARFDebugInfo.h"
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DWARFCompileUnit.h"
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26c7bbd271fba425130f82dfa028d68c92282e4fdcGreg Claytonusing namespace lldb;
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Constructor
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::DWARFDebugAranges() :
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_aranges()
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// CountArangeDescriptors
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass CountArangeDescriptors
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    CountArangeDescriptors (uint32_t& count_ref) : count(count_ref)
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      printf("constructor CountArangeDescriptors()\n");
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void operator() (const DWARFDebugArangeSet& set)
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        count += set.NumDescriptors();
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t& count;
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Extract
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::Extract(const DataExtractor &debug_aranges_data)
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (debug_aranges_data.ValidOffset(0))
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
6336da2aa6dc5ad9994b638ed09eb81c44cc05540bGreg Clayton        lldb::offset_t offset = 0;
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugArangeSet set;
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Range range;
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (set.Extract(debug_aranges_data, &offset))
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
69257663e753af15633e48c7b00eb7b5880168090bGreg Clayton            const uint32_t num_descriptors = set.NumDescriptors();
70257663e753af15633e48c7b00eb7b5880168090bGreg Clayton            if (num_descriptors > 0)
71257663e753af15633e48c7b00eb7b5880168090bGreg Clayton            {
72257663e753af15633e48c7b00eb7b5880168090bGreg Clayton                const dw_offset_t cu_offset = set.GetCompileUnitDIEOffset();
73257663e753af15633e48c7b00eb7b5880168090bGreg Clayton
74257663e753af15633e48c7b00eb7b5880168090bGreg Clayton                for (uint32_t i=0; i<num_descriptors; ++i)
75257663e753af15633e48c7b00eb7b5880168090bGreg Clayton                {
76257663e753af15633e48c7b00eb7b5880168090bGreg Clayton                    const DWARFDebugArangeSet::Descriptor &descriptor = set.GetDescriptorRef(i);
77257663e753af15633e48c7b00eb7b5880168090bGreg Clayton                    m_aranges.Append(RangeToDIE::Entry (descriptor.address, descriptor.length, cu_offset));
78257663e753af15633e48c7b00eb7b5880168090bGreg Clayton                }
79257663e753af15633e48c7b00eb7b5880168090bGreg Clayton            }
80257663e753af15633e48c7b00eb7b5880168090bGreg Clayton            set.Clear();
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Generate
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::Generate(SymbolFileDWARF* dwarf2Data)
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Clear();
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (debug_info)
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
96144188bc458a35997d2f2e52206ab69747439073Greg Clayton        const bool clear_dies_if_already_not_parsed = true;
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t cu_idx = 0;
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (cu)
103144188bc458a35997d2f2e52206ab69747439073Greg Clayton                cu->BuildAddressRangeTable(dwarf2Data, this, clear_dies_if_already_not_parsed);
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return !IsEmpty();
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
111144188bc458a35997d2f2e52206ab69747439073Greg ClaytonDWARFDebugAranges::Dump (Log *log) const
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
113144188bc458a35997d2f2e52206ab69747439073Greg Clayton    if (log == NULL)
114144188bc458a35997d2f2e52206ab69747439073Greg Clayton        return;
115257663e753af15633e48c7b00eb7b5880168090bGreg Clayton
116bc36a861b8e0b2f2dde34f27c9fa9629a357d598Greg Clayton    const size_t num_entries = m_aranges.GetSize();
117257663e753af15633e48c7b00eb7b5880168090bGreg Clayton    for (size_t i=0; i<num_entries; ++i)
118144188bc458a35997d2f2e52206ab69747439073Greg Clayton    {
119257663e753af15633e48c7b00eb7b5880168090bGreg Clayton        const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i);
1206f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham        if (entry)
1215f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf ("0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")",
1226f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham                         entry->data,
1236f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham                         entry->GetRangeBase(),
1246f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham                         entry->GetRangeEnd());
125144188bc458a35997d2f2e52206ab69747439073Greg Clayton    }
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
128178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Claytonvoid
129178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg ClaytonDWARFDebugAranges::AppendRange (dw_offset_t offset, dw_addr_t low_pc, dw_addr_t high_pc)
130178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton{
131257663e753af15633e48c7b00eb7b5880168090bGreg Clayton    if (high_pc > low_pc)
132257663e753af15633e48c7b00eb7b5880168090bGreg Clayton        m_aranges.Append(RangeToDIE::Entry (low_pc, high_pc - low_pc, offset));
133178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton}
134178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton
135178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Claytonvoid
136257663e753af15633e48c7b00eb7b5880168090bGreg ClaytonDWARFDebugAranges::Sort (bool minimize)
137178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton{
138388c057309b7692628450f988b6fa676230ec7cfJohnny Chen    Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
139388c057309b7692628450f988b6fa676230ec7cfJohnny Chen                       __PRETTY_FUNCTION__, this);
140388c057309b7692628450f988b6fa676230ec7cfJohnny Chen
141952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
142257663e753af15633e48c7b00eb7b5880168090bGreg Clayton    size_t orig_arange_size = 0;
143144188bc458a35997d2f2e52206ab69747439073Greg Clayton    if (log)
144144188bc458a35997d2f2e52206ab69747439073Greg Clayton    {
145bc36a861b8e0b2f2dde34f27c9fa9629a357d598Greg Clayton        orig_arange_size = m_aranges.GetSize();
1465f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        log->Printf ("DWARFDebugAranges::Sort(minimize = %u) with %" PRIu64 " entries", minimize, (uint64_t)orig_arange_size);
147178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton    }
148388c057309b7692628450f988b6fa676230ec7cfJohnny Chen
149257663e753af15633e48c7b00eb7b5880168090bGreg Clayton    m_aranges.Sort();
150257663e753af15633e48c7b00eb7b5880168090bGreg Clayton    m_aranges.CombineConsecutiveEntriesWithEqualData();
151388c057309b7692628450f988b6fa676230ec7cfJohnny Chen
152257663e753af15633e48c7b00eb7b5880168090bGreg Clayton    if (log)
153388c057309b7692628450f988b6fa676230ec7cfJohnny Chen    {
154257663e753af15633e48c7b00eb7b5880168090bGreg Clayton        if (minimize)
155144188bc458a35997d2f2e52206ab69747439073Greg Clayton        {
156bc36a861b8e0b2f2dde34f27c9fa9629a357d598Greg Clayton            const size_t new_arange_size = m_aranges.GetSize();
157257663e753af15633e48c7b00eb7b5880168090bGreg Clayton            const size_t delta = orig_arange_size - new_arange_size;
1585f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf ("DWARFDebugAranges::Sort() %" PRIu64 " entries after minimizing (%" PRIu64 " entries combined for %" PRIu64 " bytes saved)",
159851e30ec6a1b1d2c154bb7d69ed0d05b5fd14705Greg Clayton                         (uint64_t)new_arange_size,
160851e30ec6a1b1d2c154bb7d69ed0d05b5fd14705Greg Clayton                         (uint64_t)delta,
161851e30ec6a1b1d2c154bb7d69ed0d05b5fd14705Greg Clayton                         (uint64_t)delta * sizeof(Range));
162144188bc458a35997d2f2e52206ab69747439073Greg Clayton        }
163952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton        Dump (log);
164144188bc458a35997d2f2e52206ab69747439073Greg Clayton    }
165178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton}
166178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// FindAddress
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerdw_offset_t
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::FindAddress(dw_addr_t address) const
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
173257663e753af15633e48c7b00eb7b5880168090bGreg Clayton    const RangeToDIE::Entry *entry = m_aranges.FindEntryThatContains(address);
174257663e753af15633e48c7b00eb7b5880168090bGreg Clayton    if (entry)
175257663e753af15633e48c7b00eb7b5880168090bGreg Clayton        return entry->data;
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return DW_INVALID_OFFSET;
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
178