llvm-project/lldb/source/API/SBSection.cpp

346 lines
8.2 KiB
C++

//===-- SBSection.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/API/SBSection.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
namespace lldb_private
{
// We need a section implementation to hold onto a reference to the module
// since if the module goes away and we have anyone still holding onto a
// SBSection object, we could crash.
class SectionImpl
{
public:
SectionImpl (const lldb_private::Section *section = NULL) :
m_module_sp (),
m_section (section)
{
if (section)
m_module_sp = section->GetModule();
}
SectionImpl (const SectionImpl &rhs) :
m_module_sp (rhs.m_module_sp),
m_section (rhs.m_section)
{
}
bool
IsValid () const
{
return m_section != NULL;
}
void
operator = (const SectionImpl &rhs)
{
m_module_sp = rhs.m_module_sp;
m_section = rhs.m_section;
}
void
operator =(const lldb_private::Section *section)
{
m_section = section;
if (section)
m_module_sp.reset(section->GetModule());
else
m_module_sp.reset();
}
const lldb_private::Section *
GetSection () const
{
return m_section;
}
Module *
GetModule()
{
return m_module_sp.get();
}
const lldb::ModuleSP &
GetModuleSP() const
{
return m_module_sp;
}
protected:
lldb::ModuleSP m_module_sp;
const lldb_private::Section *m_section;
};
}
using namespace lldb;
using namespace lldb_private;
SBSection::SBSection () :
m_opaque_ap ()
{
}
SBSection::SBSection (const SBSection &rhs) :
m_opaque_ap ()
{
if (rhs.IsValid())
m_opaque_ap.reset (new SectionImpl (*rhs.m_opaque_ap));
}
SBSection::SBSection (const lldb_private::Section *section) :
m_opaque_ap ()
{
if (section)
m_opaque_ap.reset (new SectionImpl(section));
}
const SBSection &
SBSection::operator = (const SBSection &rhs)
{
if (this != &rhs && rhs.IsValid())
m_opaque_ap.reset (new SectionImpl(*rhs.m_opaque_ap));
else
m_opaque_ap.reset ();
return *this;
}
SBSection::~SBSection ()
{
}
bool
SBSection::IsValid () const
{
return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid();
}
const char *
SBSection::GetName ()
{
if (IsValid())
return m_opaque_ap->GetSection()->GetName().GetCString();
return NULL;
}
lldb::SBSection
SBSection::FindSubSection (const char *sect_name)
{
lldb::SBSection sb_section;
if (IsValid())
{
ConstString const_sect_name(sect_name);
sb_section.SetSection(m_opaque_ap->GetSection()->GetChildren ().FindSectionByName(const_sect_name).get());
}
return sb_section;
}
size_t
SBSection::GetNumSubSections ()
{
if (IsValid())
return m_opaque_ap->GetSection()->GetChildren ().GetSize();
return 0;
}
lldb::SBSection
SBSection::GetSubSectionAtIndex (size_t idx)
{
lldb::SBSection sb_section;
if (IsValid())
sb_section.SetSection(m_opaque_ap->GetSection()->GetChildren ().GetSectionAtIndex(idx).get());
return sb_section;
}
const lldb_private::Section *
SBSection::GetSection()
{
if (m_opaque_ap.get())
return m_opaque_ap->GetSection();
return NULL;
}
void
SBSection::SetSection (const lldb_private::Section *section)
{
m_opaque_ap.reset (new SectionImpl(section));
}
lldb::addr_t
SBSection::GetFileAddress ()
{
lldb::addr_t file_addr = LLDB_INVALID_ADDRESS;
if (IsValid())
return m_opaque_ap->GetSection()->GetFileAddress();
return file_addr;
}
lldb::addr_t
SBSection::GetByteSize ()
{
if (IsValid())
{
const Section *section = m_opaque_ap->GetSection();
if (section)
return section->GetByteSize();
}
return 0;
}
uint64_t
SBSection::GetFileOffset ()
{
if (IsValid())
{
const Section *section = m_opaque_ap->GetSection();
if (section)
{
Module *module = m_opaque_ap->GetModule();
if (module)
{
ObjectFile *objfile = module->GetObjectFile();
if (objfile)
return objfile->GetOffset() + section->GetFileOffset();
}
return section->GetFileOffset();
}
}
return 0;
}
uint64_t
SBSection::GetFileByteSize ()
{
if (IsValid())
{
const Section *section = m_opaque_ap->GetSection();
if (section)
return section->GetFileSize();
}
return 0;
}
SBData
SBSection::GetSectionData ()
{
return GetSectionData (0, UINT64_MAX);
}
SBData
SBSection::GetSectionData (uint64_t offset, uint64_t size)
{
SBData sb_data;
if (IsValid())
{
const Section *section = m_opaque_ap->GetSection();
if (section)
{
const uint64_t sect_file_size = section->GetFileSize();
if (sect_file_size > 0)
{
Module *module = m_opaque_ap->GetModule();
if (module)
{
ObjectFile *objfile = module->GetObjectFile();
if (objfile)
{
const uint64_t sect_file_offset = objfile->GetOffset() + section->GetFileOffset();
const uint64_t file_offset = sect_file_offset + offset;
uint64_t file_size = size;
if (file_size == UINT64_MAX)
{
file_size = section->GetByteSize();
if (file_size > offset)
file_size -= offset;
else
file_size = 0;
}
DataBufferSP data_buffer_sp (objfile->GetFileSpec().ReadFileContents (file_offset, file_size));
if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0)
{
DataExtractorSP data_extractor_sp (new DataExtractor (data_buffer_sp,
objfile->GetByteOrder(),
objfile->GetAddressByteSize()));
sb_data.SetOpaque (data_extractor_sp);
}
}
}
}
}
}
return sb_data;
}
SectionType
SBSection::GetSectionType ()
{
if (m_opaque_ap.get())
{
const Section *section = m_opaque_ap->GetSection();
if (section)
return section->GetType();
}
return eSectionTypeInvalid;
}
bool
SBSection::operator == (const SBSection &rhs)
{
SectionImpl *lhs_ptr = m_opaque_ap.get();
SectionImpl *rhs_ptr = rhs.m_opaque_ap.get();
if (lhs_ptr && rhs_ptr)
return lhs_ptr->GetSection() == rhs_ptr->GetSection();
return false;
}
bool
SBSection::operator != (const SBSection &rhs)
{
SectionImpl *lhs_ptr = m_opaque_ap.get();
SectionImpl *rhs_ptr = rhs.m_opaque_ap.get();
if (lhs_ptr && rhs_ptr)
return lhs_ptr->GetSection() != rhs_ptr->GetSection();
return false;
}
bool
SBSection::GetDescription (SBStream &description)
{
Stream &strm = description.ref();
if (IsValid())
{
const Section *section = m_opaque_ap->GetSection();
const addr_t file_addr = section->GetFileAddress();
strm.Printf ("[0x%16.16llx-0x%16.16llx) ", file_addr, file_addr + section->GetByteSize());
section->DumpName(&strm);
}
else
{
strm.PutCString ("No value");
}
return true;
}