1 //===-- DynamicLoaderStatic.cpp ---------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Core/Module.h"
11 #include "lldb/Core/PluginManager.h"
12 #include "lldb/Target/Target.h"
13 
14 #include "DynamicLoaderStatic.h"
15 
16 using namespace lldb;
17 using namespace lldb_private;
18 
19 //----------------------------------------------------------------------
20 // Create an instance of this class. This function is filled into
21 // the plugin info class that gets handed out by the plugin factory and
22 // allows the lldb to instantiate an instance of this class.
23 //----------------------------------------------------------------------
24 DynamicLoader *
25 DynamicLoaderStatic::CreateInstance (Process* process, bool force)
26 {
27     bool create = force;
28     if (!create)
29     {
30         const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
31         const llvm::Triple::OSType os_type = triple_ref.getOS();
32         if ((os_type == llvm::Triple::UnknownOS))
33             create = true;
34     }
35 
36     if (!create)
37     {
38         Module *exe_module = process->GetTarget().GetExecutableModulePointer();
39         if (exe_module)
40         {
41             ObjectFile *object_file = exe_module->GetObjectFile();
42             if (object_file)
43             {
44                 create = (object_file->GetStrata() == ObjectFile::eStrataRawImage);
45             }
46         }
47     }
48 
49     if (create)
50         return new DynamicLoaderStatic (process);
51     return NULL;
52 }
53 
54 //----------------------------------------------------------------------
55 // Constructor
56 //----------------------------------------------------------------------
57 DynamicLoaderStatic::DynamicLoaderStatic (Process* process) :
58     DynamicLoader(process)
59 {
60 }
61 
62 //----------------------------------------------------------------------
63 // Destructor
64 //----------------------------------------------------------------------
65 DynamicLoaderStatic::~DynamicLoaderStatic()
66 {
67 }
68 
69 //------------------------------------------------------------------
70 /// Called after attaching a process.
71 ///
72 /// Allow DynamicLoader plug-ins to execute some code after
73 /// attaching to a process.
74 //------------------------------------------------------------------
75 void
76 DynamicLoaderStatic::DidAttach ()
77 {
78     LoadAllImagesAtFileAddresses();
79 }
80 
81 //------------------------------------------------------------------
82 /// Called after attaching a process.
83 ///
84 /// Allow DynamicLoader plug-ins to execute some code after
85 /// attaching to a process.
86 //------------------------------------------------------------------
87 void
88 DynamicLoaderStatic::DidLaunch ()
89 {
90     LoadAllImagesAtFileAddresses();
91 }
92 
93 void
94 DynamicLoaderStatic::LoadAllImagesAtFileAddresses ()
95 {
96     ModuleList &module_list = m_process->GetTarget().GetImages();
97 
98     ModuleList loaded_module_list;
99 
100     Mutex::Locker mutex_locker(module_list.GetMutex());
101 
102     const size_t num_modules = module_list.GetSize();
103     for (uint32_t idx = 0; idx < num_modules; ++idx)
104     {
105         ModuleSP module_sp (module_list.GetModuleAtIndexUnlocked (idx));
106         if (module_sp)
107         {
108             bool changed = false;
109             ObjectFile *image_object_file = module_sp->GetObjectFile();
110             if (image_object_file)
111             {
112                 SectionList *section_list = image_object_file->GetSectionList ();
113                 if (section_list)
114                 {
115                     // All sections listed in the dyld image info structure will all
116                     // either be fixed up already, or they will all be off by a single
117                     // slide amount that is determined by finding the first segment
118                     // that is at file offset zero which also has bytes (a file size
119                     // that is greater than zero) in the object file.
120 
121                     // Determine the slide amount (if any)
122                     const size_t num_sections = section_list->GetSize();
123                     size_t sect_idx = 0;
124                     for (sect_idx = 0; sect_idx < num_sections; ++sect_idx)
125                     {
126                         // Iterate through the object file sections to find the
127                         // first section that starts of file offset zero and that
128                         // has bytes in the file...
129                         Section *section = section_list->GetSectionAtIndex (sect_idx).get();
130                         if (section)
131                         {
132                             if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section, section->GetFileAddress()))
133                                 changed = true;
134                         }
135                     }
136                 }
137             }
138 
139             if (changed)
140                 loaded_module_list.AppendIfNeeded (module_sp);
141         }
142     }
143 
144     if (loaded_module_list.GetSize())
145         m_process->GetTarget().ModulesDidLoad (loaded_module_list);
146 }
147 
148 ThreadPlanSP
149 DynamicLoaderStatic::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
150 {
151     return ThreadPlanSP();
152 }
153 
154 Error
155 DynamicLoaderStatic::CanLoadImage ()
156 {
157     Error error;
158     error.SetErrorString ("can't load images on with a static debug session");
159     return error;
160 }
161 
162 void
163 DynamicLoaderStatic::Initialize()
164 {
165     PluginManager::RegisterPlugin (GetPluginNameStatic(),
166                                    GetPluginDescriptionStatic(),
167                                    CreateInstance);
168 }
169 
170 void
171 DynamicLoaderStatic::Terminate()
172 {
173     PluginManager::UnregisterPlugin (CreateInstance);
174 }
175 
176 
177 const char *
178 DynamicLoaderStatic::GetPluginNameStatic()
179 {
180     return "dynamic-loader.static";
181 }
182 
183 const char *
184 DynamicLoaderStatic::GetPluginDescriptionStatic()
185 {
186     return "Dynamic loader plug-in that will load any images at the static addresses contained in each image.";
187 }
188 
189 
190 //------------------------------------------------------------------
191 // PluginInterface protocol
192 //------------------------------------------------------------------
193 const char *
194 DynamicLoaderStatic::GetPluginName()
195 {
196     return "DynamicLoaderStatic";
197 }
198 
199 const char *
200 DynamicLoaderStatic::GetShortPluginName()
201 {
202     return GetPluginNameStatic();
203 }
204 
205 uint32_t
206 DynamicLoaderStatic::GetPluginVersion()
207 {
208     return 1;
209 }
210 
211