//===-- Section.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/Core/Section.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/ConvertEnum.h"

#include <limits>

using namespace lldb;
using namespace lldb_private;

Section::Section (const ModuleSP &module_sp,
                  ObjectFile *obj_file,
                  user_id_t sect_id,
                  const ConstString &name,
                  SectionType sect_type,
                  addr_t file_addr,
                  addr_t byte_size,
                  lldb::offset_t file_offset,
                  lldb::offset_t file_size,
                  uint32_t log2align,
                  uint32_t flags,
                  uint32_t target_byte_size/*=1*/) :
    ModuleChild     (module_sp),
    UserID          (sect_id),
    Flags           (flags),
    m_obj_file      (obj_file),
    m_type          (sect_type),
    m_parent_wp     (),
    m_name          (name),
    m_file_addr     (file_addr),
    m_byte_size     (byte_size),
    m_file_offset   (file_offset),
    m_file_size     (file_size),
    m_log2align     (log2align),
    m_children      (),
    m_fake          (false),
    m_encrypted     (false),
    m_thread_specific (false),
    m_target_byte_size(target_byte_size)
{
//    printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
//            this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, name.GetCString());
}

Section::Section (const lldb::SectionSP &parent_section_sp,
                  const ModuleSP &module_sp,
                  ObjectFile *obj_file,
                  user_id_t sect_id,
                  const ConstString &name,
                  SectionType sect_type,
                  addr_t file_addr,
                  addr_t byte_size,
                  lldb::offset_t file_offset,
                  lldb::offset_t file_size,
                  uint32_t log2align,
                  uint32_t flags,
                  uint32_t target_byte_size/*=1*/) :
    ModuleChild     (module_sp),
    UserID          (sect_id),
    Flags           (flags),
    m_obj_file      (obj_file),
    m_type          (sect_type),
    m_parent_wp     (),
    m_name          (name),
    m_file_addr     (file_addr),
    m_byte_size     (byte_size),
    m_file_offset   (file_offset),
    m_file_size     (file_size),
    m_log2align     (log2align),
    m_children      (),
    m_fake          (false),
    m_encrypted     (false),
    m_thread_specific (false),
    m_target_byte_size(target_byte_size)
{
//    printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
//            this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, parent_section_sp->GetName().GetCString(), name.GetCString());
    if (parent_section_sp)
        m_parent_wp = parent_section_sp;
}

Section::~Section()
{
//    printf ("Section::~Section(%p)\n", this);
}

addr_t
Section::GetFileAddress () const
{
    SectionSP parent_sp (GetParent ());
    if (parent_sp)
    {
        // This section has a parent which means m_file_addr is an offset into
        // the parent section, so the file address for this section is the file
        // address of the parent plus the offset
        return parent_sp->GetFileAddress() + m_file_addr;
    }
    // This section has no parent, so m_file_addr is the file base address
    return m_file_addr;
}

bool
Section::SetFileAddress (lldb::addr_t file_addr)
{
    SectionSP parent_sp (GetParent ());
    if (parent_sp)
    {
        if (m_file_addr >= file_addr)
            return parent_sp->SetFileAddress (m_file_addr - file_addr);
        return false;
    }
    else
    {
        // This section has no parent, so m_file_addr is the file base address
        m_file_addr = file_addr;
        return true;
    }
}

lldb::addr_t
Section::GetOffset () const
{
    // This section has a parent which means m_file_addr is an offset.
    SectionSP parent_sp (GetParent ());
    if (parent_sp)
        return m_file_addr;
    
    // This section has no parent, so there is no offset to be had
    return 0;
}

addr_t
Section::GetLoadBaseAddress (Target *target) const
{
    addr_t load_base_addr = LLDB_INVALID_ADDRESS;
    SectionSP parent_sp (GetParent ());
    if (parent_sp)
    {
        load_base_addr = parent_sp->GetLoadBaseAddress (target);
        if (load_base_addr != LLDB_INVALID_ADDRESS)
            load_base_addr += GetOffset();
    }
    if (load_base_addr == LLDB_INVALID_ADDRESS)
    {
        load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (const_cast<Section *>(this)->shared_from_this());
    }
    return load_base_addr;
}

bool
Section::ResolveContainedAddress (addr_t offset, Address &so_addr) const
{
    const size_t num_children = m_children.GetSize();
    if (num_children > 0)
    {
        for (size_t i=0; i<num_children; i++)
        {
            Section* child_section = m_children.GetSectionAtIndex (i).get();

            addr_t child_offset = child_section->GetOffset();
            if (child_offset <= offset && offset - child_offset < child_section->GetByteSize())
                return child_section->ResolveContainedAddress (offset - child_offset, so_addr);
        }
    }
    so_addr.SetOffset(offset);
    so_addr.SetSection(const_cast<Section *>(this)->shared_from_this());
    
#ifdef LLDB_CONFIGURATION_DEBUG
    // For debug builds, ensure that there are no orphaned (i.e., moduleless) sections.
    assert(GetModule().get());
#endif
    return true;
}

