blob: 625cccc8e88ebd1af6329ff640cd42faee4a06d7 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Eugene Zelenko34ede342016-03-03 00:51:40 +000010// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014#include "lldb/lldb-private.h"
Steve Pucci9e02dac2014-02-06 19:02:19 +000015#include "lldb/Core/Module.h"
16#include "lldb/Core/ModuleSpec.h"
Tamas Berghammerd7d69f82016-07-22 12:55:35 +000017#include "lldb/Core/PluginManager.h"
Steve Pucci9e02dac2014-02-06 19:02:19 +000018#include "lldb/Core/Section.h"
Tamas Berghammerd7d69f82016-07-22 12:55:35 +000019#include "lldb/Target/DynamicLoader.h"
20#include "lldb/Target/MemoryRegionInfo.h"
21#include "lldb/Target/Process.h"
22#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023
24using namespace lldb;
25using namespace lldb_private;
26
27DynamicLoader*
28DynamicLoader::FindPlugin (Process *process, const char *plugin_name)
29{
Eugene Zelenko34ede342016-03-03 00:51:40 +000030 DynamicLoaderCreateInstance create_callback = nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031 if (plugin_name)
32 {
Greg Clayton57abc5d2013-05-10 21:47:16 +000033 ConstString const_plugin_name(plugin_name);
34 create_callback = PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const_plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000035 if (create_callback)
36 {
Greg Clayton7b0992d2013-04-18 22:45:39 +000037 std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true));
Eugene Zelenko34ede342016-03-03 00:51:40 +000038 if (instance_ap)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000039 return instance_ap.release();
40 }
41 }
42 else
43 {
Eugene Zelenko34ede342016-03-03 00:51:40 +000044 for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != nullptr; ++idx)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000045 {
Greg Clayton7b0992d2013-04-18 22:45:39 +000046 std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false));
Eugene Zelenko34ede342016-03-03 00:51:40 +000047 if (instance_ap)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000048 return instance_ap.release();
49 }
50 }
Eugene Zelenko34ede342016-03-03 00:51:40 +000051 return nullptr;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052}
53
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054DynamicLoader::DynamicLoader(Process *process) :
Jim Ingham29950772013-01-26 02:19:28 +000055 m_process (process)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000056{
57}
58
Eugene Zelenko34ede342016-03-03 00:51:40 +000059DynamicLoader::~DynamicLoader() = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000060
61//----------------------------------------------------------------------
Greg Claytoned8a7052010-09-18 03:37:20 +000062// Accessosors to the global setting as to whether to stop at image
Chris Lattner30fdc8d2010-06-08 16:52:24 +000063// (shared library) loading/unloading.
64//----------------------------------------------------------------------
Eugene Zelenko34ede342016-03-03 00:51:40 +000065
Chris Lattner30fdc8d2010-06-08 16:52:24 +000066bool
67DynamicLoader::GetStopWhenImagesChange () const
68{
Jim Ingham29950772013-01-26 02:19:28 +000069 return m_process->GetStopOnSharedLibraryEvents();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000070}
71
72void
73DynamicLoader::SetStopWhenImagesChange (bool stop)
74{
Jim Ingham29950772013-01-26 02:19:28 +000075 m_process->SetStopOnSharedLibraryEvents (stop);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076}
77
Steve Pucci9e02dac2014-02-06 19:02:19 +000078ModuleSP
79DynamicLoader::GetTargetExecutable()
80{
81 Target &target = m_process->GetTarget();
82 ModuleSP executable = target.GetExecutableModule();
83
Eugene Zelenko34ede342016-03-03 00:51:40 +000084 if (executable)
Steve Pucci9e02dac2014-02-06 19:02:19 +000085 {
86 if (executable->GetFileSpec().Exists())
87 {
88 ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture());
89 ModuleSP module_sp (new Module (module_spec));
90
91 // Check if the executable has changed and set it to the target executable if they differ.
Eugene Zelenko34ede342016-03-03 00:51:40 +000092 if (module_sp && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
Steve Pucci9e02dac2014-02-06 19:02:19 +000093 {
94 if (module_sp->GetUUID() != executable->GetUUID())
95 executable.reset();
96 }
97 else if (executable->FileHasChanged())
98 {
99 executable.reset();
100 }
101
Eugene Zelenko34ede342016-03-03 00:51:40 +0000102 if (!executable)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000103 {
104 executable = target.GetSharedModule(module_spec);
105 if (executable.get() != target.GetExecutableModulePointer())
106 {
107 // Don't load dependent images since we are in dyld where we will know
108 // and find out about all images that are loaded
109 const bool get_dependent_images = false;
110 target.SetExecutableModule(executable, get_dependent_images);
111 }
112 }
113 }
114 }
115 return executable;
116}
117
118void
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000119DynamicLoader::UpdateLoadedSections(ModuleSP module,
120 addr_t link_map_addr,
121 addr_t base_addr,
122 bool base_addr_is_offset)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000123{
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000124 UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
Steve Pucci9e02dac2014-02-06 19:02:19 +0000125}
126
127void
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000128DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module,
129 addr_t base_addr,
130 bool base_addr_is_offset)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000131{
132 bool changed;
Greg Clayton751caf62014-02-07 22:54:47 +0000133 module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed);
Steve Pucci9e02dac2014-02-06 19:02:19 +0000134}
135
136void
137DynamicLoader::UnloadSections(const ModuleSP module)
138{
139 UnloadSectionsCommon(module);
140}
141
142void
143DynamicLoader::UnloadSectionsCommon(const ModuleSP module)
144{
145 Target &target = m_process->GetTarget();
146 const SectionList *sections = GetSectionListFromModule(module);
147
148 assert(sections && "SectionList missing from unloaded module.");
149
150 const size_t num_sections = sections->GetSize();
151 for (size_t i = 0; i < num_sections; ++i)
152 {
153 SectionSP section_sp (sections->GetSectionAtIndex(i));
154 target.SetSectionUnloaded(section_sp);
155 }
156}
157
Steve Pucci9e02dac2014-02-06 19:02:19 +0000158const SectionList *
159DynamicLoader::GetSectionListFromModule(const ModuleSP module) const
160{
161 SectionList *sections = nullptr;
Eugene Zelenko34ede342016-03-03 00:51:40 +0000162 if (module)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000163 {
164 ObjectFile *obj_file = module->GetObjectFile();
Eugene Zelenko34ede342016-03-03 00:51:40 +0000165 if (obj_file != nullptr)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000166 {
167 sections = obj_file->GetSectionList();
168 }
169 }
170 return sections;
171}
172
173ModuleSP
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000174DynamicLoader::LoadModuleAtAddress(const FileSpec &file,
175 addr_t link_map_addr,
176 addr_t base_addr,
177 bool base_addr_is_offset)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000178{
179 Target &target = m_process->GetTarget();
180 ModuleList &modules = target.GetImages();
Tamas Berghammerd7d69f82016-07-22 12:55:35 +0000181 ModuleSpec module_spec (file, target.GetArchitecture());
Steve Pucci9e02dac2014-02-06 19:02:19 +0000182 ModuleSP module_sp;
183
Steve Pucci9e02dac2014-02-06 19:02:19 +0000184 if ((module_sp = modules.FindFirstModule (module_spec)))
185 {
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000186 UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset);
Tamas Berghammerd7d69f82016-07-22 12:55:35 +0000187 return module_sp;
Steve Pucci9e02dac2014-02-06 19:02:19 +0000188 }
Tamas Berghammerd7d69f82016-07-22 12:55:35 +0000189
190 if ((module_sp = target.GetSharedModule(module_spec)))
Steve Pucci9e02dac2014-02-06 19:02:19 +0000191 {
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000192 UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset);
Tamas Berghammerd7d69f82016-07-22 12:55:35 +0000193 return module_sp;
Steve Pucci9e02dac2014-02-06 19:02:19 +0000194 }
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000195
Tamas Berghammerd7d69f82016-07-22 12:55:35 +0000196 bool check_alternative_file_name = true;
197 if (base_addr_is_offset)
198 {
199 // Try to fetch the load address of the file from the process as we need absolute load
200 // address to read the file out of the memory instead of a load bias.
201 bool is_loaded = false;
202 lldb::addr_t load_addr;
203 Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr);
204 if (error.Success() && is_loaded)
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000205 {
Tamas Berghammerd7d69f82016-07-22 12:55:35 +0000206 check_alternative_file_name = false;
207 base_addr = load_addr;
Tamas Berghammerf2561842015-06-30 10:41:23 +0000208 }
209 }
Steve Pucci9e02dac2014-02-06 19:02:19 +0000210
Tamas Berghammerd7d69f82016-07-22 12:55:35 +0000211 // We failed to find the module based on its name. Lets try to check if we can find a
212 // different name based on the memory region info.
213 if (check_alternative_file_name)
214 {
215 MemoryRegionInfo memory_info;
216 Error error = m_process->GetMemoryRegionInfo(base_addr, memory_info);
217 if (error.Success() && memory_info.GetMapped() && memory_info.GetRange().GetRangeBase() == base_addr)
218 {
219 ModuleSpec new_module_spec(FileSpec(memory_info.GetName().AsCString(), false),
220 target.GetArchitecture());
221
222 if ((module_sp = modules.FindFirstModule(new_module_spec)))
223 {
224 UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
225 return module_sp;
226 }
227
228 if ((module_sp = target.GetSharedModule(new_module_spec)))
229 {
230 UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
231 return module_sp;
232 }
233 }
234 }
235
236 if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr)))
237 {
238 UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
239 target.GetImages().AppendIfNeeded(module_sp);
240 }
241
Steve Pucci9e02dac2014-02-06 19:02:19 +0000242 return module_sp;
243}
244
245int64_t
246DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes)
247{
248 Error error;
Steve Pucci9e02dac2014-02-06 19:02:19 +0000249 uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
250 if (error.Fail())
251 return -1;
252 else
253 return (int64_t)value;
254}
255
256addr_t
257DynamicLoader::ReadPointer(addr_t addr)
258{
259 Error error;
260 addr_t value = m_process->ReadPointerFromMemory(addr, error);
261 if (error.Fail())
262 return LLDB_INVALID_ADDRESS;
263 else
264 return value;
265}