1 | //===-- DynamicLoaderStatic.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/Core/Module.h" |
10 | #include "lldb/Core/PluginManager.h" |
11 | #include "lldb/Core/Section.h" |
12 | #include "lldb/Symbol/ObjectFile.h" |
13 | #include "lldb/Target/SectionLoadList.h" |
14 | #include "lldb/Target/Target.h" |
15 | |
16 | #include "DynamicLoaderStatic.h" |
17 | |
18 | using namespace lldb; |
19 | using namespace lldb_private; |
20 | |
21 | LLDB_PLUGIN_DEFINE(DynamicLoaderStatic) |
22 | |
23 | // Create an instance of this class. This function is filled into the plugin |
24 | // info class that gets handed out by the plugin factory and allows the lldb to |
25 | // instantiate an instance of this class. |
26 | DynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process, |
27 | bool force) { |
28 | bool create = force; |
29 | if (!create) { |
30 | const llvm::Triple &triple_ref = |
31 | process->GetTarget().GetArchitecture().GetTriple(); |
32 | const llvm::Triple::OSType os_type = triple_ref.getOS(); |
33 | const llvm::Triple::ArchType arch_type = triple_ref.getArch(); |
34 | if (os_type == llvm::Triple::UnknownOS) { |
35 | // The WASM and Hexagon plugin check the ArchType rather than the OSType, |
36 | // so explicitly reject those here. |
37 | switch(arch_type) { |
38 | case llvm::Triple::hexagon: |
39 | case llvm::Triple::wasm32: |
40 | case llvm::Triple::wasm64: |
41 | break; |
42 | default: |
43 | create = true; |
44 | } |
45 | } |
46 | } |
47 | |
48 | if (!create) { |
49 | Module *exe_module = process->GetTarget().GetExecutableModulePointer(); |
50 | if (exe_module) { |
51 | ObjectFile *object_file = exe_module->GetObjectFile(); |
52 | if (object_file) { |
53 | create = (object_file->GetStrata() == ObjectFile::eStrataRawImage); |
54 | } |
55 | } |
56 | } |
57 | |
58 | if (create) |
59 | return new DynamicLoaderStatic(process); |
60 | return nullptr; |
61 | } |
62 | |
63 | // Constructor |
64 | DynamicLoaderStatic::DynamicLoaderStatic(Process *process) |
65 | : DynamicLoader(process) {} |
66 | |
67 | /// Called after attaching a process. |
68 | /// |
69 | /// Allow DynamicLoader plug-ins to execute some code after |
70 | /// attaching to a process. |
71 | void DynamicLoaderStatic::DidAttach() { LoadAllImagesAtFileAddresses(); } |
72 | |
73 | /// Called after attaching a process. |
74 | /// |
75 | /// Allow DynamicLoader plug-ins to execute some code after |
76 | /// attaching to a process. |
77 | void DynamicLoaderStatic::DidLaunch() { LoadAllImagesAtFileAddresses(); } |
78 | |
79 | void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() { |
80 | const ModuleList &module_list = m_process->GetTarget().GetImages(); |
81 | |
82 | ModuleList loaded_module_list; |
83 | |
84 | // Disable JIT for static dynamic loader targets |
85 | m_process->SetCanJIT(false); |
86 | |
87 | Target &target = m_process->GetTarget(); |
88 | for (ModuleSP module_sp : module_list.Modules()) { |
89 | if (module_sp) { |
90 | bool changed = false; |
91 | bool no_load_addresses = true; |
92 | // If this module has a section with a load address set in |
93 | // the target, assume all necessary work is already done. There |
94 | // may be sections without a load address set intentionally |
95 | // and we don't want to mutate that. |
96 | // For a module with no load addresses set, set the load addresses |
97 | // to slide == 0, the same as the file addresses, in the target. |
98 | ObjectFile *image_object_file = module_sp->GetObjectFile(); |
99 | if (image_object_file) { |
100 | SectionList *section_list = image_object_file->GetSectionList(); |
101 | if (section_list) { |
102 | const size_t num_sections = section_list->GetSize(); |
103 | for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) { |
104 | SectionSP section_sp(section_list->GetSectionAtIndex(idx: sect_idx)); |
105 | if (section_sp) { |
106 | if (target.GetSectionLoadList().GetSectionLoadAddress( |
107 | section_sp) != LLDB_INVALID_ADDRESS) { |
108 | no_load_addresses = false; |
109 | break; |
110 | } |
111 | } |
112 | } |
113 | } |
114 | } |
115 | if (no_load_addresses) |
116 | module_sp->SetLoadAddress(target, value: 0, value_is_offset: true /*value_is_offset*/, changed); |
117 | |
118 | if (changed) |
119 | loaded_module_list.AppendIfNeeded(new_module: module_sp); |
120 | } |
121 | } |
122 | |
123 | target.ModulesDidLoad(module_list&: loaded_module_list); |
124 | } |
125 | |
126 | ThreadPlanSP |
127 | DynamicLoaderStatic::GetStepThroughTrampolinePlan(Thread &thread, |
128 | bool stop_others) { |
129 | return ThreadPlanSP(); |
130 | } |
131 | |
132 | Status DynamicLoaderStatic::CanLoadImage() { |
133 | Status error; |
134 | error.SetErrorString("can't load images on with a static debug session" ); |
135 | return error; |
136 | } |
137 | |
138 | void DynamicLoaderStatic::Initialize() { |
139 | PluginManager::RegisterPlugin(name: GetPluginNameStatic(), |
140 | description: GetPluginDescriptionStatic(), create_callback: CreateInstance); |
141 | } |
142 | |
143 | void DynamicLoaderStatic::Terminate() { |
144 | PluginManager::UnregisterPlugin(create_callback: CreateInstance); |
145 | } |
146 | |
147 | llvm::StringRef DynamicLoaderStatic::GetPluginDescriptionStatic() { |
148 | return "Dynamic loader plug-in that will load any images at the static " |
149 | "addresses contained in each image." ; |
150 | } |
151 | |