//===-- SectionLoadList.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/Target/SectionLoadList.h"

// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"

using namespace lldb;
using namespace lldb_private;


bool
SectionLoadList::IsEmpty() const
{
    Mutex::Locker locker(m_mutex);
    return m_addr_to_sect.empty();
}

void
SectionLoadList::Clear ()
{
    Mutex::Locker locker(m_mutex);
    m_addr_to_sect.clear();
    m_sect_to_addr.clear();
}

addr_t
SectionLoadList::GetSectionLoadAddress (const lldb::SectionSP &section) const
{
    // TODO: add support for the same section having multiple load addresses
    addr_t section_load_addr = LLDB_INVALID_ADDRESS;
    if (section)
    {
        Mutex::Locker locker(m_mutex);
        sect_to_addr_collection::const_iterator pos = m_sect_to_addr.find (section.get());
        
        if (pos != m_sect_to_addr.end())
            section_load_addr = pos->second;
    }
    return section_load_addr;
}

bool
SectionLoadList::SetSectionLoadAddress (const lldb::SectionSP &section, addr_t load_addr, bool warn_multiple)
{
    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));

    if (log)
    {
        const FileSpec &module_file_spec (section->GetModule()->GetFileSpec());
        log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s), load_addr = 0x%16.16" PRIx64 ")",
                     __FUNCTION__,
                     section.get(),
                     module_file_spec.GetDirectory().AsCString(),
                     module_file_spec.GetDirectory() ? "/" : "",
                     module_file_spec.GetFilename().AsCString(),
                     section->GetName().AsCString(),
                     load_addr);
    }

    if (section->GetByteSize() == 0)
        return false; // No change

    // Fill in the section -> load_addr map
    Mutex::Locker locker(m_mutex);
    sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section.get());
    if (sta_pos != m_sect_to_addr.end())
    {
        if (load_addr == sta_pos->second)
            return false; // No change...
        else
            sta_pos->second = load_addr;
    }
    else
        m_sect_to_addr[section.get()] = load_addr;

    // Fill in the load_addr -> section map
    addr_to_sect_collection::iterator ats_pos = m_addr_to_sect.find(load_addr);
    if (ats_pos != m_addr_to_sect.end())
    {
        // Some sections are ok to overlap, and for others we should warn. When
        // we have multiple load addresses that correspond to a section, we will
        // allways attribute the section to the be last section that claims it
        // exists at that address. Sometimes it is ok for more that one section
        // to be loaded at a specific load address, and other times it isn't.
        // The "warn_multiple" parameter tells us if we should warn in this case
        // or not. The DynamicLoader plug-in subclasses should know which
        // sections should warn and which shouldn't (darwin shared cache modules
        // all shared the same "__LINKEDIT" sections, so the dynamic loader can
        // pass false for "warn_multiple").
        if (warn_multiple && section != ats_pos->second)
        {
            ModuleSP module_sp (section->GetModule());
            if (module_sp)
            {
                ModuleSP curr_module_sp (ats_pos->second->GetModule());
                if (curr_module_sp)
                {
                    module_sp->ReportWarning ("address 0x%16.16" PRIx64 " maps to more than one section: %s.%s and %s.%s",
                                              load_addr, 
                                              module_sp->GetFileSpec().GetFilename().GetCString(), 
                                              section->GetName().GetCString(),
                                              curr_module_sp->GetFileSpec().GetFilename().GetCString(),
                                              ats_pos->second->GetName().GetCString());
                }
            }
        }
        ats_pos->second = section;
    }
    else
        m_addr_to_sect[load_addr] = section;

    return true;    // Changed
}

