1254721Semaste//===-- DynamicLoaderStatic.cpp ---------------------------------*- C++ -*-===//
2254721Semaste//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6254721Semaste//
7254721Semaste//===----------------------------------------------------------------------===//
8254721Semaste
9254721Semaste#include "lldb/Core/Module.h"
10254721Semaste#include "lldb/Core/PluginManager.h"
11254721Semaste#include "lldb/Core/Section.h"
12254721Semaste#include "lldb/Symbol/ObjectFile.h"
13254721Semaste#include "lldb/Target/Target.h"
14254721Semaste
15254721Semaste#include "DynamicLoaderStatic.h"
16254721Semaste
17254721Semasteusing namespace lldb;
18254721Semasteusing namespace lldb_private;
19254721Semaste
20341825Sdim// Create an instance of this class. This function is filled into the plugin
21341825Sdim// info class that gets handed out by the plugin factory and allows the lldb to
22341825Sdim// instantiate an instance of this class.
23314564SdimDynamicLoader *DynamicLoaderStatic::CreateInstance(Process *process,
24314564Sdim                                                   bool force) {
25314564Sdim  bool create = force;
26314564Sdim  if (!create) {
27314564Sdim    const llvm::Triple &triple_ref =
28314564Sdim        process->GetTarget().GetArchitecture().GetTriple();
29314564Sdim    const llvm::Triple::OSType os_type = triple_ref.getOS();
30314564Sdim    if ((os_type == llvm::Triple::UnknownOS))
31314564Sdim      create = true;
32314564Sdim  }
33314564Sdim
34314564Sdim  if (!create) {
35314564Sdim    Module *exe_module = process->GetTarget().GetExecutableModulePointer();
36314564Sdim    if (exe_module) {
37314564Sdim      ObjectFile *object_file = exe_module->GetObjectFile();
38314564Sdim      if (object_file) {
39314564Sdim        create = (object_file->GetStrata() == ObjectFile::eStrataRawImage);
40314564Sdim      }
41254721Semaste    }
42314564Sdim  }
43314564Sdim
44314564Sdim  if (create)
45314564Sdim    return new DynamicLoaderStatic(process);
46353358Sdim  return nullptr;
47254721Semaste}
48254721Semaste
49254721Semaste// Constructor
50314564SdimDynamicLoaderStatic::DynamicLoaderStatic(Process *process)
51314564Sdim    : DynamicLoader(process) {}
52254721Semaste
53254721Semaste// Destructor
54314564SdimDynamicLoaderStatic::~DynamicLoaderStatic() {}
55254721Semaste
56254721Semaste/// Called after attaching a process.
57254721Semaste///
58254721Semaste/// Allow DynamicLoader plug-ins to execute some code after
59254721Semaste/// attaching to a process.
60314564Sdimvoid DynamicLoaderStatic::DidAttach() { LoadAllImagesAtFileAddresses(); }
61254721Semaste
62254721Semaste/// Called after attaching a process.
63254721Semaste///
64254721Semaste/// Allow DynamicLoader plug-ins to execute some code after
65254721Semaste/// attaching to a process.
66314564Sdimvoid DynamicLoaderStatic::DidLaunch() { LoadAllImagesAtFileAddresses(); }
67254721Semaste
68314564Sdimvoid DynamicLoaderStatic::LoadAllImagesAtFileAddresses() {
69314564Sdim  const ModuleList &module_list = m_process->GetTarget().GetImages();
70254721Semaste
71314564Sdim  ModuleList loaded_module_list;
72254721Semaste
73314564Sdim  // Disable JIT for static dynamic loader targets
74314564Sdim  m_process->SetCanJIT(false);
75309124Sdim
76314564Sdim  std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
77254721Semaste
78314564Sdim  const size_t num_modules = module_list.GetSize();
79314564Sdim  for (uint32_t idx = 0; idx < num_modules; ++idx) {
80314564Sdim    ModuleSP module_sp(module_list.GetModuleAtIndexUnlocked(idx));
81314564Sdim    if (module_sp) {
82314564Sdim      bool changed = false;
83314564Sdim      ObjectFile *image_object_file = module_sp->GetObjectFile();
84314564Sdim      if (image_object_file) {
85314564Sdim        SectionList *section_list = image_object_file->GetSectionList();
86314564Sdim        if (section_list) {
87314564Sdim          // All sections listed in the dyld image info structure will all
88314564Sdim          // either be fixed up already, or they will all be off by a single
89341825Sdim          // slide amount that is determined by finding the first segment that
90341825Sdim          // is at file offset zero which also has bytes (a file size that is
91341825Sdim          // greater than zero) in the object file.
92314564Sdim
93314564Sdim          // Determine the slide amount (if any)
94314564Sdim          const size_t num_sections = section_list->GetSize();
95314564Sdim          size_t sect_idx = 0;
96314564Sdim          for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
97341825Sdim            // Iterate through the object file sections to find the first
98341825Sdim            // section that starts of file offset zero and that has bytes in
99341825Sdim            // the file...
100314564Sdim            SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
101314564Sdim            if (section_sp) {
102314564Sdim              if (m_process->GetTarget().SetSectionLoadAddress(
103314564Sdim                      section_sp, section_sp->GetFileAddress()))
104314564Sdim                changed = true;
105254721Semaste            }
106314564Sdim          }
107254721Semaste        }
108314564Sdim      }
109314564Sdim
110314564Sdim      if (changed)
111314564Sdim        loaded_module_list.AppendIfNeeded(module_sp);
112254721Semaste    }
113314564Sdim  }
114254721Semaste
115314564Sdim  m_process->GetTarget().ModulesDidLoad(loaded_module_list);
116254721Semaste}
117254721Semaste
118254721SemasteThreadPlanSP
119314564SdimDynamicLoaderStatic::GetStepThroughTrampolinePlan(Thread &thread,
120314564Sdim                                                  bool stop_others) {
121314564Sdim  return ThreadPlanSP();
122254721Semaste}
123254721Semaste
124321369SdimStatus DynamicLoaderStatic::CanLoadImage() {
125321369Sdim  Status error;
126314564Sdim  error.SetErrorString("can't load images on with a static debug session");
127314564Sdim  return error;
128254721Semaste}
129254721Semaste
130314564Sdimvoid DynamicLoaderStatic::Initialize() {
131314564Sdim  PluginManager::RegisterPlugin(GetPluginNameStatic(),
132314564Sdim                                GetPluginDescriptionStatic(), CreateInstance);
133254721Semaste}
134254721Semaste
135314564Sdimvoid DynamicLoaderStatic::Terminate() {
136314564Sdim  PluginManager::UnregisterPlugin(CreateInstance);
137254721Semaste}
138254721Semaste
139314564Sdimlldb_private::ConstString DynamicLoaderStatic::GetPluginNameStatic() {
140314564Sdim  static ConstString g_name("static");
141314564Sdim  return g_name;
142254721Semaste}
143254721Semaste
144314564Sdimconst char *DynamicLoaderStatic::GetPluginDescriptionStatic() {
145314564Sdim  return "Dynamic loader plug-in that will load any images at the static "
146314564Sdim         "addresses contained in each image.";
147254721Semaste}
148254721Semaste
149254721Semaste// PluginInterface protocol
150314564Sdimlldb_private::ConstString DynamicLoaderStatic::GetPluginName() {
151314564Sdim  return GetPluginNameStatic();
152254721Semaste}
153254721Semaste
154314564Sdimuint32_t DynamicLoaderStatic::GetPluginVersion() { return 1; }
155