|  | //===-- DynamicLoaderStatic.cpp ---------------------------------*- C++ -*-===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "lldb/Core/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 NULL; | 
|  | } | 
|  |  | 
|  | //---------------------------------------------------------------------- | 
|  | // 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); | 
|  |  | 
|  | Mutex::Locker mutex_locker(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(); | 
|  | } | 
|  |  | 
|  | Error | 
|  | DynamicLoaderStatic::CanLoadImage () | 
|  | { | 
|  | Error 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; | 
|  | } | 
|  |  |