summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/ModuleList.h1
-rw-r--r--lldb/include/lldb/Core/UserSettingsController.h6
-rw-r--r--lldb/include/lldb/Host/Host.h22
-rw-r--r--lldb/include/lldb/Symbol/ObjectFile.h11
-rw-r--r--lldb/include/lldb/Target/Platform.h4
-rw-r--r--lldb/include/lldb/Target/Process.h24
-rw-r--r--lldb/include/lldb/Target/Target.h17
-rw-r--r--lldb/source/API/SBModule.cpp9
-rw-r--r--lldb/source/Commands/CommandObjectTarget.cpp38
-rw-r--r--lldb/source/Core/ModuleList.cpp1
-rw-r--r--lldb/source/Host/common/Host.cpp8
-rw-r--r--lldb/source/Host/macosx/Host.mm25
-rw-r--r--lldb/source/Host/macosx/Symbols.cpp8
-rw-r--r--lldb/source/Host/macosx/cfcpp/CFCBundle.cpp16
-rw-r--r--lldb/source/Host/macosx/cfcpp/CFCBundle.h3
-rw-r--r--lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp580
-rw-r--r--lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h165
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp46
-rw-r--r--lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp287
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp102
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h14
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp47
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h10
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp10
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h6
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp3
-rw-r--r--lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h3
-rw-r--r--lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp200
-rw-r--r--lldb/source/Plugins/Process/mach-core/ProcessMachCore.h12
-rw-r--r--lldb/source/Target/Platform.cpp7
-rw-r--r--lldb/source/Target/Process.cpp42
-rw-r--r--lldb/source/Target/SectionLoadList.cpp17
-rw-r--r--lldb/source/Target/Target.cpp91
-rw-r--r--lldb/source/Target/TargetList.cpp17
34 files changed, 1088 insertions, 764 deletions
diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h
index 8a30b56b100..e54e58b61bf 100644
--- a/lldb/include/lldb/Core/ModuleList.h
+++ b/lldb/include/lldb/Core/ModuleList.h
@@ -416,6 +416,7 @@ public:
const ConstString *object_name,
off_t object_offset,
lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
lldb::ModuleSP *old_module_sp_ptr,
bool *did_create_ptr,
bool always_create = false);
diff --git a/lldb/include/lldb/Core/UserSettingsController.h b/lldb/include/lldb/Core/UserSettingsController.h
index 370bfad516a..a99457a775e 100644
--- a/lldb/include/lldb/Core/UserSettingsController.h
+++ b/lldb/include/lldb/Core/UserSettingsController.h
@@ -262,6 +262,12 @@ public:
FinalizeSettingsController (lldb::UserSettingsControllerSP &controller_sp);
+ lldb::InstanceSettingsSP
+ GetDefaultInstanceSettings ()
+ {
+ return m_default_settings;
+ }
+
protected:
// -------------------------------------------------------------------------
diff --git a/lldb/include/lldb/Host/Host.h b/lldb/include/lldb/Host/Host.h
index d80fab4beea..83691849f2d 100644
--- a/lldb/include/lldb/Host/Host.h
+++ b/lldb/include/lldb/Host/Host.h
@@ -298,6 +298,28 @@ public:
GetModuleFileSpecForHostAddress (const void *host_addr);
+
+ //------------------------------------------------------------------
+ /// If you have an executable that is in a bundle and want to get
+ /// back to the bundle directory from the path itself, this
+ /// function will change a path to a file within a bundle to the
+ /// bundle directory itself.
+ ///
+ /// @param[in] file
+ /// A file spec that might point to a file in a bundle.
+ ///
+ /// @param[out] bundle_directory
+ /// An object will be filled in with the bundle directory for
+ /// the bundle when \b true is returned. Otherwise \a file is
+ /// left untouched and \b false is returned.
+ ///
+ /// @return
+ /// \b true if \a file was resolved in \a bundle_directory,
+ /// \b false otherwise.
+ //------------------------------------------------------------------
+ static bool
+ GetBundleDirectory (const FileSpec &file, FileSpec &bundle_directory);
+
//------------------------------------------------------------------
/// When executable files may live within a directory, where the
/// directory represents an executable bundle (like the MacOSX
diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h
index 094285a65ea..bb65be70efb 100644
--- a/lldb/include/lldb/Symbol/ObjectFile.h
+++ b/lldb/include/lldb/Symbol/ObjectFile.h
@@ -505,6 +505,12 @@ public:
size_t
MemoryMapSectionData (const Section *section,
DataExtractor& section_data) const;
+
+ bool
+ IsInMemory () const
+ {
+ return m_memory_addr != LLDB_INVALID_ADDRESS;
+ }
protected:
//------------------------------------------------------------------
// Member variables.
@@ -519,11 +525,6 @@ protected:
lldb::ProcessWP m_process_wp;
const lldb::addr_t m_memory_addr;
- bool
- IsInMemory () const
- {
- return m_memory_addr != LLDB_INVALID_ADDRESS;
- }
//------------------------------------------------------------------
/// Sets the architecture for a module. At present the architecture
/// can only be set if it is invalid. It is not allowed to switch from
diff --git a/lldb/include/lldb/Target/Platform.h b/lldb/include/lldb/Target/Platform.h
index 5cb57ea7361..ac025c418a3 100644
--- a/lldb/include/lldb/Target/Platform.h
+++ b/lldb/include/lldb/Target/Platform.h
@@ -108,7 +108,8 @@ namespace lldb_private {
virtual Error
ResolveExecutable (const FileSpec &exe_file,
const ArchSpec &arch,
- lldb::ModuleSP &module_sp);
+ lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr);
//------------------------------------------------------------------
/// Resolves the FileSpec to a (possibly) remote path. Remote
@@ -237,6 +238,7 @@ namespace lldb_private {
const ConstString *object_name_ptr,
off_t object_offset,
lldb::ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
lldb::ModuleSP *old_module_sp_ptr,
bool *did_create_ptr);
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 39857610850..f4a4f8e3536 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -1601,6 +1601,18 @@ public:
error.SetErrorStringWithFormat("error: %s does not support loading core files.", GetShortPluginName());
return error;
}
+
+ //------------------------------------------------------------------
+ /// Get the dynamic loader plug-in for this process.
+ ///
+ /// The default action is to let the DynamicLoader plug-ins check
+ /// the main executable and the DynamicLoader will select itself
+ /// automatically. Subclasses can override this if inspecting the
+ /// executable is not desired, or if Process subclasses can only
+ /// use a specific DynamicLoader plug-in.
+ //------------------------------------------------------------------
+ virtual DynamicLoader *
+ GetDynamicLoader ();
//------------------------------------------------------------------
/// Attach to an existing process using the process attach info.
@@ -2400,7 +2412,7 @@ public:
/// vm_addr, \a buf, and \a size updated appropriately. Zero is
/// returned to indicate an error.
//------------------------------------------------------------------
- size_t
+ virtual size_t
ReadMemory (lldb::addr_t vm_addr,
void *buf,
size_t size,
@@ -2631,7 +2643,9 @@ public:
lldb::ModuleSP
ReadModuleFromMemory (const FileSpec& file_spec,
- lldb::addr_t header_addr);
+ lldb::addr_t header_addr,
+ bool add_image_to_target,
+ bool load_sections_in_target);
//------------------------------------------------------------------
/// Attempt to get the attributes for a region of memory in the process.
@@ -2976,12 +2990,6 @@ public:
const lldb::ABISP &
GetABI ();
- DynamicLoader *
- GetDynamicLoader ()
- {
- return m_dyld_ap.get();
- }
-
OperatingSystem *
GetOperatingSystem ()
{
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 5e51e4151ea..26e3df68e0c 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -87,6 +87,19 @@ public:
return m_source_map;
}
+ FileSpecList &
+ GetExecutableSearchPaths ()
+ {
+ return m_exe_search_paths;
+ }
+
+ const FileSpecList &
+ GetExecutableSearchPaths () const
+ {
+ return m_exe_search_paths;
+ }
+
+
uint32_t
GetMaximumNumberOfChildrenToDisplay()
{
@@ -225,6 +238,7 @@ protected:
int m_prefer_dynamic_value;
OptionValueBoolean m_skip_prologue;
PathMappingList m_source_map;
+ FileSpecList m_exe_search_paths;
uint32_t m_max_children_display;
uint32_t m_max_strlen_length;
OptionValueBoolean m_breakpoints_use_platform_avoid;
@@ -273,6 +287,9 @@ public:
static lldb::UserSettingsControllerSP &
GetSettingsController ();
+ static FileSpecList
+ GetDefaultExecutableSearchPaths ();
+
static ArchSpec
GetDefaultArchitecture ();
diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp
index a1ec5574b74..09f354e2710 100644
--- a/lldb/source/API/SBModule.cpp
+++ b/lldb/source/API/SBModule.cpp
@@ -46,7 +46,14 @@ SBModule::SBModule (lldb::SBProcess &process, lldb::addr_t header_addr) :
{
ProcessSP process_sp (process.GetSP());
if (process_sp)
- m_opaque_sp = process_sp->ReadModuleFromMemory (FileSpec(), header_addr);
+ {
+ const bool add_image_to_target = true;
+ const bool load_image_sections_in_target = true;
+ m_opaque_sp = process_sp->ReadModuleFromMemory (FileSpec(),
+ header_addr,
+ add_image_to_target,
+ load_image_sections_in_target);
+ }
}
const SBModule &
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 6ea4486b24c..5d8cb5be468 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -211,31 +211,43 @@ public:
debugger.GetTargetList().SetSelectedTarget(target_sp.get());
if (core_file)
{
- ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file));
char core_path[PATH_MAX];
core_file.GetPath(core_path, sizeof(core_path));
-
- if (process_sp)
+ if (core_file.Exists())
{
- // Seems wierd that we Launch a core file, but that is
- // what we do!
- error = process_sp->LoadCore();
+ FileSpec core_file_dir;
+ core_file_dir.GetDirectory() = core_file.GetDirectory();
+ target_sp->GetExecutableSearchPaths ().Append (core_file_dir);
- if (error.Fail())
+ ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file));
+
+ if (process_sp)
{
- result.AppendError(error.AsCString("can't find plug-in for core file"));
- result.SetStatus (eReturnStatusFailed);
- return false;
+ // Seems wierd that we Launch a core file, but that is
+ // what we do!
+ error = process_sp->LoadCore();
+
+ if (error.Fail())
+ {
+ result.AppendError(error.AsCString("can't find plug-in for core file"));
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ else
+ {
+ result.AppendMessageWithFormat ("Core file '%s' (%s) was loaded.\n", core_path, target_sp->GetArchitecture().GetArchitectureName());
+ result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ }
}
else
{
- result.AppendMessageWithFormat ("Core file '%s' (%s) was loaded.\n", core_path, target_sp->GetArchitecture().GetArchitectureName());
- result.SetStatus (eReturnStatusSuccessFinishNoResult);
+ result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path);
+ result.SetStatus (eReturnStatusFailed);
}
}
else
{
- result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path);
+ result.AppendErrorWithFormat ("Core file '%s' does not exist\n", core_path);
result.SetStatus (eReturnStatusFailed);
}
}
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index 360c868cb5a..f1715758e59 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -729,6 +729,7 @@ ModuleList::GetSharedModule
const ConstString *object_name_ptr,
off_t object_offset,
ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
ModuleSP *old_module_sp_ptr,
bool *did_create_ptr,
bool always_create
diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp
index d230815df9a..5f0362bcae4 100644
--- a/lldb/source/Host/common/Host.cpp
+++ b/lldb/source/Host/common/Host.cpp
@@ -754,6 +754,14 @@ Host::GetModuleFileSpecForHostAddress (const void *host_addr)
}
#if !defined (__APPLE__) // see Host.mm
+
+bool
+Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle)
+{
+ bundle.Clear();
+ return false;
+}
+
bool
Host::ResolveExecutableInBundle (FileSpec &file)
{
diff --git a/lldb/source/Host/macosx/Host.mm b/lldb/source/Host/macosx/Host.mm
index ac5f5f6dead..fe3c450e167 100644
--- a/lldb/source/Host/macosx/Host.mm
+++ b/lldb/source/Host/macosx/Host.mm
@@ -137,6 +137,28 @@ Host::ThreadCreated (const char *thread_name)
}
}
+bool
+Host::GetBundleDirectory (const FileSpec &file, FileSpec &bundle_directory)
+{
+#if defined (__APPLE__)
+ if (file.GetFileType () == FileSpec::eFileTypeDirectory)
+ {
+ char path[PATH_MAX];
+ if (file.GetPath(path, sizeof(path)))
+ {
+ CFCBundle bundle (path);
+ if (bundle.GetPath (path, sizeof(path)))
+ {
+ bundle_directory.SetFile (path, false);
+ return true;
+ }
+ }
+ }
+#endif
+ bundle_directory.Clear();
+ return false;
+}
+
bool
Host::ResolveExecutableInBundle (FileSpec &file)
@@ -1215,7 +1237,8 @@ Host::LaunchProcess (ProcessLaunchInfo &launch_info)
lldb::ModuleSP exe_module_sp;
error = host_platform_sp->ResolveExecutable (exe_spec,
arch_spec,
- exe_module_sp);
+ exe_module_sp,
+ NULL);
if (error.Fail())
return error;
diff --git a/lldb/source/Host/macosx/Symbols.cpp b/lldb/source/Host/macosx/Symbols.cpp
index 820126674bb..50161def0db 100644
--- a/lldb/source/Host/macosx/Symbols.cpp
+++ b/lldb/source/Host/macosx/Symbols.cpp
@@ -367,7 +367,8 @@ LocateMacOSXFilesUsingDebugSymbols
if (out_exec_fspec)
{
- CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get()));;
+ CFCReleaser<CFDictionaryRef> dict(::DBGCopyDSYMPropertyLists (dsym_url.get()));
+ bool success = false;
if (dict.get())
{
char uuid_cstr_buf[64];
@@ -381,10 +382,13 @@ LocateMacOSXFilesUsingDebugSymbols
{
++items_found;
out_exec_fspec->SetFile(path, path[0] == '~');
+ if (out_exec_fspec->Exists())
+ success = true;
}
}
}
- else
+
+ if (!success)
{
// No dictionary, check near the dSYM bundle for an executable that matches...
if (::CFURLGetFileSystemRepresentation (dsym_url.get(), true, (UInt8*)path, sizeof(path)-1))
diff --git a/lldb/source/Host/macosx/cfcpp/CFCBundle.cpp b/lldb/source/Host/macosx/cfcpp/CFCBundle.cpp
index 6e68af5c597..71b07499366 100644
--- a/lldb/source/Host/macosx/cfcpp/CFCBundle.cpp
+++ b/lldb/source/Host/macosx/cfcpp/CFCBundle.cpp
@@ -55,6 +55,22 @@ CFCBundle::SetPath (const char *path)
return get() != NULL;
}
+bool
+CFCBundle::GetPath (char *dst, size_t dst_len)
+{
+ CFBundleRef bundle = get();
+ if (bundle)
+ {
+ CFCReleaser<CFURLRef> bundle_url (CFBundleCopyBundleURL (bundle));
+ if (bundle_url.get())
+ {
+ Boolean resolveAgainstBase = 0;
+ return ::CFURLGetFileSystemRepresentation (bundle_url.get(), resolveAgainstBase, (UInt8 *)dst, dst_len) != 0;
+ }
+ }
+ return false;
+}
+
CFStringRef
CFCBundle::GetIdentifier () const
{
diff --git a/lldb/source/Host/macosx/cfcpp/CFCBundle.h b/lldb/source/Host/macosx/cfcpp/CFCBundle.h
index c07a48cb055..1cd1b681af8 100644
--- a/lldb/source/Host/macosx/cfcpp/CFCBundle.h
+++ b/lldb/source/Host/macosx/cfcpp/CFCBundle.h
@@ -34,6 +34,9 @@ public:
GetValueForInfoDictionaryKey(CFStringRef key) const;
bool
+ GetPath (char *dst, size_t dst_len);
+
+ bool
SetPath (const char *path);
private:
diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index b82d6869edf..c719654998c 100644
--- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -154,246 +154,178 @@ DynamicLoaderDarwinKernel::Clear (bool clear_process)
}
-//----------------------------------------------------------------------
-// Load the kernel module and initialize the "m_kernel" member. Return
-// true _only_ if the kernel is loaded the first time through (subsequent
-// calls to this function should return false after the kernel has been
-// already loaded).
-//----------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded()
-{
- if (!m_kext_summary_header_ptr_addr.IsValid())
- {
- m_kernel.Clear(false);
- m_kernel.module_sp = m_process->GetTarget().GetExecutableModule();
- if (m_kernel.module_sp)
- {
- static ConstString mach_header_name ("_mh_execute_header");
- static ConstString kext_summary_symbol ("gLoadedKextSummaries");
- const Symbol *symbol = NULL;
- symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
- if (symbol)
- m_kext_summary_header_ptr_addr = symbol->GetValue();
-
- symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (mach_header_name, eSymbolTypeAbsolute);
- if (symbol)
- {
- // The "_mh_execute_header" symbol is absolute and not a section based
- // symbol that will have a valid address, so we need to resolve it...
- m_process->GetTarget().GetImages().ResolveFileAddress (symbol->GetValue().GetFileAddress(), m_kernel.so_address);
- DataExtractor data; // Load command data
- if (ReadMachHeader (m_kernel, &data))
- {
- if (m_kernel.header.filetype == llvm::MachO::HeaderFileTypeExecutable)
- {
- if (ParseLoadCommands (data, m_kernel))
- UpdateImageLoadAddress (m_kernel);
-
- // Update all image infos
- ReadAllKextSummaries ();
- }
- }
- else
- {
- m_kernel.Clear(false);
- }
- }
- }
- }
-}
-
bool
-DynamicLoaderDarwinKernel::FindTargetModule (OSKextLoadedKextSummary &image_info, bool can_create, bool *did_create_ptr)
+DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process)
{
- if (did_create_ptr)
- *did_create_ptr = false;
-
- const bool image_info_uuid_is_valid = image_info.uuid.IsValid();
+ if (IsLoaded())
+ return true;
- if (image_info.module_sp)
- {
- if (image_info_uuid_is_valid)
- {
- if (image_info.module_sp->GetUUID() == image_info.uuid)
- return true;
- else
- image_info.module_sp.reset();
- }
- else
- return true;
- }
+ bool uuid_is_valid = uuid.IsValid();
- ModuleList &target_images = m_process->GetTarget().GetImages();
- if (image_info_uuid_is_valid)
- image_info.module_sp = target_images.FindModule(image_info.uuid);
-
- if (image_info.module_sp)
- return true;
-
- ArchSpec arch (image_info.GetArchitecture ());
- if (can_create)
+ Target &target = process->GetTarget();
+ ModuleSP memory_module_sp;
+ // Use the memory module as the module if we have one...
+ if (address != LLDB_INVALID_ADDRESS)
{
- if (image_info_uuid_is_valid)
+ FileSpec file_spec;
+ if (module_sp)
+ file_spec = module_sp->GetFileSpec();
+ else
+ file_spec.SetFile (name, false);
+
+ memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false);
+ if (memory_module_sp && !uuid_is_valid)
{
- image_info.module_sp = m_process->GetTarget().GetSharedModule (FileSpec(),
- arch,
- &image_info.uuid);
- if (did_create_ptr)
- *did_create_ptr = image_info.module_sp;
+ uuid = memory_module_sp->GetUUID();
+ uuid_is_valid = uuid.IsValid();
}
}
- return image_info.module_sp;
-}
-bool
-DynamicLoaderDarwinKernel::UpdateCommPageLoadAddress(Module *module)
-{
- bool changed = false;
- if (module)
+ if (!module_sp)
{
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file)
+ bool uuid_is_valid = uuid.IsValid();
+ if (uuid_is_valid)
{
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- uint32_t num_sections = section_list->GetSize();
- for (uint32_t i=0; i<num_sections; ++i)
- {
- Section* section = section_list->GetSectionAtIndex (i).get();
- if (section)
- {
- const addr_t new_section_load_addr = section->GetFileAddress ();
- const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section);
- if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
- old_section_load_addr != new_section_load_addr)
- {
- if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress ()))
- changed = true;
- }
- }
- }
- }
+ ModuleList &target_images = target.GetImages();
+ module_sp = target_images.FindModule(uuid);
+
+ if (!module_sp)
+ module_sp = target.GetSharedModule (FileSpec(), target.GetArchitecture(), &uuid);
}
}
- return changed;
-}
+
-//----------------------------------------------------------------------
-// Update the load addresses for all segments in MODULE using the
-// updated INFO that is passed in.
-//----------------------------------------------------------------------
-bool
-DynamicLoaderDarwinKernel::UpdateImageLoadAddress (OSKextLoadedKextSummary& info)
-{
- Module *module = info.module_sp.get();
- bool changed = false;
- if (module)
+ if (memory_module_sp)
{
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file)
+ // Someone already supplied a file, make sure it is the right one.
+ if (module_sp)
{
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
+ if (module_sp->GetUUID() == memory_module_sp->GetUUID())
{
- // We now know the slide amount, so go through all sections
- // and update the load addresses with the correct values.
- uint32_t num_segments = info.segments.size();
- for (uint32_t i=0; i<num_segments; ++i)
+ ObjectFile *ondisk_object_file = module_sp->GetObjectFile();
+ ObjectFile *memory_object_file = memory_module_sp->GetObjectFile();
+ if (memory_object_file && ondisk_object_file)
{
- const addr_t new_section_load_addr = info.segments[i].vmaddr;
- if (section_list->FindSectionByName(info.segments[i].name))
+ SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
+ SectionList *memory_section_list = memory_object_file->GetSectionList ();
+ if (memory_section_list && ondisk_section_list)
{
- SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
- if (section_sp)
+ const uint32_t num_sections = ondisk_section_list->GetSize();
+ // There may be CTF sections in the memory image so we can't
+ // always just compare the number of sections (which are actually
+ // segments in mach-o parlance)
+ uint32_t sect_idx = 0;
+ const Section *memory_section;
+ const Section *ondisk_section;
+ // Always use the number of sections from the on disk file
+ // in case there are extra sections added to the memory image.
+ for (sect_idx=0; sect_idx<num_sections; ++sect_idx)
{
- const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get());
- if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
- old_section_load_addr != new_section_load_addr)
+ memory_section = memory_section_list->GetSectionAtIndex(sect_idx).get();
+ ondisk_section = ondisk_section_list->GetSectionAtIndex(sect_idx).get();
+ if (memory_section->GetName() != ondisk_section->GetName())
{
- if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr))
- changed = true;
+ // Section count was the same, but the sections themselves do not match
+ module_sp.reset();
+ break;
}
}
- else
- {
- Host::SystemLog (Host::eSystemLogWarning, "warning: unable to find and load segment named '%s' at 0x%llx in '%s/%s' in macosx dynamic loader plug-in.\n",
- info.segments[i].name.AsCString("<invalid>"),
- (uint64_t)new_section_load_addr,
- image_object_file->GetFileSpec().GetDirectory().AsCString(),
- image_object_file->GetFileSpec().GetFilename().AsCString());
- }
- }
- else
- {
- // The segment name is empty which means this is a .o file.
- // Object files in LLDB end up getting reorganized so that
- // the segment name that is in the section is promoted into
- // an actual segment, so we just need to go through all sections
- // and slide them by a single amount.
-
- uint32_t num_sections = section_list->GetSize();
- for (uint32_t i=0; i<num_sections; ++i)
+ if (module_sp)
{
- Section* section = section_list->GetSectionAtIndex (i).get();
- if (section)
+ for (sect_idx=0; sect_idx<num_sections; ++sect_idx)
{
- if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress() + new_section_load_addr))
- changed = true;
+ memory_section = memory_section_list->GetSectionAtIndex(sect_idx).get();
+ ondisk_section = ondisk_section_list->GetSectionAtIndex(sect_idx).get();
+ target.GetSectionLoadList().SetSectionLoadAddress (ondisk_section, memory_section->GetFileAddress());
}
+ if (num_sections > 0)
+ load_process_stop_id = process->GetStopID();
}
}
+ else
+ module_sp.reset(); // One or both section lists
}
+ else
+ module_sp.reset(); // One or both object files missing
}
+ else
+ module_sp.reset(); // UUID mismatch
+ }
+
+ // Use the memory module as the module if we didn't like the file
+ // module we either found or were supplied with
+ if (!module_sp)
+ {
+ module_sp = memory_module_sp;
+ // Load the memory image in the target as all adresses are already correct
+ bool changed = false;
+ target.GetImages().Append (memory_module_sp);
+ if (module_sp->SetLoadAddress (target, 0, changed))
+ load_process_stop_id = process->GetStopID();
}
}
- return changed;
+ bool is_loaded = IsLoaded();
+
+ if (so_address.IsValid())
+ {
+ if (is_loaded)
+ so_address.SetLoadAddress (address, &target);
+ else
+ target.GetImages().ResolveFileAddress (address, so_address);
+
+ }
+ return is_loaded;
}
//----------------------------------------------------------------------
-// Update the load addresses for all segments in MODULE using the
-// updated INFO that is passed in.
+// Load the kernel module and initialize the "m_kernel" member. Return
+// true _only_ if the kernel is loaded the first time through (subsequent
+// calls to this function should return false after the kernel has been
+// already loaded).
//----------------------------------------------------------------------
-bool
-DynamicLoaderDarwinKernel::UnloadImageLoadAddress (OSKextLoadedKextSummary& info)
+void
+DynamicLoaderDarwinKernel::LoadKernelModuleIfNeeded()
{
- Module *module = info.module_sp.get();
- bool changed = false;
- if (module)
+ if (!m_kext_summary_header_ptr_addr.IsValid())
{
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file)
+ m_kernel.Clear(false);
+ m_kernel.module_sp = m_process->GetTarget().GetExecutableModule();
+ strncpy(m_kernel.name, "mach_kernel", sizeof(m_kernel.name));
+ if (m_kernel.address == LLDB_INVALID_ADDRESS)
{
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
+ m_kernel.address = m_process->GetImageInfoAddress ();
+ if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp)
{
- uint32_t num_segments = info.segments.size();
- for (uint32_t i=0; i<num_segments; ++i)
- {
- SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
- if (section_sp)
- {
- const addr_t old_section_load_addr = info.segments[i].vmaddr;
- if (m_process->GetTarget().GetSectionLoadList().SetSectionUnloaded (section_sp.get(), old_section_load_addr))
- changed = true;
- }
- else
- {
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: unable to find and unload segment named '%s' in '%s/%s' in macosx dynamic loader plug-in.\n",
- info.segments[i].name.AsCString("<invalid>"),
- image_object_file->GetFileSpec().GetDirectory().AsCString(),
- image_object_file->GetFileSpec().GetFilename().AsCString());
- }
- }
+ // We didn't get a hint from the process, so we will
+ // try the kernel at the address that it exists at in
+ // the file if we have one
+ ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile();
+ if (kernel_object_file)
+ m_kernel.address = kernel_object_file->GetHeaderAddress().GetFileAddress();
}
}
+
+ if (m_kernel.address != LLDB_INVALID_ADDRESS)
+ m_kernel.LoadImageUsingMemoryModule (m_process);
+
+ if (m_kernel.IsLoaded())
+ {
+ static ConstString kext_summary_symbol ("gLoadedKextSummaries");
+ const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
+ if (symbol)
+ {
+ m_kext_summary_header_ptr_addr = symbol->GetValue();
+ // Update all image infos
+ ReadAllKextSummaries ();
+ }
+ }
+ else
+ {
+ m_kernel.Clear(false);
+ }
}
- return changed;
}
-
//----------------------------------------------------------------------
// Static callback function that gets called when our DYLD notification
// breakpoint gets hit. We update all of our image infos and then
@@ -513,18 +445,20 @@ DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr,
}
}
- DataExtractor data; // Load command data
- if (ReadMachHeader (kext_summaries[i], &data))
- {
- ParseLoadCommands (data, kext_summaries[i]);
- }
-
+ kext_summaries[i].LoadImageUsingMemoryModule (m_process);
+
if (s)
{
if (kext_summaries[i].module_sp)
- s->Printf("\n found kext: %s/%s\n",
- kext_summaries[i].module_sp->GetFileSpec().GetDirectory().AsCString(),
- kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString());
+ {
+ if (kext_summaries[i].module_sp->GetFileSpec().GetDirectory())
+ s->Printf("\n found kext: %s/%s\n",
+ kext_summaries[i].module_sp->GetFileSpec().GetDirectory().AsCString(),
+ kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString());
+ else
+ s->Printf("\n found kext: %s\n",
+ kext_summaries[i].module_sp->GetFileSpec().GetFilename().AsCString());
+ }
else
s->Printf (" failed to locate/load.\n");
}
@@ -547,20 +481,11 @@ DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::c
for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
{
- m_kext_summaries.push_back(image_infos[idx]);
+ OSKextLoadedKextSummary &image_info = image_infos[idx];
+ m_kext_summaries.push_back(image_info);
- if (FindTargetModule (image_infos[idx], true, NULL))
- {
- // UpdateImageLoadAddress will return true if any segments
- // change load address. We need to check this so we don't
- // mention that all loaded shared libraries are newly loaded
- // each time we hit out dyld breakpoint since dyld will list all
- // shared libraries each time.
- if (UpdateImageLoadAddress (image_infos[idx]))
- {
- loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp);
- }
- }
+ if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id)
+ loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp);
}
if (loaded_module_list.GetSize() > 0)
@@ -644,6 +569,14 @@ DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
{
image_infos[i].reference_list = 0;
}
+ printf ("[%3u] %*.*s: address=0x%16.16llx, size=0x%16.16llx, version=0x%16.16llx, load_tag=0x%8.8x, flags=0x%8.8x\n",
+ i,
+ KERNEL_MODULE_MAX_NAME, KERNEL_MODULE_MAX_NAME, (char *)name_data,
+ image_infos[i].address,
+ image_infos[i].size,
+ image_infos[i].version,
+ image_infos[i].load_tag,
+ image_infos[i].flags);
}
if (i < image_infos.size())
image_infos.resize(i);
@@ -679,215 +612,6 @@ DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
}
//----------------------------------------------------------------------
-// Read a mach_header at ADDR into HEADER, and also fill in the load
-// command data into LOAD_COMMAND_DATA if it is non-NULL.
-//
-// Returns true if we succeed, false if we fail for any reason.
-//----------------------------------------------------------------------
-bool
-DynamicLoaderDarwinKernel::ReadMachHeader (OSKextLoadedKextSummary& kext_summary, DataExtractor *load_command_data)
-{
- DataBufferHeap header_bytes(sizeof(llvm::MachO::mach_header), 0);
- Error error;
- const bool prefer_file_cache = false;
- size_t bytes_read = m_process->GetTarget().ReadMemory (kext_summary.so_address,
- prefer_file_cache,
- header_bytes.GetBytes(),
- header_bytes.GetByteSize(),
- error);
- if (bytes_read == sizeof(llvm::MachO::mach_header))
- {
- uint32_t offset = 0;
- ::memset (&kext_summary.header, 0, sizeof(kext_summary.header));
-
- // Get the magic byte unswapped so we can figure out what we are dealing with
- DataExtractor data(header_bytes.GetBytes(), header_bytes.GetByteSize(), endian::InlHostByteOrder(), 4);
- kext_summary.header.magic = data.GetU32(&offset);
- Address load_cmd_addr = kext_summary.so_address;
- data.SetByteOrder(DynamicLoaderDarwinKernel::GetByteOrderFromMagic(kext_summary.header.magic));
- switch (kext_summary.header.magic)
- {
- case llvm::MachO::HeaderMagic32:
- case llvm::MachO::HeaderMagic32Swapped:
- data.SetAddressByteSize(4);
- load_cmd_addr.Slide (sizeof(llvm::MachO::mach_header));
- break;
-
- case llvm::MachO::HeaderMagic64:
- case llvm::MachO::HeaderMagic64Swapped:
- data.SetAddressByteSize(8);
- load_cmd_addr.Slide (sizeof(llvm::MachO::mach_header_64));
- break;
-
- default:
- return false;
- }
-
- // Read the rest of dyld's mach header
- if (data.GetU32(&offset, &kext_summary.header.cputype, (sizeof(llvm::MachO::mach_header)/sizeof(uint32_t)) - 1))
- {
- if (load_command_data == NULL)
- return true; // We were able to read the mach_header and weren't asked to read the load command bytes
-
- DataBufferSP load_cmd_data_sp(new DataBufferHeap(kext_summary.header.sizeofcmds, 0));
-
- size_t load_cmd_bytes_read = m_process->GetTarget().ReadMemory (load_cmd_addr,
- prefer_file_cache,
- load_cmd_data_sp->GetBytes(),
- load_cmd_data_sp->GetByteSize(),
- error);
-
- if (load_cmd_bytes_read == kext_summary.header.sizeofcmds)
- {
- // Set the load command data and also set the correct endian
- // swap settings and the correct address size
- load_command_data->SetData(load_cmd_data_sp, 0, kext_summary.header.sizeofcmds);
- load_command_data->SetByteOrder(data.GetByteOrder());
- load_command_data->SetAddressByteSize(data.GetAddressByteSize());
- return true; // We successfully read the mach_header and the load command data
- }
-
- return false; // We weren't able to read the load command data
- }
- }
- return false; // We failed the read the mach_header
-}
-
-
-//----------------------------------------------------------------------
-// Parse the load commands for an image
-//----------------------------------------------------------------------
-uint32_t
-DynamicLoaderDarwinKernel::ParseLoadCommands (const DataExtractor& data, OSKextLoadedKextSummary& image_info)
-{
- uint32_t offset = 0;
- uint32_t cmd_idx;
- Segment segment;
- image_info.Clear (true);
-
- for (cmd_idx = 0; cmd_idx < image_info.header.ncmds; cmd_idx++)
- {
- // Clear out any load command specific data from image_info since
- // we are about to read it.
-
- if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
- {
- llvm::MachO::load_command load_cmd;
- uint32_t load_cmd_offset = offset;
- load_cmd.cmd = data.GetU32 (&offset);
- load_cmd.cmdsize = data.GetU32 (&offset);
- switch (load_cmd.cmd)
- {
- case llvm::MachO::LoadCommandSegment32:
- {
- segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
- // We are putting 4 uint32_t values 4 uint64_t values so
- // we have to use multiple 32 bit gets below.
- segment.vmaddr = data.GetU32 (&offset);
- segment.vmsize = data.GetU32 (&offset);
- segment.fileoff = data.GetU32 (&offset);
- segment.filesize = data.GetU32 (&offset);
- // Extract maxprot, initprot, nsects and flags all at once
- data.GetU32(&offset, &segment.maxprot, 4);
- image_info.segments.push_back (segment);
- }
- break;
-
- case llvm::MachO::LoadCommandSegment64:
- {
- segment.name.SetTrimmedCStringWithLength ((const char *)data.GetData(&offset, 16), 16);
- // Extract vmaddr, vmsize, fileoff, and filesize all at once
- data.GetU64(&offset, &segment.vmaddr, 4);
- // Extract maxprot, initprot, nsects and flags all at once
- data.GetU32(&offset, &segment.maxprot, 4);
- image_info.segments.push_back (segment);
- }
- break;
-
- case llvm::MachO::LoadCommandUUID:
- image_info.uuid.SetBytes(data.GetData (&offset, 16));
- break;
-
- default:
- break;
- }
- // Set offset to be the beginning of the next load command.
- offset = load_cmd_offset + load_cmd.cmdsize;
- }
- }
-#if 0
- // No slide in the kernel...
-
- // All sections listed in the dyld image info structure will all
- // either be fixed up already, or they will all be off by a single
- // slide amount that is determined by finding the first segment
- // that is at file offset zero which also has bytes (a file size
- // that is greater than zero) in the object file.
-
- // Determine the slide amount (if any)
- const size_t num_sections = image_info.segments.size();
- for (size_t i = 0; i < num_sections; ++i)
- {
- // Iterate through the object file sections to find the
- // first section that starts of file offset zero and that
- // has bytes in the file...
- if (image_info.segments[i].fileoff == 0 && image_info.segments[i].filesize > 0)
- {
- image_info.slide = image_info.address - image_info.segments[i].vmaddr;
- // We have found the slide amount, so we can exit
- // this for loop.
- break;
- }
- }
-#endif
- if (image_info.uuid.IsValid())
- {
- bool did_create = false;
- if (FindTargetModule(image_info, true, &did_create))
- {
- if (did_create)
- image_info.module_create_stop_id = m_process->GetStopID();
- }
- }
- return cmd_idx;
-}
-
-//----------------------------------------------------------------------
-// Dump a Segment to the file handle provided.
-//----------------------------------------------------------------------
-void
-DynamicLoaderDarwinKernel::Segment::PutToLog (Log *log, addr_t slide) const
-{
- if (log)
- {
- if (slide == 0)
- log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx)",
- name.AsCString(""),
- vmaddr + slide,
- vmaddr + slide + vmsize);
- else
- log->Printf ("\t\t%16s [0x%16.16llx - 0x%16.16llx) slide = 0x%llx",
- name.AsCString(""),
- vmaddr + slide,
- vmaddr + slide + vmsize,
- slide);
- }
-}
-
-const DynamicLoaderDarwinKernel::Segment *
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::FindSegment (const ConstString &name) const
-{
- const size_t num_segments = segments.size();
- for (size_t i=0; i<num_segments; ++i)
- {
- if (segments[i].name == name)
- return &segments[i];
- }
- return NULL;
-}
-
-
-//----------------------------------------------------------------------
// Dump an image info structure to the file handle provided.
//----------------------------------------------------------------------
void
@@ -927,8 +651,6 @@ DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
address, address+size, version, load_tag, flags, reference_list,
name);
}
- for (uint32_t i=0; i<segments.size(); ++i)
- segments[i].PutToLog(log, 0);
}
}
@@ -971,7 +693,7 @@ DynamicLoaderDarwinKernel::PrivateInitialize(Process *process)
void
DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
{
- if (m_break_id == LLDB_INVALID_BREAK_ID)
+ if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp)
{
DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
index fd8a14a0236..4d9b42207cd 100644
--- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
+++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
@@ -113,22 +113,9 @@ protected:
lldb::user_id_t break_id,
lldb::user_id_t break_loc_id);
uint32_t
- AddrByteSize()
+ GetAddrByteSize()
{
- switch (m_kernel.header.magic)
- {
- case llvm::MachO::HeaderMagic32:
- case llvm::MachO::HeaderMagic32Swapped:
- return 4;
-
- case llvm::MachO::HeaderMagic64:
- case llvm::MachO::HeaderMagic64Swapped:
- return 8;
-
- default:
- break;
- }
- return 0;
+ return m_kernel.GetAddressByteSize();
}
static lldb::ByteOrder
@@ -152,46 +139,6 @@ protected:
}
return lldb::eByteOrderInvalid;
}
-
- class Segment
- {
- public:
-
- Segment() :
- name(),
- vmaddr(LLDB_INVALID_ADDRESS),
- vmsize(0),
- fileoff(0),
- filesize(0),
- maxprot(0),
- initprot(0),
- nsects(0),
- flags(0)
- {
- }
-
- lldb_private::ConstString name;
- lldb::addr_t vmaddr;
- lldb::addr_t vmsize;
- lldb::addr_t fileoff;
- lldb::addr_t filesize;
- uint32_t maxprot;
- uint32_t initprot;
- uint32_t nsects;
- uint32_t flags;
-
- bool
- operator==(const Segment& rhs) const
- {
- return name == rhs.name && vmaddr == rhs.vmaddr && vmsize == rhs.vmsize;
- }
-
- void
- PutToLog (lldb_private::Log *log,
- lldb::addr_t slide) const;
-
- };
-
enum
{
KERNEL_MODULE_MAX_NAME = 64u,
@@ -206,7 +153,7 @@ protected:
{
char name[KERNEL_MODULE_MAX_NAME];
lldb::ModuleSP module_sp;
- uint32_t module_create_stop_id;
+ uint32_t load_process_stop_id;
lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
lldb_private::Address so_address; // The section offset address for this kext in case it can be read from object files
uint64_t address;
@@ -215,12 +162,10 @@ protected:
uint32_t load_tag;
uint32_t flags;
uint64_t reference_list;
- llvm::MachO::mach_header header; // The mach header for this image
- std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior)
OSKextLoadedKextSummary() :
module_sp (),
- module_create_stop_id (UINT32_MAX),
+ load_process_stop_id (UINT32_MAX),
uuid (),
so_address (),
address (LLDB_INVALID_ADDRESS),
@@ -228,12 +173,16 @@ protected:
version (0),
load_tag (0),
flags (0),
- reference_list (0),
- header(),
- segments()
+ reference_list (0)
{
name[0] = '\0';
}
+
+ bool
+ IsLoaded ()
+ {
+ return load_process_stop_id != UINT32_MAX;
+ }
void
Clear (bool load_cmd_data_only)
@@ -248,30 +197,28 @@ protected:
flags = 0;
reference_list = 0;
name[0] = '\0';
- ::memset (&header, 0, sizeof(header));
}
module_sp.reset();
- module_create_stop_id = UINT32_MAX;
- uuid.Clear();
- segments.clear();
+ load_process_stop_id = UINT32_MAX;
}
bool
- operator == (const OSKextLoadedKextSummary& rhs) const
- {
- return address == rhs.address
- && size == rhs.size
- //&& module_sp.get() == rhs.module_sp.get()
- && uuid == rhs.uuid
- && version == rhs.version
- && load_tag == rhs.load_tag
- && flags == rhs.flags
- && reference_list == rhs.reference_list
- && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0
- && memcmp(&header, &rhs.header, sizeof(header)) == 0
- && segments == rhs.segments;
- }
-
+ LoadImageUsingMemoryModule (lldb_private::Process *process);
+
+// bool
+// operator == (const OSKextLoadedKextSummary& rhs) const
+// {
+// return address == rhs.address
+// && size == rhs.size
+// //&& module_sp.get() == rhs.module_sp.get()
+// && uuid == rhs.uuid
+// && version == rhs.version
+// && load_tag == rhs.load_tag
+// && flags == rhs.flags
+// && reference_list == rhs.reference_list
+// && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0;
+// }
+//
bool
UUIDValid() const
{
@@ -281,47 +228,27 @@ protected:
uint32_t
GetAddressByteSize ()
{
- if (header.cputype)
- {
- if (header.cputype & llvm::MachO::CPUArchABI64)
- return 8;
- else
- return 4;
- }
+ if (module_sp)
+ return module_sp->GetArchitecture().GetAddressByteSize();
return 0;
}
lldb::ByteOrder
GetByteOrder()
{
- switch (header.magic)
- {
- case llvm::MachO::HeaderMagic32: // MH_MAGIC
- case llvm::MachO::HeaderMagic64: // MH_MAGIC_64
- return lldb::endian::InlHostByteOrder();
-
- case llvm::MachO::HeaderMagic32Swapped: // MH_CIGAM
- case llvm::MachO::HeaderMagic64Swapped: // MH_CIGAM_64
- if (lldb::endian::InlHostByteOrder() == lldb::eByteOrderLittle)
- return lldb::eByteOrderBig;
- else
- return lldb::eByteOrderLittle;
- default:
- assert (!"invalid header.magic value");
- break;
- }
+ if (module_sp)
+ return module_sp->GetArchitecture().GetByteOrder();
return lldb::endian::InlHostByteOrder();
}
lldb_private::ArchSpec
GetArchitecture () const
{
- return lldb_private::ArchSpec (lldb_private::eArchTypeMachO, header.cputype, header.cpusubtype);
+ if (module_sp)
+ return module_sp->GetArchitecture();
+ return lldb_private::ArchSpec ();
}
- const Segment *
- FindSegment (const lldb_private::ConstString &name) const;
-
void
PutToLog (lldb_private::Log *log) const;
@@ -374,28 +301,12 @@ protected:
}
};
- bool
- ReadMachHeader (OSKextLoadedKextSummary& kext_summary,
- lldb_private::DataExtractor *load_command_data);
-
void
RegisterNotificationCallbacks();
void
UnregisterNotificationCallbacks();
- uint32_t
- ParseLoadCommands (const lldb_private::DataExtractor& data,
- OSKextLoadedKextSummary& dylib_info);
-
- bool
- UpdateImageLoadAddress(OSKextLoadedKextSummary& info);
-
- bool
- FindTargetModule (OSKextLoadedKextSummary &image_info,
- bool can_create,
- bool *did_create_ptr);
-
void
SetNotificationBreakpointIfNeeded ();
@@ -417,17 +328,11 @@ protected:
uint32_t infos_count,
bool update_executable);
- bool
- UpdateCommPageLoadAddress (lldb_private::Module *module);
-
uint32_t
ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
uint32_t image_infos_count,
OSKextLoadedKextSummary::collection &image_infos);
- bool
- UnloadImageLoadAddress (OSKextLoadedKextSummary& info);
-
OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used
lldb_private::Address m_kext_summary_header_ptr_addr;
lldb_private::Address m_kext_summary_header_addr;
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index f929ce13466..e3c48e2f85c 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -210,7 +210,7 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
// Check the image info addr as it might point to the
// mach header for dyld, or it might point to the
// dyld_all_image_infos struct
- addr_t shlib_addr = m_process->GetImageInfoAddress ();
+ const addr_t shlib_addr = m_process->GetImageInfoAddress ();
ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
uint8_t buf[4];
@@ -310,8 +310,14 @@ DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &
arch,
image_info_uuid_is_valid ? &image_info.uuid : NULL);
if (!module_sp || module_sp->GetObjectFile() == NULL)
+ {
+ const bool add_image_to_target = true;
+ const bool load_image_sections_in_target = false;
module_sp = m_process->ReadModuleFromMemory (image_info.file_spec,
- image_info.address);
+ image_info.address,
+ add_image_to_target,
+ load_image_sections_in_target);
+ }
if (did_create_ptr)
*did_create_ptr = module_sp;
@@ -434,14 +440,22 @@ DynamicLoaderMacOSXDYLD::UpdateImageLoadAddress (Module *module, DYLDImageInfo&
{
SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
const addr_t new_section_load_addr = info.segments[i].vmaddr + info.slide;
+ static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
+
if (section_sp)
{
- const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get());
- if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
- old_section_load_addr != new_section_load_addr)
+ // Don't ever load any __LINKEDIT sections since the ones in the shared
+ // cached will be coalesced into a single section and we will get warnings
+ // about multiple sections mapping to the same address.
+ if (section_sp->GetName() != g_section_name_LINKEDIT)
{
- if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr))
- changed = true;
+ const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp.get());
+ if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
+ old_section_load_addr != new_section_load_addr)
+ {
+ if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), new_section_load_addr))
+ changed = true;
+ }
}
}
else
@@ -780,10 +794,14 @@ DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfos (DYLDImageInfo::collection &i
&commpage_dbstr,
objfile->GetOffset() + commpage_section->GetFileOffset());
if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
+ {
+ const bool add_image_to_target = true;
+ const bool load_image_sections_in_target = false;
commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
- image_infos[idx].address);
-
-
+ image_infos[idx].address,
+ add_image_to_target,
+ load_image_sections_in_target);
+ }
}
if (commpage_image_module_sp)
UpdateCommPageLoadAddress (commpage_image_module_sp.get());
@@ -1249,8 +1267,14 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfosHeaderAndLoadCommands(DYLDImageInfo::co
exe_arch_spec,
&image_infos[exe_idx].uuid);
if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
+ {
+ const bool add_image_to_target = true;
+ const bool load_image_sections_in_target = false;
exe_module_sp = m_process->ReadModuleFromMemory (image_infos[exe_idx].file_spec,
- image_infos[exe_idx].address);
+ image_infos[exe_idx].address,
+ add_image_to_target,
+ load_image_sections_in_target);
+ }
}
if (exe_module_sp)
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index 565682360c3..d233ece6cb7 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -27,6 +27,8 @@
#include "lldb/Symbol/ClangNamespaceDecl.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Process.h"
+#include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
+#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
@@ -52,44 +54,162 @@ public:
void
SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
{
- int flavor;
uint32_t offset = 0;
SetError (GPRRegSet, Read, -1);
SetError (FPURegSet, Read, -1);
SetError (EXCRegSet, Read, -1);
- while ((flavor = data.GetU32 (&offset)) > 0)
+ bool done = false;
+
+ while (!done)
{
- uint32_t i;
- uint32_t count = data.GetU32 (&offset);
- switch (flavor)
+ int flavor = data.GetU32 (&offset);
+ if (flavor == 0)
+ done = true;
+ else
{
- case 7:
- case 8:
- case 9:
- // Goofy extra flavor inside state...
- flavor = data.GetU32 (&offset);
- count = data.GetU32 (&offset);
- default:
- break;
+ uint32_t i;
+ uint32_t count = data.GetU32 (&offset);
+ switch (flavor)
+ {
+ case GPRRegSet:
+ for (i=0; i<count; ++i)
+ (&gpr.rax)[i] = data.GetU64(&offset);
+ SetError (GPRRegSet, Read, 0);
+ done = true;
+
+ break;
+ case FPURegSet:
+ // TODO: fill in FPU regs....
+ //SetError (FPURegSet, Read, -1);
+ done = true;
+
+ break;
+ case EXCRegSet:
+ exc.trapno = data.GetU32(&offset);
+ exc.err = data.GetU32(&offset);
+ exc.faultvaddr = data.GetU64(&offset);
+ SetError (EXCRegSet, Read, 0);
+ done = true;
+ break;
+ case 7:
+ case 8:
+ case 9:
+ // fancy flavors that encapsulate of the the above
+ // falvors...
+ break;
+
+ default:
+ done = true;
+ break;
+ }
}
+ }
+ }
+protected:
+ virtual int
+ DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
+ {
+ return 0;
+ }
+
+ virtual int
+ DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
+ {
+ return 0;
+ }
+
+ virtual int
+ DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
+ {
+ return 0;
+ }
+
+ virtual int
+ DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
+ {
+ return 0;
+ }
+
+ virtual int
+ DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
+ {
+ return 0;
+ }
+
+ virtual int
+ DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
+ {
+ return 0;
+ }
+};
- switch (flavor)
+
+class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
+{
+public:
+ RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
+ RegisterContextDarwin_i386 (thread, 0)
+ {
+ SetRegisterDataFrom_LC_THREAD (data);
+ }
+
+ virtual void
+ InvalidateAllRegisters ()
+ {
+ // Do nothing... registers are always valid...
+ }
+
+ void
+ SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
+ {
+ uint32_t offset = 0;
+ SetError (GPRRegSet, Read, -1);
+ SetError (FPURegSet, Read, -1);
+ SetError (EXCRegSet, Read, -1);
+ bool done = false;
+
+ while (!done)
+ {
+ int flavor = data.GetU32 (&offset);
+ if (flavor == 0)
+ done = true;
+ else
{
- case GPRRegSet:
- for (i=0; i<count; ++i)
- (&gpr.rax)[i] = data.GetU64(&offset);
- SetError (GPRRegSet, Read, 0);
- break;
- case FPURegSet:
- // TODO: fill in FPU regs....
- //SetError (FPURegSet, Read, -1);
- break;
- case EXCRegSet:
- exc.trapno = data.GetU32(&offset);
- exc.err = data.GetU32(&offset);
- exc.faultvaddr = data.GetU64(&offset);
- SetError (EXCRegSet, Read, 0);
- break;
+ uint32_t i;
+ uint32_t count = data.GetU32 (&offset);
+ switch (flavor)
+ {
+ case GPRRegSet:
+ for (i=0; i<count; ++i)
+ (&gpr.eax)[i] = data.GetU32(&offset);
+ SetError (GPRRegSet, Read, 0);
+ done = true;
+
+ break;
+ case FPURegSet:
+ // TODO: fill in FPU regs....
+ //SetError (FPURegSet, Read, -1);
+ done = true;
+
+ break;
+ case EXCRegSet:
+ exc.trapno = data.GetU32(&offset);
+ exc.err = data.GetU32(&offset);
+ exc.faultvaddr = data.GetU32(&offset);
+ SetError (EXCRegSet, Read, 0);
+ done = true;
+ break;
+ case 7:
+ case 8:
+ case 9:
+ // fancy flavors that encapsulate of the the above
+ // falvors...
+ break;
+
+ default:
+ done = true;
+ break;
+ }
}
}
}
@@ -131,6 +251,87 @@ protected:
}
};
+class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
+{
+public:
+ RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
+ RegisterContextDarwin_arm (thread, 0)
+ {
+ SetRegisterDataFrom_LC_THREAD (data);
+ }
+
+ virtual void
+ InvalidateAllRegisters ()
+ {
+ // Do nothing... registers are always valid...
+ }
+
+ void
+ SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
+ {
+ uint32_t offset = 0;
+ SetError (GPRRegSet, Read, -1);
+ SetError (FPURegSet, Read, -1);
+ SetError (EXCRegSet, Read, -1);
+ int flavor = data.GetU32 (&offset);
+ uint32_t count = data.GetU32 (&offset);
+ switch (flavor)
+ {
+ case GPRRegSet:
+ for (uint32_t i=0; i<count; ++i)
+ gpr.r[i] = data.GetU32(&offset);
+ SetError (GPRRegSet, Read, 0);
+ break;
+ case FPURegSet:
+ // TODO: fill in FPU regs....
+ //SetError (FPURegSet, Read, -1);
+ break;
+ case EXCRegSet:
+ exc.exception = data.GetU32(&offset);
+ exc.fsr = data.GetU32(&offset);
+ exc.far = data.GetU32(&offset);
+ SetError (EXCRegSet, Read, 0);
+ break;
+ }
+ }
+protected:
+ virtual int
+ DoReadGPR (lldb::tid_t tid, int flavor, GPR &gpr)
+ {
+ return 0;
+ }
+
+ virtual int
+ DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
+ {
+ return 0;
+ }
+
+ virtual int
+ DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
+ {
+ return 0;
+ }
+
+ virtual int
+ DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
+ {
+ return 0;
+ }
+
+ virtual int
+ DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
+ {
+ return 0;
+ }
+
+ virtual int
+ DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
+ {
+ return 0;
+ }
+};
+
#define MACHO_NLIST_ARM_SYMBOL_IS_THUMB 0x0008
void
@@ -1017,9 +1218,11 @@ ObjectFileMachO::ParseSymtab (bool minimize)
const addr_t symoff_addr = linkedit_load_addr + symtab_load_command.symoff - linkedit_file_offset;
const addr_t stroff_addr = linkedit_load_addr + symtab_load_command.stroff - linkedit_file_offset;
DataBufferSP nlist_data_sp (ReadMemory (process_sp, symoff_addr, nlist_data_byte_size));
+ if (nlist_data_sp)
+ nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
DataBufferSP strtab_data_sp (ReadMemory (process_sp, stroff_addr, strtab_data_byte_size));
- nlist_data.SetData (nlist_data_sp, 0, nlist_data_sp->GetByteSize());
- strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
+ if (strtab_data_sp)
+ strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
}
}
else
@@ -2104,12 +2307,24 @@ ObjectFileMachO::GetThreadContextAtIndex (uint32_t idx, lldb_private::Thread &th
lldb::RegisterContextSP reg_ctx_sp;
const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
- if (thread_context_file_range)
+
+ DataExtractor data (m_data,
+ thread_context_file_range->GetRangeBase(),
+ thread_context_file_range->GetByteSize());
+
+ switch (m_header.cputype)
{
- DataExtractor data (m_data,
- thread_context_file_range->GetRangeBase(),
- thread_context_file_range->GetByteSize());
- reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
+ case llvm::MachO::CPUTypeARM:
+ reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
+ break;
+
+ case llvm::MachO::CPUTypeI386:
+ reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
+ break;
+
+ case llvm::MachO::CPUTypeX86_64:
+ reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
+ break;
}
return reg_ctx_sp;
}
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 9c8ca825c70..67e6ac85ead 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -46,7 +46,8 @@ PlatformDarwin::~PlatformDarwin()
Error
PlatformDarwin::ResolveExecutable (const FileSpec &exe_file,
const ArchSpec &exe_arch,
- lldb::ModuleSP &exe_module_sp)
+ lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr)
{
Error error;
// Nothing special to do here, just use the actual file and architecture
@@ -84,7 +85,8 @@ PlatformDarwin::ResolveExecutable (const FileSpec &exe_file,
{
error = m_remote_platform_sp->ResolveExecutable (exe_file,
exe_arch,
- exe_module_sp);
+ exe_module_sp,
+ module_search_paths_ptr);
}
else
{
@@ -111,6 +113,7 @@ PlatformDarwin::ResolveExecutable (const FileSpec &exe_file,
NULL,
0,
exe_module_sp,
+ module_search_paths_ptr,
NULL,
NULL);
@@ -139,6 +142,7 @@ PlatformDarwin::ResolveExecutable (const FileSpec &exe_file,
NULL,
0,
exe_module_sp,
+ module_search_paths_ptr,
NULL,
NULL);
// Did we find an executable using one of the
@@ -171,6 +175,100 @@ PlatformDarwin::ResolveExecutable (const FileSpec &exe_file,
}
+
+Error
+PlatformDarwin::GetSharedModule (const FileSpec &platform_file,
+ const ArchSpec &arch,
+ const UUID *uuid_ptr,
+ const ConstString *object_name_ptr,
+ off_t object_offset,
+ ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr)
+{
+ Error error;
+ module_sp.reset();
+
+ if (IsRemote())
+ {
+ // If we have a remote platform always, let it try and locate
+ // the shared module first.
+ if (m_remote_platform_sp)
+ {
+ error = m_remote_platform_sp->GetSharedModule (platform_file,
+ arch,
+ uuid_ptr,
+ object_name_ptr,
+ object_offset,
+ module_sp,
+ module_search_paths_ptr,
+ old_module_sp_ptr,
+ did_create_ptr);
+ }
+ }
+
+ if (!module_sp)
+ {
+ // Fall back to the local platform and find the file locally
+ error = Platform::GetSharedModule (platform_file,
+ arch,
+ uuid_ptr,
+ object_name_ptr,
+ object_offset,
+ module_sp,
+ module_search_paths_ptr,
+ old_module_sp_ptr,
+ did_create_ptr);
+
+ if (!module_sp && module_search_paths_ptr && platform_file)
+ {
+ // We can try to pull off part of the file path up to the bundle
+ // directory level and try any module search paths...
+ FileSpec bundle_directory;
+ if (Host::GetBundleDirectory (platform_file, bundle_directory))
+ {
+ char platform_path[PATH_MAX];
+ char bundle_dir[PATH_MAX];
+ platform_file.GetPath (platform_path, sizeof(platform_path));
+ const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir));
+ char new_path[PATH_MAX];
+ size_t num_module_search_paths = module_search_paths_ptr->GetSize();
+ for (size_t i=0; i<num_module_search_paths; ++i)
+ {
+ const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path));
+ if (search_path_len < sizeof(new_path))
+ {
+ snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len);
+ FileSpec new_file_spec (new_path, false);
+ if (new_file_spec.Exists())
+ {
+ Error new_error (Platform::GetSharedModule (new_file_spec,
+ arch,
+ uuid_ptr,
+ object_name_ptr,
+ object_offset,
+ module_sp,
+ NULL,
+ old_module_sp_ptr,
+ did_create_ptr));
+
+ if (module_sp)
+ {
+ module_sp->SetPlatformFileSpec(new_file_spec);
+ return new_error;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (module_sp)
+ module_sp->SetPlatformFileSpec(platform_file);
+ return error;
+}
+
size_t
PlatformDarwin::GetSoftwareBreakpointTrapOpcode (Target &target, BreakpointSite *bp_site)
{
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index 0052a8efde4..abb8326d1e7 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -30,7 +30,19 @@ public:
virtual lldb_private::Error
ResolveExecutable (const lldb_private::FileSpec &exe_file,
const lldb_private::ArchSpec &arch,
- lldb::ModuleSP &module_sp);
+ lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr);
+
+ virtual lldb_private::Error
+ GetSharedModule (const lldb_private::FileSpec &platform_file,
+ const lldb_private::ArchSpec &arch,
+ const lldb_private::UUID *uuid_ptr,
+ const lldb_private::ConstString *object_name_ptr,
+ off_t object_offset,
+ lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
+ lldb::ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr);
virtual size_t
GetSoftwareBreakpointTrapOpcode (lldb_private::Target &target,
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
index 3a0e036f055..3ca4dd604cf 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.cpp
@@ -128,53 +128,6 @@ PlatformMacOSX::GetFile (const FileSpec &platform_file,
return Error();
}
-Error
-PlatformMacOSX::GetSharedModule (const FileSpec &platform_file,
- const ArchSpec &arch,
- const UUID *uuid_ptr,
- const ConstString *object_name_ptr,
- off_t object_offset,
- ModuleSP &module_sp,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr)
-{
- Error error;
- module_sp.reset();
-
- if (IsRemote())
- {
- // If we have a remote platform always, let it try and locate
- // the shared module first.
- if (m_remote_platform_sp)
- {
- error = m_remote_platform_sp->GetSharedModule (platform_file,
- arch,
- uuid_ptr,
- object_name_ptr,
- object_offset,
- module_sp,
- old_module_sp_ptr,
- did_create_ptr);
- }
- }
-
- if (!module_sp)
- {
- // Fall back to the local platform and find the file locally
- error = Platform::GetSharedModule (platform_file,
- arch,
- uuid_ptr,
- object_name_ptr,
- object_offset,
- module_sp,
- old_module_sp_ptr,
- did_create_ptr);
- }
- if (module_sp)
- module_sp->SetPlatformFileSpec(platform_file);
- return error;
-}
-
bool
PlatformMacOSX::GetSupportedArchitectureAtIndex (uint32_t idx, ArchSpec &arch)
{
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
index 0642ff38ffb..4a47b7fb50c 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformMacOSX.h
@@ -81,16 +81,6 @@ public:
const lldb_private::UUID *uuid_ptr,
lldb_private::FileSpec &local_file);
- lldb_private::Error
- GetSharedModule (const lldb_private::FileSpec &platform_file,
- const lldb_private::ArchSpec &arch,
- const lldb_private::UUID *uuid_ptr,
- const lldb_private::ConstString *object_name_ptr,
- off_t object_offset,
- lldb::ModuleSP &module_sp,
- lldb::ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr);
-
virtual bool
GetSupportedArchitectureAtIndex (uint32_t idx,
lldb_private::ArchSpec &arch);
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
index 12c104b24de..4a32e718e72 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.cpp
@@ -121,7 +121,8 @@ PlatformRemoteiOS::GetStatus (Stream &strm)
Error
PlatformRemoteiOS::ResolveExecutable (const FileSpec &exe_file,
const ArchSpec &exe_arch,
- lldb::ModuleSP &exe_module_sp)
+ lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr)
{
Error error;
// Nothing special to do here, just use the actual file and architecture
@@ -148,6 +149,7 @@ PlatformRemoteiOS::ResolveExecutable (const FileSpec &exe_file,
NULL,
0,
exe_module_sp,
+ NULL,
NULL,
NULL);
@@ -168,6 +170,7 @@ PlatformRemoteiOS::ResolveExecutable (const FileSpec &exe_file,
NULL,
0,
exe_module_sp,
+ NULL,
NULL,
NULL);
// Did we find an executable using one of the
@@ -429,6 +432,7 @@ PlatformRemoteiOS::GetSharedModule (const FileSpec &platform_file,
const ConstString *object_name_ptr,
off_t object_offset,
ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
ModuleSP *old_module_sp_ptr,
bool *did_create_ptr)
{
@@ -441,8 +445,7 @@ PlatformRemoteiOS::GetSharedModule (const FileSpec &platform_file,
error = GetFile (platform_file, uuid_ptr, local_file);
if (error.Success())
{
-
- error = ResolveExecutable (local_file, arch, module_sp);
+ error = ResolveExecutable (local_file, arch, module_sp, module_search_paths_ptr);
}
else
{
@@ -453,6 +456,7 @@ PlatformRemoteiOS::GetSharedModule (const FileSpec &platform_file,
object_name_ptr,
object_offset,
module_sp,
+ module_search_paths_ptr,
old_module_sp_ptr,
did_create_ptr,
always_create);
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
index 08968f4f110..13fd11e5a9b 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformRemoteiOS.h
@@ -76,7 +76,8 @@ public:
virtual lldb_private::Error
ResolveExecutable (const lldb_private::FileSpec &exe_file,
const lldb_private::ArchSpec &arch,
- lldb::ModuleSP &module_sp);
+ lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr);
virtual const char *
GetDescription ()
@@ -92,13 +93,14 @@ public:
const lldb_private::UUID *uuid_ptr,
lldb_private::FileSpec &local_file);
- lldb_private::Error
+ virtual lldb_private::Error
GetSharedModule (const lldb_private::FileSpec &platform_file,
const lldb_private::ArchSpec &arch,
const lldb_private::UUID *uuid_ptr,
const lldb_private::ConstString *object_name_ptr,
off_t object_offset,
lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr,
lldb::ModuleSP *old_module_sp_ptr,
bool *did_create_ptr);
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
index 7114ac5a8e1..248475af9c3 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp
@@ -92,7 +92,8 @@ PlatformRemoteGDBServer::GetDescription ()
Error
PlatformRemoteGDBServer::ResolveExecutable (const FileSpec &exe_file,
const ArchSpec &exe_arch,
- lldb::ModuleSP &exe_module_sp)
+ lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr)
{
Error error;
error.SetErrorString ("PlatformRemoteGDBServer::ResolveExecutable() is unimplemented");
diff --git a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
index e141f7fc080..48f36136aef 100644
--- a/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
+++ b/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h
@@ -72,7 +72,8 @@ public:
virtual lldb_private::Error
ResolveExecutable (const lldb_private::FileSpec &exe_file,
const lldb_private::ArchSpec &arch,
- lldb::ModuleSP &module_sp);
+ lldb::ModuleSP &module_sp,
+ const lldb_private::FileSpecList *module_search_paths_ptr);
virtual const char *
GetDescription ();
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
index 9bfc0ff2e00..0dff8fd8572 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -13,6 +13,7 @@
// C++ Includes
#include "llvm/Support/MachO.h"
+#include "llvm/Support/MathExtras.h"
// Other libraries and framework includes
#include "lldb/Core/Debugger.h"
@@ -27,6 +28,9 @@
#include "ThreadMachCore.h"
#include "StopInfoMachException.h"
+#include "Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h"
+#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
+
using namespace lldb;
using namespace lldb_private;
@@ -67,7 +71,15 @@ ProcessMachCore::CanDebug(Target &target, bool plugin_specified_by_name)
// For now we are just making sure the file exists for a given module
if (!m_core_module_sp && m_core_file.Exists())
{
- Error error (ModuleList::GetSharedModule(m_core_file, target.GetArchitecture(), NULL, NULL, 0, m_core_module_sp, NULL, NULL));
+ Error error (ModuleList::GetSharedModule (m_core_file,
+ target.GetArchitecture(),
+ NULL,
+ NULL,
+ 0,
+ m_core_module_sp,
+ NULL,
+ NULL,
+ NULL));
if (m_core_module_sp)
{
@@ -92,7 +104,8 @@ ProcessMachCore::ProcessMachCore(Target& target, Listener &listener, const FileS
m_core_aranges (),
m_core_module_sp (),
m_core_file (core_file),
- m_shlib_addr (LLDB_INVALID_ADDRESS)
+ m_dyld_addr (LLDB_INVALID_ADDRESS),
+ m_dyld_plugin_name ()
{
}
@@ -130,6 +143,61 @@ ProcessMachCore::GetPluginVersion()
return 1;
}
+bool
+ProcessMachCore::GetDynamicLoaderAddress (lldb::addr_t addr)
+{
+ llvm::MachO::mach_header header;
+ Error error;
+ if (DoReadMemory (addr, &header, sizeof(header), error) != sizeof(header))
+ return false;
+ if (header.magic == llvm::MachO::HeaderMagic32Swapped ||
+ header.magic == llvm::MachO::HeaderMagic64Swapped)
+ {
+ header.magic = llvm::ByteSwap_32(header.magic);
+ header.cputype = llvm::ByteSwap_32(header.cputype);
+ header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
+ header.filetype = llvm::ByteSwap_32(header.filetype);
+ header.ncmds = llvm::ByteSwap_32(header.ncmds);
+ header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
+ header.flags = llvm::ByteSwap_32(header.flags);
+ }
+
+ // TODO: swap header if needed...
+ //printf("0x%16.16llx: magic = 0x%8.8x, file_type= %u\n", vaddr, header.magic, header.filetype);
+ if (header.magic == llvm::MachO::HeaderMagic32 ||
+ header.magic == llvm::MachO::HeaderMagic64)
+ {
+ // Check MH_EXECUTABLE to see if we can find the mach image
+ // that contains the shared library list. The dynamic loader
+ // (dyld) is what contains the list for user applications,
+ // and the mach kernel contains a global that has the list
+ // of kexts to load
+ switch (header.filetype)
+ {
+ case llvm::MachO::HeaderFileTypeDynamicLinkEditor:
+ //printf("0x%16.16llx: file_type = MH_DYLINKER\n", vaddr);
+ // Address of dyld "struct mach_header" in the core file
+ m_dyld_plugin_name = DynamicLoaderMacOSXDYLD::GetPluginNameStatic();
+ m_dyld_addr = addr;
+ return true;
+
+ case llvm::MachO::HeaderFileTypeExecutable:
+ //printf("0x%16.16llx: file_type = MH_EXECUTE\n", vaddr);
+ // Check MH_EXECUTABLE file types to see if the dynamic link object flag
+ // is NOT set. If it isn't, then we have a mach_kernel.
+ if ((header.flags & llvm::MachO::HeaderFlagBitIsDynamicLinkObject) == 0)
+ {
+ m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
+ // Address of the mach kernel "struct mach_header" in the core file.
+ m_dyld_addr = addr;
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+}
+
//----------------------------------------------------------------------
// Process Control
//----------------------------------------------------------------------
@@ -137,7 +205,12 @@ Error
ProcessMachCore::DoLoadCore ()
{
Error error;
- DataExtractor data;
+ if (!m_core_module_sp)
+ {
+ error.SetErrorString ("invalid core module");
+ return error;
+ }
+
ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
if (core_objfile == NULL)
{
@@ -157,6 +230,13 @@ ProcessMachCore::DoLoadCore ()
error.SetErrorString ("core file has no sections");
return error;
}
+
+ llvm::MachO::mach_header header;
+ DataExtractor data (&header,
+ sizeof(header),
+ m_core_module_sp->GetArchitecture().GetByteOrder(),
+ m_core_module_sp->GetArchitecture().GetAddressByteSize());
+
bool ranges_are_sorted = true;
addr_t vm_addr = 0;
for (uint32_t i=0; i<num_sections; ++i)
@@ -165,44 +245,6 @@ ProcessMachCore::DoLoadCore ()
if (section)
{
lldb::addr_t section_vm_addr = section->GetFileAddress();
-
- if (m_shlib_addr == LLDB_INVALID_ADDRESS)
- {
- if (core_objfile->ReadSectionData (section, data))
- {
- uint32_t offset = 0;
- llvm::MachO::mach_header header;
- if (data.GetU32(&offset, &header, sizeof(header)/sizeof(uint32_t)))
- {
-
- if (header.magic == llvm::MachO::HeaderMagic32 ||
- header.magic == llvm::MachO::HeaderMagic64)
- {
- // Check MH_EXECUTABLE to see if we can find the mach image
- // that contains the shared library list. The dynamic loader
- // (dyld) is what contains the list for user applications,
- // and the mach kernel contains a global that has the list
- // of kexts to load
- switch (header.filetype)
- {
- case llvm::MachO::HeaderFileTypeDynamicLinkEditor:
- // Address of dyld "struct mach_header" in the core file
- m_shlib_addr = section_vm_addr;
- break;
- case llvm::MachO::HeaderFileTypeExecutable:
- // Check MH_EXECUTABLE file types to see if the dynamic link object flag
- // is NOT set. If it isn't, then we have a mach_kernel.
- if ((header.flags & llvm::MachO::HeaderFlagBitIsDynamicLinkObject) == 0)
- {
- // Address of the mach kernel "struct mach_header" in the core file.
- m_shlib_addr = section_vm_addr;
- }
- break;
- }
- }
- }
- }
- }
FileRange file_range (section->GetFileOffset(), section->GetFileSize());
VMRangeToFileOffset::Entry range_entry (section_vm_addr,
section->GetByteSize(),
@@ -212,29 +254,91 @@ ProcessMachCore::DoLoadCore ()
ranges_are_sorted = false;
vm_addr = section->GetFileAddress();
VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back();
+// printf ("LC_SEGMENT[%u] arange=[0x%16.16llx - 0x%16.16llx), frange=[0x%8.8x - 0x%8.8x)\n",
+// i,
+// range_entry.GetRangeBase(),
+// range_entry.GetRangeEnd(),
+// range_entry.data.GetRangeBase(),
+// range_entry.data.GetRangeEnd());
+
if (last_entry &&
last_entry->GetRangeEnd() == range_entry.GetRangeBase() &&
last_entry->data.GetRangeEnd() == range_entry.data.GetRangeBase())
{
last_entry->SetRangeEnd (range_entry.GetRangeEnd());
last_entry->data.SetRangeEnd (range_entry.data.GetRangeEnd());
+ //puts("combine");
}
else
{
m_core_aranges.Append(range_entry);
}
+
+ // After we have added this section to our m_core_aranges map,
+ // we can check the start of the section to see if it might
+ // contain dyld for user space apps, or the mach kernel file
+ // for kernel cores.
+ if (m_dyld_addr == LLDB_INVALID_ADDRESS)
+ GetDynamicLoaderAddress (section_vm_addr);
}
}
if (!ranges_are_sorted)
{
m_core_aranges.Sort();
}
- if (!m_target.GetArchitecture().IsValid())
- m_target.SetArchitecture(m_core_module_sp->GetArchitecture());
+
+ // Even if the architecture is set in the target, we need to override
+ // it to match the core file which is always single arch.
+ ArchSpec arch (m_core_module_sp->GetArchitecture());
+ if (arch.GetCore() == ArchSpec::eCore_x86_32_i486)
+ {
+ arch.SetTriple ("i386", m_target.GetPlatform().get());
+ }
+ if (arch.IsValid())
+ m_target.SetArchitecture(arch);
+
+ if (m_dyld_addr == LLDB_INVALID_ADDRESS)
+ {
+ // Check the magic kernel address for the mach image header address in case
+ // it is there.
+ if (arch.GetAddressByteSize() == 8)
+ {
+ Error header_addr_error;
+ addr_t header_addr = ReadPointerFromMemory (0xffffff8000002010ull, header_addr_error);
+ if (header_addr != LLDB_INVALID_ADDRESS)
+ GetDynamicLoaderAddress (header_addr);
+ }
+
+// if (m_dyld_addr == LLDB_INVALID_ADDRESS)
+// {
+// // We haven't found our dyld or mach_kernel yet,
+// // so we need to exhaustively look
+// const size_t num_core_aranges = m_core_aranges.GetSize();
+// bool done = false;
+// for (size_t i=0; !done && i<num_core_aranges; ++i)
+// {
+// const addr_t start_vaddr = m_core_aranges.GetEntryRef(i).GetRangeBase();
+// const addr_t end_vaddr = m_core_aranges.GetEntryRef(i).GetRangeEnd();
+// // printf("core_arange[%u] [0x%16.16llx - 0x%16.16llx)\n", (uint32_t)i, start_vaddr, end_vaddr);
+//
+// for (addr_t vaddr = start_vaddr; !done && start_vaddr < end_vaddr; vaddr += 0x1000)
+// {
+// done = GetDynamicLoaderAddress (vaddr);
+// }
+// }
+// }
+ }
return error;
}
+lldb_private::DynamicLoader *
+ProcessMachCore::GetDynamicLoader ()
+{
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset (DynamicLoader::FindPlugin(this, m_dyld_plugin_name.empty() ? NULL : m_dyld_plugin_name.c_str()));
+ return m_dyld_ap.get();
+}
uint32_t
ProcessMachCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
@@ -293,6 +397,14 @@ ProcessMachCore::IsAlive ()
// Process Memory
//------------------------------------------------------------------
size_t
+ProcessMachCore::ReadMemory (addr_t addr, void *buf, size_t size, Error &error)
+{
+ // Don't allow the caching that lldb_private::Process::ReadMemory does
+ // since in core files we have it all cached our our core file anyway.
+ return DoReadMemory (addr, buf, size, error);
+}
+
+size_t
ProcessMachCore::DoReadMemory (addr_t addr, void *buf, size_t size, Error &error)
{
ObjectFile *core_objfile = m_core_module_sp->GetObjectFile();
@@ -340,7 +452,7 @@ ProcessMachCore::Initialize()
addr_t
ProcessMachCore::GetImageInfoAddress()
{
- return m_shlib_addr;
+ return m_dyld_addr;
}
diff --git a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
index 79b18e58bdd..924f549475e 100644
--- a/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
+++ b/lldb/source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -68,6 +68,9 @@ public:
virtual lldb_private::Error
DoLoadCore ();
+ virtual lldb_private::DynamicLoader *
+ GetDynamicLoader ();
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
@@ -99,6 +102,9 @@ public:
// Process Memory
//------------------------------------------------------------------
virtual size_t
+ ReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error);
+
+ virtual size_t
DoReadMemory (lldb::addr_t addr, void *buf, size_t size, lldb_private::Error &error);
virtual lldb::addr_t
@@ -120,6 +126,9 @@ protected:
return m_core_module_sp->GetObjectFile();
}
private:
+ bool
+ GetDynamicLoaderAddress (lldb::addr_t addr);
+
//------------------------------------------------------------------
// For ProcessMachCore only
//------------------------------------------------------------------
@@ -129,7 +138,8 @@ private:
VMRangeToFileOffset m_core_aranges;
lldb::ModuleSP m_core_module_sp;
lldb_private::FileSpec m_core_file;
- lldb::addr_t m_shlib_addr;
+ lldb::addr_t m_dyld_addr;
+ std::string m_dyld_plugin_name;
DISALLOW_COPY_AND_ASSIGN (ProcessMachCore);
};
diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp
index 737b8d4914b..1c07db9c644 100644
--- a/lldb/source/Target/Platform.cpp
+++ b/lldb/source/Target/Platform.cpp
@@ -94,6 +94,7 @@ Platform::GetSharedModule (const FileSpec &platform_file,
const ConstString *object_name_ptr,
off_t object_offset,
ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
ModuleSP *old_module_sp_ptr,
bool *did_create_ptr)
{
@@ -111,6 +112,7 @@ Platform::GetSharedModule (const FileSpec &platform_file,
object_name_ptr,
object_offset,
module_sp,
+ module_search_paths_ptr,
old_module_sp_ptr,
did_create_ptr,
always_create);
@@ -403,7 +405,8 @@ Platform::SetOSVersion (uint32_t major,
Error
Platform::ResolveExecutable (const FileSpec &exe_file,
const ArchSpec &exe_arch,
- lldb::ModuleSP &exe_module_sp)
+ lldb::ModuleSP &exe_module_sp,
+ const FileSpecList *module_search_paths_ptr)
{
Error error;
if (exe_file.Exists())
@@ -416,6 +419,7 @@ Platform::ResolveExecutable (const FileSpec &exe_file,
NULL,
0,
exe_module_sp,
+ module_search_paths_ptr,
NULL,
NULL);
}
@@ -433,6 +437,7 @@ Platform::ResolveExecutable (const FileSpec &exe_file,
NULL,
0,
exe_module_sp,
+ module_search_paths_ptr,
NULL,
NULL);
// Did we find an executable using one of the
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 6ed2b2ac040..10922feb7db 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -2193,14 +2193,23 @@ Process::DeallocateMemory (addr_t ptr)
}
ModuleSP
-Process::ReadModuleFromMemory (const FileSpec& file_spec, lldb::addr_t header_addr)
+Process::ReadModuleFromMemory (const FileSpec& file_spec,
+ lldb::addr_t header_addr,
+ bool add_image_to_target,
+ bool load_sections_in_target)
{
ModuleSP module_sp (new Module (file_spec, shared_from_this(), header_addr));
if (module_sp)
{
- m_target.GetImages().Append(module_sp);
- bool changed = false;
- module_sp->SetLoadAddress (m_target, 0, changed);
+ if (add_image_to_target)
+ {
+ m_target.GetImages().Append(module_sp);
+ if (load_sections_in_target)
+ {
+ bool changed = false;
+ module_sp->SetLoadAddress (m_target, 0, changed);
+ }
+ }
}
return module_sp;
}
@@ -2306,9 +2315,9 @@ Process::Launch (const ProcessLaunchInfo &launch_info)
DidLaunch ();
- m_dyld_ap.reset (DynamicLoader::FindPlugin (this, NULL));
- if (m_dyld_ap.get())
- m_dyld_ap->DidLaunch();
+ DynamicLoader *dyld = GetDynamicLoader ();
+ if (dyld)
+ dyld->DidLaunch();
m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
// This delays passing the stopped event to listeners till DidLaunch gets
@@ -2349,7 +2358,11 @@ Process::LoadCore ()
else
StartPrivateStateThread ();
- CompleteAttach ();
+ DynamicLoader *dyld = GetDynamicLoader ();
+ if (dyld)
+ dyld->DidAttach();
+
+ m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
// We successfully loaded a core file, now pretend we stopped so we can
// show all of the threads in the core file and explore the crashed
// state.
@@ -2359,6 +2372,13 @@ Process::LoadCore ()
return error;
}
+DynamicLoader *
+Process::GetDynamicLoader ()
+{
+ if (m_dyld_ap.get() == NULL)
+ m_dyld_ap.reset (DynamicLoader::FindPlugin(this, NULL));
+ return m_dyld_ap.get();
+}
Process::NextEventAction::EventActionResult
@@ -2622,9 +2642,9 @@ Process::CompleteAttach ()
// We have completed the attach, now it is time to find the dynamic loader
// plug-in
- m_dyld_ap.reset (DynamicLoader::FindPlugin(this, NULL));
- if (m_dyld_ap.get())
- m_dyld_ap->DidAttach();
+ DynamicLoader *dyld = GetDynamicLoader ();
+ if (dyld)
+ dyld->DidAttach();
m_os_ap.reset (OperatingSystem::FindPlugin (this, NULL));
// Figure out which one is the executable, and set that in our target:
diff --git a/lldb/source/Target/SectionLoadList.cpp b/lldb/source/Target/SectionLoadList.cpp
index 09431abc00f..df2802378b1 100644
--- a/lldb/source/Target/SectionLoadList.cpp
+++ b/lldb/source/Target/SectionLoadList.cpp
@@ -74,6 +74,9 @@ SectionLoadList::SetSectionLoadAddress (const Section *section, addr_t load_addr
load_addr);
}
+ if (section->GetByteSize() == 0)
+ return false; // No change
+
Mutex::Locker locker(m_mutex);
sect_to_addr_collection::iterator sta_pos = m_sect_to_addr.find(section);
if (sta_pos != m_sect_to_addr.end())
@@ -89,7 +92,19 @@ SectionLoadList::SetSectionLoadAddress (const Section *section, addr_t load_addr
addr_to_sect_collection::iterator ats_pos = m_addr_to_sect.find(load_addr);
if (ats_pos != m_addr_to_sect.end())
{
- assert (section != ats_pos->second);
+ if (section != ats_pos->second)
+ {
+ Module *module = section->GetModule();
+ if (module)
+ {
+ module->ReportWarning ("address 0x%16.16llx maps to more than one section: %s.%s and %s.%s",
+ load_addr,
+ module->GetFileSpec().GetFilename().GetCString(),
+ section->GetName().GetCString(),
+ ats_pos->second->GetModule()->GetFileSpec().GetFilename().GetCString(),
+ ats_pos->second->GetName().GetCString());
+ }
+ }
ats_pos->second = section;
}
else
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 20b8e938fe1..6a6cb0eae7e 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -869,6 +869,7 @@ Target::SetArchitecture (const ArchSpec &arch_spec)
NULL,
0,
executable_sp,
+ &GetExecutableSearchPaths(),
NULL,
NULL);
@@ -1227,7 +1228,15 @@ Target::GetSharedModule
if (m_image_search_paths.RemapPath (file_spec.GetDirectory(), transformed_spec.GetDirectory()))
{
transformed_spec.GetFilename() = file_spec.GetFilename();
- error = ModuleList::GetSharedModule (transformed_spec, arch, uuid_ptr, object_name, object_offset, module_sp, &old_module_sp, &did_create_module);
+ error = ModuleList::GetSharedModule (transformed_spec,
+ arch,
+ uuid_ptr,
+ object_name,
+ object_offset,
+ module_sp,
+ &GetExecutableSearchPaths(),
+ &old_module_sp,
+ &did_create_module);
}
}
@@ -1242,6 +1251,7 @@ Target::GetSharedModule
object_name,
object_offset,
module_sp,
+ &GetExecutableSearchPaths(),
&old_module_sp,
&did_create_module);
}
@@ -1395,6 +1405,20 @@ Target::GetSettingsController ()
return g_settings_controller_sp;
}
+FileSpecList
+Target::GetDefaultExecutableSearchPaths ()
+{
+ lldb::UserSettingsControllerSP settings_controller_sp (GetSettingsController());
+ if (settings_controller_sp)
+ {
+ lldb::InstanceSettingsSP instance_settings_sp (settings_controller_sp->GetDefaultInstanceSettings ());
+ if (instance_settings_sp)
+ return static_cast<TargetInstanceSettings *>(instance_settings_sp.get())->GetExecutableSearchPaths ();
+ }
+ return FileSpecList();
+}
+
+
ArchSpec
Target::GetDefaultArchitecture ()
{
@@ -2016,6 +2040,7 @@ Target::SettingsController::CreateInstanceSettings (const char *instance_name)
#define TSC_PREFER_DYNAMIC "prefer-dynamic-value"
#define TSC_SKIP_PROLOGUE "skip-prologue"
#define TSC_SOURCE_MAP "source-map"
+#define TSC_EXE_SEARCH_PATHS "exec-search-paths"
#define TSC_MAX_CHILDREN "max-children-count"
#define TSC_MAX_STRLENSUMMARY "max-string-summary-length"
#define TSC_PLATFORM_AVOID "breakpoints-use-platform-avoid-list"
@@ -2058,6 +2083,13 @@ GetSettingNameForSourcePathMap ()
}
static const ConstString &
+GetSettingNameForExecutableSearchPaths ()
+{
+ static ConstString g_const_string (TSC_EXE_SEARCH_PATHS);
+ return g_const_string;
+}
+
+static const ConstString &
GetSettingNameForSkipPrologue ()
{
static ConstString g_const_string (TSC_SKIP_PROLOGUE);
@@ -2193,6 +2225,7 @@ TargetInstanceSettings::TargetInstanceSettings
m_prefer_dynamic_value (2),
m_skip_prologue (true, true),
m_source_map (NULL, NULL),
+ m_exe_search_paths (),
m_max_children_display(256),
m_max_strlen_length(1024),
m_breakpoints_use_platform_avoid (true, true),
@@ -2231,6 +2264,7 @@ TargetInstanceSettings::TargetInstanceSettings (const TargetInstanceSettings &rh
m_prefer_dynamic_value (rhs.m_prefer_dynamic_value),
m_skip_prologue (rhs.m_skip_prologue),
m_source_map (rhs.m_source_map),
+ m_exe_search_paths (rhs.m_exe_search_paths),
m_max_children_display (rhs.m_max_children_display),
m_max_strlen_length (rhs.m_max_strlen_length),
m_breakpoints_use_platform_avoid (rhs.m_breakpoints_use_platform_avoid),
@@ -2265,6 +2299,7 @@ TargetInstanceSettings::operator= (const TargetInstanceSettings &rhs)
m_prefer_dynamic_value = rhs.m_prefer_dynamic_value;
m_skip_prologue = rhs.m_skip_prologue;
m_source_map = rhs.m_source_map;
+ m_exe_search_paths = rhs.m_exe_search_paths;
m_max_children_display = rhs.m_max_children_display;
m_max_strlen_length = rhs.m_max_strlen_length;
m_breakpoints_use_platform_avoid = rhs.m_breakpoints_use_platform_avoid;
@@ -2357,6 +2392,49 @@ TargetInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_n
if (ok)
m_max_strlen_length = new_value;
}
+ else if (var_name == GetSettingNameForExecutableSearchPaths())
+ {
+ switch (op)
+ {
+ case eVarSetOperationReplace:
+ case eVarSetOperationInsertBefore:
+ case eVarSetOperationInsertAfter:
+ case eVarSetOperationRemove:
+ default:
+ break;
+ case eVarSetOperationAssign:
+ m_exe_search_paths.Clear();
+ // Fall through to append....
+ case eVarSetOperationAppend:
+ {
+ Args args(value);
+ const uint32_t argc = args.GetArgumentCount();
+ if (argc > 0)
+ {
+ const char *exe_search_path_dir;
+ for (uint32_t idx = 0; (exe_search_path_dir = args.GetArgumentAtIndex(idx)) != NULL; ++idx)
+ {
+ FileSpec file_spec;
+ file_spec.GetDirectory().SetCString(exe_search_path_dir);
+ FileSpec::FileType file_type = file_spec.GetFileType();
+ if (file_type == FileSpec::eFileTypeDirectory || file_type == FileSpec::eFileTypeInvalid)
+ {
+ m_exe_search_paths.Append(file_spec);
+ }
+ else
+ {
+ err.SetErrorStringWithFormat("executable search path '%s' exists, but it does not resolve to a directory", exe_search_path_dir);
+ }
+ }
+ }
+ }
+ break;
+
+ case eVarSetOperationClear:
+ m_exe_search_paths.Clear();
+ break;
+ }
+ }
else if (var_name == GetSettingNameForSourcePathMap ())
{
switch (op)
@@ -2487,6 +2565,16 @@ TargetInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry,
else
value.AppendString ("false");
}
+ else if (var_name == GetSettingNameForExecutableSearchPaths())
+ {
+ if (m_exe_search_paths.GetSize())
+ {
+ for (size_t i = 0, n = m_exe_search_paths.GetSize(); i < n; ++i)
+ {
+ value.AppendString(m_exe_search_paths.GetFileSpecAtIndex (i).GetDirectory().AsCString());
+ }
+ }
+ }
else if (var_name == GetSettingNameForSourcePathMap ())
{
if (m_source_map.GetSize())
@@ -2670,6 +2758,7 @@ Target::SettingsController::instance_settings_table[] =
{ TSC_PREFER_DYNAMIC , eSetVarTypeEnum , NULL , g_dynamic_value_types, false, false, "Should printed values be shown as their dynamic value." },
{ TSC_SKIP_PROLOGUE , eSetVarTypeBoolean, "true" , NULL, false, false, "Skip function prologues when setting breakpoints by name." },
{ TSC_SOURCE_MAP , eSetVarTypeArray , NULL , NULL, false, false, "Source path remappings to use when locating source files from debug information." },
+ { TSC_EXE_SEARCH_PATHS , eSetVarTypeArray , NULL , NULL, false, false, "Executable search paths to use when locating executable files whose paths don't match the local file system." },
{ TSC_MAX_CHILDREN , eSetVarTypeInt , "256" , NULL, true, false, "Maximum number of children to expand in any level of depth." },
{ TSC_MAX_STRLENSUMMARY , eSetVarTypeInt , "1024" , NULL, true, false, "Maximum number of characters to show when using %s in summary strings." },
{ TSC_PLATFORM_AVOID , eSetVarTypeBoolean, "true" , NULL, false, false, "Consult the platform module avoid list when setting non-module specific breakpoints." },
diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp
index 6ca58b86ef5..e412beb1da5 100644
--- a/lldb/source/Target/TargetList.cpp
+++ b/lldb/source/Target/TargetList.cpp
@@ -92,6 +92,16 @@ TargetList::CreateTarget (Debugger &debugger,
get_dependent_files,
platform_sp,
target_sp);
+
+ if (target_sp)
+ {
+ if (file.GetDirectory())
+ {
+ FileSpec file_dir;
+ file_dir.GetDirectory() = file.GetDirectory();
+ target_sp->GetExecutableSearchPaths ().Append (file_dir);
+ }
+ }
return error;
}
@@ -120,7 +130,12 @@ TargetList::CreateTarget
FileSpec resolved_file(file);
if (platform_sp)
- error = platform_sp->ResolveExecutable (file, arch, exe_module_sp);
+ {
+ FileSpecList executable_search_paths (Target::GetDefaultExecutableSearchPaths());
+ error = platform_sp->ResolveExecutable (file, arch,
+ exe_module_sp,
+ executable_search_paths.GetSize() ? &executable_search_paths : NULL);
+ }
if (error.Success() && exe_module_sp)
{
OpenPOWER on IntegriCloud