diff options
Diffstat (limited to 'lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp')
| -rw-r--r-- | lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp | 154 | 
1 files changed, 154 insertions, 0 deletions
diff --git a/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp new file mode 100644 index 000000000000..6bc951c4d35b --- /dev/null +++ b/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp @@ -0,0 +1,154 @@ +//===-- DynamicLoaderStatic.cpp ---------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/Target.h" + +#include "DynamicLoaderStatic.h" + +using namespace lldb; +using namespace lldb_private; + +// Create an instance of this class. This function is filled into the plugin +// info class that gets handed out by the plugin factory and allows the lldb to +// instantiate an instance of this class. +DynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process, +                                                   bool force) { +  bool create = force; +  if (!create) { +    const llvm::Triple &triple_ref = +        process->GetTarget().GetArchitecture().GetTriple(); +    const llvm::Triple::OSType os_type = triple_ref.getOS(); +    if ((os_type == llvm::Triple::UnknownOS)) +      create = true; +  } + +  if (!create) { +    Module *exe_module = process->GetTarget().GetExecutableModulePointer(); +    if (exe_module) { +      ObjectFile *object_file = exe_module->GetObjectFile(); +      if (object_file) { +        create = (object_file->GetStrata() == ObjectFile::eStrataRawImage); +      } +    } +  } + +  if (create) +    return new DynamicLoaderStatic(process); +  return nullptr; +} + +// Constructor +DynamicLoaderStatic::DynamicLoaderStatic(Process *process) +    : DynamicLoader(process) {} + +// Destructor +DynamicLoaderStatic::~DynamicLoaderStatic() {} + +/// Called after attaching a process. +/// +/// Allow DynamicLoader plug-ins to execute some code after +/// attaching to a process. +void DynamicLoaderStatic::DidAttach() { LoadAllImagesAtFileAddresses(); } + +/// Called after attaching a process. +/// +/// Allow DynamicLoader plug-ins to execute some code after +/// attaching to a process. +void DynamicLoaderStatic::DidLaunch() { LoadAllImagesAtFileAddresses(); } + +void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() { +  const ModuleList &module_list = m_process->GetTarget().GetImages(); + +  ModuleList loaded_module_list; + +  // Disable JIT for static dynamic loader targets +  m_process->SetCanJIT(false); + +  std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex()); + +  const size_t num_modules = module_list.GetSize(); +  for (uint32_t idx = 0; idx < num_modules; ++idx) { +    ModuleSP module_sp(module_list.GetModuleAtIndexUnlocked(idx)); +    if (module_sp) { +      bool changed = false; +      ObjectFile *image_object_file = module_sp->GetObjectFile(); +      if (image_object_file) { +        SectionList *section_list = image_object_file->GetSectionList(); +        if (section_list) { +          // 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 = section_list->GetSize(); +          size_t sect_idx = 0; +          for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) { +            // Iterate through the object file sections to find the first +            // section that starts of file offset zero and that has bytes in +            // the file... +            SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); +            if (section_sp) { +              if (m_process->GetTarget().SetSectionLoadAddress( +                      section_sp, section_sp->GetFileAddress())) +                changed = true; +            } +          } +        } +      } + +      if (changed) +        loaded_module_list.AppendIfNeeded(module_sp); +    } +  } + +  m_process->GetTarget().ModulesDidLoad(loaded_module_list); +} + +ThreadPlanSP +DynamicLoaderStatic::GetStepThroughTrampolinePlan(Thread &thread, +                                                  bool stop_others) { +  return ThreadPlanSP(); +} + +Status DynamicLoaderStatic::CanLoadImage() { +  Status error; +  error.SetErrorString("can't load images on with a static debug session"); +  return error; +} + +void DynamicLoaderStatic::Initialize() { +  PluginManager::RegisterPlugin(GetPluginNameStatic(), +                                GetPluginDescriptionStatic(), CreateInstance); +} + +void DynamicLoaderStatic::Terminate() { +  PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ConstString DynamicLoaderStatic::GetPluginNameStatic() { +  static ConstString g_name("static"); +  return g_name; +} + +const char *DynamicLoaderStatic::GetPluginDescriptionStatic() { +  return "Dynamic loader plug-in that will load any images at the static " +         "addresses contained in each image."; +} + +// PluginInterface protocol +lldb_private::ConstString DynamicLoaderStatic::GetPluginName() { +  return GetPluginNameStatic(); +} + +uint32_t DynamicLoaderStatic::GetPluginVersion() { return 1; }  | 
