LLDB  mainline
ObjectFileJIT.cpp
Go to the documentation of this file.
1 //===-- ObjectFileJIT.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 "llvm/ADT/StringRef.h"
10 
11 #include "ObjectFileJIT.h"
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Core/FileSpecList.h"
14 #include "lldb/Core/Module.h"
15 #include "lldb/Core/ModuleSpec.h"
17 #include "lldb/Core/Section.h"
18 #include "lldb/Core/StreamFile.h"
19 #include "lldb/Host/Host.h"
20 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Target/Platform.h"
22 #include "lldb/Target/Process.h"
24 #include "lldb/Target/Target.h"
25 #include "lldb/Utility/ArchSpec.h"
28 #include "lldb/Utility/FileSpec.h"
29 #include "lldb/Utility/Log.h"
30 #include "lldb/Utility/RangeMap.h"
32 #include "lldb/Utility/Timer.h"
33 #include "lldb/Utility/UUID.h"
34 
35 #ifndef __APPLE__
37 #endif
38 
39 using namespace lldb;
40 using namespace lldb_private;
41 
43 
45 
47  PluginManager::RegisterPlugin(GetPluginNameStatic(),
48  GetPluginDescriptionStatic(), CreateInstance,
49  CreateMemoryInstance, GetModuleSpecifications);
50 }
51 
53  PluginManager::UnregisterPlugin(CreateInstance);
54 }
55 
57  static ConstString g_name("jit");
58  return g_name;
59 }
60 
62  return "JIT code object file";
63 }
64 
65 ObjectFile *ObjectFileJIT::CreateInstance(const lldb::ModuleSP &module_sp,
66  DataBufferSP &data_sp,
67  lldb::offset_t data_offset,
68  const FileSpec *file,
69  lldb::offset_t file_offset,
70  lldb::offset_t length) {
71  // JIT'ed object file is backed by the ObjectFileJITDelegate, never read from
72  // a file
73  return nullptr;
74 }
75 
76 ObjectFile *ObjectFileJIT::CreateMemoryInstance(const lldb::ModuleSP &module_sp,
77  DataBufferSP &data_sp,
78  const ProcessSP &process_sp,
79  lldb::addr_t header_addr) {
80  // JIT'ed object file is backed by the ObjectFileJITDelegate, never read from
81  // memory
82  return nullptr;
83 }
84 
86  const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
87  lldb::offset_t data_offset, lldb::offset_t file_offset,
89  // JIT'ed object file can't be read from a file on disk
90  return 0;
91 }
92 
93 ObjectFileJIT::ObjectFileJIT(const lldb::ModuleSP &module_sp,
94  const ObjectFileJITDelegateSP &delegate_sp)
95  : ObjectFile(module_sp, nullptr, 0, 0, DataBufferSP(), 0), m_delegate_wp() {
96  if (delegate_sp) {
97  m_delegate_wp = delegate_sp;
98  m_data.SetByteOrder(delegate_sp->GetByteOrder());
99  m_data.SetAddressByteSize(delegate_sp->GetAddressByteSize());
100  }
101 }
102 
104 
106  // JIT code is never in a file, nor is it required to have any header
107  return false;
108 }
109 
111 
112 bool ObjectFileJIT::IsExecutable() const { return false; }
113 
115  return m_data.GetAddressByteSize();
116 }
117 
119  ModuleSP module_sp(GetModule());
120  if (module_sp) {
121  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
122  if (m_symtab_up == nullptr) {
123  m_symtab_up.reset(new Symtab(this));
124  std::lock_guard<std::recursive_mutex> symtab_guard(
125  m_symtab_up->GetMutex());
126  ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
127  if (delegate_sp)
128  delegate_sp->PopulateSymtab(this, *m_symtab_up);
129  // TODO: get symbols from delegate
130  m_symtab_up->Finalize();
131  }
132  }
133  return m_symtab_up.get();
134 }
135 
137  return false; // JIT code that is in a module is never stripped
138 }
139 
140 void ObjectFileJIT::CreateSections(SectionList &unified_section_list) {
141  if (!m_sections_up) {
142  m_sections_up.reset(new SectionList());
143  ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());
144  if (delegate_sp) {
145  delegate_sp->PopulateSectionList(this, *m_sections_up);
146  unified_section_list = *m_sections_up;
147  }
148  }
149 }
150 
152  ModuleSP module_sp(GetModule());
153  if (module_sp) {
154  std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
155  s->Printf("%p: ", static_cast<void *>(this));
156  s->Indent();
157  s->PutCString("ObjectFileJIT");
158 
159  if (ArchSpec arch = GetArchitecture())
160  *s << ", arch = " << arch.GetArchitectureName();
161 
162  s->EOL();
163 
164  SectionList *sections = GetSectionList();
165  if (sections)
166  sections->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,
167  UINT32_MAX);
168 
169  if (m_symtab_up)
170  m_symtab_up->Dump(s, nullptr, eSortOrderNone);
171  }
172 }
173 
175  // TODO: maybe get from delegate, not needed for first pass
176  return UUID();
177 }
178 
180  // JIT modules don't have dependencies, but they could
181  // if external functions are called and we know where they are
182  files.Clear();
183  return 0;
184 }
185 
187  return Address();
188 }
189 
191 
193 
195 
197  if (ObjectFileJITDelegateSP delegate_sp = m_delegate_wp.lock())
198  return delegate_sp->GetArchitecture();
199  return ArchSpec();
200 }
201 
202 // PluginInterface protocol
204  return GetPluginNameStatic();
205 }
206 
208 
210  bool value_is_offset) {
211  size_t num_loaded_sections = 0;
212  SectionList *section_list = GetSectionList();
213  if (section_list) {
214  const size_t num_sections = section_list->GetSize();
215  // "value" is an offset to apply to each top level segment
216  for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
217  // Iterate through the object file sections to find all of the sections
218  // that size on disk (to avoid __PAGEZERO) and load them
219  SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
220  if (section_sp && section_sp->GetFileSize() > 0 &&
221  !section_sp->IsThreadSpecific()) {
223  section_sp, section_sp->GetFileAddress() + value))
224  ++num_loaded_sections;
225  }
226  }
227  }
228  return num_loaded_sections > 0;
229 }
230 
232  lldb::offset_t section_offset, void *dst,
233  size_t dst_len) {
234  lldb::offset_t file_size = section->GetFileSize();
235  if (section_offset < file_size) {
236  size_t src_len = file_size - section_offset;
237  if (src_len > dst_len)
238  src_len = dst_len;
239  const uint8_t *src =
240  ((uint8_t *)(uintptr_t)section->GetFileOffset()) + section_offset;
241 
242  memcpy(dst, src, src_len);
243  return src_len;
244  }
245  return 0;
246 }
247 
249  lldb_private::Section *section,
250  lldb_private::DataExtractor &section_data) {
251  if (section->GetFileSize()) {
252  const void *src = (void *)(uintptr_t)section->GetFileOffset();
253 
254  DataBufferSP data_sp =
255  std::make_shared<DataBufferHeap>(src, section->GetFileSize());
256  section_data.SetData(data_sp, 0, data_sp->GetByteSize());
257  section_data.SetByteOrder(GetByteOrder());
258  section_data.SetAddressByteSize(GetAddressByteSize());
259  return section_data.GetByteSize();
260  }
261  section_data.Clear();
262  return 0;
263 }
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:62
An data extractor class.
Definition: DataExtractor.h:46
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition: Stream.h:356
A class that represents a running process on the host machine.
A stream class that can stream formatted output to a file.
Definition: Stream.h:28
void Dump(llvm::raw_ostream &s, unsigned indent, Target *target, bool show_header, uint32_t depth) const
Definition: Section.cpp:570
static void Terminate()
lldb::offset_t GetFileOffset() const
Definition: Section.h:140
static lldb_private::ObjectFile * CreateMemoryInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, const lldb::ProcessSP &process_sp, lldb::addr_t header_addr)
A file utility class.
Definition: FileSpec.h:56
An architecture specification class.
Definition: ArchSpec.h:33
JIT code that has symbols, sections and possibly debug info.
Definition: ObjectFile.h:81
A plug-in interface definition class for object file parsers.
Definition: ObjectFile.h:58
lldb::ObjectFileJITDelegateWP m_delegate_wp
ObjectFile::Strata CalculateStrata() override
The object file should be able to calculate the strata of the object file.
std::unique_ptr< lldb_private::Symtab > m_symtab_up
Definition: ObjectFile.h:668
uint32_t GetAddressByteSize() const override
Gets the address size in bytes for the current object file.
lldb_private::Address GetEntryPointAddress() override
Returns the address of the Entry Point in this object file - if the object file doesn&#39;t have an entry...
void SetAddressByteSize(uint32_t addr_size)
Set the address byte size.
bool IsStripped() override
Detect if this object file has been stripped of local symbols.
bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, bool value_is_offset) override
Sets the load address for an entire module, assuming a rigid slide of sections, if possible in the im...
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
Definition: ModuleChild.cpp:24
lldb::offset_t GetFileSize() const
Definition: Section.h:146
unsigned GetIndentLevel() const
Get the current indentation level.
Definition: Stream.cpp:159
std::unique_ptr< lldb_private::SectionList > m_sections_up
Definition: ObjectFile.h:667
~ObjectFileJIT() override
bool SetSectionLoadAddress(const lldb::SectionSP &section_sp, lldb::addr_t load_addr, bool warn_multiple=false)
uint32_t GetDependentModules(lldb_private::FileSpecList &files) override
lldb_private::Address GetBaseAddress() override
Returns base address of this object file.
#define UINT32_MAX
Definition: lldb-defines.h:31
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
lldb_private::ConstString GetPluginName() override
size_t Indent(llvm::StringRef s="")
Indent the current line in the stream.
Definition: Stream.cpp:129
lldb::offset_t SetData(const void *bytes, lldb::offset_t length, lldb::ByteOrder byte_order)
Set data with a buffer that is caller owned.
bool IsExecutable() const override
Tells whether this object file is capable of being the main executable for a process.
uint64_t offset_t
Definition: lldb-types.h:87
void Clear()
Clears the object state.
static void Initialize()
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:127
SectionLoadList & GetSectionLoadList()
Definition: Target.h:1012
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
virtual SectionList * GetSectionList(bool update_module_section_list=true)
Gets the section list for the currently selected architecture (and object for archives).
Definition: ObjectFile.cpp:607
ByteOrder
Byte ordering definitions.
lldb_private::ArchSpec GetArchitecture() override
Get the ArchSpec for this object file.
lldb::SectionSP GetSectionAtIndex(size_t idx) const
Definition: Section.cpp:476
ObjectFileJIT(const lldb::ModuleSP &module_sp, const lldb::ObjectFileJITDelegateSP &delegate_sp)
bool ParseHeader() override
Attempts to parse the object header.
ObjectFile::Type CalculateType() override
The object file should be able to calculate its type by looking at its file header and possibly the s...
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:106
A section + offset based address class.
Definition: Address.h:59
static const char * GetPluginDescriptionStatic()
size_t ReadSectionData(lldb_private::Section *section, lldb::offset_t section_offset, void *dst, size_t dst_len) override
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
static lldb_private::ConstString GetPluginNameStatic()
DataExtractor m_data
The data for this object file so things can be parsed lazily.
Definition: ObjectFile.h:664
static lldb_private::ObjectFile * CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, const lldb_private::FileSpec *file, lldb::offset_t file_offset, lldb::offset_t length)
uint64_t addr_t
Definition: lldb-types.h:83
static size_t GetModuleSpecifications(const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, lldb::offset_t file_offset, lldb::offset_t length, lldb_private::ModuleSpecList &specs)
void CreateSections(lldb_private::SectionList &unified_section_list) override
A uniqued constant string class.
Definition: ConstString.h:40
uint32_t GetPluginVersion() override
Definition: SBAddress.h:15
size_t GetSize() const
Definition: Section.h:74
void Dump(lldb_private::Stream *s) override
Dump a description of this object to a Stream.
lldb_private::Symtab * GetSymtab() override
Gets the symbol table for the currently selected architecture (and object for archives).
static char ID
Definition: ObjectFileJIT.h:50
lldb_private::UUID GetUUID() override
Gets the UUID for this object file.
uint32_t GetAddressByteSize() const
Get the current address size.
lldb::ByteOrder GetByteOrder() const override
Gets whether endian swapping should occur when extracting data from this object file.
void SetByteOrder(lldb::ByteOrder byte_order)
Set the byte_order value.