bool
Section::ContainsFileAddress (addr_t vm_addr) const
{
    const addr_t file_addr = GetFileAddress();
    if (file_addr != LLDB_INVALID_ADDRESS)
    {
        if (file_addr <= vm_addr)
        {
            const addr_t offset = (vm_addr - file_addr) *  m_target_byte_size;
            return offset < GetByteSize();
        }
    }
    return false;
}

int
Section::Compare (const Section& a, const Section& b)
{
    if (&a == &b)
        return 0;

    const ModuleSP a_module_sp = a.GetModule();
    const ModuleSP b_module_sp = b.GetModule();
    if (a_module_sp == b_module_sp)
    {
        user_id_t a_sect_uid = a.GetID();
        user_id_t b_sect_uid = b.GetID();
        if (a_sect_uid < b_sect_uid)
            return -1;
        if (a_sect_uid > b_sect_uid)
            return 1;
        return 0;
    }
    else
    {
        // The modules are different, just compare the module pointers
        if (a_module_sp.get() < b_module_sp.get())
            return -1;
        else
            return 1;   // We already know the modules aren't equal
    }
}


void
Section::Dump (Stream *s, Target *target, uint32_t depth) const
{
//    s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
    s->Indent();
    s->Printf("0x%8.8" PRIx64 " %-16s ", GetID(), GetSectionTypeAsCString (m_type));
    bool resolved = true;
    addr_t addr = LLDB_INVALID_ADDRESS;

    if (GetByteSize() == 0)
        s->Printf("%39s", "");
    else
    {
        if (target)
            addr = GetLoadBaseAddress (target);

        if (addr == LLDB_INVALID_ADDRESS)
        {
            if (target)
                resolved = false;
            addr = GetFileAddress();
        }

        VMRange range(addr, addr + m_byte_size);
        range.Dump (s, 0);
    }

    s->Printf("%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", resolved ? ' ' : '*', m_file_offset, m_file_size, Get());

    DumpName (s);

    s->EOL();

    if (depth > 0)
        m_children.Dump(s, target, false, depth - 1);
}

void
Section::DumpName (Stream *s) const
{
    SectionSP parent_sp (GetParent ());
    if (parent_sp)
    {
        parent_sp->DumpName (s);
        s->PutChar('.');
    }
    else
    {
        // The top most section prints the module basename
        const char * name = NULL;
        ModuleSP module_sp (GetModule());
        const FileSpec &file_spec = m_obj_file->GetFileSpec();

        if (m_obj_file)
            name = file_spec.GetFilename().AsCString();
        if ((!name || !name[0]) && module_sp)
            name = module_sp->GetFileSpec().GetFilename().AsCString();
        if (name && name[0])
            s->Printf("%s.", name);
    }
    m_name.Dump(s);
}

bool
Section::IsDescendant (const Section *section)
{
    if (this == section)
        return true;
    SectionSP parent_sp (GetParent ());
    if (parent_sp)
        return parent_sp->IsDescendant (section);
    return false;
}

bool
Section::Slide (addr_t slide_amount, bool slide_children)
{
    if (m_file_addr != LLDB_INVALID_ADDRESS)
    {
        if (slide_amount == 0)
            return true;

        m_file_addr += slide_amount;

        if (slide_children)
            m_children.Slide (slide_amount, slide_children);

        return true;
    }
    return false;
}

#pragma mark SectionList

SectionList::SectionList () :
    m_sections()
{
}


SectionList::~SectionList ()
{
}

SectionList &
SectionList::operator = (const SectionList& rhs)
{
    if (this != &rhs)
        m_sections = rhs.m_sections;
    return *this;
}

size_t
SectionList::AddSection (const lldb::SectionSP& section_sp)
{
    if (section_sp)
    {
        size_t section_index = m_sections.size();
        m_sections.push_back(section_sp);
        return section_index;
    }

    return std::numeric_limits<size_t>::max ();
}

// Warning, this can be slow as it's removing items from a std::vector.
bool
SectionList::DeleteSection (size_t idx)
{
    if (idx < m_sections.size())
    {
        m_sections.erase (m_sections.begin() + idx);
        return true; 
    }
    return false;
}

size_t
SectionList::FindSectionIndex (const Section* sect)
{
    iterator sect_iter;
    iterator begin = m_sections.begin();
    iterator end = m_sections.end();
    for (sect_iter = begin; sect_iter != end; ++sect_iter)
    {
        if (sect_iter->get() == sect)
        {
            // The secton was already in this section list
            return std::distance (begin, sect_iter);
        }
    }
    return UINT32_MAX;
}

size_t
SectionList::AddUniqueSection (const lldb::SectionSP& sect_sp)
{
    size_t sect_idx = FindSectionIndex (sect_sp.get());
    if (sect_idx == UINT32_MAX)
    {
        sect_idx = AddSection (sect_sp);
    }
    return sect_idx;
}

