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

#include "lldb/Symbol/UnwindTable.h"

#include <stdio.h>

#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/FuncUnwinders.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/ArmUnwindInfo.h"
#include "lldb/Symbol/CompactUnwindInfo.h"

// There is one UnwindTable object per ObjectFile.
// It contains a list of Unwind objects -- one per function, populated lazily -- for the ObjectFile.
// Each Unwind object has multiple UnwindPlans for different scenarios.

using namespace lldb;
using namespace lldb_private;

UnwindTable::UnwindTable (ObjectFile& objfile) : 
    m_object_file (objfile), 
    m_unwinds (),
    m_initialized (false),
    m_mutex (),
    m_eh_frame_up (),
    m_compact_unwind_up (),
    m_arm_unwind_up ()
{
}

// We can't do some of this initialization when the ObjectFile is running its ctor; delay doing it
// until needed for something.

void
UnwindTable::Initialize ()
{
    if (m_initialized)
        return;

    Mutex::Locker locker(m_mutex);

    if (m_initialized) // check again once we've acquired the lock
        return;

    SectionList* sl = m_object_file.GetSectionList ();
    if (sl)
    {
        SectionSP sect = sl->FindSectionByType (eSectionTypeEHFrame, true);
        if (sect.get())
        {
            m_eh_frame_up.reset(new DWARFCallFrameInfo(m_object_file, sect, eRegisterKindEHFrame, true));
        }
        sect = sl->FindSectionByType (eSectionTypeCompactUnwind, true);
        if (sect.get())
        {
            m_compact_unwind_up.reset(new CompactUnwindInfo(m_object_file, sect));
        }
        sect = sl->FindSectionByType (eSectionTypeARMexidx, true);
        if (sect.get())
        {
            SectionSP sect_extab = sl->FindSectionByType (eSectionTypeARMextab, true);
            if (sect_extab.get())
            {
                m_arm_unwind_up.reset(new ArmUnwindInfo(m_object_file, sect, sect_extab));
            }
        }
    }
    
    m_initialized = true;
}

UnwindTable::~UnwindTable ()
{
}

FuncUnwindersSP
UnwindTable::GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc)
{
    FuncUnwindersSP no_unwind_found;

    Initialize();

    Mutex::Locker locker(m_mutex);

    // There is an UnwindTable per object file, so we can safely use file handles
    addr_t file_addr = addr.GetFileAddress();
    iterator end = m_unwinds.end ();
    iterator insert_pos = end;
    if (!m_unwinds.empty())
    {
        insert_pos = m_unwinds.lower_bound (file_addr);
        iterator pos = insert_pos;
        if ((pos == m_unwinds.end ()) || (pos != m_unwinds.begin() && pos->second->GetFunctionStartAddress() != addr))
            --pos;

        if (pos->second->ContainsAddress (addr))
            return pos->second;
    }

    AddressRange range;
    if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, false, range) || !range.GetBaseAddress().IsValid())
    {
        // Does the eh_frame unwind info has a function bounds for this addr?
        if (m_eh_frame_up == nullptr || !m_eh_frame_up->GetAddressRange (addr, range))
        {
            return no_unwind_found;
        }
    }

    FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, range));
    m_unwinds.insert (insert_pos, std::make_pair(range.GetBaseAddress().GetFileAddress(), func_unwinder_sp));
//    StreamFile s(stdout, false);
//    Dump (s);
    return func_unwinder_sp;
}

// Ignore any existing FuncUnwinders for this function, create a new one and don't add it to the
// UnwindTable.  This is intended for use by target modules show-unwind where we want to create 
// new UnwindPlans, not re-use existing ones.

FuncUnwindersSP
UnwindTable::GetUncachedFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc)
{
    FuncUnwindersSP no_unwind_found;
    Initialize();

    AddressRange range;
    if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, false, range) || !range.GetBaseAddress().IsValid())
    {
        // Does the eh_frame unwind info has a function bounds for this addr?
        if (m_eh_frame_up == nullptr || !m_eh_frame_up->GetAddressRange (addr, range))
        {
            return no_unwind_found;
        }
    }

    FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, range));
    return func_unwinder_sp;
}


void
UnwindTable::Dump (Stream &s)
{
    Mutex::Locker locker(m_mutex);
    s.Printf("UnwindTable for '%s':\n", m_object_file.GetFileSpec().GetPath().c_str());
    const_iterator begin = m_unwinds.begin();
    const_iterator end = m_unwinds.end();
    for (const_iterator pos = begin; pos != end; ++pos)
    {
        s.Printf ("[%u] 0x%16.16" PRIx64 "\n", (unsigned)std::distance (begin, pos), pos->first);
    }
    s.EOL();
}

DWARFCallFrameInfo *
UnwindTable::GetEHFrameInfo ()
{
    Initialize();
    return m_eh_frame_up.get();
}

CompactUnwindInfo *
UnwindTable::GetCompactUnwindInfo ()
{
    Initialize();
    return m_compact_unwind_up.get();
}

ArmUnwindInfo *
UnwindTable::GetArmUnwindInfo ()
{
    Initialize();
    return m_arm_unwind_up.get();
}

bool
UnwindTable::GetArchitecture (lldb_private::ArchSpec &arch)
{
    return m_object_file.GetArchitecture (arch);
}
