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