LLVM  16.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() = default;
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 =
72  static_cast<typename ELFT::uint>(Range.getStart().getValue());
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();
247  StringRef Name = Buffer.getBufferIdentifier();
248  if (auto Copy = WritableMemoryBuffer::getNewUninitMemBuffer(Size, Name)) {
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  if (!(Header.sh_flags & ELF::SHF_ALLOC))
293  continue;
294 
295  auto Wrapped = std::make_unique<ELFDebugObjectSection<ELFT>>(&Header);
296  if (Error Err = DebugObj->recordSection(*Name, std::move(Wrapped)))
297  return std::move(Err);
298  }
299 
300  if (!HasDwarfSection) {
301  LLVM_DEBUG(dbgs() << "Aborting debug registration for LinkGraph \""
302  << DebugObj->Buffer->getBufferIdentifier()
303  << "\": input object contains no debug info\n");
304  return nullptr;
305  }
306 
307  return std::move(DebugObj);
308 }
309 
310 Expected<std::unique_ptr<DebugObject>>
311 ELFDebugObject::Create(MemoryBufferRef Buffer, JITLinkContext &Ctx,
312  ExecutionSession &ES) {
313  unsigned char Class, Endian;
314  std::tie(Class, Endian) = getElfArchType(Buffer.getBuffer());
315 
316  if (Class == ELF::ELFCLASS32) {
317  if (Endian == ELF::ELFDATA2LSB)
318  return CreateArchType<ELF32LE>(Buffer, Ctx.getMemoryManager(),
319  Ctx.getJITLinkDylib(), ES);
320  if (Endian == ELF::ELFDATA2MSB)
321  return CreateArchType<ELF32BE>(Buffer, Ctx.getMemoryManager(),
322  Ctx.getJITLinkDylib(), ES);
323  return nullptr;
324  }
325  if (Class == ELF::ELFCLASS64) {
326  if (Endian == ELF::ELFDATA2LSB)
327  return CreateArchType<ELF64LE>(Buffer, Ctx.getMemoryManager(),
328  Ctx.getJITLinkDylib(), ES);
329  if (Endian == ELF::ELFDATA2MSB)
330  return CreateArchType<ELF64BE>(Buffer, Ctx.getMemoryManager(),
331  Ctx.getJITLinkDylib(), ES);
332  return nullptr;
333  }
334  return nullptr;
335 }
336 
337 Expected<SimpleSegmentAlloc> ELFDebugObject::finalizeWorkingMemory() {
338  LLVM_DEBUG({
339  dbgs() << "Section load-addresses in debug object for \""
340  << Buffer->getBufferIdentifier() << "\":\n";
341  for (const auto &KV : Sections)
342  KV.second->dump(dbgs(), KV.first());
343  });
344 
345  // TODO: This works, but what actual alignment requirements do we have?
347  size_t Size = Buffer->getBufferSize();
348 
349  // Allocate working memory for debug object in read-only segment.
350  auto Alloc = SimpleSegmentAlloc::Create(
351  MemMgr, JD, {{MemProt::Read, {Size, Align(PageSize)}}});
352  if (!Alloc)
353  return Alloc;
354 
355  // Initialize working memory with a copy of our object buffer.
356  auto SegInfo = Alloc->getSegInfo(MemProt::Read);
357  memcpy(SegInfo.WorkingMem.data(), Buffer->getBufferStart(), Size);
358  Buffer.reset();
359 
360  return Alloc;
361 }
362 
363 void ELFDebugObject::reportSectionTargetMemoryRange(StringRef Name,
364  SectionRange TargetMem) {
365  if (auto *DebugObjSection = getSection(Name))
366  DebugObjSection->setTargetMemoryRange(TargetMem);
367 }
368 
369 template <typename ELFT>
370 Error ELFDebugObject::recordSection(
371  StringRef Name, std::unique_ptr<ELFDebugObjectSection<ELFT>> Section) {
372  if (Error Err = Section->validateInBounds(this->getBuffer(), Name.data()))
373  return Err;
374  auto ItInserted = Sections.try_emplace(Name, std::move(Section));
375  if (!ItInserted.second)
376  return make_error<StringError>("In " + Buffer->getBufferIdentifier() +
377  ", encountered duplicate section \"" +
378  Name + "\" while building debug object",
380  return Error::success();
381 }
382 
384  auto It = Sections.find(Name);
385  return It == Sections.end() ? nullptr : It->second.get();
386 }
387 
388 /// Creates a debug object based on the input object file from
389 /// ObjectLinkingLayerJITLinkContext.
390 ///
393  JITLinkContext &Ctx, MemoryBufferRef ObjBuffer) {
394  switch (G.getTargetTriple().getObjectFormat()) {
395  case Triple::ELF:
396  return ELFDebugObject::Create(ObjBuffer, Ctx, ES);
397 
398  default:
399  // TODO: Once we add support for other formats, we might want to split this
400  // into multiple files.
401  return nullptr;
402  }
403 }
404 
405 DebugObjectManagerPlugin::DebugObjectManagerPlugin(
406  ExecutionSession &ES, std::unique_ptr<DebugObjectRegistrar> Target)
407  : ES(ES), Target(std::move(Target)) {}
408 
410 
413  MemoryBufferRef ObjBuffer) {
414  std::lock_guard<std::mutex> Lock(PendingObjsLock);
415  assert(PendingObjs.count(&MR) == 0 &&
416  "Cannot have more than one pending debug object per "
417  "MaterializationResponsibility");
418 
419  if (auto DebugObj = createDebugObjectFromBuffer(ES, G, Ctx, ObjBuffer)) {
420  // Not all link artifacts allow debugging.
421  if (*DebugObj != nullptr)
422  PendingObjs[&MR] = std::move(*DebugObj);
423  } else {
424  ES.reportError(DebugObj.takeError());
425  }
426 }
427 
430  PassConfiguration &PassConfig) {
431  // Not all link artifacts have associated debug objects.
432  std::lock_guard<std::mutex> Lock(PendingObjsLock);
433  auto It = PendingObjs.find(&MR);
434  if (It == PendingObjs.end())
435  return;
436 
437  DebugObject &DebugObj = *It->second;
439  PassConfig.PostAllocationPasses.push_back(
440  [&DebugObj](LinkGraph &Graph) -> Error {
441  for (const Section &GraphSection : Graph.sections())
442  DebugObj.reportSectionTargetMemoryRange(GraphSection.getName(),
443  SectionRange(GraphSection));
444  return Error::success();
445  });
446  }
447 }
448 
451  std::lock_guard<std::mutex> Lock(PendingObjsLock);
452  auto It = PendingObjs.find(&MR);
453  if (It == PendingObjs.end())
454  return Error::success();
455 
456  // During finalization the debug object is registered with the target.
457  // Materialization must wait for this process to finish. Otherwise we might
458  // start running code before the debugger processed the corresponding debug
459  // info.
460  std::promise<MSVCPError> FinalizePromise;
461  std::future<MSVCPError> FinalizeErr = FinalizePromise.get_future();
462 
463  It->second->finalizeAsync(
464  [this, &FinalizePromise, &MR](Expected<ExecutorAddrRange> TargetMem) {
465  // Any failure here will fail materialization.
466  if (!TargetMem) {
467  FinalizePromise.set_value(TargetMem.takeError());
468  return;
469  }
470  if (Error Err = Target->registerDebugObject(*TargetMem)) {
471  FinalizePromise.set_value(std::move(Err));
472  return;
473  }
474 
475  // Once our tracking info is updated, notifyEmitted() can return and
476  // finish materialization.
477  FinalizePromise.set_value(MR.withResourceKeyDo([&](ResourceKey K) {
478  assert(PendingObjs.count(&MR) && "We still hold PendingObjsLock");
479  std::lock_guard<std::mutex> Lock(RegisteredObjsLock);
480  RegisteredObjs[K].push_back(std::move(PendingObjs[&MR]));
481  PendingObjs.erase(&MR);
482  }));
483  });
484 
485  return FinalizeErr.get();
486 }
487 
490  std::lock_guard<std::mutex> Lock(PendingObjsLock);
491  PendingObjs.erase(&MR);
492  return Error::success();
493 }
494 
496  ResourceKey SrcKey) {
497  // Debug objects are stored by ResourceKey only after registration.
498  // Thus, pending objects don't need to be updated here.
499  std::lock_guard<std::mutex> Lock(RegisteredObjsLock);
500  auto SrcIt = RegisteredObjs.find(SrcKey);
501  if (SrcIt != RegisteredObjs.end()) {
502  // Resources from distinct MaterializationResponsibilitys can get merged
503  // after emission, so we can have multiple debug objects per resource key.
504  for (std::unique_ptr<DebugObject> &DebugObj : SrcIt->second)
505  RegisteredObjs[DstKey].push_back(std::move(DebugObj));
506  RegisteredObjs.erase(SrcIt);
507  }
508 }
509 
511  // Removing the resource for a pending object fails materialization, so they
512  // get cleaned up in the notifyFailed() handler.
513  std::lock_guard<std::mutex> Lock(RegisteredObjsLock);
514  RegisteredObjs.erase(Key);
515 
516  // TODO: Implement unregister notifications.
517  return Error::success();
518 }
519 
520 } // namespace orc
521 } // namespace llvm
llvm::orc::ExecutorAddr
Represents an address in the executor process.
Definition: ExecutorAddress.h:31
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:519
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:392
llvm::MemoryBufferRef::getBufferStart
const char * getBufferStart() const
Definition: MemoryBufferRef.h:35
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::ELF::SHF_EXECINSTR
@ SHF_EXECINSTR
Definition: ELF.h:1071
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()
StringRef.h
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:149
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::orc::ELFDebugObject::getBuffer
StringRef getBuffer() const
Definition: DebugObjectManagerPlugin.cpp:202
llvm::pdb::PDB_ColorItem::SectionHeader
@ SectionHeader
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:406
Errc.h
MSVCErrorWorkarounds.h
llvm::orc::DebugObjectManagerPlugin::notifyFailed
Error notifyFailed(MaterializationResponsibility &MR) override
Definition: DebugObjectManagerPlugin.cpp:488
llvm::MemoryBufferRef::getBufferSize
size_t getBufferSize() const
Definition: MemoryBufferRef.h:37
llvm::ELF::SHT_PROGBITS
@ SHT_PROGBITS
Definition: ELF.h:980
llvm::dump
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Definition: SparseBitVector.h:877
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
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::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:251
Process.h
llvm::object
Definition: DWARFDebugLoc.h:25
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:92
llvm::AMDGPU::PALMD::Key
Key
PAL metadata keys.
Definition: AMDGPUMetadata.h:486
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:1096
llvm::orc::ExecutorAddrRange
Represents an address range in the exceutor process.
Definition: ExecutorAddress.h:191
Align
uint64_t Align
Definition: ELFObjHandler.cpp:82
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:110
llvm::orc::MaterializationResponsibility::withResourceKeyDo
Error withResourceKeyDo(Func &&F) const
Returns the ResourceTracker for this instance.
Definition: Core.h:1779
llvm::orc::DebugObject::FinalizeContinuation
std::function< void(Expected< ExecutorAddrRange >)> FinalizeContinuation
Definition: DebugObjectManagerPlugin.cpp:135
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:200
llvm::errc::not_enough_memory
@ not_enough_memory
llvm::Triple::ELF
@ ELF
Definition: Triple.h:283
llvm::orc::DwarfSectionNames
static const std::set< StringRef > DwarfSectionNames
Definition: DebugObjectManagerPlugin.cpp:232
uint64_t
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:79
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::orc::Requirement
Requirement
Definition: DebugObjectManagerPlugin.cpp:116
ArrayRef.h
llvm::ELF::SHF_ALLOC
@ SHF_ALLOC
Definition: ELF.h:1068
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:1861
ObjectFile.h
llvm::orc::DebugObjectManagerPlugin::notifyEmitted
Error notifyEmitted(MaterializationResponsibility &MR) override
Definition: DebugObjectManagerPlugin.cpp:449
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:82
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:510
llvm::ELF::SHT_X86_64_UNWIND
@ SHT_X86_64_UNWIND
Definition: ELF.h:1044
llvm::StringRef::bytes_begin
const unsigned char * bytes_begin() const
Definition: StringRef.h:115
_
#define _
Definition: HexagonMCCodeEmitter.cpp:47
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
this
Analysis the ScalarEvolution expression for r is this
Definition: README.txt:8
llvm::ELF::ELFDATA2LSB
@ ELFDATA2LSB
Definition: ELF.h:335
JITLinkMemoryManager.h
llvm::orc::DebugObjectManagerPlugin::notifyMaterializing
void notifyMaterializing(MaterializationResponsibility &MR, jitlink::LinkGraph &G, jitlink::JITLinkContext &Ctx, MemoryBufferRef InputObject) override
Definition: DebugObjectManagerPlugin.cpp:411
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:274
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
std
Definition: BitVector.h:851
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:79
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:155
llvm::ELF::ELFDATA2MSB
@ ELFDATA2MSB
Definition: ELF.h:336
llvm::orc::ExecutionSession
An ExecutionSession represents a running JIT program.
Definition: Core.h:1365
llvm::orc::DebugObjectManagerPlugin::notifyTransferringResources
void notifyTransferringResources(ResourceKey DstKey, ResourceKey SrcKey) override
Definition: DebugObjectManagerPlugin.cpp:495
llvm::orc::DebugObjectManagerPlugin::modifyPassConfig
void modifyPassConfig(MaterializationResponsibility &MR, jitlink::LinkGraph &LG, jitlink::PassConfiguration &PassConfig) override
Definition: DebugObjectManagerPlugin.cpp:428
llvm::orc::ELFDebugObjectSection
Definition: DebugObjectManagerPlugin.cpp:49
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:596
llvm::orc::DebugObject::reportSectionTargetMemoryRange
virtual void reportSectionTargetMemoryRange(StringRef Name, SectionRange TargetMem)
Definition: DebugObjectManagerPlugin.cpp:148
JITLinkDylib.h
llvm::ELF::EM_X86_64
@ EM_X86_64
Definition: ELF.h:178
llvm::orc::DebugObject
The plugin creates a debug object from when JITLink starts processing the corresponding LinkGraph.
Definition: DebugObjectManagerPlugin.cpp:126
llvm::ELF::ELFCLASS64
@ ELFCLASS64
Definition: ELF.h:329
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:77
llvm::sys::Process::getPageSizeEstimate
static unsigned getPageSizeEstimate()
Get the process's estimated page size.
Definition: Process.h:61
StringMap.h
llvm::ELF::ELFCLASS32
@ ELFCLASS32
Definition: ELF.h:328
isDwarfSection
static bool isDwarfSection(const MCObjectFileInfo *FI, const MCSection *Section)
Definition: NVPTXTargetStreamer.cpp:45
raw_ostream.h
llvm::orc::DebugObject::~DebugObject
virtual ~DebugObject()
Definition: DebugObjectManagerPlugin.cpp:139
llvm::object::ELFFile
Definition: ELF.h:95
llvm::WritableMemoryBuffer::getNewUninitMemBuffer
static std::unique_ptr< WritableMemoryBuffer > getNewUninitMemBuffer(size_t Size, const Twine &BufferName="", Optional< Align > Alignment=None)
Allocate a new MemoryBuffer of the specified size that is not initialized.
Definition: MemoryBuffer.cpp:296
Shdr
Elf_Shdr Shdr
Definition: ELFObjHandler.cpp:78
llvm::orc::Requirement::ReportFinalSectionLoadAddresses
@ ReportFinalSectionLoadAddresses
llvm::StringRef::bytes_end
const unsigned char * bytes_end() const
Definition: StringRef.h:118