LLDB  mainline
DynamicLoader.cpp
Go to the documentation of this file.
1 //===-- DynamicLoader.cpp -------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include "lldb/Core/Module.h"
12 #include "lldb/Core/ModuleList.h"
13 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Core/Section.h"
16 #include "lldb/Symbol/ObjectFile.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/Target.h"
22 
23 #include "llvm/ADT/StringRef.h"
24 
25 #include <memory>
26 
27 #include <cassert>
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 DynamicLoader *DynamicLoader::FindPlugin(Process *process,
33  const char *plugin_name) {
34  DynamicLoaderCreateInstance create_callback = nullptr;
35  if (plugin_name) {
36  ConstString const_plugin_name(plugin_name);
37  create_callback =
38  PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
39  const_plugin_name);
40  if (create_callback) {
41  std::unique_ptr<DynamicLoader> instance_up(
42  create_callback(process, true));
43  if (instance_up)
44  return instance_up.release();
45  }
46  } else {
47  for (uint32_t idx = 0;
48  (create_callback =
49  PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) !=
50  nullptr;
51  ++idx) {
52  std::unique_ptr<DynamicLoader> instance_up(
53  create_callback(process, false));
54  if (instance_up)
55  return instance_up.release();
56  }
57  }
58  return nullptr;
59 }
60 
61 DynamicLoader::DynamicLoader(Process *process) : m_process(process) {}
62 
63 // Accessosors to the global setting as to whether to stop at image (shared
64 // library) loading/unloading.
65 
68 }
69 
72 }
73 
75  Target &target = m_process->GetTarget();
76  ModuleSP executable = target.GetExecutableModule();
77 
78  if (executable) {
79  if (FileSystem::Instance().Exists(executable->GetFileSpec())) {
80  ModuleSpec module_spec(executable->GetFileSpec(),
81  executable->GetArchitecture());
82  auto module_sp = std::make_shared<Module>(module_spec);
83 
84  // Check if the executable has changed and set it to the target
85  // executable if they differ.
86  if (module_sp && module_sp->GetUUID().IsValid() &&
87  executable->GetUUID().IsValid()) {
88  if (module_sp->GetUUID() != executable->GetUUID())
89  executable.reset();
90  } else if (executable->FileHasChanged()) {
91  executable.reset();
92  }
93 
94  if (!executable) {
95  executable = target.GetOrCreateModule(module_spec, true /* notify */);
96  if (executable.get() != target.GetExecutableModulePointer()) {
97  // Don't load dependent images since we are in dyld where we will
98  // know and find out about all images that are loaded
99  target.SetExecutableModule(executable, eLoadDependentsNo);
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 
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 
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.GetOrCreateModule(module_spec,
166  true /* notify */))) {
167  UpdateLoadedSections(module_sp, link_map_addr, base_addr,
168  base_addr_is_offset);
169  return module_sp;
170  }
171 
172  bool check_alternative_file_name = true;
173  if (base_addr_is_offset) {
174  // Try to fetch the load address of the file from the process as we need
175  // absolute load address to read the file out of the memory instead of a
176  // load bias.
177  bool is_loaded = false;
178  lldb::addr_t load_addr;
179  Status error = m_process->GetFileLoadAddress(file, is_loaded, load_addr);
180  if (error.Success() && is_loaded) {
181  check_alternative_file_name = false;
182  base_addr = load_addr;
183  }
184  }
185 
186  // We failed to find the module based on its name. Lets try to check if we
187  // can find a different name based on the memory region info.
188  if (check_alternative_file_name) {
189  MemoryRegionInfo memory_info;
190  Status error = m_process->GetMemoryRegionInfo(base_addr, memory_info);
191  if (error.Success() && memory_info.GetMapped() &&
192  memory_info.GetRange().GetRangeBase() == base_addr &&
193  !(memory_info.GetName().IsEmpty())) {
194  ModuleSpec new_module_spec(FileSpec(memory_info.GetName().GetStringRef()),
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.GetOrCreateModule(new_module_spec,
203  true /* notify */))) {
204  UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
205  return module_sp;
206  }
207  }
208  }
209 
210  if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr))) {
211  UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
212  target.GetImages().AppendIfNeeded(module_sp);
213  }
214 
215  return module_sp;
216 }
217 
219  int size_in_bytes) {
220  Status error;
221  uint64_t value =
222  m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
223  if (error.Fail())
224  return -1;
225  else
226  return (int64_t)value;
227 }
228 
230  Status error;
232  if (error.Fail())
233  return LLDB_INVALID_ADDRESS;
234  else
235  return value;
236 }
237 
239 {
240  if (m_process)
242 }
243 
lldb_private::DynamicLoader::SetStopWhenImagesChange
void SetStopWhenImagesChange(bool stop)
Set whether the process should stop when images change.
Definition: DynamicLoader.cpp:70
lldb_private::Range::GetRangeBase
BaseType GetRangeBase() const
Definition: RangeMap.h:46
ModuleSpec.h
lldb_private::Target::GetOrCreateModule
lldb::ModuleSP GetOrCreateModule(const ModuleSpec &module_spec, bool notify, Status *error_ptr=nullptr)
Find a binary on the system and return its Module, or return an existing Module that is already in th...
Definition: Target.cpp:1979
lldb-private-interfaces.h
lldb_private::SectionList::GetSize
size_t GetSize() const
Definition: Section.h:74
lldb_private::Process::ReadModuleFromMemory
lldb::ModuleSP ReadModuleFromMemory(const FileSpec &file_spec, lldb::addr_t header_addr, size_t size_to_read=512)
Definition: Process.cpp:2388
lldb_private::Process
Definition: Process.h:342
lldb_private::Target::GetExecutableModulePointer
Module * GetExecutableModulePointer()
Definition: Target.cpp:1362
lldb_private::Target::GetExecutableModule
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1348
Module.h
lldb_private::Process::GetTarget
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1214
lldb_private::ProcessProperties::SetStopOnSharedLibraryEvents
void SetStopOnSharedLibraryEvents(bool stop)
Definition: Process.cpp:261
lldb_private::DynamicLoader::UnloadSectionsCommon
void UnloadSectionsCommon(const lldb::ModuleSP module)
Definition: DynamicLoader.cpp:125
lldb_private::SectionList
Definition: Section.h:34
lldb_private::MemoryRegionInfo
Definition: MemoryRegionInfo.h:21
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::Target
Definition: Target.h:454
Section.h
lldb_private::Target::GetImages
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:928
Process.h
lldb_private::DynamicLoader::LoadOperatingSystemPlugin
void LoadOperatingSystemPlugin(bool flush)
Definition: DynamicLoader.cpp:238
Target.h
lldb_private::FileSpec
Definition: FileSpec.h:56
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
lldb_private::ObjectFile::GetSectionList
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
Definition: ObjectFile.cpp:583
ModuleList.h
lldb_private::ConstString::GetStringRef
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:202
lldb_private::ModuleList
Definition: ModuleList.h:72
lldb_private::Process::LoadOperatingSystemPlugin
void LoadOperatingSystemPlugin(bool flush)
Definition: Process.cpp:2467
lldb_private::ConstString::IsEmpty
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:304
lldb_private::ModuleList::AppendIfNeeded
bool AppendIfNeeded(const lldb::ModuleSP &module_sp, bool notify=true)
Append a module to the module list, if it is not already there.
lldb_private::eLoadDependentsNo
@ eLoadDependentsNo
Definition: Target.h:63
MemoryRegionInfo.h
lldb_private::Process::GetMemoryRegionInfo
virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info)
Locate the memory region that contains load_addr.
Definition: Process.h:1821
lldb_private::DynamicLoader::ReadUnsignedIntWithSizeInBytes
int64_t ReadUnsignedIntWithSizeInBytes(lldb::addr_t addr, int size_in_bytes)
Definition: DynamicLoader.cpp:218
lldb_private::DynamicLoader::ReadPointer
lldb::addr_t ReadPointer(lldb::addr_t addr)
Definition: DynamicLoader.cpp:229
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::ModuleList::FindFirstModule
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Definition: ModuleList.cpp:582
lldb_private::DynamicLoader::UpdateLoadedSections
virtual void UpdateLoadedSections(lldb::ModuleSP module, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset)
Updates the load address of every allocatable section in module.
Definition: DynamicLoader.cpp:107
lldb_private::SectionList::GetSectionAtIndex
lldb::SectionSP GetSectionAtIndex(size_t idx) const
Definition: Section.cpp:476
lldb_private::DynamicLoader
Definition: DynamicLoader.h:52
lldb_private::DynamicLoader::m_process
Process * m_process
The process that this dynamic loader plug-in is tracking.
Definition: DynamicLoader.h:312
lldb_private::MemoryRegionInfo::GetName
ConstString GetName() const
Definition: MemoryRegionInfo.h:50
lldb_private::DynamicLoader::UpdateLoadedSectionsCommon
void UpdateLoadedSectionsCommon(lldb::ModuleSP module, lldb::addr_t base_addr, bool base_addr_is_offset)
Definition: DynamicLoader.cpp:113
ObjectFile.h
lldb_private::Target::SetExecutableModule
void SetExecutableModule(lldb::ModuleSP &module_sp, LoadDependentFiles load_dependent_files=eLoadDependentsDefault)
Set the main executable module.
Definition: Target.cpp:1397
lldb_private::ModuleSpec
Definition: ModuleSpec.h:26
lldb_private::Target::GetArchitecture
const ArchSpec & GetArchitecture() const
Definition: Target.h:970
lldb_private::Target::SetSectionUnloaded
bool SetSectionUnloaded(const lldb::SectionSP &section_sp)
Definition: Target.cpp:2886
lldb_private::Status
Definition: Status.h:44
uint32_t
lldb_private::ProcessProperties::GetStopOnSharedLibraryEvents
bool GetStopOnSharedLibraryEvents() const
Definition: Process.cpp:255
lldb_private::DynamicLoader::LoadModuleAtAddress
virtual lldb::ModuleSP LoadModuleAtAddress(const lldb_private::FileSpec &file, lldb::addr_t link_map_addr, lldb::addr_t base_addr, bool base_addr_is_offset)
Locates or creates a module given by file and updates/loads the resulting module at the virtual base ...
Definition: DynamicLoader.cpp:150
lldb_private::DynamicLoader::GetStopWhenImagesChange
bool GetStopWhenImagesChange() const
Get whether the process should stop when images change.
Definition: DynamicLoader.cpp:66
PluginManager.h
lldb_private::DynamicLoader::GetTargetExecutable
lldb::ModuleSP GetTargetExecutable()
Checks to see if the target module has changed, updates the target accordingly and returns the target...
Definition: DynamicLoader.cpp:74
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:86
lldb_private::MemoryRegionInfo::GetRange
RangeType & GetRange()
Definition: MemoryRegionInfo.h:36
lldb_private::FileSystem::Instance
static FileSystem & Instance()
Definition: common/FileSystem.cpp:45
lldb_private::DynamicLoader::UnloadSections
virtual void UnloadSections(const lldb::ModuleSP module)
Removes the loaded sections from the target in module.
Definition: DynamicLoader.cpp:121
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
ConstString.h
lldb_private::Process::ReadUnsignedIntegerFromMemory
uint64_t ReadUnsignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, uint64_t fail_value, Status &error)
Reads an unsigned integer of the specified byte size from process memory.
Definition: Process.cpp:2100
lldb_private::Process::ReadPointerFromMemory
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Definition: Process.cpp:2122
lldb_private::Process::GetFileLoadAddress
virtual Status GetFileLoadAddress(const FileSpec &file, bool &is_loaded, lldb::addr_t &load_addr)
Try to find the load address of a file.
Definition: Process.h:2451
DynamicLoader.h
lldb_private::DynamicLoader::GetSectionListFromModule
const lldb_private::SectionList * GetSectionListFromModule(const lldb::ModuleSP module) const
Definition: DynamicLoader.cpp:139
lldb_private::MemoryRegionInfo::GetMapped
OptionalBool GetMapped() const
Definition: MemoryRegionInfo.h:48
lldb
Definition: SBAddress.h:15
lldb_private::ObjectFile
Definition: ObjectFile.h:58