15ffd83dbSDimitry Andric //===-- DynamicLoaderStatic.cpp -------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "lldb/Core/Module.h" 100b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h" 110b57cec5SDimitry Andric #include "lldb/Core/Section.h" 120b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h" 13fe6060f1SDimitry Andric #include "lldb/Target/SectionLoadList.h" 140b57cec5SDimitry Andric #include "lldb/Target/Target.h" 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "DynamicLoaderStatic.h" 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric using namespace lldb; 190b57cec5SDimitry Andric using namespace lldb_private; 200b57cec5SDimitry Andric 215ffd83dbSDimitry Andric LLDB_PLUGIN_DEFINE(DynamicLoaderStatic) 225ffd83dbSDimitry Andric 230b57cec5SDimitry Andric // Create an instance of this class. This function is filled into the plugin 240b57cec5SDimitry Andric // info class that gets handed out by the plugin factory and allows the lldb to 250b57cec5SDimitry Andric // instantiate an instance of this class. 260b57cec5SDimitry Andric DynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process, 270b57cec5SDimitry Andric bool force) { 280b57cec5SDimitry Andric bool create = force; 290b57cec5SDimitry Andric if (!create) { 300b57cec5SDimitry Andric const llvm::Triple &triple_ref = 310b57cec5SDimitry Andric process->GetTarget().GetArchitecture().GetTriple(); 320b57cec5SDimitry Andric const llvm::Triple::OSType os_type = triple_ref.getOS(); 335ffd83dbSDimitry Andric const llvm::Triple::ArchType arch_type = triple_ref.getArch(); 345ffd83dbSDimitry Andric if (os_type == llvm::Triple::UnknownOS) { 355ffd83dbSDimitry Andric // The WASM and Hexagon plugin check the ArchType rather than the OSType, 365ffd83dbSDimitry Andric // so explicitly reject those here. 375ffd83dbSDimitry Andric switch(arch_type) { 385ffd83dbSDimitry Andric case llvm::Triple::hexagon: 395ffd83dbSDimitry Andric case llvm::Triple::wasm32: 405ffd83dbSDimitry Andric case llvm::Triple::wasm64: 415ffd83dbSDimitry Andric break; 425ffd83dbSDimitry Andric default: 430b57cec5SDimitry Andric create = true; 440b57cec5SDimitry Andric } 455ffd83dbSDimitry Andric } 465ffd83dbSDimitry Andric } 470b57cec5SDimitry Andric 480b57cec5SDimitry Andric if (!create) { 490b57cec5SDimitry Andric Module *exe_module = process->GetTarget().GetExecutableModulePointer(); 500b57cec5SDimitry Andric if (exe_module) { 510b57cec5SDimitry Andric ObjectFile *object_file = exe_module->GetObjectFile(); 520b57cec5SDimitry Andric if (object_file) { 530b57cec5SDimitry Andric create = (object_file->GetStrata() == ObjectFile::eStrataRawImage); 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric } 560b57cec5SDimitry Andric } 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric if (create) 590b57cec5SDimitry Andric return new DynamicLoaderStatic(process); 600b57cec5SDimitry Andric return nullptr; 610b57cec5SDimitry Andric } 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric // Constructor 640b57cec5SDimitry Andric DynamicLoaderStatic::DynamicLoaderStatic(Process *process) 650b57cec5SDimitry Andric : DynamicLoader(process) {} 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric /// Called after attaching a process. 680b57cec5SDimitry Andric /// 690b57cec5SDimitry Andric /// Allow DynamicLoader plug-ins to execute some code after 700b57cec5SDimitry Andric /// attaching to a process. 710b57cec5SDimitry Andric void DynamicLoaderStatic::DidAttach() { LoadAllImagesAtFileAddresses(); } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric /// Called after attaching a process. 740b57cec5SDimitry Andric /// 750b57cec5SDimitry Andric /// Allow DynamicLoader plug-ins to execute some code after 760b57cec5SDimitry Andric /// attaching to a process. 770b57cec5SDimitry Andric void DynamicLoaderStatic::DidLaunch() { LoadAllImagesAtFileAddresses(); } 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() { 800b57cec5SDimitry Andric const ModuleList &module_list = m_process->GetTarget().GetImages(); 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric ModuleList loaded_module_list; 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric // Disable JIT for static dynamic loader targets 850b57cec5SDimitry Andric m_process->SetCanJIT(false); 860b57cec5SDimitry Andric 87*0fca6ea1SDimitry Andric Target &target = m_process->GetTarget(); 88e8d8bef9SDimitry Andric for (ModuleSP module_sp : module_list.Modules()) { 890b57cec5SDimitry Andric if (module_sp) { 900b57cec5SDimitry Andric bool changed = false; 91*0fca6ea1SDimitry Andric bool no_load_addresses = true; 92*0fca6ea1SDimitry Andric // If this module has a section with a load address set in 93*0fca6ea1SDimitry Andric // the target, assume all necessary work is already done. There 94*0fca6ea1SDimitry Andric // may be sections without a load address set intentionally 95*0fca6ea1SDimitry Andric // and we don't want to mutate that. 96*0fca6ea1SDimitry Andric // For a module with no load addresses set, set the load addresses 97*0fca6ea1SDimitry Andric // to slide == 0, the same as the file addresses, in the target. 980b57cec5SDimitry Andric ObjectFile *image_object_file = module_sp->GetObjectFile(); 990b57cec5SDimitry Andric if (image_object_file) { 1000b57cec5SDimitry Andric SectionList *section_list = image_object_file->GetSectionList(); 1010b57cec5SDimitry Andric if (section_list) { 1020b57cec5SDimitry Andric const size_t num_sections = section_list->GetSize(); 103*0fca6ea1SDimitry Andric for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) { 1040b57cec5SDimitry Andric SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); 1050b57cec5SDimitry Andric if (section_sp) { 106*0fca6ea1SDimitry Andric if (target.GetSectionLoadList().GetSectionLoadAddress( 107*0fca6ea1SDimitry Andric section_sp) != LLDB_INVALID_ADDRESS) { 108*0fca6ea1SDimitry Andric no_load_addresses = false; 109*0fca6ea1SDimitry Andric break; 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric } 114*0fca6ea1SDimitry Andric } 115*0fca6ea1SDimitry Andric if (no_load_addresses) 116*0fca6ea1SDimitry Andric module_sp->SetLoadAddress(target, 0, true /*value_is_offset*/, changed); 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric if (changed) 1190b57cec5SDimitry Andric loaded_module_list.AppendIfNeeded(module_sp); 1200b57cec5SDimitry Andric } 1210b57cec5SDimitry Andric } 1220b57cec5SDimitry Andric 123*0fca6ea1SDimitry Andric target.ModulesDidLoad(loaded_module_list); 1240b57cec5SDimitry Andric } 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric ThreadPlanSP 1270b57cec5SDimitry Andric DynamicLoaderStatic::GetStepThroughTrampolinePlan(Thread &thread, 1280b57cec5SDimitry Andric bool stop_others) { 1290b57cec5SDimitry Andric return ThreadPlanSP(); 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric Status DynamicLoaderStatic::CanLoadImage() { 1330b57cec5SDimitry Andric Status error; 1340b57cec5SDimitry Andric error.SetErrorString("can't load images on with a static debug session"); 1350b57cec5SDimitry Andric return error; 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric void DynamicLoaderStatic::Initialize() { 1390b57cec5SDimitry Andric PluginManager::RegisterPlugin(GetPluginNameStatic(), 1400b57cec5SDimitry Andric GetPluginDescriptionStatic(), CreateInstance); 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric void DynamicLoaderStatic::Terminate() { 1440b57cec5SDimitry Andric PluginManager::UnregisterPlugin(CreateInstance); 1450b57cec5SDimitry Andric } 1460b57cec5SDimitry Andric 147349cc55cSDimitry Andric llvm::StringRef DynamicLoaderStatic::GetPluginDescriptionStatic() { 1480b57cec5SDimitry Andric return "Dynamic loader plug-in that will load any images at the static " 1490b57cec5SDimitry Andric "addresses contained in each image."; 1500b57cec5SDimitry Andric } 151