1 //===-- DynamicLoader.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/lldb-private.h"
11 #include "lldb/Target/DynamicLoader.h"
12 #include "lldb/Target/Process.h"
13 #include "lldb/Target/Target.h"
14 #include "lldb/Core/PluginManager.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/ModuleSpec.h"
17 #include "lldb/Core/Section.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 DynamicLoader*
23 DynamicLoader::FindPlugin (Process *process, const char *plugin_name)
24 {
25     DynamicLoaderCreateInstance create_callback = NULL;
26     if (plugin_name)
27     {
28         ConstString const_plugin_name(plugin_name);
29         create_callback  = PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const_plugin_name);
30         if (create_callback)
31         {
32             std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true));
33             if (instance_ap.get())
34                 return instance_ap.release();
35         }
36     }
37     else
38     {
39         for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != NULL; ++idx)
40         {
41             std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false));
42             if (instance_ap.get())
43                 return instance_ap.release();
44         }
45     }
46     return NULL;
47 }
48 
49 
50 //----------------------------------------------------------------------
51 // DynamicLoader constructor
52 //----------------------------------------------------------------------
53 DynamicLoader::DynamicLoader(Process *process) :
54     m_process (process)
55 {
56 }
57 
58 //----------------------------------------------------------------------
59 // Destructor
60 //----------------------------------------------------------------------
61 DynamicLoader::~DynamicLoader()
62 {
63 }
64 
65 //----------------------------------------------------------------------
66 // Accessosors to the global setting as to whether to stop at image
67 // (shared library) loading/unloading.
68 //----------------------------------------------------------------------
69 bool
70 DynamicLoader::GetStopWhenImagesChange () const
71 {
72     return m_process->GetStopOnSharedLibraryEvents();
73 }
74 
75 void
76 DynamicLoader::SetStopWhenImagesChange (bool stop)
77 {
78     m_process->SetStopOnSharedLibraryEvents (stop);
79 }
80 
81 ModuleSP
82 DynamicLoader::GetTargetExecutable()
83 {
84     Target &target = m_process->GetTarget();
85     ModuleSP executable = target.GetExecutableModule();
86 
87     if (executable.get())
88     {
89         if (executable->GetFileSpec().Exists())
90         {
91             ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture());
92             ModuleSP module_sp (new Module (module_spec));
93 
94             // Check if the executable has changed and set it to the target executable if they differ.
95             if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
96             {
97                 if (module_sp->GetUUID() != executable->GetUUID())
98                     executable.reset();
99             }
100             else if (executable->FileHasChanged())
101             {
102                 executable.reset();
103             }
104 
105             if (!executable.get())
106             {
107                 executable = target.GetSharedModule(module_spec);
108                 if (executable.get() != target.GetExecutableModulePointer())
109                 {
110                     // Don't load dependent images since we are in dyld where we will know
111                     // and find out about all images that are loaded
112                     const bool get_dependent_images = false;
113                     target.SetExecutableModule(executable, get_dependent_images);
114                 }
115             }
116         }
117     }
118     return executable;
119 }
120 
121 void
122 DynamicLoader::UpdateLoadedSections(ModuleSP module,
123                                     addr_t link_map_addr,
124                                     addr_t base_addr,
125                                     bool base_addr_is_offset)
126 {
127     UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
128 }
129 
130 void
131 DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module,
132                                           addr_t base_addr,
133                                           bool base_addr_is_offset)
134 {
135     bool changed;
136     module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed);
137 }
138 
139 void
140 DynamicLoader::UnloadSections(const ModuleSP module)
141 {
142     UnloadSectionsCommon(module);
143 }
144 
145 void
146 DynamicLoader::UnloadSectionsCommon(const ModuleSP module)
147 {
148     Target &target = m_process->GetTarget();
149     const SectionList *sections = GetSectionListFromModule(module);
150 
151     assert(sections && "SectionList missing from unloaded module.");
152 
153     const size_t num_sections = sections->GetSize();
154     for (size_t i = 0; i < num_sections; ++i)
155     {
156         SectionSP section_sp (sections->GetSectionAtIndex(i));
157         target.SetSectionUnloaded(section_sp);
158     }
159 }
160 
161 
162 const SectionList *
163 DynamicLoader::GetSectionListFromModule(const ModuleSP module) const
164 {
165     SectionList *sections = nullptr;
166     if (module.get())
167     {
168         ObjectFile *obj_file = module->GetObjectFile();
169         if (obj_file)
170         {
171             sections = obj_file->GetSectionList();
172         }
173     }
174     return sections;
175 }
176 
177 ModuleSP
178 DynamicLoader::LoadModuleAtAddress(const FileSpec &file,
179                                    addr_t link_map_addr,
180                                    addr_t base_addr,
181                                    bool base_addr_is_offset)
182 {
183     Target &target = m_process->GetTarget();
184     ModuleList &modules = target.GetImages();
185     ModuleSP module_sp;
186 
187     ModuleSpec module_spec (file, target.GetArchitecture());
188     if ((module_sp = modules.FindFirstModule (module_spec)))
189     {
190         UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset);
191     }
192     else if ((module_sp = target.GetSharedModule(module_spec)))
193     {
194         UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset);
195     }
196     else
197     {
198         if (base_addr_is_offset)
199         {
200             // Try to fetch the load address of the file from the process as we need absolute load
201             // address to read the file out of the memory instead of a load bias.
202             bool is_loaded;
203             lldb::addr_t load_addr;
204             Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr);
205             if (error.Success() && is_loaded)
206                 base_addr = load_addr;
207         }
208 
209         if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr)))
210         {
211             UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
212             target.GetImages().AppendIfNeeded(module_sp);
213         }
214     }
215 
216     return module_sp;
217 }
218 
219 int64_t
220 DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes)
221 {
222     Error error;
223 
224     uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
225     if (error.Fail())
226         return -1;
227     else
228         return (int64_t)value;
229 }
230 
231 addr_t
232 DynamicLoader::ReadPointer(addr_t addr)
233 {
234     Error error;
235     addr_t value = m_process->ReadPointerFromMemory(addr, error);
236     if (error.Fail())
237         return LLDB_INVALID_ADDRESS;
238     else
239         return value;
240 }
241