//===-- 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;
}

lldb::offset_t
Section::GetSectionData (void *dst, lldb::offset_t dst_len, lldb::offset_t offset)
{
    if (m_obj_file)
        return m_obj_file->ReadSectionData (this,
                                            offset,
                                            dst,
                                            dst_len);
    return 0;
}

lldb::offset_t
Section::GetSectionData (DataExtractor& section_data) const
{
    if (m_obj_file)
        return m_obj_file->ReadSectionData (this, section_data);
    return 0;
}

#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;
}
