//===-- 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.16llx)",
                     __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.16llx 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.16llx)",
                     __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.16llx, section = %p: ", pos->first, pos->second.get());
        pos->second->Dump (&s, target, 0);
    }
}


