blob: 4d2824c5f33420273fbc7c7549492a616d02aacd [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
10#include "lldb/lldb-private.h"
11#include "lldb/Target/DynamicLoader.h"
Jim Ingham29950772013-01-26 02:19:28 +000012#include "lldb/Target/Process.h"
Steve Pucci9e02dac2014-02-06 19:02:19 +000013#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000014#include "lldb/Core/PluginManager.h"
Steve Pucci9e02dac2014-02-06 19:02:19 +000015#include "lldb/Core/Module.h"
16#include "lldb/Core/ModuleSpec.h"
17#include "lldb/Core/Section.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018
19using namespace lldb;
20using namespace lldb_private;
21
22DynamicLoader*
23DynamicLoader::FindPlugin (Process *process, const char *plugin_name)
24{
25 DynamicLoaderCreateInstance create_callback = NULL;
26 if (plugin_name)
27 {
Greg Clayton57abc5d2013-05-10 21:47:16 +000028 ConstString const_plugin_name(plugin_name);
29 create_callback = PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const_plugin_name);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030 if (create_callback)
31 {
Greg Clayton7b0992d2013-04-18 22:45:39 +000032 std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033 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 {
Greg Clayton7b0992d2013-04-18 22:45:39 +000041 std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false));
Chris Lattner30fdc8d2010-06-08 16:52:24 +000042 if (instance_ap.get())
43 return instance_ap.release();
44 }
45 }
46 return NULL;
47}
48
49
50//----------------------------------------------------------------------
51// DynamicLoader constructor
52//----------------------------------------------------------------------
53DynamicLoader::DynamicLoader(Process *process) :
Jim Ingham29950772013-01-26 02:19:28 +000054 m_process (process)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055{
56}
57
58//----------------------------------------------------------------------
59// Destructor
60//----------------------------------------------------------------------
61DynamicLoader::~DynamicLoader()
62{
63}
64
65//----------------------------------------------------------------------
Greg Claytoned8a7052010-09-18 03:37:20 +000066// Accessosors to the global setting as to whether to stop at image
Chris Lattner30fdc8d2010-06-08 16:52:24 +000067// (shared library) loading/unloading.
68//----------------------------------------------------------------------
69bool
70DynamicLoader::GetStopWhenImagesChange () const
71{
Jim Ingham29950772013-01-26 02:19:28 +000072 return m_process->GetStopOnSharedLibraryEvents();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073}
74
75void
76DynamicLoader::SetStopWhenImagesChange (bool stop)
77{
Jim Ingham29950772013-01-26 02:19:28 +000078 m_process->SetStopOnSharedLibraryEvents (stop);
Chris Lattner30fdc8d2010-06-08 16:52:24 +000079}
80
Steve Pucci9e02dac2014-02-06 19:02:19 +000081ModuleSP
82DynamicLoader::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
121void
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000122DynamicLoader::UpdateLoadedSections(ModuleSP module,
123 addr_t link_map_addr,
124 addr_t base_addr,
125 bool base_addr_is_offset)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000126{
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000127 UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
Steve Pucci9e02dac2014-02-06 19:02:19 +0000128}
129
130void
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000131DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module,
132 addr_t base_addr,
133 bool base_addr_is_offset)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000134{
135 bool changed;
Greg Clayton751caf62014-02-07 22:54:47 +0000136 module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed);
Steve Pucci9e02dac2014-02-06 19:02:19 +0000137}
138
139void
140DynamicLoader::UnloadSections(const ModuleSP module)
141{
142 UnloadSectionsCommon(module);
143}
144
145void
146DynamicLoader::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
162const SectionList *
163DynamicLoader::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
177ModuleSP
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000178DynamicLoader::LoadModuleAtAddress(const FileSpec &file,
179 addr_t link_map_addr,
180 addr_t base_addr,
181 bool base_addr_is_offset)
Steve Pucci9e02dac2014-02-06 19:02:19 +0000182{
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 {
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000190 UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset);
Steve Pucci9e02dac2014-02-06 19:02:19 +0000191 }
192 else if ((module_sp = target.GetSharedModule(module_spec)))
193 {
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000194 UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset);
Steve Pucci9e02dac2014-02-06 19:02:19 +0000195 }
Tamas Berghammerf2561842015-06-30 10:41:23 +0000196 else
197 {
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000198 if (base_addr_is_offset)
Tamas Berghammerf2561842015-06-30 10:41:23 +0000199 {
Tamas Berghammer42ecef32015-08-24 10:21:55 +0000200 // 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);
Tamas Berghammerf2561842015-06-30 10:41:23 +0000212 target.GetImages().AppendIfNeeded(module_sp);
213 }
214 }
Steve Pucci9e02dac2014-02-06 19:02:19 +0000215
216 return module_sp;
217}
218
219int64_t
220DynamicLoader::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
231addr_t
232DynamicLoader::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}