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  llvm::StringRef plugin_name) {
34  DynamicLoaderCreateInstance create_callback = nullptr;
35  if (!plugin_name.empty()) {
36  create_callback =
37  PluginManager::GetDynamicLoaderCreateCallbackForPluginName(plugin_name);
38  if (create_callback) {
39  std::unique_ptr<DynamicLoader> instance_up(
40  create_callback(process, true));
41  if (instance_up)
42  return instance_up.release();
43  }
44  } else {
45  for (uint32_t idx = 0;
46  (create_callback =
47  PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) !=
48  nullptr;
49  ++idx) {
50  std::unique_ptr<DynamicLoader> instance_up(
51  create_callback(process, false));
52  if (instance_up)
53  return instance_up.release();
54  }
55  }
56  return nullptr;
57 }
58 
59 DynamicLoader::DynamicLoader(Process *process) : m_process(process) {}
60 
61 // Accessosors to the global setting as to whether to stop at image (shared
62 // library) loading/unloading.
63 
66 }
67 
70 }
71 
73  Target &target = m_process->GetTarget();
74  ModuleSP executable = target.GetExecutableModule();
75 
76  if (executable) {
77  if (FileSystem::Instance().Exists(executable->GetFileSpec())) {
78  ModuleSpec module_spec(executable->GetFileSpec(),
79  executable->GetArchitecture());
80  auto module_sp = std::make_shared<Module>(module_spec);
81 
82  // Check if the executable has changed and set it to the target
83  // executable if they differ.
84  if (module_sp && module_sp->GetUUID().IsValid() &&
85  executable->GetUUID().IsValid()) {
86  if (module_sp->GetUUID() != executable->GetUUID())
87  executable.reset();
88  } else if (executable->FileHasChanged()) {
89  executable.reset();
90  }
91 
92  if (!executable) {
93  executable = target.GetOrCreateModule(module_spec, true /* notify */);
94  if (executable.get() != target.GetExecutableModulePointer()) {
95  // Don't load dependent images since we are in dyld where we will
96  // know and find out about all images that are loaded
97  target.SetExecutableModule(executable, eLoadDependentsNo);
98  }
99  }
100  }
101  }
102  return executable;
103 }
104 
105 void DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr,
106  addr_t base_addr,
107  bool base_addr_is_offset) {
108  UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
109 }
110 
112  addr_t base_addr,
113  bool base_addr_is_offset) {
114  bool changed;
115  module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset,
116  changed);
117 }
118 
119 void DynamicLoader::UnloadSections(const ModuleSP module) {
120  UnloadSectionsCommon(module);
121 }
122 
123 void DynamicLoader::UnloadSectionsCommon(const ModuleSP module) {
124  Target &target = m_process->GetTarget();
125  const SectionList *sections = GetSectionListFromModule(module);
126 
127  assert(sections && "SectionList missing from unloaded module.");
128 
129  const size_t num_sections = sections->GetSize();
130  for (size_t i = 0; i < num_sections; ++i) {
131  SectionSP section_sp(sections->GetSectionAtIndex(i));
132  target.SetSectionUnloaded(section_sp);
133  }
134 }
135 
136 const SectionList *
137 DynamicLoader::GetSectionListFromModule(const ModuleSP module) const {
138  SectionList *sections = nullptr;
139  if (module) {
140  ObjectFile *obj_file = module->GetObjectFile();
141  if (obj_file != nullptr) {
142  sections = obj_file->GetSectionList();
143  }
144  }
145  return sections;
146 }
147 
149  addr_t link_map_addr,
150  addr_t base_addr,
151  bool base_addr_is_offset) {
152  Target &target = m_process->GetTarget();
153  ModuleList &modules = target.GetImages();
154  ModuleSpec module_spec(file, target.GetArchitecture());
155  ModuleSP module_sp;
156 
157  if ((module_sp = modules.FindFirstModule(module_spec))) {
158  UpdateLoadedSections(module_sp, link_map_addr, base_addr,
159  base_addr_is_offset);
160  return module_sp;
161  }
162 
163  if ((module_sp = target.GetOrCreateModule(module_spec,
164  true /* notify */))) {
165  UpdateLoadedSections(module_sp, link_map_addr, base_addr,
166  base_addr_is_offset);
167  return module_sp;
168  }
169 
170  bool check_alternative_file_name = true;
171  if (base_addr_is_offset) {
172  // Try to fetch the load address of the file from the process as we need
173  // absolute load address to read the file out of the memory instead of a
174  // load bias.
175  bool is_loaded = false;
176  lldb::addr_t load_addr;
177  Status error = m_process->GetFileLoadAddress(file, is_loaded, load_addr);
178  if (error.Success() && is_loaded) {
179  check_alternative_file_name = false;
180  base_addr = load_addr;
181  }
182  }
183 
184  // We failed to find the module based on its name. Lets try to check if we
185  // can find a different name based on the memory region info.
186  if (check_alternative_file_name) {
187  MemoryRegionInfo memory_info;
188  Status error = m_process->GetMemoryRegionInfo(base_addr, memory_info);
189  if (error.Success() && memory_info.GetMapped() &&
190  memory_info.GetRange().GetRangeBase() == base_addr &&
191  !(memory_info.GetName().IsEmpty())) {
192  ModuleSpec new_module_spec(FileSpec(memory_info.GetName().GetStringRef()),
193  target.GetArchitecture());
194 
195  if ((module_sp = modules.FindFirstModule(new_module_spec))) {
196  UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
197  return module_sp;
198  }
199 
200  if ((module_sp = target.GetOrCreateModule(new_module_spec,
201  true /* notify */))) {
202  UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
203  return module_sp;
204  }
205  }
206  }
207 
208  if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr))) {
209  UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
210  target.GetImages().AppendIfNeeded(module_sp);
211  }
212 
213  return module_sp;
214 }
215 
217  int size_in_bytes) {
218  Status error;
219  uint64_t value =
220  m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
221  if (error.Fail())
222  return -1;
223  else
224  return (int64_t)value;
225 }
226 
228  Status error;
230  if (error.Fail())
231  return LLDB_INVALID_ADDRESS;
232  else
233  return value;
234 }
235 
237 {
238  if (m_process)
240 }
241 
lldb_private::DynamicLoader::SetStopWhenImagesChange
void SetStopWhenImagesChange(bool stop)
Set whether the process should stop when images change.
Definition: DynamicLoader.cpp:68
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:2038
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:2348
lldb_private::Process
Definition: Process.h:338
lldb_private::Target::GetExecutableModulePointer
Module * GetExecutableModulePointer()
Definition: Target.cpp:1358
lldb_private::Target::GetExecutableModule
lldb::ModuleSP GetExecutableModule()
Gets the module for the main executable.
Definition: Target.cpp:1344
Module.h
lldb_private::Process::GetTarget
Target & GetTarget()
Get the target object pointer for this module.
Definition: Process.h:1206
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:123
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:452
Section.h
lldb_private::Target::GetImages
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition: Target.h:926
Process.h
lldb_private::DynamicLoader::LoadOperatingSystemPlugin
void LoadOperatingSystemPlugin(bool flush)
Definition: DynamicLoader.cpp:236
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:587
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:79
lldb_private::Process::LoadOperatingSystemPlugin
void LoadOperatingSystemPlugin(bool flush)
Definition: Process.cpp:2427
lldb_private::ConstString::IsEmpty
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:304
lldb_private::eLoadDependentsNo
@ eLoadDependentsNo
Definition: Target.h:65
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:1782
lldb_private::DynamicLoader::ReadUnsignedIntWithSizeInBytes
int64_t ReadUnsignedIntWithSizeInBytes(lldb::addr_t addr, int size_in_bytes)
Definition: DynamicLoader.cpp:216
lldb_private::DynamicLoader::ReadPointer
lldb::addr_t ReadPointer(lldb::addr_t addr)
Definition: DynamicLoader.cpp:227
lldb_private::ModuleList::FindFirstModule
lldb::ModuleSP FindFirstModule(const ModuleSpec &module_spec) const
Definition: ModuleList.cpp:613
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:105
lldb_private::SectionList::GetSectionAtIndex
lldb::SectionSP GetSectionAtIndex(size_t idx) const
Definition: Section.cpp:546
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:313
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:111
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:1393
lldb_private::ModuleSpec
Definition: ModuleSpec.h:26
lldb_private::Target::GetArchitecture
const ArchSpec & GetArchitecture() const
Definition: Target.h:968
lldb_private::Target::SetSectionUnloaded
bool SetSectionUnloaded(const lldb::SectionSP &section_sp)
Definition: Target.cpp:2941
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:148
lldb_private::ModuleList::AppendIfNeeded
bool AppendIfNeeded(const lldb::ModuleSP &new_module, bool notify=true)
Append a module to the module list, if it is not already there.
lldb_private::DynamicLoader::GetStopWhenImagesChange
bool GetStopWhenImagesChange() const
Get whether the process should stop when images change.
Definition: DynamicLoader.cpp:64
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:72
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
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:119
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:2060
lldb_private::Process::ReadPointerFromMemory
lldb::addr_t ReadPointerFromMemory(lldb::addr_t vm_addr, Status &error)
Definition: Process.cpp:2082
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:2410
DynamicLoader.h
lldb_private::DynamicLoader::GetSectionListFromModule
const lldb_private::SectionList * GetSectionListFromModule(const lldb::ModuleSP module) const
Definition: DynamicLoader.cpp:137
lldb_private::MemoryRegionInfo::GetMapped
OptionalBool GetMapped() const
Definition: MemoryRegionInfo.h:48
lldb
Definition: SBAddress.h:15
lldb_private::ObjectFile
Definition: ObjectFile.h:60