DWARFDebugAranges.cpp revision 54e7afa84d945f9137f9372ecde432f9e1a702fc
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>
1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <algorithm>
1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "lldb/Core/Stream.h"
1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "SymbolFileDWARF.h"
1924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DWARFDebugInfo.h"
2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "DWARFCompileUnit.h"
2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerusing namespace lldb_private;
2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Constructor
2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::DWARFDebugAranges() :
2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_aranges()
2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Compare function DWARFDebugAranges::Range structures
3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic bool RangeLessThan (const DWARFDebugAranges::Range& range1, const DWARFDebugAranges::Range& range2)
3724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
3824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  printf("RangeLessThan -- 0x%8.8x < 0x%8.8x ? %d\n", range1.lo_pc, range1.lo_pc, range1.lo_pc < range2.lo_pc);
3924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return range1.lo_pc < range2.lo_pc;
4024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
4124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
4224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// CountArangeDescriptors
4424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass CountArangeDescriptors
4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
4724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    CountArangeDescriptors (uint32_t& count_ref) : count(count_ref)
4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      printf("constructor CountArangeDescriptors()\n");
5124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
5224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void operator() (const DWARFDebugArangeSet& set)
5324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
5424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        count += set.NumDescriptors();
5524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
5624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    uint32_t& count;
5724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
5824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
5924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
6024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// AddArangeDescriptors
6124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
6224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass AddArangeDescriptors
6324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
6424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
6524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    AddArangeDescriptors (DWARFDebugAranges::RangeColl& ranges) : range_collection(ranges) {}
6624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    void operator() (const DWARFDebugArangeSet& set)
6724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
6824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const DWARFDebugArangeSet::Descriptor* arange_desc_ptr;
6924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugAranges::Range range;
7024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        range.offset = set.GetCompileUnitDIEOffset();
7124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7254e7afa84d945f9137f9372ecde432f9e1a702fcGreg Clayton        for (uint32_t i=0; (arange_desc_ptr = set.GetDescriptor(i)) != NULL; ++i)
7324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
7424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            range.lo_pc = arange_desc_ptr->address;
7524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            range.hi_pc = arange_desc_ptr->address + arange_desc_ptr->length;
7624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
7724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // Insert each item in increasing address order so binary searching
7824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            // can later be done!
7924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            DWARFDebugAranges::RangeColl::iterator insert_pos = lower_bound(range_collection.begin(), range_collection.end(), range, RangeLessThan);
8024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            range_collection.insert(insert_pos, range);
8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
8224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFDebugAranges::RangeColl& range_collection;
8424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
8524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
8624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
8724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// PrintRange
8824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
8924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerstatic void PrintRange(const DWARFDebugAranges::Range& range)
9024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
9124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Cast the address values in case the address type is compiled as 32 bit
9224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    printf("0x%8.8x: [0x%8.8llx - 0x%8.8llx)\n", range.offset, (uint64_t)range.lo_pc, (uint64_t)range.hi_pc);
9324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
9424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
9524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Extract
9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::Extract(const DataExtractor &debug_aranges_data)
10024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
10124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (debug_aranges_data.ValidOffset(0))
10224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
10324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t offset = 0;
10424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        typedef std::vector<DWARFDebugArangeSet>    SetCollection;
10624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        typedef SetCollection::const_iterator       SetCollectionIter;
10724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        SetCollection sets;
10824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
10924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugArangeSet set;
11024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        Range range;
11124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (set.Extract(debug_aranges_data, &offset))
11224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            sets.push_back(set);
11324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t count = 0;
11524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        for_each(sets.begin(), sets.end(), CountArangeDescriptors(count));
11724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
11824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if (count > 0)
11924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
12024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            m_aranges.reserve(count);
12124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            AddArangeDescriptors range_adder(m_aranges);
12224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            for_each(sets.begin(), sets.end(), range_adder);
12324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
12424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
12524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //  puts("\n\nDWARFDebugAranges list is:\n");
12624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    //  for_each(m_aranges.begin(), m_aranges.end(), PrintRange);
12724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
12824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return false;
12924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
13024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
13124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
13224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Generate
13324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
13424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
13524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::Generate(SymbolFileDWARF* dwarf2Data)
13624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
13724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    Clear();
13824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFDebugInfo* debug_info = dwarf2Data->DebugInfo();
13924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (debug_info)
14024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
14124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t cu_idx = 0;
14224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        const uint32_t num_compile_units = dwarf2Data->GetNumCompileUnits();
14324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
14424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
14524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
14624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if (cu)
14724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                cu->DIE()->BuildAddressRangeTable(dwarf2Data, cu, this);
14824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
14924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
15024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return !IsEmpty();
15124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
15224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
15424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
15524943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::Print() const
15624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
15724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    puts("\n\nDWARFDebugAranges address range list is:\n");
15824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for_each(m_aranges.begin(), m_aranges.end(), PrintRange);
15924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
16024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
16324943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::Range::Dump(Stream *s) const
16424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
16524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    s->Printf("{0x%8.8x}: [0x%8.8llx - 0x%8.8llx)\n", offset, lo_pc, hi_pc);
16624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
16724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
16824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
16924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Dump
17024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
17124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
17224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::Dump(SymbolFileDWARF* dwarf2Data, Stream *s)
17324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
17424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const DataExtractor &debug_aranges_data = dwarf2Data->get_debug_aranges_data();
17524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (debug_aranges_data.ValidOffset(0))
17624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
17724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        uint32_t offset = 0;
17824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
17924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugArangeSet set;
18024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        while (set.Extract(debug_aranges_data, &offset))
18124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            set.Dump(s);
18224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
18324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    else
18424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        s->PutCString("< EMPTY >\n");
18524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
18624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
18824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
18924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// AppendDebugRanges
19024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
19124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//void
19224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//DWARFDebugAranges::AppendDebugRanges(BinaryStreamBuf& debug_ranges, dw_addr_t cu_base_addr, uint32_t addr_size) const
19324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//{
19424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  if (!m_aranges.empty())
19524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  {
19624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      RangeCollIterator end = m_aranges.end();
19724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      RangeCollIterator pos;
19824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      RangeCollIterator lo_pos = end;
19924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      for (pos = m_aranges.begin(); pos != end; ++pos)
20024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      {
20124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          if (lo_pos == end)
20224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              lo_pos = pos;
20324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
20424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          RangeCollIterator next = pos + 1;
20524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          if (next != end)
20624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          {
20724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              // Check to see if we can combine two consecutive ranges?
20824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              if (pos->hi_pc == next->lo_pc)
20924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//                  continue;   // We can combine them!
21024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          }
21124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
21224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          if (cu_base_addr == 0 || cu_base_addr == DW_INVALID_ADDRESS)
21324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          {
21424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              debug_ranges.AppendMax64(lo_pos->lo_pc, addr_size);
21524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              debug_ranges.AppendMax64(pos->hi_pc, addr_size);
21624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          }
21724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          else
21824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          {
21924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              assert(lo_pos->lo_pc >= cu_base_addr);
22024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              assert(pos->hi_pc >= cu_base_addr);
22124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              debug_ranges.AppendMax64(lo_pos->lo_pc - cu_base_addr, addr_size);
22224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//              debug_ranges.AppendMax64(pos->hi_pc - cu_base_addr, addr_size);
22324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          }
22424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
22524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          // Reset the low part of the next address range
22624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//          lo_pos = end;
22724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//      }
22824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  }
22924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  // Terminate the .debug_ranges with two zero addresses
23024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  debug_ranges.AppendMax64(0, addr_size);
23124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//  debug_ranges.AppendMax64(0, addr_size);
23224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
23324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//}
23424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//
23524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
23624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// ArangeSetContainsAddress
23724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
23824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerclass ArangeSetContainsAddress
23924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
24024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerpublic:
24124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    ArangeSetContainsAddress (dw_addr_t the_address) : address(the_address), offset(DW_INVALID_OFFSET) {}
24224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    bool operator() (const DWARFDebugArangeSet& set)
24324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
24424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        offset = set.FindAddress(address);
24524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return (offset != DW_INVALID_OFFSET);
24624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
24724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    const dw_addr_t address;
24824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dw_offset_t offset;
24924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner};
25024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
25224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
25324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// InsertRange
25424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
25524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
25624943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::InsertRange(dw_offset_t offset, dw_addr_t low_pc, dw_addr_t high_pc)
25724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
25824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Insert each item in increasing address order so binary searching
25924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // can later be done!
26024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFDebugAranges::Range range(low_pc, high_pc, offset);
26124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    InsertRange(range);
26224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
26324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
26424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
26524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// InsertRange
26624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
26724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnervoid
26824943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::InsertRange(const DWARFDebugAranges::Range& range)
26924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
27024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // Insert each item in increasing address order so binary searching
27124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    // can later be done!
27224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    RangeColl::iterator insert_pos = lower_bound(m_aranges.begin(), m_aranges.end(), range, RangeLessThan);
27324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    m_aranges.insert(insert_pos, range);
27424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
27524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
27724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
27824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// FindAddress
27924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
28024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerdw_offset_t
28124943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::FindAddress(dw_addr_t address) const
28224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
28324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if ( !m_aranges.empty() )
28424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
28524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugAranges::Range range(address);
28624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugAranges::RangeCollIterator begin = m_aranges.begin();
28724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugAranges::RangeCollIterator end = m_aranges.end();
28824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        DWARFDebugAranges::RangeCollIterator pos = lower_bound(begin, end, range, RangeLessThan);
28924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
29024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if ((pos != end) && (pos->lo_pc <= address && address < pos->hi_pc))
29124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
29224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        //  printf("FindAddress(1) found 0x%8.8x in compile unit: 0x%8.8x\n", address, pos->offset);
29324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return pos->offset;
29424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
29524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        else if (pos != begin)
29624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        {
29724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            --pos;
29824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            if ((pos->lo_pc <= address) && (address < pos->hi_pc))
29924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            {
30024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            //  printf("FindAddress(2) found 0x%8.8x in compile unit: 0x%8.8x\n", address, pos->offset);
30124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner                return (*pos).offset;
30224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            }
30324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        }
30424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
30524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return DW_INVALID_OFFSET;
30624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
30724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
30824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
30924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// AllRangesAreContiguous
31024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//----------------------------------------------------------------------
31124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
31224943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::AllRangesAreContiguous(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const
31324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
31424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_aranges.empty())
31524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
31624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
31724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFDebugAranges::RangeCollIterator begin = m_aranges.begin();
31824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFDebugAranges::RangeCollIterator end = m_aranges.end();
31924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    DWARFDebugAranges::RangeCollIterator pos;
32024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    dw_addr_t next_addr = 0;
32124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
32224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    for (pos = begin; pos != end; ++pos)
32324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    {
32424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        if ((pos != begin) && (pos->lo_pc != next_addr))
32524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner            return false;
32624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        next_addr = pos->hi_pc;
32724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    }
32824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    lo_pc = m_aranges.front().lo_pc;    // We checked for empty at the start of function so front() will be valid
32924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    hi_pc = m_aranges.back().hi_pc;     // We checked for empty at the start of function so back() will be valid
33024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
33124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
33224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerbool
33424943d2ee8bfaa7cf5893e4709143924157a5c1eChris LattnerDWARFDebugAranges::GetMaxRange(dw_addr_t& lo_pc, dw_addr_t& hi_pc) const
33524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{
33624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    if (m_aranges.empty())
33724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner        return false;
33824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
33924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    lo_pc = m_aranges.front().lo_pc;    // We checked for empty at the start of function so front() will be valid
34024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    hi_pc = m_aranges.back().hi_pc;     // We checked for empty at the start of function so back() will be valid
34124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner    return true;
34224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner}
34324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner
344