LLVM  14.0.0git
DebugObjectManagerPlugin.cpp
Go to the documentation of this file.
1 //===------- DebugObjectManagerPlugin.cpp - JITLink debug objects ---------===//
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 // FIXME: Update Plugin to poke the debug object into a new JITLink section,
10 // rather than creating a new allocation.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 
16 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/StringMap.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/BinaryFormat/ELF.h"
24 #include "llvm/Object/ObjectFile.h"
25 #include "llvm/Support/Errc.h"
28 #include "llvm/Support/Process.h"
30 
31 #include <set>
32 
33 #define DEBUG_TYPE "orc"
34 
35 using namespace llvm::jitlink;
36 using namespace llvm::object;
37 
38 namespace llvm {
39 namespace orc {
40 
42 public:
43  virtual void setTargetMemoryRange(SectionRange Range) = 0;
44  virtual void dump(raw_ostream &OS, StringRef Name) {}
45  virtual ~DebugObjectSection() {}
46 };
47 
48 template <typename ELFT>
50 public:
51  // BinaryFormat ELF is not meant as a mutable format. We can only make changes
52  // that don't invalidate the file structure.
53  ELFDebugObjectSection(const typename ELFT::Shdr *Header)
54  : Header(const_cast<typename ELFT::Shdr *>(Header)) {}
55 
56  void setTargetMemoryRange(SectionRange Range) override;
57  void dump(raw_ostream &OS, StringRef Name) override;
58 
59  Error validateInBounds(StringRef Buffer, const char *Name) const;
60 
61 private:
62  typename ELFT::Shdr *Header;
63 
64  bool isTextOrDataSection() const;
65 };
66 
67 template <typename ELFT>
69  // Only patch load-addresses for executable and data sections.
70  if (isTextOrDataSection()) {
71  Header->sh_addr = static_cast<typename ELFT::uint>(Range.getStart());
72  }
73 }
74 
75 template <typename ELFT>
77  switch (Header->sh_type) {
78  case ELF::SHT_PROGBITS:
80  return Header->sh_flags & (ELF::SHF_EXECINSTR | ELF::SHF_ALLOC);
81  }
82  return false;
83 }
84 
85 template <typename ELFT>
87  const char *Name) const {
88  const uint8_t *Start = Buffer.bytes_begin();
89  const uint8_t *End = Buffer.bytes_end();
90  const uint8_t *HeaderPtr = reinterpret_cast<uint8_t *>(Header);
91  if (HeaderPtr < Start || HeaderPtr + sizeof(typename ELFT::Shdr) > End)
92  return make_error<StringError>(
93  formatv("{0} section header at {1:x16} not within bounds of the "
94  "given debug object buffer [{2:x16} - {3:x16}]",
95  Name, &Header->sh_addr, Start, End),
97  if (Header->sh_offset + Header->sh_size > Buffer.size())
98  return make_error<StringError>(
99  formatv("{0} section data [{1:x16} - {2:x16}] not within bounds of "
100  "the given debug object buffer [{3:x16} - {4:x16}]",
101  Name, Start + Header->sh_offset,
102  Start + Header->sh_offset + Header->sh_size, Start, End),
104  return Error::success();
105 }
106 
107 template <typename ELFT>
109  if (auto Addr = static_cast<JITTargetAddress>(Header->sh_addr)) {
110  OS << formatv(" {0:x16} {1}\n", Addr, Name);
111  } else {
112  OS << formatv(" {0}\n", Name);
113  }
114 }
115 
116 enum class Requirement {
117  // Request final target memory load-addresses for all sections.
119 };
120 
121 /// The plugin creates a debug object from when JITLink starts processing the
122 /// corresponding LinkGraph. It provides access to the pass configuration of
123 /// the LinkGraph and calls the finalization function, once the resulting link
124 /// artifact was emitted.
125 ///
126 class DebugObject {
127 public:
129  ExecutionSession &ES)
130  : MemMgr(MemMgr), JD(JD), ES(ES) {}
131 
132  void set(Requirement Req) { Reqs.insert(Req); }
133  bool has(Requirement Req) const { return Reqs.count(Req) > 0; }
134 
136 
137  void finalizeAsync(FinalizeContinuation OnFinalize);
138 
139  virtual ~DebugObject() {
140  if (Alloc) {
141  std::vector<FinalizedAlloc> Allocs;
142  Allocs.push_back(std::move(Alloc));
143  if (Error Err = MemMgr.deallocate(std::move(Allocs)))
144  ES.reportError(std::move(Err));
145  }
146  }
147 
149  SectionRange TargetMem) {}
150 
151 protected:
154 
155  virtual Expected<SimpleSegmentAlloc> finalizeWorkingMemory() = 0;
156 
158  const JITLinkDylib *JD = nullptr;
159 
160 private:
161  ExecutionSession &ES;
162  std::set<Requirement> Reqs;
163  FinalizedAlloc Alloc;
164 };
165 
166 // Finalize working memory and take ownership of the resulting allocation. Start
167 // copying memory over to the target and pass on the result once we're done.
168 // Ownership of the allocation remains with us for the rest of our lifetime.
169 void DebugObject::finalizeAsync(FinalizeContinuation OnFinalize) {
170  assert(!Alloc && "Cannot finalize more than once");
171 
172  if (auto SimpleSegAlloc = finalizeWorkingMemory()) {
173  auto ROSeg = SimpleSegAlloc->getSegInfo(MemProt::Read);
174  ExecutorAddrRange DebugObjRange(ExecutorAddr(ROSeg.Addr),
175  ExecutorAddrDiff(ROSeg.WorkingMem.size()));
176  SimpleSegAlloc->finalize(
177  [this, DebugObjRange,
178  OnFinalize = std::move(OnFinalize)](Expected<FinalizedAlloc> FA) {
179  if (FA) {
180  Alloc = std::move(*FA);
181  OnFinalize(DebugObjRange);
182  } else
183  OnFinalize(FA.takeError());
184  });
185  } else
186  OnFinalize(SimpleSegAlloc.takeError());
187 }
188 
189 /// The current implementation of ELFDebugObject replicates the approach used in
190 /// RuntimeDyld: It patches executable and data section headers in the given
191 /// object buffer with load-addresses of their corresponding sections in target
192 /// memory.
193 ///
194 class ELFDebugObject : public DebugObject {
195 public:
197  Create(MemoryBufferRef Buffer, JITLinkContext &Ctx, ExecutionSession &ES);
198 
199  void reportSectionTargetMemoryRange(StringRef Name,
200  SectionRange TargetMem) override;
201 
202  StringRef getBuffer() const { return Buffer->getMemBufferRef().getBuffer(); }
203 
204 protected:
205  Expected<SimpleSegmentAlloc> finalizeWorkingMemory() override;
206 
207  template <typename ELFT>
208  Error recordSection(StringRef Name,
209  std::unique_ptr<ELFDebugObjectSection<ELFT>> Section);
211 
212 private:
213  template <typename ELFT>
215  CreateArchType(MemoryBufferRef Buffer, JITLinkMemoryManager &MemMgr,
216  const JITLinkDylib *JD, ExecutionSession &ES);
217 
218  static std::unique_ptr<WritableMemoryBuffer>
219  CopyBuffer(MemoryBufferRef Buffer, Error &Err);
220 
221  ELFDebugObject(std::unique_ptr<WritableMemoryBuffer> Buffer,
222  JITLinkMemoryManager &MemMgr, const JITLinkDylib *JD,
223  ExecutionSession &ES)
224  : DebugObject(MemMgr, JD, ES), Buffer(std::move(Buffer)) {
225  set(Requirement::ReportFinalSectionLoadAddresses);
226  }
227 
228  std::unique_ptr<WritableMemoryBuffer> Buffer;
230 };
231 
232 static const std::set<StringRef> DwarfSectionNames = {
233 #define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME, OPTION) \
234  ELF_NAME,
235 #include "llvm/BinaryFormat/Dwarf.def"
236 #undef HANDLE_DWARF_SECTION
237 };
238 
240  return DwarfSectionNames.count(SectionName) == 1;
241 }
242 
243 std::unique_ptr<WritableMemoryBuffer>
244 ELFDebugObject::CopyBuffer(MemoryBufferRef Buffer, Error &Err) {
245  ErrorAsOutParameter _(&Err);
246  size_t Size = Buffer.getBufferSize();
249  memcpy(Copy->getBufferStart(), Buffer.getBufferStart(), Size);
250  return Copy;
251  }
252 
254  return nullptr;
255 }
256 
257 template <typename ELFT>
258 Expected<std::unique_ptr<ELFDebugObject>>
259 ELFDebugObject::CreateArchType(MemoryBufferRef Buffer,
260  JITLinkMemoryManager &MemMgr,
261  const JITLinkDylib *JD, ExecutionSession &ES) {
262  using SectionHeader = typename ELFT::Shdr;
263 
264  Error Err = Error::success();
265  std::unique_ptr<ELFDebugObject> DebugObj(
266  new ELFDebugObject(CopyBuffer(Buffer, Err), MemMgr, JD, ES));
267  if (Err)
268  return std::move(Err);
269 
270  Expected<ELFFile<ELFT>> ObjRef = ELFFile<ELFT>::create(DebugObj->getBuffer());
271  if (!ObjRef)
272  return ObjRef.takeError();
273 
274  // TODO: Add support for other architectures.
275  uint16_t TargetMachineArch = ObjRef->getHeader().e_machine;
276  if (TargetMachineArch != ELF::EM_X86_64)
277  return nullptr;
278 
279  Expected<ArrayRef<SectionHeader>> Sections = ObjRef->sections();
280  if (!Sections)
281  return Sections.takeError();
282 
283  bool HasDwarfSection = false;
284  for (const SectionHeader &Header : *Sections) {
285  Expected<StringRef> Name = ObjRef->getSectionName(Header);
286  if (!Name)
287  return Name.takeError();
288  if (Name->empty())
289  continue;
290  HasDwarfSection |= isDwarfSection(*Name);
291 
292  auto Wrapped = std::make_unique<ELFDebugObjectSection<ELFT>>(&Header);
293  if (Error Err = DebugObj->recordSection(*Name, std::move(Wrapped)))
294  return std::move(Err);
295  }
296 
297  if (!HasDwarfSection) {
298  LLVM_DEBUG(dbgs() << "Aborting debug registration for LinkGraph \""
299  << DebugObj->Buffer->getBufferIdentifier()
300  << "\": input object contains no debug info\n");
301  return nullptr;
302  }
303 
304  return std::move(DebugObj);
305 }
306 
307 Expected<std::unique_ptr<DebugObject>>
308 ELFDebugObject::Create(MemoryBufferRef Buffer, JITLinkContext &Ctx,
309  ExecutionSession &ES) {
310  unsigned char Class, Endian;
311  std::tie(Class, Endian) = getElfArchType(Buffer.getBuffer());
312 
313  if (Class == ELF::ELFCLASS32) {
314  if (Endian == ELF::ELFDATA2LSB)
315  return CreateArchType<ELF32LE>(Buffer, Ctx.getMemoryManager(),
316  Ctx.getJITLinkDylib(), ES);
317  if (Endian == ELF::ELFDATA2MSB)
318  return CreateArchType<ELF32BE>(Buffer, Ctx.getMemoryManager(),
319  Ctx.getJITLinkDylib(), ES);
320  return nullptr;
321  }
322  if (Class == ELF::ELFCLASS64) {
323  if (Endian == ELF::ELFDATA2LSB)
324  return CreateArchType<ELF64LE>(Buffer, Ctx.getMemoryManager(),
325  Ctx.getJITLinkDylib(), ES);
326  if (Endian == ELF::ELFDATA2MSB)
327  return CreateArchType<ELF64BE>(Buffer, Ctx.getMemoryManager(),
328  Ctx.getJITLinkDylib(), ES);
329  return nullptr;
330  }
331  return nullptr;
332 }
333 
334 Expected<SimpleSegmentAlloc> ELFDebugObject::finalizeWorkingMemory() {
335  LLVM_DEBUG({
336  dbgs() << "Section load-addresses in debug object for \""
337  << Buffer->getBufferIdentifier() << "\":\n";
338  for (const auto &KV : Sections)
339  KV.second->dump(dbgs(), KV.first());
340  });
341 
342  // TODO: This works, but what actual alignment requirements do we have?
344  size_t Size = Buffer->getBufferSize();
345 
346  // Allocate working memory for debug object in read-only segment.
347  auto Alloc = SimpleSegmentAlloc::Create(
348  MemMgr, JD, {{MemProt::Read, {Size, Align(PageSize)}}});
349  if (!Alloc)
350  return Alloc;
351 
352  // Initialize working memory with a copy of our object buffer.
353  auto SegInfo = Alloc->getSegInfo(MemProt::Read);
354  memcpy(SegInfo.WorkingMem.data(), Buffer->getBufferStart(), Size);
355  Buffer.reset();
356 
357  return Alloc;
358 }
359 
360 void ELFDebugObject::reportSectionTargetMemoryRange(StringRef Name,
361  SectionRange TargetMem) {
362  if (auto *DebugObjSection = getSection(Name))
363  DebugObjSection->setTargetMemoryRange(TargetMem);
364 }
365 
366 template <typename ELFT>
367 Error ELFDebugObject::recordSection(
369  if (Error Err = Section->validateInBounds(this->getBuffer(), Name.data()))
370  return Err;
371  auto ItInserted = Sections.try_emplace(Name, std::move(Section));
372  if (!ItInserted.second)
373  return make_error<StringError>("Duplicate section",
375  return Error::success();
376 }
377 
379  auto It = Sections.find(Name);
380  return It == Sections.end() ? nullptr : It->second.get();
381 }
382 
383 /// Creates a debug object based on the input object file from
384 /// ObjectLinkingLayerJITLinkContext.
385 ///
388  JITLinkContext &Ctx, MemoryBufferRef ObjBuffer) {
389  switch (G.getTargetTriple().getObjectFormat()) {
390  case Triple::ELF:
391  return ELFDebugObject::Create(ObjBuffer, Ctx, ES);
392 
393  default:
394  // TODO: Once we add support for other formats, we might want to split this
395  // into multiple files.
396  return nullptr;
397  }
398 }
399 
400 DebugObjectManagerPlugin::DebugObjectManagerPlugin(
401  ExecutionSession &ES, std::unique_ptr<DebugObjectRegistrar> Target)
402  : ES(ES), Target(std::move(Target)) {}
403 
405 
408  MemoryBufferRef ObjBuffer) {
409  std::lock_guard<std::mutex> Lock(PendingObjsLock);
410  assert(PendingObjs.count(&MR) == 0 &&
411  "Cannot have more than one pending debug object per "
412  "MaterializationResponsibility");
413 
414  if (auto DebugObj = createDebugObjectFromBuffer(ES, G, Ctx, ObjBuffer)) {
415  // Not all link artifacts allow debugging.
416  if (*DebugObj != nullptr)
417  PendingObjs[&MR] = std::move(*DebugObj);
418  } else {
419  ES.reportError(DebugObj.takeError());
420  }
421 }
422 
425  PassConfiguration &PassConfig) {
426  // Not all link artifacts have associated debug objects.
427  std::lock_guard<std::mutex> Lock(PendingObjsLock);
428  auto It = PendingObjs.find(&MR);
429  if (It == PendingObjs.end())
430  return;
431 
432  DebugObject &DebugObj = *It->second;
434  PassConfig.PostAllocationPasses.push_back(
435  [&DebugObj](LinkGraph &Graph) -> Error {
436  for (const Section &GraphSection : Graph.sections())
437  DebugObj.reportSectionTargetMemoryRange(GraphSection.getName(),
438  SectionRange(GraphSection));
439  return Error::success();
440  });
441  }
442 }
443 
446  std::lock_guard<std::mutex> Lock(PendingObjsLock);
447  auto It = PendingObjs.find(&MR);
448  if (It == PendingObjs.end())
449  return Error::success();
450 
451  // During finalization the debug object is registered with the target.
452  // Materialization must wait for this process to finish. Otherwise we might
453  // start running code before the debugger processed the corresponding debug
454  // info.
455  std::promise<MSVCPError> FinalizePromise;
456  std::future<MSVCPError> FinalizeErr = FinalizePromise.get_future();
457 
458  It->second->finalizeAsync(
459  [this, &FinalizePromise, &MR](Expected<ExecutorAddrRange> TargetMem) {
460  // Any failure here will fail materialization.
461  if (!TargetMem) {
462  FinalizePromise.set_value(TargetMem.takeError());
463  return;
464  }
465  if (Error Err = Target->registerDebugObject(*TargetMem)) {
466  FinalizePromise.set_value(std::move(Err));
467  return;
468  }
469 
470  // Once our tracking info is updated, notifyEmitted() can return and
471  // finish materialization.
472  FinalizePromise.set_value(MR.withResourceKeyDo([&](ResourceKey K) {
473  assert(PendingObjs.count(&MR) && "We still hold PendingObjsLock");
474  std::lock_guard<std::mutex> Lock(RegisteredObjsLock);
475  RegisteredObjs[K].push_back(std::move(PendingObjs[&MR]));
476  PendingObjs.erase(&MR);
477  }));
478  });
479 
480  return FinalizeErr.get();
481 }
482 
485  std::lock_guard<std::mutex> Lock(PendingObjsLock);
486  PendingObjs.erase(&MR);
487  return Error::success();
488 }
489 
491  ResourceKey SrcKey) {
492  // Debug objects are stored by ResourceKey only after registration.
493  // Thus, pending objects don't need to be updated here.
494  std::lock_guard<std::mutex> Lock(RegisteredObjsLock);
495  auto SrcIt = RegisteredObjs.find(SrcKey);
496  if (SrcIt != RegisteredObjs.end()) {
497  // Resources from distinct MaterializationResponsibilitys can get merged
498  // after emission, so we can have multiple debug objects per resource key.
499  for (std::unique_ptr<DebugObject> &DebugObj : SrcIt->second)
500  RegisteredObjs[DstKey].push_back(std::move(DebugObj));
501  RegisteredObjs.erase(SrcIt);
502  }
503 }
504 
506  // Removing the resource for a pending object fails materialization, so they
507  // get cleaned up in the notifyFailed() handler.
508  std::lock_guard<std::mutex> Lock(RegisteredObjsLock);
509  RegisteredObjs.erase(Key);
510 
511  // TODO: Implement unregister notifications.
512  return Error::success();
513 }
514 
515 } // namespace orc
516 } // namespace llvm
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:37
llvm::orc::ResourceKey
uintptr_t ResourceKey
Definition: Core.h:50
MemoryBuffer.h
set
We currently generate a but we really shouldn eax ecx xorl edx divl ecx eax divl ecx movl eax ret A similar code sequence works for division We currently compile i32 v2 eax eax jo LBB1_2 atomic and others It is also currently not done for read modify write instructions It is also current not done if the OF or CF flags are needed The shift operators have the complication that when the shift count is EFLAGS is not set
Definition: README.txt:1277
llvm::orc::MaterializationResponsibility
Tracks responsibility for materialization, and mediates interactions between MaterializationUnits and...
Definition: Core.h:520
llvm::orc::ExecutorAddrDiff
Represents the difference between two addresses in the executor process.
Definition: ExecutorAddress.h:25
llvm::orc::createDebugObjectFromBuffer
static Expected< std::unique_ptr< DebugObject > > createDebugObjectFromBuffer(ExecutionSession &ES, LinkGraph &G, JITLinkContext &Ctx, MemoryBufferRef ObjBuffer)
Creates a debug object based on the input object file from ObjectLinkingLayerJITLinkContext.
Definition: DebugObjectManagerPlugin.cpp:387
llvm::MemoryBufferRef::getBufferStart
const char * getBufferStart() const
Definition: MemoryBufferRef.h:35
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
JITSymbol.h
llvm::lltok::Error
@ Error
Definition: LLToken.h:21
llvm::orc::DebugObject::set
void set(Requirement Req)
Definition: DebugObjectManagerPlugin.cpp:132
llvm::orc::DebugObjectManagerPlugin::~DebugObjectManagerPlugin
~DebugObjectManagerPlugin()
llvm::ELF::ELFCLASS32
@ ELFCLASS32
Definition: ELF.h:328
StringRef.h
llvm::ELF::SHT_X86_64_UNWIND
@ SHT_X86_64_UNWIND
Definition: ELF.h:972
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:137
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
llvm::orc::ELFDebugObject::getBuffer
StringRef getBuffer() const
Definition: DebugObjectManagerPlugin.cpp:202
llvm::orc::DebugObject::has
bool has(Requirement Req) const
Definition: DebugObjectManagerPlugin.cpp:133
llvm::object::getSection
Expected< const typename ELFT::Shdr * > getSection(typename ELFT::ShdrRange Sections, uint32_t Index)
Definition: ELF.h:402
Errc.h
MSVCErrorWorkarounds.h
llvm::ELF::ELFDATA2LSB
@ ELFDATA2LSB
Definition: ELF.h:335
llvm::orc::DebugObjectManagerPlugin::notifyFailed
Error notifyFailed(MaterializationResponsibility &MR) override
Definition: DebugObjectManagerPlugin.cpp:483
llvm::MemoryBufferRef::getBufferSize
size_t getBufferSize() const
Definition: MemoryBufferRef.h:37
llvm::orc::DebugObjectSection::~DebugObjectSection
virtual ~DebugObjectSection()
Definition: DebugObjectManagerPlugin.cpp:45
llvm::dump
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Definition: SparseBitVector.h:876
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::ELF::SHF_EXECINSTR
@ SHF_EXECINSTR
Definition: ELF.h:997
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
uint
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint
Definition: README.txt:239
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::Lock
static sys::Mutex Lock
Definition: NVPTXUtilities.cpp:39
llvm::orc::ELFDebugObjectSection::ELFDebugObjectSection
ELFDebugObjectSection(const typename ELFT::Shdr *Header)
Definition: DebugObjectManagerPlugin.cpp:53
llvm::formatv
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
Definition: FormatVariadic.h:250
Process.h
llvm::object
Definition: ObjectFileTransformer.h:18
ELF.h
PageSize
static cl::opt< int > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in bytes"), cl::init(4096), cl::Hidden)
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:87
llvm::AMDGPU::PALMD::Key
Key
PAL metadata keys.
Definition: AMDGPUMetadata.h:481
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::ErrorAsOutParameter
Helper for Errors used as out-parameters.
Definition: Error.h:1089
llvm::orc::ExecutorAddrRange
Represents an address range in the exceutor process.
Definition: ExecutorAddress.h:134
StringMap.h
Align
uint64_t Align
Definition: ELFObjHandler.cpp:83
llvm::ELF::ELFDATA2MSB
@ ELFDATA2MSB
Definition: ELF.h:336
llvm::orc::DebugObjectSection
Definition: DebugObjectManagerPlugin.cpp:41
llvm::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:108
llvm::orc::MaterializationResponsibility::withResourceKeyDo
Error withResourceKeyDo(Func &&F) const
Returns the ResourceTracker for this instance.
Definition: Core.h:1672
llvm::orc::DebugObject::FinalizeContinuation
std::function< void(Expected< ExecutorAddrRange >)> FinalizeContinuation
Definition: DebugObjectManagerPlugin.cpp:135
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
llvm::errc::not_enough_memory
@ not_enough_memory
llvm::Triple::ELF
@ ELF
Definition: Triple.h:238
llvm::ELF::ELFCLASS64
@ ELFCLASS64
Definition: ELF.h:329
llvm::orc::DwarfSectionNames
static const std::set< StringRef > DwarfSectionNames
Definition: DebugObjectManagerPlugin.cpp:232
uint64_t
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
llvm::ELF::SHT_PROGBITS
@ SHT_PROGBITS
Definition: ELF.h:916
llvm::orc::ELFDebugObject
The current implementation of ELFDebugObject replicates the approach used in RuntimeDyld: It patches ...
Definition: DebugObjectManagerPlugin.cpp:194
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::ELF::SHF_ALLOC
@ SHF_ALLOC
Definition: ELF.h:994
llvm::orc::Requirement
Requirement
Definition: DebugObjectManagerPlugin.cpp:116
ArrayRef.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1609
llvm::WritableMemoryBuffer::getNewUninitMemBuffer
static std::unique_ptr< WritableMemoryBuffer > getNewUninitMemBuffer(size_t Size, const Twine &BufferName="")
Allocate a new MemoryBuffer of the specified size that is not initialized.
Definition: MemoryBuffer.cpp:289
ObjectFile.h
llvm::orc::DebugObjectManagerPlugin::notifyEmitted
Error notifyEmitted(MaterializationResponsibility &MR) override
Definition: DebugObjectManagerPlugin.cpp:444
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
llvm::MemoryBufferRef::getBuffer
StringRef getBuffer() const
Definition: MemoryBufferRef.h:32
DebugObjectManagerPlugin.h
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::orc::DebugObject::DebugObject
DebugObject(JITLinkMemoryManager &MemMgr, const JITLinkDylib *JD, ExecutionSession &ES)
Definition: DebugObjectManagerPlugin.cpp:128
llvm::orc::DebugObjectManagerPlugin::notifyRemovingResources
Error notifyRemovingResources(ResourceKey K) override
Definition: DebugObjectManagerPlugin.cpp:505
llvm::StringRef::bytes_begin
const unsigned char * bytes_begin() const
Definition: StringRef.h:132
_
#define _
Definition: HexagonMCCodeEmitter.cpp:47
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
this
Analysis the ScalarEvolution expression for r is this
Definition: README.txt:8
JITLinkMemoryManager.h
llvm::orc::DebugObjectManagerPlugin::notifyMaterializing
void notifyMaterializing(MaterializationResponsibility &MR, jitlink::LinkGraph &G, jitlink::JITLinkContext &Ctx, MemoryBufferRef InputObject) override
Definition: DebugObjectManagerPlugin.cpp:406
llvm::orc::DebugObject::MemMgr
JITLinkMemoryManager & MemMgr
Definition: DebugObjectManagerPlugin.cpp:157
ELFObjectFile.h
llvm::make_error_code
std::error_code make_error_code(BitcodeError E)
Definition: BitcodeReader.h:270
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
std
Definition: BitVector.h:838
llvm::inconvertibleErrorCode
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:77
uint16_t
llvm::orc::DebugObjectSection::dump
virtual void dump(raw_ostream &OS, StringRef Name)
Definition: DebugObjectManagerPlugin.cpp:44
llvm::SectionName
Definition: DWARFSection.h:21
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1275
llvm::orc::DebugObjectManagerPlugin::notifyTransferringResources
void notifyTransferringResources(ResourceKey DstKey, ResourceKey SrcKey) override
Definition: DebugObjectManagerPlugin.cpp:490
llvm::orc::DebugObjectManagerPlugin::modifyPassConfig
void modifyPassConfig(MaterializationResponsibility &MR, jitlink::LinkGraph &LG, jitlink::PassConfiguration &PassConfig) override
Definition: DebugObjectManagerPlugin.cpp:423
llvm::orc::ELFDebugObjectSection
Definition: DebugObjectManagerPlugin.cpp:49
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:589
llvm::orc::DebugObject::reportSectionTargetMemoryRange
virtual void reportSectionTargetMemoryRange(StringRef Name, SectionRange TargetMem)
Definition: DebugObjectManagerPlugin.cpp:148
JITLinkDylib.h
llvm::orc::DebugObject
The plugin creates a debug object from when JITLink starts processing the corresponding LinkGraph.
Definition: DebugObjectManagerPlugin.cpp:126
llvm::ELF::EM_X86_64
@ EM_X86_64
Definition: ELF.h:179
llvm::MemoryBufferRef::getBufferIdentifier
StringRef getBufferIdentifier() const
Definition: MemoryBufferRef.h:33
llvm::object::getElfArchType
std::pair< unsigned char, unsigned char > getElfArchType(StringRef Object)
Definition: ELF.h:76
llvm::sys::Process::getPageSizeEstimate
static unsigned getPageSizeEstimate()
Get the process's estimated page size.
Definition: Process.h:62
isDwarfSection
static bool isDwarfSection(const MCObjectFileInfo *FI, const MCSection *Section)
Definition: NVPTXTargetStreamer.cpp:42
raw_ostream.h
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::orc::DebugObject::~DebugObject
virtual ~DebugObject()
Definition: DebugObjectManagerPlugin.cpp:139
llvm::object::ELFFile
Definition: ELF.h:94
Shdr
Elf_Shdr Shdr
Definition: ELFObjHandler.cpp:79
llvm::orc::Requirement::ReportFinalSectionLoadAddresses
@ ReportFinalSectionLoadAddresses
llvm::StringRef::bytes_end
const unsigned char * bytes_end() const
Definition: StringRef.h:135