bool
SectionList::ReplaceSection (user_id_t sect_id, const lldb::SectionSP& sect_sp, uint32_t depth)
{
    iterator sect_iter, end = m_sections.end();
    for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter)
    {
        if ((*sect_iter)->GetID() == sect_id)
        {
            *sect_iter = sect_sp;
            return true;
        }
        else if (depth > 0)
        {
            if ((*sect_iter)->GetChildren().ReplaceSection(sect_id, sect_sp, depth - 1))
                return true;
        }
    }
    return false;
}

size_t
SectionList::GetNumSections (uint32_t depth) const
{
    size_t count = m_sections.size();
    if (depth > 0)
    {
        const_iterator sect_iter, end = m_sections.end();
        for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter)
        {
            count += (*sect_iter)->GetChildren().GetNumSections(depth - 1);
        }
    }
    return count;
}

SectionSP
SectionList::GetSectionAtIndex (size_t idx) const
{
    SectionSP sect_sp;
    if (idx < m_sections.size())
        sect_sp = m_sections[idx];
    return sect_sp;
}

SectionSP
SectionList::FindSectionByName (const ConstString &section_dstr) const
{
    SectionSP sect_sp;
    // Check if we have a valid section string
    if (section_dstr && !m_sections.empty())
    {
        const_iterator sect_iter;
        const_iterator end = m_sections.end();
        for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter)
        {
            Section *child_section = sect_iter->get();
            if (child_section)
            {
                if (child_section->GetName() == section_dstr)
                {
                    sect_sp = *sect_iter;
                }
                else
                {
                    sect_sp = child_section->GetChildren().FindSectionByName(section_dstr);
                }
            }
        }
    }
    return sect_sp;
}

SectionSP
SectionList::FindSectionByID (user_id_t sect_id) const
{
    SectionSP sect_sp;
    if (sect_id)
    {
        const_iterator sect_iter;
        const_iterator end = m_sections.end();
        for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter)
        {
            if ((*sect_iter)->GetID() == sect_id)
            {
                sect_sp = *sect_iter;
                break;
            }
            else
            {
                sect_sp = (*sect_iter)->GetChildren().FindSectionByID (sect_id);
            }
        }
    }
    return sect_sp;
}


SectionSP
SectionList::FindSectionByType (SectionType sect_type, bool check_children, size_t start_idx) const
{
    SectionSP sect_sp;
    size_t num_sections = m_sections.size();
    for (size_t idx = start_idx; idx < num_sections; ++idx)
    {
        if (m_sections[idx]->GetType() == sect_type)
        {
            sect_sp = m_sections[idx];
            break;
        }
        else if (check_children)
        {
            sect_sp = m_sections[idx]->GetChildren().FindSectionByType (sect_type, check_children, 0);
            if (sect_sp)
                break;
        }
    }
    return sect_sp;
}

SectionSP
SectionList::FindSectionContainingFileAddress (addr_t vm_addr, uint32_t depth) const
{
    SectionSP sect_sp;
    const_iterator sect_iter;
    const_iterator end = m_sections.end();
    for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter)
    {
        Section *sect = sect_iter->get();
        if (sect->ContainsFileAddress (vm_addr))
        {
            // The file address is in this section. We need to make sure one of our child
            // sections doesn't contain this address as well as obeying the depth limit
            // that was passed in.
            if (depth > 0)
                sect_sp = sect->GetChildren().FindSectionContainingFileAddress(vm_addr, depth - 1);

            if (sect_sp.get() == NULL && !sect->IsFake())
                sect_sp = *sect_iter;
        }
    }
    return sect_sp;
}

bool
SectionList::ContainsSection(user_id_t sect_id) const
{
    return FindSectionByID (sect_id).get() != NULL;
}

void
SectionList::Dump (Stream *s, Target *target, bool show_header, uint32_t depth) const
{
    bool target_has_loaded_sections = target && !target->GetSectionLoadList().IsEmpty();
    if (show_header && !m_sections.empty())
    {
        s->Indent();
        s->Printf(    "SectID     Type             %s Address                             File Off.  File Size  Flags      Section Name\n", target_has_loaded_sections ? "Load" : "File");
        s->Indent();
        s->PutCString("---------- ---------------- ---------------------------------------  ---------- ---------- ---------- ----------------------------\n");
    }


    const_iterator sect_iter;
    const_iterator end = m_sections.end();
    for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter)
    {
        (*sect_iter)->Dump(s, target_has_loaded_sections ? target : NULL, depth);
    }

    if (show_header && !m_sections.empty())
        s->IndentLess();

}

size_t
SectionList::Slide (addr_t slide_amount, bool slide_children)
{
    size_t count = 0;
    const_iterator pos, end = m_sections.end();
    for (pos = m_sections.begin(); pos != end; ++pos)
    {
        if ((*pos)->Slide(slide_amount, slide_children))
            ++count;
    }
    return count;
}
