Added to the public API to allow symbolication:
- New SBSection objects that are object file sections which can be accessed
through the SBModule classes. You can get the number of sections, get a
section at index, and find a section by name.
- SBSections can contain subsections (first find "__TEXT" on darwin, then
us the resulting SBSection to find "__text" sub section).
- Set load addresses for a SBSection in the SBTarget interface
- Set the load addresses of all SBSection in a SBModule in the SBTarget interface
- Add a new module the an existing target in the SBTarget interface
- Get a SBSection from a SBAddress object
This should get us a lot closer to being able to symbolicate using LLDB through
the public API.
llvm-svn: 140437
diff --git a/lldb/source/API/SBAddress.cpp b/lldb/source/API/SBAddress.cpp
index e4161a2..9066bb4 100644
--- a/lldb/source/API/SBAddress.cpp
+++ b/lldb/source/API/SBAddress.cpp
@@ -9,6 +9,7 @@
#include "lldb/API/SBAddress.h"
#include "lldb/API/SBProcess.h"
+#include "lldb/API/SBSection.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Address.h"
#include "lldb/Core/Log.h"
@@ -16,6 +17,69 @@
#include "lldb/Host/Mutex.h"
#include "lldb/Target/Target.h"
+namespace lldb_private
+{
+ // We need a address implementation to hold onto a reference to the module
+ // since if the module goes away and we have anyone still holding onto a
+ // SBAddress object, we could crash.
+ class AddressImpl
+ {
+ public:
+ AddressImpl () :
+ m_module_sp(),
+ m_address()
+ {
+ }
+
+ AddressImpl (const Address &addr) :
+ m_module_sp (addr.GetModule()),
+ m_address (addr)
+ {
+ }
+
+ AddressImpl (const AddressImpl &rhs) :
+ m_module_sp (rhs.m_module_sp),
+ m_address (rhs.m_address)
+ {
+ }
+
+ bool
+ IsValid () const
+ {
+ return m_address.IsValid();
+ }
+
+ void
+ operator = (const AddressImpl &rhs)
+ {
+ m_module_sp = rhs.m_module_sp;
+ m_address = rhs.m_address;
+ }
+
+ Address &
+ GetAddress ()
+ {
+ return m_address;
+ }
+
+ Module *
+ GetModule()
+ {
+ return m_module_sp.get();
+ }
+
+ const lldb::ModuleSP &
+ GetModuleSP() const
+ {
+ return m_module_sp;
+ }
+ protected:
+ lldb::ModuleSP m_module_sp;
+ Address m_address;
+ };
+}
+
+
using namespace lldb;
using namespace lldb_private;
@@ -25,18 +89,18 @@
{
}
-SBAddress::SBAddress (const lldb_private::Address *lldb_object_ptr) :
+SBAddress::SBAddress (const Address *lldb_object_ptr) :
m_opaque_ap ()
{
if (lldb_object_ptr)
- m_opaque_ap.reset (new lldb_private::Address(*lldb_object_ptr));
+ m_opaque_ap.reset (new AddressImpl(*lldb_object_ptr));
}
SBAddress::SBAddress (const SBAddress &rhs) :
m_opaque_ap ()
{
if (rhs.IsValid())
- m_opaque_ap.reset (new lldb_private::Address(*rhs.m_opaque_ap.get()));
+ m_opaque_ap.reset (new AddressImpl(*rhs.m_opaque_ap.get()));
}
// Create an address by resolving a load address using the supplied target
@@ -55,8 +119,13 @@
const SBAddress &
SBAddress::operator = (const SBAddress &rhs)
{
- if (this != &rhs && rhs.IsValid())
- m_opaque_ap.reset (new lldb_private::Address(*rhs.m_opaque_ap.get()));
+ if (this != &rhs)
+ {
+ if (rhs.IsValid())
+ m_opaque_ap.reset(new AddressImpl(*rhs.m_opaque_ap.get()));
+ else
+ m_opaque_ap.reset();
+ }
return *this;
}
@@ -73,25 +142,24 @@
}
void
-SBAddress::SetAddress (const lldb_private::Address *lldb_object_ptr)
+SBAddress::SetAddress (const Address *lldb_object_ptr)
{
if (lldb_object_ptr)
{
if (m_opaque_ap.get())
*m_opaque_ap = *lldb_object_ptr;
else
- m_opaque_ap.reset (new lldb_private::Address(*lldb_object_ptr));
- return;
+ m_opaque_ap.reset (new AddressImpl(*lldb_object_ptr));
}
- if (m_opaque_ap.get())
- m_opaque_ap->Clear();
+ else
+ m_opaque_ap.reset();
}
lldb::addr_t
SBAddress::GetFileAddress () const
{
if (m_opaque_ap.get())
- return m_opaque_ap->GetFileAddress();
+ return m_opaque_ap->GetAddress().GetFileAddress();
else
return LLDB_INVALID_ADDRESS;
}
@@ -99,13 +167,13 @@
lldb::addr_t
SBAddress::GetLoadAddress (const SBTarget &target) const
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
lldb::addr_t addr = LLDB_INVALID_ADDRESS;
if (m_opaque_ap.get())
{
Mutex::Locker api_locker (target->GetAPIMutex());
- addr = m_opaque_ap->GetLoadAddress (target.get());
+ addr = m_opaque_ap->GetAddress().GetLoadAddress (target.get());
}
if (log)
@@ -127,14 +195,14 @@
if (target.IsValid())
*this = target.ResolveLoadAddress(load_addr);
else
- m_opaque_ap->Clear();
+ m_opaque_ap->GetAddress().Clear();
// Check if we weren't were able to resolve a section offset address.
// If we weren't it is ok, the load address might be a location on the
// stack or heap, so we should just have an address with no section and
// a valid offset
if (!m_opaque_ap->IsValid())
- m_opaque_ap->SetOffset(load_addr);
+ m_opaque_ap->GetAddress().SetOffset(load_addr);
}
bool
@@ -142,50 +210,66 @@
{
if (m_opaque_ap.get())
{
- addr_t addr_offset = m_opaque_ap->GetOffset();
+ addr_t addr_offset = m_opaque_ap->GetAddress().GetOffset();
if (addr_offset != LLDB_INVALID_ADDRESS)
{
- m_opaque_ap->SetOffset(addr_offset + offset);
+ m_opaque_ap->GetAddress().SetOffset(addr_offset + offset);
return true;
}
}
return false;
}
-lldb_private::Address *
+lldb::SBSection
+SBAddress::GetSection ()
+{
+ lldb::SBSection sb_section;
+ if (m_opaque_ap.get())
+ sb_section.SetSection(m_opaque_ap->GetAddress().GetSection());
+ return sb_section;
+}
+
+
+Address *
SBAddress::operator->()
{
- return m_opaque_ap.get();
+ if (m_opaque_ap.get())
+ return &m_opaque_ap->GetAddress();
+ return NULL;
}
-const lldb_private::Address *
+const Address *
SBAddress::operator->() const
{
- return m_opaque_ap.get();
+ if (m_opaque_ap.get())
+ return &m_opaque_ap->GetAddress();
+ return NULL;
}
-lldb_private::Address &
+Address &
SBAddress::ref ()
{
if (m_opaque_ap.get() == NULL)
- m_opaque_ap.reset (new lldb_private::Address);
- return *m_opaque_ap;
+ m_opaque_ap.reset (new AddressImpl());
+ return m_opaque_ap->GetAddress();
}
-const lldb_private::Address &
+const Address &
SBAddress::ref () const
{
// "const SBAddress &addr" should already have checked "addr.IsValid()"
// prior to calling this function. In case you didn't we will assert
// and die to let you know.
assert (m_opaque_ap.get());
- return *m_opaque_ap;
+ return m_opaque_ap->GetAddress();
}
-lldb_private::Address *
+Address *
SBAddress::get ()
{
- return m_opaque_ap.get();
+ if (m_opaque_ap.get())
+ return &m_opaque_ap->GetAddress();
+ return NULL;
}
bool
@@ -195,26 +279,13 @@
// case there isn't one already...
description.ref();
if (m_opaque_ap.get())
- m_opaque_ap->Dump (description.get(), NULL, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleInvalid, 4);
+ m_opaque_ap->GetAddress().Dump (description.get(), NULL, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleInvalid, 4);
else
description.Printf ("No value");
return true;
}
-SectionType
-SBAddress::GetSectionType ()
-{
- if (m_opaque_ap.get())
- {
- const Section *section = m_opaque_ap->GetSection();
- if (section)
- return section->GetType();
- }
- return eSectionTypeInvalid;
-}
-
-
SBModule
SBAddress::GetModule ()
{
@@ -233,7 +304,7 @@
{
SBSymbolContext sb_sc;
if (m_opaque_ap.get())
- m_opaque_ap->CalculateSymbolContext (&sb_sc.ref(), resolve_scope);
+ m_opaque_ap->GetAddress().CalculateSymbolContext (&sb_sc.ref(), resolve_scope);
return sb_sc;
}
@@ -242,7 +313,7 @@
{
SBCompileUnit sb_comp_unit;
if (m_opaque_ap.get())
- sb_comp_unit.reset(m_opaque_ap->CalculateSymbolContextCompileUnit());
+ sb_comp_unit.reset(m_opaque_ap->GetAddress().CalculateSymbolContextCompileUnit());
return sb_comp_unit;
}
@@ -251,7 +322,7 @@
{
SBFunction sb_function;
if (m_opaque_ap.get())
- sb_function.reset(m_opaque_ap->CalculateSymbolContextFunction());
+ sb_function.reset(m_opaque_ap->GetAddress().CalculateSymbolContextFunction());
return sb_function;
}
@@ -260,7 +331,7 @@
{
SBBlock sb_block;
if (m_opaque_ap.get())
- sb_block.reset(m_opaque_ap->CalculateSymbolContextBlock());
+ sb_block.reset(m_opaque_ap->GetAddress().CalculateSymbolContextBlock());
return sb_block;
}
@@ -269,7 +340,7 @@
{
SBSymbol sb_symbol;
if (m_opaque_ap.get())
- sb_symbol.reset(m_opaque_ap->CalculateSymbolContextSymbol());
+ sb_symbol.reset(m_opaque_ap->GetAddress().CalculateSymbolContextSymbol());
return sb_symbol;
}
@@ -280,7 +351,7 @@
if (m_opaque_ap.get())
{
LineEntry line_entry;
- if (m_opaque_ap->CalculateSymbolContextLineEntry (line_entry))
+ if (m_opaque_ap->GetAddress().CalculateSymbolContextLineEntry (line_entry))
sb_line_entry.SetLineEntry (line_entry);
}
return sb_line_entry;
diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index acb69fa..0f5472a 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -29,6 +29,7 @@
#include "lldb/Core/State.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/OptionGroupPlatform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/TargetList.h"
@@ -459,6 +460,52 @@
return result;
}
+lldb::SBTarget
+SBDebugger::CreateTarget (const char *filename,
+ const char *target_triple,
+ const char *platform_name,
+ bool add_dependent_modules,
+ lldb::SBError& sb_error)
+{
+ SBTarget sb_target;
+ if (m_opaque_sp)
+ {
+ sb_error.Clear();
+ FileSpec filename_spec (filename, true);
+ OptionGroupPlatform platform_options (false);
+ platform_options.SetPlatformName (platform_name);
+
+ TargetSP target_sp;
+ sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp,
+ filename_spec,
+ target_triple,
+ add_dependent_modules,
+ &platform_options,
+ target_sp);
+
+ if (sb_error.Success())
+ sb_target.reset (target_sp);
+ }
+ else
+ {
+ sb_error.SetErrorString("invalid target");
+ }
+
+ LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+ if (log)
+ {
+ log->Printf ("SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, platform_name=%s, add_dependent_modules=%u, error=%s) => SBTarget(%p)",
+ m_opaque_sp.get(),
+ filename,
+ target_triple,
+ platform_name,
+ add_dependent_modules,
+ sb_error.GetCString(),
+ sb_target.get());
+ }
+
+ return sb_target;
+}
SBTarget
SBDebugger::CreateTargetWithFileAndTargetTriple (const char *filename,
@@ -467,11 +514,15 @@
SBTarget target;
if (m_opaque_sp)
{
- ArchSpec arch;
FileSpec file_spec (filename, true);
- arch.SetTriple (target_triple, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
TargetSP target_sp;
- Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file_spec, arch, true, target_sp));
+ const bool add_dependent_modules = true;
+ Error error (m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp,
+ file_spec,
+ target_triple,
+ add_dependent_modules,
+ NULL,
+ target_sp));
target.reset (target_sp);
}
@@ -494,14 +545,16 @@
if (m_opaque_sp)
{
FileSpec file (filename, true);
- ArchSpec arch;
TargetSP target_sp;
Error error;
+ const bool add_dependent_modules = true;
- if (arch_cstr)
- arch.SetTriple (arch_cstr, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get());
-
- error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, true, target_sp);
+ error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp,
+ file,
+ arch_cstr,
+ add_dependent_modules,
+ NULL,
+ target_sp);
if (error.Success())
{
@@ -529,8 +582,14 @@
ArchSpec arch = Target::GetDefaultArchitecture ();
TargetSP target_sp;
Error error;
+ const bool add_dependent_modules = true;
- error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp, file, arch, true, target_sp);
+ error = m_opaque_sp->GetTargetList().CreateTarget (*m_opaque_sp,
+ file,
+ arch,
+ add_dependent_modules,
+ m_opaque_sp->GetPlatformList().GetSelectedPlatform(),
+ target_sp);
if (error.Success())
{
diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp
index 1a76af6..790d8dd 100644
--- a/lldb/source/API/SBModule.cpp
+++ b/lldb/source/API/SBModule.cpp
@@ -217,6 +217,11 @@
return m_opaque_sp.get();
}
+const lldb::ModuleSP &
+SBModule::get_sp() const
+{
+ return m_opaque_sp;
+}
void
SBModule::SetModule (const lldb::ModuleSP& module_sp)
@@ -225,15 +230,17 @@
}
-bool
-SBModule::ResolveFileAddress (lldb::addr_t vm_addr, SBAddress& addr)
+SBAddress
+SBModule::ResolveFileAddress (lldb::addr_t vm_addr)
{
- if (m_opaque_sp && addr.IsValid())
- return m_opaque_sp->ResolveFileAddress (vm_addr, addr.ref());
-
- if (addr.IsValid())
- addr->Clear();
- return false;
+ lldb::SBAddress sb_addr;
+ if (m_opaque_sp)
+ {
+ Address addr;
+ if (m_opaque_sp->ResolveFileAddress (vm_addr, addr))
+ sb_addr.ref() = addr;
+ }
+ return sb_addr;
}
SBSymbolContext
@@ -292,6 +299,40 @@
return sb_symbol;
}
+size_t
+SBModule::GetNumSections ()
+{
+ if (m_opaque_sp)
+ {
+ ObjectFile *obj_file = m_opaque_sp->GetObjectFile();
+ if (obj_file)
+ {
+ SectionList *section_list = obj_file->GetSectionList ();
+ if (section_list)
+ return section_list->GetSize();
+ }
+ }
+ return 0;
+}
+
+SBSection
+SBModule::GetSectionAtIndex (size_t idx)
+{
+ SBSection sb_section;
+ if (m_opaque_sp)
+ {
+ ObjectFile *obj_file = m_opaque_sp->GetObjectFile();
+ if (obj_file)
+ {
+ SectionList *section_list = obj_file->GetSectionList ();
+
+ if (section_list)
+ sb_section.SetSection(section_list->GetSectionAtIndex (idx).get());
+ }
+ }
+ return sb_section;
+}
+
uint32_t
SBModule::FindFunctions (const char *name,
uint32_t name_type_mask,
@@ -396,3 +437,30 @@
return retval;
}
+
+
+SBSection
+SBModule::FindSection (const char *sect_name)
+{
+ SBSection sb_section;
+
+ if (IsValid())
+ {
+ ObjectFile *objfile = m_opaque_sp->GetObjectFile();
+ if (objfile)
+ {
+ SectionList *section_list = objfile->GetSectionList();
+ if (section_list)
+ {
+ ConstString const_sect_name(sect_name);
+ SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
+ if (section_sp)
+ {
+ sb_section.SetSection(section_sp.get());
+ }
+ }
+ }
+ }
+ return sb_section;
+}
+
diff --git a/lldb/source/API/SBSection.cpp b/lldb/source/API/SBSection.cpp
new file mode 100644
index 0000000..6d66596
--- /dev/null
+++ b/lldb/source/API/SBSection.cpp
@@ -0,0 +1,324 @@
+//===-- 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/Section.h"
+#include "lldb/Core/Module.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();
+}
+
+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 (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)
+{
+ if (m_opaque_ap.get())
+ {
+ description.Printf ("SBSection");
+ }
+ else
+ {
+ description.Printf ("No value");
+ }
+
+ return true;
+}
+
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index e17f258..74580c4 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -867,6 +867,52 @@
}
+lldb::SBModule
+SBTarget::AddModule (const char *path,
+ const char *triple,
+ const char *uuid_cstr)
+{
+ lldb::SBModule sb_module;
+ if (m_opaque_sp)
+ {
+ FileSpec module_file_spec;
+ UUID module_uuid;
+ ArchSpec module_arch;
+
+ if (path)
+ module_file_spec.SetFile(path, false);
+
+ if (uuid_cstr)
+ module_uuid.SetfromCString(uuid_cstr);
+
+ if (triple)
+ module_arch.SetTriple (triple, m_opaque_sp->GetPlatform ().get());
+
+ sb_module.SetModule(m_opaque_sp->GetSharedModule (module_file_spec,
+ module_arch,
+ uuid_cstr ? &module_uuid : NULL));
+ }
+ return sb_module;
+}
+
+bool
+SBTarget::AddModule (lldb::SBModule &module)
+{
+ if (m_opaque_sp)
+ {
+ m_opaque_sp->GetImages().AppendIfNeeded (module.get_sp());
+ return true;
+ }
+ return false;
+}
+
+lldb::SBModule
+AddModule (const char *path,
+ const char *triple,
+ const char *uuid);
+
+
+
uint32_t
SBTarget::GetNumModules () const
{
@@ -930,6 +976,14 @@
return sb_module;
}
+bool
+SBTarget::RemoveModule (lldb::SBModule module)
+{
+ if (m_opaque_sp)
+ return m_opaque_sp->GetImages().Remove(module.get_sp());
+ return false;
+}
+
SBBroadcaster
SBTarget::GetBroadcaster () const
@@ -1079,3 +1133,149 @@
SBSourceManager source_manager (*this);
return source_manager;
}
+
+
+SBError
+SBTarget::SetSectionLoadAddress (lldb::SBSection section,
+ lldb::addr_t section_base_addr)
+{
+ SBError sb_error;
+
+ if (IsValid())
+ {
+ if (!section.IsValid())
+ {
+ sb_error.SetErrorStringWithFormat ("invalid section");
+ }
+ else
+ {
+ m_opaque_sp->GetSectionLoadList().SetSectionLoadAddress (section.GetSection(), section_base_addr);
+ }
+ }
+ else
+ {
+ sb_error.SetErrorStringWithFormat ("invalid target");
+ }
+ return sb_error;
+}
+
+SBError
+SBTarget::ClearSectionLoadAddress (lldb::SBSection section)
+{
+ SBError sb_error;
+
+ if (IsValid())
+ {
+ if (!section.IsValid())
+ {
+ sb_error.SetErrorStringWithFormat ("invalid section");
+ }
+ else
+ {
+ m_opaque_sp->GetSectionLoadList().SetSectionUnloaded (section.GetSection());
+ }
+ }
+ else
+ {
+ sb_error.SetErrorStringWithFormat ("invalid target");
+ }
+ return sb_error;
+}
+
+SBError
+SBTarget::SetModuleLoadAddress (lldb::SBModule module, int64_t slide_offset)
+{
+ SBError sb_error;
+
+ char path[PATH_MAX];
+ if (IsValid())
+ {
+ if (!module.IsValid())
+ {
+ sb_error.SetErrorStringWithFormat ("invalid module");
+ }
+ else
+ {
+ ObjectFile *objfile = module->GetObjectFile();
+ if (objfile)
+ {
+ SectionList *section_list = objfile->GetSectionList();
+ if (section_list)
+ {
+ const size_t num_sections = section_list->GetSize();
+ for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
+ {
+ SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
+ if (section_sp)
+ m_opaque_sp->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), section_sp->GetFileAddress() + slide_offset);
+ }
+ }
+ else
+ {
+ module->GetFileSpec().GetPath (path, sizeof(path));
+ sb_error.SetErrorStringWithFormat ("no sections in object file '%s'", path);
+ }
+ }
+ else
+ {
+ module->GetFileSpec().GetPath (path, sizeof(path));
+ sb_error.SetErrorStringWithFormat ("no object file for module '%s'", path);
+ }
+ }
+ }
+ else
+ {
+ sb_error.SetErrorStringWithFormat ("invalid target");
+ }
+ return sb_error;
+}
+
+SBError
+SBTarget::ClearModuleLoadAddress (lldb::SBModule module)
+{
+ SBError sb_error;
+
+ char path[PATH_MAX];
+ if (IsValid())
+ {
+ if (!module.IsValid())
+ {
+ sb_error.SetErrorStringWithFormat ("invalid module");
+ }
+ else
+ {
+ ObjectFile *objfile = module->GetObjectFile();
+ if (objfile)
+ {
+ SectionList *section_list = objfile->GetSectionList();
+ if (section_list)
+ {
+ const size_t num_sections = section_list->GetSize();
+ for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
+ {
+ SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
+ if (section_sp)
+ m_opaque_sp->GetSectionLoadList().SetSectionUnloaded (section_sp.get());
+ }
+ }
+ else
+ {
+ module->GetFileSpec().GetPath (path, sizeof(path));
+ sb_error.SetErrorStringWithFormat ("no sections in object file '%s'", path);
+ }
+ }
+ else
+ {
+ module->GetFileSpec().GetPath (path, sizeof(path));
+ sb_error.SetErrorStringWithFormat ("no object file for module '%s'", path);
+ }
+ }
+ }
+ else
+ {
+ sb_error.SetErrorStringWithFormat ("invalid target");
+ }
+ return sb_error;
+}
+
+
diff --git a/lldb/source/Commands/CommandObjectProcess.cpp b/lldb/source/Commands/CommandObjectProcess.cpp
index 980f9d2..72aba1c 100644
--- a/lldb/source/Commands/CommandObjectProcess.cpp
+++ b/lldb/source/Commands/CommandObjectProcess.cpp
@@ -585,13 +585,13 @@
// If there isn't a current target create one.
TargetSP new_target_sp;
FileSpec emptyFileSpec;
- ArchSpec emptyArchSpec;
Error error;
error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
emptyFileSpec,
- emptyArchSpec,
+ NULL,
false,
+ NULL, // No platform options
new_target_sp);
target = new_target_sp.get();
if (target == NULL || error.Fail())
@@ -1041,12 +1041,12 @@
{
// If there isn't a current target create one.
FileSpec emptyFileSpec;
- ArchSpec emptyArchSpec;
error = m_interpreter.GetDebugger().GetTargetList().CreateTarget (m_interpreter.GetDebugger(),
emptyFileSpec,
- emptyArchSpec,
+ NULL,
false,
+ NULL, // No platform options
target_sp);
if (!target_sp || error.Fail())
{
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index eb2ef07..4ff540d 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -186,48 +186,18 @@
const char *file_path = command.GetArgumentAtIndex(0);
Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
FileSpec file_spec (file_path, true);
-
- bool select = true;
- PlatformSP platform_sp;
-
- Error error;
-
- if (m_platform_options.PlatformWasSpecified ())
- {
- platform_sp = m_platform_options.CreatePlatformWithOptions(m_interpreter, select, error);
- if (!platform_sp)
- {
- result.AppendError(error.AsCString());
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
- ArchSpec file_arch;
-
- const char *arch_cstr = m_arch_option.GetArchitectureName();
- if (arch_cstr)
- {
- if (!platform_sp)
- platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
- if (!m_arch_option.GetArchitecture(platform_sp.get(), file_arch))
- {
- result.AppendErrorWithFormat("invalid architecture '%s'\n", arch_cstr);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
- }
-
- if (! file_spec.Exists() && !file_spec.ResolveExecutableLocation())
- {
- result.AppendErrorWithFormat ("File '%s' does not exist.\n", file_path);
- result.SetStatus (eReturnStatusFailed);
- return false;
- }
-
+
TargetSP target_sp;
Debugger &debugger = m_interpreter.GetDebugger();
- error = debugger.GetTargetList().CreateTarget (debugger, file_spec, file_arch, true, target_sp);
-
+ const char *arch_cstr = m_arch_option.GetArchitectureName();
+ const bool get_dependent_files = true;
+ Error error (debugger.GetTargetList().CreateTarget (debugger,
+ file_spec,
+ arch_cstr,
+ get_dependent_files,
+ &m_platform_options,
+ target_sp));
+
if (target_sp)
{
debugger.GetTargetList().SetSelectedTarget(target_sp.get());
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index ebbbcd3..4ee475b 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -61,7 +61,7 @@
}
void
-ModuleList::Append (ModuleSP &module_sp)
+ModuleList::Append (const ModuleSP &module_sp)
{
if (module_sp)
{
@@ -71,7 +71,7 @@
}
bool
-ModuleList::AppendIfNeeded (ModuleSP &module_sp)
+ModuleList::AppendIfNeeded (const ModuleSP &module_sp)
{
if (module_sp)
{
@@ -90,7 +90,7 @@
}
bool
-ModuleList::Remove (ModuleSP &module_sp)
+ModuleList::Remove (const ModuleSP &module_sp)
{
if (module_sp)
{
diff --git a/lldb/source/Interpreter/OptionGroupPlatform.cpp b/lldb/source/Interpreter/OptionGroupPlatform.cpp
index 910a6e9..e65ee8c 100644
--- a/lldb/source/Interpreter/OptionGroupPlatform.cpp
+++ b/lldb/source/Interpreter/OptionGroupPlatform.cpp
@@ -21,7 +21,7 @@
using namespace lldb_private;
PlatformSP
-OptionGroupPlatform::CreatePlatformWithOptions (CommandInterpreter &interpreter, bool make_selected, Error& error)
+OptionGroupPlatform::CreatePlatformWithOptions (CommandInterpreter &interpreter, bool make_selected, Error& error) const
{
PlatformSP platform_sp;
if (!m_platform_name.empty())
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index d33d16d..93be923 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -423,12 +423,12 @@
{
TargetSP new_target_sp;
FileSpec emptyFileSpec;
- ArchSpec emptyArchSpec;
error = debugger.GetTargetList().CreateTarget (debugger,
emptyFileSpec,
- emptyArchSpec,
+ NULL,
false,
+ NULL,
new_target_sp);
target = new_target_sp.get();
}
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 66534c3..01c0fb8 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -360,12 +360,12 @@
{
TargetSP new_target_sp;
FileSpec emptyFileSpec;
- ArchSpec emptyArchSpec;
error = debugger.GetTargetList().CreateTarget (debugger,
emptyFileSpec,
- emptyArchSpec,
+ NULL,
false,
+ NULL,
new_target_sp);
target = new_target_sp.get();
}
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 299f4ae..60831ba 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -782,7 +782,7 @@
}
}
- if (executable_objfile)
+ if (executable_objfile && get_dependent_files)
{
executable_objfile->GetDependentModules(dependent_files);
for (uint32_t i=0; i<dependent_files.GetSize(); i++)
diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp
index e8a8ba9..d30cfa1 100644
--- a/lldb/source/Target/TargetList.cpp
+++ b/lldb/source/Target/TargetList.cpp
@@ -17,6 +17,7 @@
#include "lldb/Core/State.h"
#include "lldb/Core/Timer.h"
#include "lldb/Host/Host.h"
+#include "lldb/Interpreter/OptionGroupPlatform.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/TargetList.h"
@@ -46,12 +47,59 @@
}
Error
+TargetList::CreateTarget (Debugger &debugger,
+ const FileSpec& file,
+ const char *triple_cstr,
+ bool get_dependent_files,
+ const OptionGroupPlatform *platform_options,
+ TargetSP &target_sp)
+{
+ Error error;
+ PlatformSP platform_sp;
+ if (platform_options)
+ {
+ if (platform_options->PlatformWasSpecified ())
+ {
+ const bool select_platform = true;
+ platform_sp = platform_options->CreatePlatformWithOptions (debugger.GetCommandInterpreter(),
+ select_platform,
+ error);
+ if (!platform_sp)
+ return error;
+ }
+ }
+
+ if (!platform_sp)
+ platform_sp = debugger.GetPlatformList().GetSelectedPlatform ();
+
+ ArchSpec arch;
+
+ if (triple_cstr)
+ {
+ arch.SetTriple(triple_cstr, platform_sp.get());
+ if (!arch.IsValid())
+ {
+ error.SetErrorStringWithFormat("invalid triple '%s'\n", triple_cstr);
+ return error;
+ }
+ }
+ error = TargetList::CreateTarget (debugger,
+ file,
+ arch,
+ get_dependent_files,
+ platform_sp,
+ target_sp);
+ return error;
+}
+
+Error
TargetList::CreateTarget
(
Debugger &debugger,
const FileSpec& file,
const ArchSpec& arch,
bool get_dependent_files,
+ const PlatformSP &platform_sp,
TargetSP &target_sp
)
{
@@ -62,7 +110,6 @@
arch.GetArchitectureName());
Error error;
- PlatformSP platform_sp (debugger.GetPlatformList().GetSelectedPlatform ());
if (file)
{