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 9 #include "lldb/Target/DynamicLoader.h" 10 11 #include "lldb/Core/Debugger.h" 12 #include "lldb/Core/Module.h" 13 #include "lldb/Core/ModuleList.h" 14 #include "lldb/Core/ModuleSpec.h" 15 #include "lldb/Core/PluginManager.h" 16 #include "lldb/Core/Progress.h" 17 #include "lldb/Core/Section.h" 18 #include "lldb/Symbol/ObjectFile.h" 19 #include "lldb/Target/MemoryRegionInfo.h" 20 #include "lldb/Target/Platform.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/Target.h" 23 #include "lldb/Utility/ConstString.h" 24 #include "lldb/Utility/LLDBLog.h" 25 #include "lldb/Utility/Log.h" 26 #include "lldb/lldb-private-interfaces.h" 27 28 #include "llvm/ADT/StringRef.h" 29 30 #include <memory> 31 32 #include <cassert> 33 34 using namespace lldb; 35 using namespace lldb_private; 36 37 DynamicLoader *DynamicLoader::FindPlugin(Process *process, 38 llvm::StringRef plugin_name) { 39 DynamicLoaderCreateInstance create_callback = nullptr; 40 if (!plugin_name.empty()) { 41 create_callback = 42 PluginManager::GetDynamicLoaderCreateCallbackForPluginName(plugin_name); 43 if (create_callback) { 44 std::unique_ptr<DynamicLoader> instance_up( 45 create_callback(process, true)); 46 if (instance_up) 47 return instance_up.release(); 48 } 49 } else { 50 for (uint32_t idx = 0; 51 (create_callback = 52 PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != 53 nullptr; 54 ++idx) { 55 std::unique_ptr<DynamicLoader> instance_up( 56 create_callback(process, false)); 57 if (instance_up) 58 return instance_up.release(); 59 } 60 } 61 return nullptr; 62 } 63 64 DynamicLoader::DynamicLoader(Process *process) : m_process(process) {} 65 66 // Accessors to the global setting as to whether to stop at image (shared 67 // library) loading/unloading. 68 69 bool DynamicLoader::GetStopWhenImagesChange() const { 70 return m_process->GetStopOnSharedLibraryEvents(); 71 } 72 73 void DynamicLoader::SetStopWhenImagesChange(bool stop) { 74 m_process->SetStopOnSharedLibraryEvents(stop); 75 } 76 77 ModuleSP DynamicLoader::GetTargetExecutable() { 78 Target &target = m_process->GetTarget(); 79 ModuleSP executable = target.GetExecutableModule(); 80 81 if (executable) { 82 if (FileSystem::Instance().Exists(executable->GetFileSpec())) { 83 ModuleSpec module_spec(executable->GetFileSpec(), 84 executable->GetArchitecture()); 85 auto module_sp = std::make_shared<Module>(module_spec); 86 // If we're a coredump and we already have a main executable, we don't 87 // need to reload the module list that target already has 88 if (!m_process->IsLiveDebugSession()) { 89 return executable; 90 } 91 // Check if the executable has changed and set it to the target 92 // executable if they differ. 93 if (module_sp && module_sp->GetUUID().IsValid() && 94 executable->GetUUID().IsValid()) { 95 if (module_sp->GetUUID() != executable->GetUUID()) 96 executable.reset(); 97 } else if (executable->FileHasChanged()) { 98 executable.reset(); 99 } 100 101 if (!executable) { 102 executable = target.GetOrCreateModule(module_spec, true /* notify */); 103 if (executable.get() != target.GetExecutableModulePointer()) { 104 // Don't load dependent images since we are in dyld where we will 105 // know and find out about all images that are loaded 106 target.SetExecutableModule(executable, eLoadDependentsNo); 107 } 108 } 109 } 110 } 111 return executable; 112 } 113 114 void DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, 115 addr_t base_addr, 116 bool base_addr_is_offset) { 117 UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset); 118 } 119 120 void DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, 121 addr_t base_addr, 122 bool base_addr_is_offset) { 123 bool changed; 124 module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, 125 changed); 126 } 127 128 void DynamicLoader::UnloadSections(const ModuleSP module) { 129 UnloadSectionsCommon(module); 130 } 131 132 void DynamicLoader::UnloadSectionsCommon(const ModuleSP module) { 133 Target &target = m_process->GetTarget(); 134 const SectionList *sections = GetSectionListFromModule(module); 135 136 assert(sections && "SectionList missing from unloaded module."); 137 138 const size_t num_sections = sections->GetSize(); 139 for (size_t i = 0; i < num_sections; ++i) { 140 SectionSP section_sp(sections->GetSectionAtIndex(i)); 141 target.SetSectionUnloaded(section_sp); 142 } 143 } 144 145 const SectionList * 146 DynamicLoader::GetSectionListFromModule(const ModuleSP module) const { 147 SectionList *sections = nullptr; 148 if (module) { 149 ObjectFile *obj_file = module->GetObjectFile(); 150 if (obj_file != nullptr) { 151 sections = obj_file->GetSectionList(); 152 } 153 } 154 return sections; 155 } 156 157 ModuleSP DynamicLoader::FindModuleViaTarget(const FileSpec &file) { 158 Target &target = m_process->GetTarget(); 159 ModuleSpec module_spec(file, target.GetArchitecture()); 160 if (UUID uuid = m_process->FindModuleUUID(file.GetPath())) { 161 // Process may be able to augment the module_spec with UUID, e.g. ELF core. 162 module_spec.GetUUID() = uuid; 163 } 164 165 if (ModuleSP module_sp = target.GetImages().FindFirstModule(module_spec)) 166 return module_sp; 167 168 if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, false)) 169 return module_sp; 170 171 return nullptr; 172 } 173 174 ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file, 175 addr_t link_map_addr, 176 addr_t base_addr, 177 bool base_addr_is_offset) { 178 if (ModuleSP module_sp = FindModuleViaTarget(file)) { 179 UpdateLoadedSections(module_sp, link_map_addr, base_addr, 180 base_addr_is_offset); 181 return module_sp; 182 } 183 184 return nullptr; 185 } 186 187 static ModuleSP ReadUnnamedMemoryModule(Process *process, addr_t addr, 188 llvm::StringRef name) { 189 char namebuf[80]; 190 if (name.empty()) { 191 snprintf(namebuf, sizeof(namebuf), "memory-image-0x%" PRIx64, addr); 192 name = namebuf; 193 } 194 return process->ReadModuleFromMemory(FileSpec(name), addr); 195 } 196 197 ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress( 198 Process *process, llvm::StringRef name, UUID uuid, addr_t value, 199 bool value_is_offset, bool force_symbol_search, bool notify, 200 bool set_address_in_target, bool allow_memory_image_last_resort) { 201 ModuleSP memory_module_sp; 202 ModuleSP module_sp; 203 PlatformSP platform_sp = process->GetTarget().GetPlatform(); 204 Target &target = process->GetTarget(); 205 Status error; 206 207 StreamString prog_str; 208 if (!name.empty()) { 209 prog_str << name.str() << " "; 210 } 211 if (uuid.IsValid()) 212 prog_str << uuid.GetAsString(); 213 if (value_is_offset == 0 && value != LLDB_INVALID_ADDRESS) { 214 prog_str << "at 0x"; 215 prog_str.PutHex64(value); 216 } 217 218 if (!uuid.IsValid() && !value_is_offset) { 219 memory_module_sp = ReadUnnamedMemoryModule(process, value, name); 220 221 if (memory_module_sp) { 222 uuid = memory_module_sp->GetUUID(); 223 if (uuid.IsValid()) { 224 prog_str << " "; 225 prog_str << uuid.GetAsString(); 226 } 227 } 228 } 229 ModuleSpec module_spec; 230 module_spec.GetUUID() = uuid; 231 FileSpec name_filespec(name); 232 233 if (uuid.IsValid()) { 234 Progress progress("Locating binary", prog_str.GetString().str()); 235 236 // Has lldb already seen a module with this UUID? 237 // Or have external lookup enabled in DebugSymbols on macOS. 238 if (!module_sp) 239 error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr, 240 nullptr, nullptr); 241 242 // Can lldb's symbol/executable location schemes 243 // find an executable and symbol file. 244 if (!module_sp) { 245 FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); 246 module_spec.GetSymbolFileSpec() = 247 PluginManager::LocateExecutableSymbolFile(module_spec, search_paths); 248 ModuleSpec objfile_module_spec = 249 PluginManager::LocateExecutableObjectFile(module_spec); 250 module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec(); 251 if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) && 252 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec())) { 253 module_sp = std::make_shared<Module>(module_spec); 254 } 255 } 256 257 // If we haven't found a binary, or we don't have a SymbolFile, see 258 // if there is an external search tool that can find it. 259 if (!module_sp || !module_sp->GetSymbolFileFileSpec()) { 260 PluginManager::DownloadObjectAndSymbolFile(module_spec, error, 261 force_symbol_search); 262 if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { 263 module_sp = std::make_shared<Module>(module_spec); 264 } else if (force_symbol_search && error.AsCString("") && 265 error.AsCString("")[0] != '\0') { 266 target.GetDebugger().GetErrorStream() << error.AsCString(); 267 } 268 } 269 270 // If we only found the executable, create a Module based on that. 271 if (!module_sp && FileSystem::Instance().Exists(module_spec.GetFileSpec())) 272 module_sp = std::make_shared<Module>(module_spec); 273 } 274 275 // If we couldn't find the binary anywhere else, as a last resort, 276 // read it out of memory. 277 if (allow_memory_image_last_resort && !module_sp.get() && 278 value != LLDB_INVALID_ADDRESS && !value_is_offset) { 279 if (!memory_module_sp) 280 memory_module_sp = ReadUnnamedMemoryModule(process, value, name); 281 if (memory_module_sp) 282 module_sp = memory_module_sp; 283 } 284 285 Log *log = GetLog(LLDBLog::DynamicLoader); 286 if (module_sp.get()) { 287 // Ensure the Target has an architecture set in case 288 // we need it while processing this binary/eh_frame/debug info. 289 if (!target.GetArchitecture().IsValid()) 290 target.SetArchitecture(module_sp->GetArchitecture()); 291 target.GetImages().AppendIfNeeded(module_sp, false); 292 293 bool changed = false; 294 if (set_address_in_target) { 295 if (module_sp->GetObjectFile()) { 296 if (value != LLDB_INVALID_ADDRESS) { 297 LLDB_LOGF(log, 298 "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading " 299 "binary %s UUID %s at %s 0x%" PRIx64, 300 name.str().c_str(), uuid.GetAsString().c_str(), 301 value_is_offset ? "offset" : "address", value); 302 module_sp->SetLoadAddress(target, value, value_is_offset, changed); 303 } else { 304 // No address/offset/slide, load the binary at file address, 305 // offset 0. 306 LLDB_LOGF(log, 307 "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading " 308 "binary %s UUID %s at file address", 309 name.str().c_str(), uuid.GetAsString().c_str()); 310 module_sp->SetLoadAddress(target, 0, true /* value_is_slide */, 311 changed); 312 } 313 } else { 314 // In-memory image, load at its true address, offset 0. 315 LLDB_LOGF(log, 316 "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading binary " 317 "%s UUID %s from memory at address 0x%" PRIx64, 318 name.str().c_str(), uuid.GetAsString().c_str(), value); 319 module_sp->SetLoadAddress(target, 0, true /* value_is_slide */, 320 changed); 321 } 322 } 323 324 if (notify) { 325 ModuleList added_module; 326 added_module.Append(module_sp, false); 327 target.ModulesDidLoad(added_module); 328 } 329 } else { 330 if (force_symbol_search) { 331 Stream &s = target.GetDebugger().GetErrorStream(); 332 s.Printf("Unable to find file"); 333 if (!name.empty()) 334 s.Printf(" %s", name.str().c_str()); 335 if (uuid.IsValid()) 336 s.Printf(" with UUID %s", uuid.GetAsString().c_str()); 337 if (value != LLDB_INVALID_ADDRESS) { 338 if (value_is_offset) 339 s.Printf(" with slide 0x%" PRIx64, value); 340 else 341 s.Printf(" at address 0x%" PRIx64, value); 342 } 343 s.Printf("\n"); 344 } 345 LLDB_LOGF(log, 346 "Unable to find binary %s with UUID %s and load it at " 347 "%s 0x%" PRIx64, 348 name.str().c_str(), uuid.GetAsString().c_str(), 349 value_is_offset ? "offset" : "address", value); 350 } 351 352 return module_sp; 353 } 354 355 int64_t DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, 356 int size_in_bytes) { 357 Status error; 358 uint64_t value = 359 m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error); 360 if (error.Fail()) 361 return -1; 362 else 363 return (int64_t)value; 364 } 365 366 addr_t DynamicLoader::ReadPointer(addr_t addr) { 367 Status error; 368 addr_t value = m_process->ReadPointerFromMemory(addr, error); 369 if (error.Fail()) 370 return LLDB_INVALID_ADDRESS; 371 else 372 return value; 373 } 374 375 void DynamicLoader::LoadOperatingSystemPlugin(bool flush) 376 { 377 if (m_process) 378 m_process->LoadOperatingSystemPlugin(flush); 379 } 380