1dda28197Spatrick //===-- DynamicLoaderStatic.cpp -------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "lldb/Core/Module.h"
10061da546Spatrick #include "lldb/Core/PluginManager.h"
11061da546Spatrick #include "lldb/Core/Section.h"
12061da546Spatrick #include "lldb/Symbol/ObjectFile.h"
13be691f3bSpatrick #include "lldb/Target/SectionLoadList.h"
14061da546Spatrick #include "lldb/Target/Target.h"
15061da546Spatrick 
16061da546Spatrick #include "DynamicLoaderStatic.h"
17061da546Spatrick 
18061da546Spatrick using namespace lldb;
19061da546Spatrick using namespace lldb_private;
20061da546Spatrick 
LLDB_PLUGIN_DEFINE(DynamicLoaderStatic)21dda28197Spatrick LLDB_PLUGIN_DEFINE(DynamicLoaderStatic)
22dda28197Spatrick 
23061da546Spatrick // Create an instance of this class. This function is filled into the plugin
24061da546Spatrick // info class that gets handed out by the plugin factory and allows the lldb to
25061da546Spatrick // instantiate an instance of this class.
26061da546Spatrick DynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process,
27061da546Spatrick                                                    bool force) {
28061da546Spatrick   bool create = force;
29061da546Spatrick   if (!create) {
30061da546Spatrick     const llvm::Triple &triple_ref =
31061da546Spatrick         process->GetTarget().GetArchitecture().GetTriple();
32061da546Spatrick     const llvm::Triple::OSType os_type = triple_ref.getOS();
33dda28197Spatrick     const llvm::Triple::ArchType arch_type = triple_ref.getArch();
34dda28197Spatrick     if (os_type == llvm::Triple::UnknownOS) {
35dda28197Spatrick       // The WASM and Hexagon plugin check the ArchType rather than the OSType,
36dda28197Spatrick       // so explicitly reject those here.
37dda28197Spatrick       switch(arch_type) {
38dda28197Spatrick         case llvm::Triple::hexagon:
39dda28197Spatrick         case llvm::Triple::wasm32:
40dda28197Spatrick         case llvm::Triple::wasm64:
41dda28197Spatrick           break;
42dda28197Spatrick         default:
43061da546Spatrick           create = true;
44061da546Spatrick       }
45dda28197Spatrick     }
46dda28197Spatrick   }
47061da546Spatrick 
48061da546Spatrick   if (!create) {
49061da546Spatrick     Module *exe_module = process->GetTarget().GetExecutableModulePointer();
50061da546Spatrick     if (exe_module) {
51061da546Spatrick       ObjectFile *object_file = exe_module->GetObjectFile();
52061da546Spatrick       if (object_file) {
53061da546Spatrick         create = (object_file->GetStrata() == ObjectFile::eStrataRawImage);
54061da546Spatrick       }
55061da546Spatrick     }
56061da546Spatrick   }
57061da546Spatrick 
58061da546Spatrick   if (create)
59061da546Spatrick     return new DynamicLoaderStatic(process);
60061da546Spatrick   return nullptr;
61061da546Spatrick }
62061da546Spatrick 
63061da546Spatrick // Constructor
DynamicLoaderStatic(Process * process)64061da546Spatrick DynamicLoaderStatic::DynamicLoaderStatic(Process *process)
65061da546Spatrick     : DynamicLoader(process) {}
66061da546Spatrick 
67061da546Spatrick /// Called after attaching a process.
68061da546Spatrick ///
69061da546Spatrick /// Allow DynamicLoader plug-ins to execute some code after
70061da546Spatrick /// attaching to a process.
DidAttach()71061da546Spatrick void DynamicLoaderStatic::DidAttach() { LoadAllImagesAtFileAddresses(); }
72061da546Spatrick 
73061da546Spatrick /// Called after attaching a process.
74061da546Spatrick ///
75061da546Spatrick /// Allow DynamicLoader plug-ins to execute some code after
76061da546Spatrick /// attaching to a process.
DidLaunch()77061da546Spatrick void DynamicLoaderStatic::DidLaunch() { LoadAllImagesAtFileAddresses(); }
78061da546Spatrick 
LoadAllImagesAtFileAddresses()79061da546Spatrick void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() {
80061da546Spatrick   const ModuleList &module_list = m_process->GetTarget().GetImages();
81061da546Spatrick 
82061da546Spatrick   ModuleList loaded_module_list;
83061da546Spatrick 
84061da546Spatrick   // Disable JIT for static dynamic loader targets
85061da546Spatrick   m_process->SetCanJIT(false);
86061da546Spatrick 
87be691f3bSpatrick   for (ModuleSP module_sp : module_list.Modules()) {
88061da546Spatrick     if (module_sp) {
89061da546Spatrick       bool changed = false;
90061da546Spatrick       ObjectFile *image_object_file = module_sp->GetObjectFile();
91061da546Spatrick       if (image_object_file) {
92061da546Spatrick         SectionList *section_list = image_object_file->GetSectionList();
93061da546Spatrick         if (section_list) {
94061da546Spatrick           // All sections listed in the dyld image info structure will all
95061da546Spatrick           // either be fixed up already, or they will all be off by a single
96061da546Spatrick           // slide amount that is determined by finding the first segment that
97061da546Spatrick           // is at file offset zero which also has bytes (a file size that is
98061da546Spatrick           // greater than zero) in the object file.
99061da546Spatrick 
100061da546Spatrick           // Determine the slide amount (if any)
101061da546Spatrick           const size_t num_sections = section_list->GetSize();
102061da546Spatrick           size_t sect_idx = 0;
103061da546Spatrick           for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
104061da546Spatrick             // Iterate through the object file sections to find the first
105061da546Spatrick             // section that starts of file offset zero and that has bytes in
106061da546Spatrick             // the file...
107061da546Spatrick             SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
108061da546Spatrick             if (section_sp) {
109be691f3bSpatrick               // If this section already has a load address set in the target,
110be691f3bSpatrick               // don't re-set it to the file address.  Something may have
111be691f3bSpatrick               // set it to a more correct value already.
112be691f3bSpatrick               if (m_process->GetTarget()
113be691f3bSpatrick                       .GetSectionLoadList()
114be691f3bSpatrick                       .GetSectionLoadAddress(section_sp) !=
115be691f3bSpatrick                   LLDB_INVALID_ADDRESS) {
116be691f3bSpatrick                 continue;
117be691f3bSpatrick               }
118061da546Spatrick               if (m_process->GetTarget().SetSectionLoadAddress(
119061da546Spatrick                       section_sp, section_sp->GetFileAddress()))
120061da546Spatrick                 changed = true;
121061da546Spatrick             }
122061da546Spatrick           }
123061da546Spatrick         }
124061da546Spatrick       }
125061da546Spatrick 
126061da546Spatrick       if (changed)
127061da546Spatrick         loaded_module_list.AppendIfNeeded(module_sp);
128061da546Spatrick     }
129061da546Spatrick   }
130061da546Spatrick 
131061da546Spatrick   m_process->GetTarget().ModulesDidLoad(loaded_module_list);
132061da546Spatrick }
133061da546Spatrick 
134061da546Spatrick ThreadPlanSP
GetStepThroughTrampolinePlan(Thread & thread,bool stop_others)135061da546Spatrick DynamicLoaderStatic::GetStepThroughTrampolinePlan(Thread &thread,
136061da546Spatrick                                                   bool stop_others) {
137061da546Spatrick   return ThreadPlanSP();
138061da546Spatrick }
139061da546Spatrick 
CanLoadImage()140061da546Spatrick Status DynamicLoaderStatic::CanLoadImage() {
141061da546Spatrick   Status error;
142061da546Spatrick   error.SetErrorString("can't load images on with a static debug session");
143061da546Spatrick   return error;
144061da546Spatrick }
145061da546Spatrick 
Initialize()146061da546Spatrick void DynamicLoaderStatic::Initialize() {
147061da546Spatrick   PluginManager::RegisterPlugin(GetPluginNameStatic(),
148061da546Spatrick                                 GetPluginDescriptionStatic(), CreateInstance);
149061da546Spatrick }
150061da546Spatrick 
Terminate()151061da546Spatrick void DynamicLoaderStatic::Terminate() {
152061da546Spatrick   PluginManager::UnregisterPlugin(CreateInstance);
153061da546Spatrick }
154061da546Spatrick 
GetPluginDescriptionStatic()155*f6aab3d8Srobert llvm::StringRef DynamicLoaderStatic::GetPluginDescriptionStatic() {
156061da546Spatrick   return "Dynamic loader plug-in that will load any images at the static "
157061da546Spatrick          "addresses contained in each image.";
158061da546Spatrick }
159