JITLoaderGDB.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. //===- JITLoaderGDB.h - Register objects via GDB JIT interface -*- C++ -*-===//
  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. #include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
  9. #include "llvm/ExecutionEngine/JITSymbol.h"
  10. #include "llvm/Support/BinaryStreamReader.h"
  11. #include "llvm/Support/FormatVariadic.h"
  12. #include <cstdint>
  13. #include <mutex>
  14. #include <utility>
  15. #define DEBUG_TYPE "orc"
  16. // First version as landed in August 2009
  17. static constexpr uint32_t JitDescriptorVersion = 1;
  18. // Keep in sync with gdb/gdb/jit.h
  19. extern "C" {
  20. typedef enum {
  21. JIT_NOACTION = 0,
  22. JIT_REGISTER_FN,
  23. JIT_UNREGISTER_FN
  24. } jit_actions_t;
  25. struct jit_code_entry {
  26. struct jit_code_entry *next_entry;
  27. struct jit_code_entry *prev_entry;
  28. const char *symfile_addr;
  29. uint64_t symfile_size;
  30. };
  31. struct jit_descriptor {
  32. uint32_t version;
  33. // This should be jit_actions_t, but we want to be specific about the
  34. // bit-width.
  35. uint32_t action_flag;
  36. struct jit_code_entry *relevant_entry;
  37. struct jit_code_entry *first_entry;
  38. };
  39. // We put information about the JITed function in this global, which the
  40. // debugger reads. Make sure to specify the version statically, because the
  41. // debugger checks the version before we can set it during runtime.
  42. struct jit_descriptor __jit_debug_descriptor = {JitDescriptorVersion, 0,
  43. nullptr, nullptr};
  44. // Debuggers that implement the GDB JIT interface put a special breakpoint in
  45. // this function.
  46. LLVM_ATTRIBUTE_NOINLINE void __jit_debug_register_code() {
  47. // The noinline and the asm prevent calls to this function from being
  48. // optimized out.
  49. #if !defined(_MSC_VER)
  50. asm volatile("" ::: "memory");
  51. #endif
  52. }
  53. }
  54. using namespace llvm;
  55. using namespace llvm::orc;
  56. // Register debug object, return error message or null for success.
  57. static void registerJITLoaderGDBImpl(const char *ObjAddr, size_t Size) {
  58. LLVM_DEBUG({
  59. dbgs() << "Registering debug object with GDB JIT interface "
  60. << formatv("([{0:x16} -- {1:x16}])",
  61. reinterpret_cast<uintptr_t>(ObjAddr),
  62. reinterpret_cast<uintptr_t>(ObjAddr + Size))
  63. << "\n";
  64. });
  65. jit_code_entry *E = new jit_code_entry;
  66. E->symfile_addr = ObjAddr;
  67. E->symfile_size = Size;
  68. E->prev_entry = nullptr;
  69. // Serialize rendezvous with the debugger as well as access to shared data.
  70. static std::mutex JITDebugLock;
  71. std::lock_guard<std::mutex> Lock(JITDebugLock);
  72. // Insert this entry at the head of the list.
  73. jit_code_entry *NextEntry = __jit_debug_descriptor.first_entry;
  74. E->next_entry = NextEntry;
  75. if (NextEntry) {
  76. NextEntry->prev_entry = E;
  77. }
  78. __jit_debug_descriptor.first_entry = E;
  79. __jit_debug_descriptor.relevant_entry = E;
  80. // Run into the rendezvous breakpoint.
  81. __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
  82. __jit_debug_register_code();
  83. }
  84. extern "C" orc::shared::CWrapperFunctionResult
  85. llvm_orc_registerJITLoaderGDBAllocAction(const char *Data, size_t Size) {
  86. using namespace orc::shared;
  87. return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle(
  88. Data, Size,
  89. [](ExecutorAddrRange R) {
  90. registerJITLoaderGDBImpl(R.Start.toPtr<const char *>(),
  91. R.size());
  92. return Error::success();
  93. })
  94. .release();
  95. }
  96. extern "C" orc::shared::CWrapperFunctionResult
  97. llvm_orc_registerJITLoaderGDBWrapper(const char *Data, uint64_t Size) {
  98. using namespace orc::shared;
  99. return WrapperFunction<SPSError(SPSExecutorAddrRange)>::handle(
  100. Data, Size,
  101. [](ExecutorAddrRange R) {
  102. registerJITLoaderGDBImpl(R.Start.toPtr<const char *>(),
  103. R.size());
  104. return Error::success();
  105. })
  106. .release();
  107. }