1*0b57cec5SDimitry Andric //===-- DynamicLoaderStatic.cpp -------------------------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric
9*0b57cec5SDimitry Andric #include "lldb/Core/Module.h"
10*0b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h"
11*0b57cec5SDimitry Andric #include "lldb/Core/Section.h"
12*0b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
13*0b57cec5SDimitry Andric #include "lldb/Target/SectionLoadList.h"
14*0b57cec5SDimitry Andric #include "lldb/Target/Target.h"
15*0b57cec5SDimitry Andric
16*0b57cec5SDimitry Andric #include "DynamicLoaderStatic.h"
17*0b57cec5SDimitry Andric
18*0b57cec5SDimitry Andric using namespace lldb;
19*0b57cec5SDimitry Andric using namespace lldb_private;
20*0b57cec5SDimitry Andric
LLDB_PLUGIN_DEFINE(DynamicLoaderStatic)21*0b57cec5SDimitry Andric LLDB_PLUGIN_DEFINE(DynamicLoaderStatic)
22*0b57cec5SDimitry Andric
23*0b57cec5SDimitry Andric // Create an instance of this class. This function is filled into the plugin
24*0b57cec5SDimitry Andric // info class that gets handed out by the plugin factory and allows the lldb to
25*0b57cec5SDimitry Andric // instantiate an instance of this class.
26*0b57cec5SDimitry Andric DynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process,
27*0b57cec5SDimitry Andric bool force) {
28*0b57cec5SDimitry Andric bool create = force;
29*0b57cec5SDimitry Andric if (!create) {
30*0b57cec5SDimitry Andric const llvm::Triple &triple_ref =
31*0b57cec5SDimitry Andric process->GetTarget().GetArchitecture().GetTriple();
32*0b57cec5SDimitry Andric const llvm::Triple::OSType os_type = triple_ref.getOS();
33*0b57cec5SDimitry Andric const llvm::Triple::ArchType arch_type = triple_ref.getArch();
34*0b57cec5SDimitry Andric if (os_type == llvm::Triple::UnknownOS) {
35*0b57cec5SDimitry Andric // The WASM and Hexagon plugin check the ArchType rather than the OSType,
36*0b57cec5SDimitry Andric // so explicitly reject those here.
37*0b57cec5SDimitry Andric switch(arch_type) {
38*0b57cec5SDimitry Andric case llvm::Triple::hexagon:
39*0b57cec5SDimitry Andric case llvm::Triple::wasm32:
40*0b57cec5SDimitry Andric case llvm::Triple::wasm64:
41*0b57cec5SDimitry Andric break;
42*0b57cec5SDimitry Andric default:
43*0b57cec5SDimitry Andric create = true;
44*0b57cec5SDimitry Andric }
45*0b57cec5SDimitry Andric }
46*0b57cec5SDimitry Andric }
47*0b57cec5SDimitry Andric
48*0b57cec5SDimitry Andric if (!create) {
49*0b57cec5SDimitry Andric Module *exe_module = process->GetTarget().GetExecutableModulePointer();
50*0b57cec5SDimitry Andric if (exe_module) {
51*0b57cec5SDimitry Andric ObjectFile *object_file = exe_module->GetObjectFile();
52*0b57cec5SDimitry Andric if (object_file) {
53*0b57cec5SDimitry Andric create = (object_file->GetStrata() == ObjectFile::eStrataRawImage);
54*0b57cec5SDimitry Andric }
55*0b57cec5SDimitry Andric }
56*0b57cec5SDimitry Andric }
57*0b57cec5SDimitry Andric
58*0b57cec5SDimitry Andric if (create)
59*0b57cec5SDimitry Andric return new DynamicLoaderStatic(process);
60*0b57cec5SDimitry Andric return nullptr;
61*0b57cec5SDimitry Andric }
62*0b57cec5SDimitry Andric
63*0b57cec5SDimitry Andric // Constructor
DynamicLoaderStatic(Process * process)64*0b57cec5SDimitry Andric DynamicLoaderStatic::DynamicLoaderStatic(Process *process)
65*0b57cec5SDimitry Andric : DynamicLoader(process) {}
66*0b57cec5SDimitry Andric
67*0b57cec5SDimitry Andric /// Called after attaching a process.
68*0b57cec5SDimitry Andric ///
69*0b57cec5SDimitry Andric /// Allow DynamicLoader plug-ins to execute some code after
70*0b57cec5SDimitry Andric /// attaching to a process.
DidAttach()71*0b57cec5SDimitry Andric void DynamicLoaderStatic::DidAttach() { LoadAllImagesAtFileAddresses(); }
72*0b57cec5SDimitry Andric
73*0b57cec5SDimitry Andric /// Called after attaching a process.
74*0b57cec5SDimitry Andric ///
75*0b57cec5SDimitry Andric /// Allow DynamicLoader plug-ins to execute some code after
76*0b57cec5SDimitry Andric /// attaching to a process.
DidLaunch()77*0b57cec5SDimitry Andric void DynamicLoaderStatic::DidLaunch() { LoadAllImagesAtFileAddresses(); }
78*0b57cec5SDimitry Andric
LoadAllImagesAtFileAddresses()79*0b57cec5SDimitry Andric void DynamicLoaderStatic::LoadAllImagesAtFileAddresses() {
80*0b57cec5SDimitry Andric const ModuleList &module_list = m_process->GetTarget().GetImages();
81*0b57cec5SDimitry Andric
82*0b57cec5SDimitry Andric ModuleList loaded_module_list;
83*0b57cec5SDimitry Andric
84*0b57cec5SDimitry Andric // Disable JIT for static dynamic loader targets
85*0b57cec5SDimitry Andric m_process->SetCanJIT(false);
86*0b57cec5SDimitry Andric
87*0b57cec5SDimitry Andric for (ModuleSP module_sp : module_list.Modules()) {
88*0b57cec5SDimitry Andric if (module_sp) {
89*0b57cec5SDimitry Andric bool changed = false;
90*0b57cec5SDimitry Andric ObjectFile *image_object_file = module_sp->GetObjectFile();
91*0b57cec5SDimitry Andric if (image_object_file) {
92*0b57cec5SDimitry Andric SectionList *section_list = image_object_file->GetSectionList();
93*0b57cec5SDimitry Andric if (section_list) {
94*0b57cec5SDimitry Andric // All sections listed in the dyld image info structure will all
95*0b57cec5SDimitry Andric // either be fixed up already, or they will all be off by a single
96*0b57cec5SDimitry Andric // slide amount that is determined by finding the first segment that
97*0b57cec5SDimitry Andric // is at file offset zero which also has bytes (a file size that is
98*0b57cec5SDimitry Andric // greater than zero) in the object file.
99*0b57cec5SDimitry Andric
100*0b57cec5SDimitry Andric // Determine the slide amount (if any)
101*0b57cec5SDimitry Andric const size_t num_sections = section_list->GetSize();
102*0b57cec5SDimitry Andric size_t sect_idx = 0;
103*0b57cec5SDimitry Andric for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
104*0b57cec5SDimitry Andric // Iterate through the object file sections to find the first
105*0b57cec5SDimitry Andric // section that starts of file offset zero and that has bytes in
106*0b57cec5SDimitry Andric // the file...
107*0b57cec5SDimitry Andric SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
108*0b57cec5SDimitry Andric if (section_sp) {
109*0b57cec5SDimitry Andric // If this section already has a load address set in the target,
110*0b57cec5SDimitry Andric // don't re-set it to the file address. Something may have
111*0b57cec5SDimitry Andric // set it to a more correct value already.
112*0b57cec5SDimitry Andric if (m_process->GetTarget()
113*0b57cec5SDimitry Andric .GetSectionLoadList()
114*0b57cec5SDimitry Andric .GetSectionLoadAddress(section_sp) !=
115*0b57cec5SDimitry Andric LLDB_INVALID_ADDRESS) {
116*0b57cec5SDimitry Andric continue;
117*0b57cec5SDimitry Andric }
118*0b57cec5SDimitry Andric if (m_process->GetTarget().SetSectionLoadAddress(
119*0b57cec5SDimitry Andric section_sp, section_sp->GetFileAddress()))
120*0b57cec5SDimitry Andric changed = true;
121*0b57cec5SDimitry Andric }
122*0b57cec5SDimitry Andric }
123*0b57cec5SDimitry Andric }
124*0b57cec5SDimitry Andric }
125*0b57cec5SDimitry Andric
126*0b57cec5SDimitry Andric if (changed)
127*0b57cec5SDimitry Andric loaded_module_list.AppendIfNeeded(module_sp);
128*0b57cec5SDimitry Andric }
129*0b57cec5SDimitry Andric }
130*0b57cec5SDimitry Andric
131*0b57cec5SDimitry Andric m_process->GetTarget().ModulesDidLoad(loaded_module_list);
132*0b57cec5SDimitry Andric }
133*0b57cec5SDimitry Andric
134*0b57cec5SDimitry Andric ThreadPlanSP
GetStepThroughTrampolinePlan(Thread & thread,bool stop_others)135*0b57cec5SDimitry Andric DynamicLoaderStatic::GetStepThroughTrampolinePlan(Thread &thread,
136*0b57cec5SDimitry Andric bool stop_others) {
137*0b57cec5SDimitry Andric return ThreadPlanSP();
138*0b57cec5SDimitry Andric }
139*0b57cec5SDimitry Andric
CanLoadImage()140*0b57cec5SDimitry Andric Status DynamicLoaderStatic::CanLoadImage() {
141*0b57cec5SDimitry Andric Status error;
142*0b57cec5SDimitry Andric error.SetErrorString("can't load images on with a static debug session");
143*0b57cec5SDimitry Andric return error;
144*0b57cec5SDimitry Andric }
145*0b57cec5SDimitry Andric
Initialize()146*0b57cec5SDimitry Andric void DynamicLoaderStatic::Initialize() {
147*0b57cec5SDimitry Andric PluginManager::RegisterPlugin(GetPluginNameStatic(),
148*0b57cec5SDimitry Andric GetPluginDescriptionStatic(), CreateInstance);
149*0b57cec5SDimitry Andric }
150*0b57cec5SDimitry Andric
Terminate()151*0b57cec5SDimitry Andric void DynamicLoaderStatic::Terminate() {
152*0b57cec5SDimitry Andric PluginManager::UnregisterPlugin(CreateInstance);
153*0b57cec5SDimitry Andric }
154*0b57cec5SDimitry Andric
GetPluginDescriptionStatic()155 llvm::StringRef DynamicLoaderStatic::GetPluginDescriptionStatic() {
156 return "Dynamic loader plug-in that will load any images at the static "
157 "addresses contained in each image.";
158 }
159