size_t
SectionLoadList::SetSectionUnloaded (const lldb::SectionSP &section_sp)
{
    size_t unload_count = 0;

    if (section_sp)
    {
        LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));

        if (log)
        {
            const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec());
            log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s))",
                         __FUNCTION__,
                         section_sp.get(),
                         module_file_spec.GetDirectory().AsCString(),
                         module_file_spec.GetDirectory() ? "/" : "",
                         module_file_spec.GetFilename().AsCString(),
                         section_sp->GetName().AsCString());
        }

        Mutex::Locker locker(m_mutex);
        
        sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section_sp.get());
        if (sta_pos != m_sect_to_addr.end())
        {
            addr_t load_addr = sta_pos->second;
            m_sect_to_addr.erase (sta_pos);

            addr_to_sect_collection::iterator ats_pos = m_addr_to_sect.find(load_addr);
            if (ats_pos != m_addr_to_sect.end())
                m_addr_to_sect.erase (ats_pos);
        }
    }
    return unload_count;
}

bool
SectionLoadList::SetSectionUnloaded (const lldb::SectionSP &section_sp, addr_t load_addr)
{
    LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER | LIBLLDB_LOG_VERBOSE));

    if (log)
    {
        const FileSpec &module_file_spec (section_sp->GetModule()->GetFileSpec());
        log->Printf ("SectionLoadList::%s (section = %p (%s%s%s.%s), load_addr = 0x%16.16" PRIx64 ")",
                     __FUNCTION__,
                     section_sp.get(),
                     module_file_spec.GetDirectory().AsCString(),
                     module_file_spec.GetDirectory() ? "/" : "",
                     module_file_spec.GetFilename().AsCString(),
                     section_sp->GetName().AsCString(),
                     load_addr);
    }
    bool erased = false;
    Mutex::Locker locker(m_mutex);
    sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section_sp.get());
    if (sta_pos != m_sect_to_addr.end())
    {
        erased = true;
        m_sect_to_addr.erase (sta_pos);
    }
        
    addr_to_sect_collection::iterator ats_pos = m_addr_to_sect.find(load_addr);
    if (ats_pos != m_addr_to_sect.end())
    {
        erased = true;
        m_addr_to_sect.erase (ats_pos);
    }

    return erased;
}


bool
SectionLoadList::ResolveLoadAddress (addr_t load_addr, Address &so_addr) const
{
    // First find the top level section that this load address exists in    
    Mutex::Locker locker(m_mutex);
    if (!m_addr_to_sect.empty())
    {
        addr_to_sect_collection::const_iterator pos = m_addr_to_sect.lower_bound (load_addr);
        if (pos != m_addr_to_sect.end())
        {
            if (load_addr != pos->first && pos != m_addr_to_sect.begin())
                --pos;
            if (load_addr >= pos->first)
            {
                addr_t offset = load_addr - pos->first;
                if (offset < pos->second->GetByteSize())
                {
                    // We have found the top level section, now we need to find the
                    // deepest child section.
                    return pos->second->ResolveContainedAddress (offset, so_addr);
                }
            }
        }
        else
        {
            // There are no entries that have an address that is >= load_addr,
            // so we need to check the last entry on our collection.
            addr_to_sect_collection::const_reverse_iterator rpos = m_addr_to_sect.rbegin();
            if (load_addr >= rpos->first)
            {
                addr_t offset = load_addr - rpos->first;
                if (offset < rpos->second->GetByteSize())
                {
                    // We have found the top level section, now we need to find the
                    // deepest child section.
                    return rpos->second->ResolveContainedAddress (offset, so_addr);
                }
            }
        }
    }
    so_addr.Clear();
    return false;
}

void
SectionLoadList::Dump (Stream &s, Target *target)
{
    Mutex::Locker locker(m_mutex);
    addr_to_sect_collection::const_iterator pos, end;
    for (pos = m_addr_to_sect.begin(), end = m_addr_to_sect.end(); pos != end; ++pos)
    {
        s.Printf("addr = 0x%16.16" PRIx64 ", section = %p: ", pos->first, pos->second.get());
        pos->second->Dump (&s, target, 0);
    }
}


