DWARFDebugAranges.cpp revision c7bbd271fba425130f82dfa028d68c92282e4fdc
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//----------------------------------------------------------------------
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Compare function DWARFDebugAranges::Range structures
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool RangeLessThan (const DWARFDebugAranges::Range& range1, const DWARFDebugAranges::Range& range2)
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return range1.lo_pc < range2.lo_pc;
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// CountArangeDescriptors
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass CountArangeDescriptors
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    CountArangeDescriptors (uint32_t& count_ref) : count(count_ref)
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      printf("constructor CountArangeDescriptors()\n");
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void operator() (const DWARFDebugArangeSet& set)
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        count += set.NumDescriptors();
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t& count;
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// AddArangeDescriptors
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass AddArangeDescriptors
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    AddArangeDescriptors (DWARFDebugAranges::RangeColl& ranges) : range_collection(ranges) {}
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void operator() (const DWARFDebugArangeSet& set)
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
7224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const DWARFDebugArangeSet::Descriptor* arange_desc_ptr;
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugAranges::Range range;
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        range.offset = set.GetCompileUnitDIEOffset();
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7654e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton        for (uint32_t i=0; (arange_desc_ptr = set.GetDescriptor(i)) != NULL; ++i)
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            range.lo_pc = arange_desc_ptr->address;
79144188bc458a35997d2f2e52206ab69747439073Greg Clayton            range.length = arange_desc_ptr->length;
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Insert each item in increasing address order so binary searching
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // can later be done!
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            DWARFDebugAranges::RangeColl::iterator insert_pos = lower_bound(range_collection.begin(), range_collection.end(), range, RangeLessThan);
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            range_collection.insert(insert_pos, range);
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFDebugAranges::RangeColl& range_collection;
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// PrintRange
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic void PrintRange(const DWARFDebugAranges::Range& range)
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Cast the address values in case the address type is compiled as 32 bit
96144188bc458a35997d2f2e52206ab69747439073Greg Clayton    printf("0x%8.8x: [0x%8.8llx - 0x%8.8llx)\n", range.offset, (long long)range.lo_pc, (long long)range.hi_pc());
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Extract
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::Extract(const DataExtractor &debug_aranges_data)
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (debug_aranges_data.ValidOffset(0))
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t offset = 0;
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        typedef std::vector<DWARFDebugArangeSet>    SetCollection;
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        typedef SetCollection::const_iterator       SetCollectionIter;
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        SetCollection sets;
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugArangeSet set;
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Range range;
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (set.Extract(debug_aranges_data, &offset))
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            sets.push_back(set);
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t count = 0;
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        for_each(sets.begin(), sets.end(), CountArangeDescriptors(count));
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (count > 0)
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_aranges.reserve(count);
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            AddArangeDescriptors range_adder(m_aranges);
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            for_each(sets.begin(), sets.end(), range_adder);
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //  puts("\n\nDWARFDebugAranges list is:\n");
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //  for_each(m_aranges.begin(), m_aranges.end(), PrintRange);
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Generate
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::Generate(SymbolFileDWARF* dwarf2Data)
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Clear();
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (debug_info)
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
145144188bc458a35997d2f2e52206ab69747439073Greg Clayton        const bool clear_dies_if_already_not_parsed = true;
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t cu_idx = 0;
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (cu)
152144188bc458a35997d2f2e52206ab69747439073Greg Clayton                cu->BuildAddressRangeTable(dwarf2Data, this, clear_dies_if_already_not_parsed);
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return !IsEmpty();
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
160144188bc458a35997d2f2e52206ab69747439073Greg ClaytonDWARFDebugAranges::Dump (Log *log) const
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
162144188bc458a35997d2f2e52206ab69747439073Greg Clayton    if (log == NULL)
163144188bc458a35997d2f2e52206ab69747439073Greg Clayton        return;
164144188bc458a35997d2f2e52206ab69747439073Greg Clayton    const uint32_t num_ranges = NumRanges();
165144188bc458a35997d2f2e52206ab69747439073Greg Clayton    for (uint32_t i = 0; i < num_ranges; ++i)
166144188bc458a35997d2f2e52206ab69747439073Greg Clayton    {
167144188bc458a35997d2f2e52206ab69747439073Greg Clayton        const Range &range = m_aranges[i];
168144188bc458a35997d2f2e52206ab69747439073Greg Clayton        log->Printf ("0x%8.8x: [0x%8.8llx - 0x%8.8llx)", range.offset, (uint64_t)range.lo_pc, (uint64_t)range.hi_pc());
169144188bc458a35997d2f2e52206ab69747439073Greg Clayton    }
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::Range::Dump(Stream *s) const
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
176144188bc458a35997d2f2e52206ab69747439073Greg Clayton    s->Printf("{0x%8.8x}: [0x%8.8llx - 0x%8.8llx)\n", offset, lo_pc, hi_pc());
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Dump
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
18274124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//void
18374124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//DWARFDebugAranges::Dump(SymbolFileDWARF* dwarf2Data, Stream *s)
18474124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//{
18574124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//    const DataExtractor &debug_aranges_data = dwarf2Data->get_debug_aranges_data();
18674124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//    if (debug_aranges_data.ValidOffset(0))
18774124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//    {
18874124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//        uint32_t offset = 0;
18974124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//
19074124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//        DWARFDebugArangeSet set;
19174124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//        while (set.Extract(debug_aranges_data, &offset))
19274124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//            set.Dump(s);
19374124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//    }
19474124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//    else
19574124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//        s->PutCString("< EMPTY >\n");
19674124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//}
19774124754d6d8ffda5bdaef8ac87e7faaeef3b358Greg Clayton//
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// AppendDebugRanges
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//void
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//DWARFDebugAranges::AppendDebugRanges(BinaryStreamBuf& debug_ranges, dw_addr_t cu_base_addr, uint32_t addr_size) const
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//{
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  if (!m_aranges.empty())
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  {
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      RangeCollIterator end = m_aranges.end();
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      RangeCollIterator pos;
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      RangeCollIterator lo_pos = end;
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      for (pos = m_aranges.begin(); pos != end; ++pos)
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      {
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          if (lo_pos == end)
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              lo_pos = pos;
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          RangeCollIterator next = pos + 1;
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          if (next != end)
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          {
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              // Check to see if we can combine two consecutive ranges?
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              if (pos->hi_pc == next->lo_pc)
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                  continue;   // We can combine them!
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          }
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          if (cu_base_addr == 0 || cu_base_addr == DW_INVALID_ADDRESS)
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          {
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              debug_ranges.AppendMax64(lo_pos->lo_pc, addr_size);
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              debug_ranges.AppendMax64(pos->hi_pc, addr_size);
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          }
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          else
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          {
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              assert(lo_pos->lo_pc >= cu_base_addr);
23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              assert(pos->hi_pc >= cu_base_addr);
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              debug_ranges.AppendMax64(lo_pos->lo_pc - cu_base_addr, addr_size);
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              debug_ranges.AppendMax64(pos->hi_pc - cu_base_addr, addr_size);
23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          }
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          // Reset the low part of the next address range
23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          lo_pos = end;
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      }
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  }
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  // Terminate the .debug_ranges with two zero addresses
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  debug_ranges.AppendMax64(0, addr_size);
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  debug_ranges.AppendMax64(0, addr_size);
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//}
245178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Claytonvoid
246178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg ClaytonDWARFDebugAranges::AppendRange (dw_offset_t offset, dw_addr_t low_pc, dw_addr_t high_pc)
247178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton{
248178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton    if (!m_aranges.empty())
249178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton    {
250144188bc458a35997d2f2e52206ab69747439073Greg Clayton        if (m_aranges.back().offset == offset && m_aranges.back().hi_pc() == low_pc)
251178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton        {
252144188bc458a35997d2f2e52206ab69747439073Greg Clayton            m_aranges.back().set_hi_pc(high_pc);
253178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton            return;
254178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton        }
255178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton    }
256178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton    m_aranges.push_back (DWARFDebugAranges::Range(low_pc, high_pc, offset));
257178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton}
258178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton
259178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Claytonvoid
260144188bc458a35997d2f2e52206ab69747439073Greg ClaytonDWARFDebugAranges::Sort (bool minimize, uint32_t n)
261178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton{
262388c057309b7692628450f988b6fa676230ec7cfJohnny Chen    Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
263388c057309b7692628450f988b6fa676230ec7cfJohnny Chen                       __PRETTY_FUNCTION__, this);
264388c057309b7692628450f988b6fa676230ec7cfJohnny Chen
265c7bbd271fba425130f82dfa028d68c92282e4fdcGreg Clayton    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES));
266144188bc458a35997d2f2e52206ab69747439073Greg Clayton    const size_t orig_arange_size = m_aranges.size();
267144188bc458a35997d2f2e52206ab69747439073Greg Clayton    if (log)
268144188bc458a35997d2f2e52206ab69747439073Greg Clayton    {
269144188bc458a35997d2f2e52206ab69747439073Greg Clayton        log->Printf ("DWARFDebugAranges::Sort(minimize = %u, n = %u) with %zu entries", minimize, n, orig_arange_size);
270c7bbd271fba425130f82dfa028d68c92282e4fdcGreg Clayton        Dump (log.get());
271144188bc458a35997d2f2e52206ab69747439073Greg Clayton    }
272144188bc458a35997d2f2e52206ab69747439073Greg Clayton
273144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // Size of one? If so, no sorting is needed
274144188bc458a35997d2f2e52206ab69747439073Greg Clayton    if (orig_arange_size <= 1)
275144188bc458a35997d2f2e52206ab69747439073Greg Clayton        return;
276178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton    // Sort our address range entries
277178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton    std::stable_sort (m_aranges.begin(), m_aranges.end(), RangeLessThan);
278178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton
279144188bc458a35997d2f2e52206ab69747439073Greg Clayton
280144188bc458a35997d2f2e52206ab69747439073Greg Clayton    if (!minimize)
281144188bc458a35997d2f2e52206ab69747439073Greg Clayton        return;
282388c057309b7692628450f988b6fa676230ec7cfJohnny Chen
283144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // Most address ranges are contiguous from function to function
284144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // so our new ranges will likely be smaller. We calculate the size
285144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // of the new ranges since although std::vector objects can be resized,
286144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // the will never reduce their allocated block size and free any excesss
287144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // memory, so we might as well start a brand new collection so it is as
288144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // small as possible.
289144188bc458a35997d2f2e52206ab69747439073Greg Clayton
290144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // First calculate the size of the new minimal arange vector
291144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // so we don't have to do a bunch of re-allocations as we
292144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // copy the new minimal stuff over to the new collection
293144188bc458a35997d2f2e52206ab69747439073Greg Clayton    size_t minimal_size = 1;
294144188bc458a35997d2f2e52206ab69747439073Greg Clayton    size_t i;
295144188bc458a35997d2f2e52206ab69747439073Greg Clayton    for (i=1; i<orig_arange_size; ++i)
296144188bc458a35997d2f2e52206ab69747439073Greg Clayton    {
297144188bc458a35997d2f2e52206ab69747439073Greg Clayton        if (!DWARFDebugAranges::Range::SortedOverlapCheck (m_aranges[i-1], m_aranges[i], n))
298144188bc458a35997d2f2e52206ab69747439073Greg Clayton            ++minimal_size;
299178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton    }
300388c057309b7692628450f988b6fa676230ec7cfJohnny Chen
301144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // If the sizes are the same, then no consecutive aranges can be
302144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // combined, we are done
303144188bc458a35997d2f2e52206ab69747439073Greg Clayton    if (minimal_size == orig_arange_size)
304388c057309b7692628450f988b6fa676230ec7cfJohnny Chen        return;
305388c057309b7692628450f988b6fa676230ec7cfJohnny Chen
306144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // Else, make a new RangeColl that _only_ contains what we need.
307144188bc458a35997d2f2e52206ab69747439073Greg Clayton    RangeColl minimal_aranges;
308144188bc458a35997d2f2e52206ab69747439073Greg Clayton    minimal_aranges.resize(minimal_size);
309144188bc458a35997d2f2e52206ab69747439073Greg Clayton    uint32_t j=0;
310144188bc458a35997d2f2e52206ab69747439073Greg Clayton    minimal_aranges[j] = m_aranges[0];
311144188bc458a35997d2f2e52206ab69747439073Greg Clayton    for (i=1; i<orig_arange_size; ++i)
312388c057309b7692628450f988b6fa676230ec7cfJohnny Chen    {
313144188bc458a35997d2f2e52206ab69747439073Greg Clayton        if (DWARFDebugAranges::Range::SortedOverlapCheck (minimal_aranges[j], m_aranges[i], n))
314144188bc458a35997d2f2e52206ab69747439073Greg Clayton        {
315144188bc458a35997d2f2e52206ab69747439073Greg Clayton            minimal_aranges[j].set_hi_pc (m_aranges[i].hi_pc());
316144188bc458a35997d2f2e52206ab69747439073Greg Clayton        }
317144188bc458a35997d2f2e52206ab69747439073Greg Clayton        else
318144188bc458a35997d2f2e52206ab69747439073Greg Clayton        {
319144188bc458a35997d2f2e52206ab69747439073Greg Clayton            // Only increment j if we aren't merging
320144188bc458a35997d2f2e52206ab69747439073Greg Clayton            minimal_aranges[++j] = m_aranges[i];
321303596715711a06d03369e7b5f468d6e4cf1eb53Johnny Chen        }
322388c057309b7692628450f988b6fa676230ec7cfJohnny Chen    }
323144188bc458a35997d2f2e52206ab69747439073Greg Clayton    assert (j+1 == minimal_size);
324144188bc458a35997d2f2e52206ab69747439073Greg Clayton
325144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // Now swap our new minimal aranges into place. The local
326144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // minimal_aranges will then contian the old big collection
327144188bc458a35997d2f2e52206ab69747439073Greg Clayton    // which will get freed.
328144188bc458a35997d2f2e52206ab69747439073Greg Clayton    minimal_aranges.swap(m_aranges);
329144188bc458a35997d2f2e52206ab69747439073Greg Clayton
330144188bc458a35997d2f2e52206ab69747439073Greg Clayton    if (log)
331144188bc458a35997d2f2e52206ab69747439073Greg Clayton    {
332144188bc458a35997d2f2e52206ab69747439073Greg Clayton        size_t delta = orig_arange_size - m_aranges.size();
333144188bc458a35997d2f2e52206ab69747439073Greg Clayton        log->Printf ("DWARFDebugAranges::Sort() %zu entries after minimizing (%zu entries combined for %zu bytes saved)",
334144188bc458a35997d2f2e52206ab69747439073Greg Clayton                     m_aranges.size(), delta, delta * sizeof(Range));
335c7bbd271fba425130f82dfa028d68c92282e4fdcGreg Clayton        Dump (log.get());
336144188bc458a35997d2f2e52206ab69747439073Greg Clayton    }
337178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton}
338178710cd4307f3d44dc76ebd70fc7daf7ebe17c5Greg Clayton
33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// FindAddress
34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerdw_offset_t
34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::FindAddress(dw_addr_t address) const
34424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
34524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if ( !m_aranges.empty() )
34624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
34724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugAranges::Range range(address);
34824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugAranges::RangeCollIterator begin = m_aranges.begin();
34924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugAranges::RangeCollIterator end = m_aranges.end();
35024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugAranges::RangeCollIterator pos = lower_bound(begin, end, range, RangeLessThan);
35124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
352144188bc458a35997d2f2e52206ab69747439073Greg Clayton        if ((pos != end) && (pos->lo_pc <= address && address < pos->hi_pc()))
35324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
35424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //  printf("FindAddress(1) found 0x%8.8x in compile unit: 0x%8.8x\n", address, pos->offset);
35524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return pos->offset;
35624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
35724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else if (pos != begin)
35824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
35924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            --pos;
360144188bc458a35997d2f2e52206ab69747439073Greg Clayton            if ((pos->lo_pc <= address) && (address < pos->hi_pc()))
36124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
36224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            //  printf("FindAddress(2) found 0x%8.8x in compile unit: 0x%8.8x\n", address, pos->offset);
36324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return (*pos).offset;
36424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
36524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
36624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
36724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return DW_INVALID_OFFSET;
36824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
36924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
37024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
37124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// AllRangesAreContiguous
37224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
37324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
37424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::AllRangesAreContiguous(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const
37524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
37624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_aranges.empty())
37724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
37824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
37924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFDebugAranges::RangeCollIterator begin = m_aranges.begin();
38024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFDebugAranges::RangeCollIterator end = m_aranges.end();
38124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFDebugAranges::RangeCollIterator pos;
38224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dw_addr_t next_addr = 0;
38324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
38424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (pos = begin; pos != end; ++pos)
38524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
38624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if ((pos != begin) && (pos->lo_pc != next_addr))
38724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
388144188bc458a35997d2f2e52206ab69747439073Greg Clayton        next_addr = pos->hi_pc();
38924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
39024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    lo_pc = m_aranges.front().lo_pc;    // We checked for empty at the start of function so front() will be valid
391144188bc458a35997d2f2e52206ab69747439073Greg Clayton    hi_pc = m_aranges.back().hi_pc();     // We checked for empty at the start of function so back() will be valid
39224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
39324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
39424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
39524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
39624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::GetMaxRange(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const
39724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
39824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_aranges.empty())
39924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
40024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
40124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    lo_pc = m_aranges.front().lo_pc;    // We checked for empty at the start of function so front() will be valid
402144188bc458a35997d2f2e52206ab69747439073Greg Clayton    hi_pc = m_aranges.back().hi_pc();   // We checked for empty at the start of function so back() will be valid
40324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
40424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
40524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
406