//===-- DWARFDebugRanges.cpp ------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "DWARFDebugRanges.h"
#include "SymbolFileDWARF.h"
#include "lldb/Core/Stream.h"
#include <assert.h>

using namespace lldb_private;
using namespace std;

DWARFDebugRanges::DWARFDebugRanges() :
    m_range_map()
{
}

DWARFDebugRanges::~DWARFDebugRanges()
{
}

void
DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data)
{
    RangeList range_list;
    lldb::offset_t offset = 0;
    dw_offset_t debug_ranges_offset = offset;
    while (Extract(dwarf2Data, &offset, range_list))
    {
        range_list.Sort();
        m_range_map[debug_ranges_offset] = range_list;
        debug_ranges_offset = offset;
    }
}

//void
//DWARFDebugRanges::RangeList::AddOffset(dw_addr_t offset)
//{
//    if (!ranges.empty())
//    {
//        Range::iterator pos = ranges.begin();
//        Range::iterator end_pos = ranges.end();
//        for (pos = ranges.begin(); pos != end_pos; ++pos)
//        {
//            // assert for unsigned overflows
//            assert (~pos->begin_offset >= offset);
//            assert (~pos->end_offset >= offset);
//            pos->begin_offset += offset;
//            pos->end_offset += offset;
//        }
//    }
//}
//
//void
//DWARFDebugRanges::RangeList::SubtractOffset(dw_addr_t offset)
//{
//    if (!ranges.empty())
//    {
//        Range::iterator pos = ranges.begin();
//        Range::iterator end_pos = ranges.end();
//        for (pos = ranges.begin(); pos != end_pos; ++pos)
//        {
//            assert (pos->begin_offset >= offset);
//            assert (pos->end_offset >= offset);
//            pos->begin_offset -= offset;
//            pos->end_offset -= offset;
//        }
//    }
//}
//
//
//const DWARFDebugRanges::Range*
//DWARFDebugRanges::RangeList::RangeAtIndex(size_t i) const
//{
//    if (i < ranges.size())
//        return &ranges[i];
//    return NULL;
//}

bool
DWARFDebugRanges::Extract(SymbolFileDWARF* dwarf2Data, lldb::offset_t *offset_ptr, RangeList &range_list)
{
    range_list.Clear();

    lldb::offset_t range_offset = *offset_ptr;
    const DWARFDataExtractor& debug_ranges_data = dwarf2Data->get_debug_ranges_data();
    uint32_t addr_size = debug_ranges_data.GetAddressByteSize();

    while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size))
    {
        dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
        dw_addr_t end   = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
        if (!begin && !end)
        {
            // End of range list
            break;
        }
        // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
        // of ones
        switch (addr_size)
        {
        case 2:
            if (begin == 0xFFFFull)
                begin = LLDB_INVALID_ADDRESS;
            break;

        case 4:
            if (begin == 0xFFFFFFFFull)
                begin = LLDB_INVALID_ADDRESS;
            break;

        case 8:
            break;

        default:
            assert(!"DWARFDebugRanges::RangeList::Extract() unsupported address size.");
            break;
        }

        // Filter out empty ranges
        if (begin < end)
            range_list.Append(Range(begin, end - begin));
    }

    // Make sure we consumed at least something
    return range_offset != *offset_ptr;
}


void
DWARFDebugRanges::Dump(Stream &s, const DWARFDataExtractor& debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr)
{
    uint32_t addr_size = s.GetAddressByteSize();
    bool verbose = s.GetVerbose();

    dw_addr_t base_addr = cu_base_addr;
    while (debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size))
    {
        dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
        dw_addr_t end   = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
        // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits
        // of ones
        if (begin == 0xFFFFFFFFull && addr_size == 4)
            begin = LLDB_INVALID_ADDRESS;

        s.Indent();
        if (verbose)
        {
            s.AddressRange(begin, end, sizeof (dw_addr_t), " offsets = ");
        }


        if (begin == 0 && end == 0)
        {
            s.PutCString(" End");
            break;
        }
        else if (begin == LLDB_INVALID_ADDRESS)
        {
            // A base address selection entry
            base_addr = end;
            s.Address(base_addr, sizeof (dw_addr_t), " Base address = ");
        }
        else
        {
            // Convert from offset to an address
            dw_addr_t begin_addr = begin + base_addr;
            dw_addr_t end_addr = end + base_addr;

            s.AddressRange(begin_addr, end_addr, sizeof (dw_addr_t), verbose ? " ==> addrs = " : NULL);
        }
    }
}

bool
DWARFDebugRanges::FindRanges(dw_offset_t debug_ranges_offset, RangeList& range_list) const
{
    range_map_const_iterator pos = m_range_map.find(debug_ranges_offset);
    if (pos != m_range_map.end())
    {
        range_list = pos->second;
        return true;
    }
    return false;
}



