1ac7ddfbfSEd Maste //===-- DynamicLoaderStatic.cpp ---------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "lldb/Core/Module.h"
11ac7ddfbfSEd Maste #include "lldb/Core/PluginManager.h"
12ac7ddfbfSEd Maste #include "lldb/Core/Section.h"
13ac7ddfbfSEd Maste #include "lldb/Symbol/ObjectFile.h"
14ac7ddfbfSEd Maste #include "lldb/Target/Target.h"
15ac7ddfbfSEd Maste 
16ac7ddfbfSEd Maste #include "DynamicLoaderStatic.h"
17ac7ddfbfSEd Maste 
18ac7ddfbfSEd Maste using namespace lldb;
19ac7ddfbfSEd Maste using namespace lldb_private;
20ac7ddfbfSEd Maste 
21ac7ddfbfSEd Maste //----------------------------------------------------------------------
22*4ba319b5SDimitry Andric // Create an instance of this class. This function is filled into the plugin
23*4ba319b5SDimitry Andric // info class that gets handed out by the plugin factory and allows the lldb to
24*4ba319b5SDimitry Andric // instantiate an instance of this class.
25ac7ddfbfSEd Maste //----------------------------------------------------------------------
CreateInstance(Process * process,bool force)26435933ddSDimitry Andric DynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process,
27435933ddSDimitry Andric                                                    bool force) {
28ac7ddfbfSEd Maste   bool create = force;
29435933ddSDimitry Andric   if (!create) {
30435933ddSDimitry Andric     const llvm::Triple &triple_ref =
31435933ddSDimitry Andric         process->GetTarget().GetArchitecture().GetTriple();
32ac7ddfbfSEd Maste     const llvm::Triple::OSType os_type = triple_ref.getOS();
33ac7ddfbfSEd Maste     if ((os_type == llvm::Triple::UnknownOS))
34ac7ddfbfSEd Maste       create = true;
35ac7ddfbfSEd Maste   }
36ac7ddfbfSEd Maste 
37435933ddSDimitry Andric   if (!create) {
38ac7ddfbfSEd Maste     Module *exe_module = process->GetTarget().GetExecutableModulePointer();
39435933ddSDimitry Andric     if (exe_module) {
40ac7ddfbfSEd Maste       ObjectFile *object_file = exe_module->GetObjectFile();
41435933ddSDimitry Andric       if (object_file) {
42ac7ddfbfSEd Maste         create = (object_file->GetStrata() == ObjectFile::eStrataRawImage);
43ac7ddfbfSEd Maste       }
44ac7ddfbfSEd Maste     }
45ac7ddfbfSEd Maste   }
46ac7ddfbfSEd Maste 
47ac7ddfbfSEd Maste   if (create)
48ac7ddfbfSEd Maste     return new DynamicLoaderStatic(process);
49ac7ddfbfSEd Maste   return NULL;
50ac7ddfbfSEd Maste }
51ac7ddfbfSEd Maste 
52ac7ddfbfSEd Maste //----------------------------------------------------------------------
53ac7ddfbfSEd Maste // Constructor
54ac7ddfbfSEd Maste //----------------------------------------------------------------------
DynamicLoaderStatic(Process * process)55435933ddSDimitry Andric DynamicLoaderStatic::DynamicLoaderStatic(Process *process)
56435933ddSDimitry Andric     : DynamicLoader(process) {}
57ac7ddfbfSEd Maste 
58ac7ddfbfSEd Maste //----------------------------------------------------------------------
59ac7ddfbfSEd Maste // Destructor
60ac7ddfbfSEd Maste //----------------------------------------------------------------------
~DynamicLoaderStatic()61435933ddSDimitry Andric DynamicLoaderStatic::~DynamicLoaderStatic() {}
62ac7ddfbfSEd Maste 
63ac7ddfbfSEd Maste //------------------------------------------------------------------
64ac7ddfbfSEd Maste /// Called after attaching a process.
65ac7ddfbfSEd Maste ///
66ac7ddfbfSEd Maste /// Allow DynamicLoader plug-ins to execute some code after
67ac7ddfbfSEd Maste /// attaching to a process.
68ac7ddfbfSEd Maste //------------------------------------------------------------------
DidAttach()69435933ddSDimitry Andric void DynamicLoaderStatic::DidAttach() { LoadAllImagesAtFileAddresses(); }
70ac7ddfbfSEd Maste 
71ac7ddfbfSEd Maste //------------------------------------------------------------------
72ac7ddfbfSEd Maste /// Called after attaching a process.
73ac7ddfbfSEd Maste ///
74ac7ddfbfSEd Maste /// Allow DynamicLoader plug-ins to execute some code after
75ac7ddfbfSEd Maste /// attaching to a process.
76ac7ddfbfSEd Maste //------------------------------------------------------------------
DidLaunch()77435933ddSDimitry Andric void DynamicLoaderStatic::DidLaunch() { LoadAllImagesAtFileAddresses(); }
78ac7ddfbfSEd Maste 
LoadAllImagesAtFileAddresses()79435933ddSDimitry Andric void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() {
80ac7ddfbfSEd Maste   const ModuleList &module_list = m_process->GetTarget().GetImages();
81ac7ddfbfSEd Maste 
82ac7ddfbfSEd Maste   ModuleList loaded_module_list;
83ac7ddfbfSEd Maste 
84ac7ddfbfSEd Maste   // Disable JIT for static dynamic loader targets
85ac7ddfbfSEd Maste   m_process->SetCanJIT(false);
86ac7ddfbfSEd Maste 
874bb0738eSEd Maste   std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
88ac7ddfbfSEd Maste 
89ac7ddfbfSEd Maste   const size_t num_modules = module_list.GetSize();
90435933ddSDimitry Andric   for (uint32_t idx = 0; idx < num_modules; ++idx) {
91ac7ddfbfSEd Maste     ModuleSP module_sp(module_list.GetModuleAtIndexUnlocked(idx));
92435933ddSDimitry Andric     if (module_sp) {
93ac7ddfbfSEd Maste       bool changed = false;
94ac7ddfbfSEd Maste       ObjectFile *image_object_file = module_sp->GetObjectFile();
95435933ddSDimitry Andric       if (image_object_file) {
96ac7ddfbfSEd Maste         SectionList *section_list = image_object_file->GetSectionList();
97435933ddSDimitry Andric         if (section_list) {
98ac7ddfbfSEd Maste           // All sections listed in the dyld image info structure will all
99ac7ddfbfSEd Maste           // either be fixed up already, or they will all be off by a single
100*4ba319b5SDimitry Andric           // slide amount that is determined by finding the first segment that
101*4ba319b5SDimitry Andric           // is at file offset zero which also has bytes (a file size that is
102*4ba319b5SDimitry Andric           // greater than zero) in the object file.
103ac7ddfbfSEd Maste 
104ac7ddfbfSEd Maste           // Determine the slide amount (if any)
105ac7ddfbfSEd Maste           const size_t num_sections = section_list->GetSize();
106ac7ddfbfSEd Maste           size_t sect_idx = 0;
107435933ddSDimitry Andric           for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
108*4ba319b5SDimitry Andric             // Iterate through the object file sections to find the first
109*4ba319b5SDimitry Andric             // section that starts of file offset zero and that has bytes in
110*4ba319b5SDimitry Andric             // the file...
111ac7ddfbfSEd Maste             SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
112435933ddSDimitry Andric             if (section_sp) {
113435933ddSDimitry Andric               if (m_process->GetTarget().SetSectionLoadAddress(
114435933ddSDimitry Andric                       section_sp, section_sp->GetFileAddress()))
115ac7ddfbfSEd Maste                 changed = true;
116ac7ddfbfSEd Maste             }
117ac7ddfbfSEd Maste           }
118ac7ddfbfSEd Maste         }
119ac7ddfbfSEd Maste       }
120ac7ddfbfSEd Maste 
121ac7ddfbfSEd Maste       if (changed)
122ac7ddfbfSEd Maste         loaded_module_list.AppendIfNeeded(module_sp);
123ac7ddfbfSEd Maste     }
124ac7ddfbfSEd Maste   }
125ac7ddfbfSEd Maste 
126ac7ddfbfSEd Maste   m_process->GetTarget().ModulesDidLoad(loaded_module_list);
127ac7ddfbfSEd Maste }
128ac7ddfbfSEd Maste 
129ac7ddfbfSEd Maste ThreadPlanSP
GetStepThroughTrampolinePlan(Thread & thread,bool stop_others)130435933ddSDimitry Andric DynamicLoaderStatic::GetStepThroughTrampolinePlan(Thread &thread,
131435933ddSDimitry Andric                                                   bool stop_others) {
132ac7ddfbfSEd Maste   return ThreadPlanSP();
133ac7ddfbfSEd Maste }
134ac7ddfbfSEd Maste 
CanLoadImage()1355517e702SDimitry Andric Status DynamicLoaderStatic::CanLoadImage() {
1365517e702SDimitry Andric   Status error;
137ac7ddfbfSEd Maste   error.SetErrorString("can't load images on with a static debug session");
138ac7ddfbfSEd Maste   return error;
139ac7ddfbfSEd Maste }
140ac7ddfbfSEd Maste 
Initialize()141435933ddSDimitry Andric void DynamicLoaderStatic::Initialize() {
142ac7ddfbfSEd Maste   PluginManager::RegisterPlugin(GetPluginNameStatic(),
143435933ddSDimitry Andric                                 GetPluginDescriptionStatic(), CreateInstance);
144ac7ddfbfSEd Maste }
145ac7ddfbfSEd Maste 
Terminate()146435933ddSDimitry Andric void DynamicLoaderStatic::Terminate() {
147ac7ddfbfSEd Maste   PluginManager::UnregisterPlugin(CreateInstance);
148ac7ddfbfSEd Maste }
149ac7ddfbfSEd Maste 
GetPluginNameStatic()150435933ddSDimitry Andric lldb_private::ConstString DynamicLoaderStatic::GetPluginNameStatic() {
151ac7ddfbfSEd Maste   static ConstString g_name("static");
152ac7ddfbfSEd Maste   return g_name;
153ac7ddfbfSEd Maste }
154ac7ddfbfSEd Maste 
GetPluginDescriptionStatic()155435933ddSDimitry Andric const char *DynamicLoaderStatic::GetPluginDescriptionStatic() {
156435933ddSDimitry Andric   return "Dynamic loader plug-in that will load any images at the static "
157435933ddSDimitry Andric          "addresses contained in each image.";
158ac7ddfbfSEd Maste }
159ac7ddfbfSEd Maste 
160ac7ddfbfSEd Maste //------------------------------------------------------------------
161ac7ddfbfSEd Maste // PluginInterface protocol
162ac7ddfbfSEd Maste //------------------------------------------------------------------
GetPluginName()163435933ddSDimitry Andric lldb_private::ConstString DynamicLoaderStatic::GetPluginName() {
164ac7ddfbfSEd Maste   return GetPluginNameStatic();
165ac7ddfbfSEd Maste }
166ac7ddfbfSEd Maste 
GetPluginVersion()167435933ddSDimitry Andric uint32_t DynamicLoaderStatic::GetPluginVersion() { return 1; }
168