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