brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · f255de0 Raw
91 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"10 11#include "llvm/Support/Compiler.h"12#include "llvm/Support/FormatVariadic.h"13 14#include <cstdint>15#include <mutex>16 17#define DEBUG_TYPE "orc"18 19// First version as landed in August 200920static constexpr uint32_t JitDescriptorVersion = 1;21 22extern "C" {23 24// We put information about the JITed function in this global, which the25// debugger reads.  Make sure to specify the version statically, because the26// debugger checks the version before we can set it during runtime.27LLVM_ABI LLVM_ALWAYS_EXPORT struct jit_descriptor __jit_debug_descriptor = {28    JitDescriptorVersion, 0, nullptr, nullptr};29 30// Debuggers that implement the GDB JIT interface put a special breakpoint in31// this function.32LLVM_ABI LLVM_ALWAYS_EXPORT LLVM_ATTRIBUTE_NOINLINE void33__jit_debug_register_code() {34  // The noinline and the asm prevent calls to this function from being35  // optimized out.36#if !defined(_MSC_VER)37  asm volatile("" ::: "memory");38#endif39}40}41 42using namespace llvm;43using namespace llvm::orc;44 45// Register debug object, return error message or null for success.46static void appendJITDebugDescriptor(const char *ObjAddr, size_t Size) {47  LLVM_DEBUG({48    dbgs() << "Adding debug object to GDB JIT interface "49           << formatv("([{0:x16} -- {1:x16}])",50                      reinterpret_cast<uintptr_t>(ObjAddr),51                      reinterpret_cast<uintptr_t>(ObjAddr + Size))52           << "\n";53  });54 55  jit_code_entry *E = new jit_code_entry;56  E->symfile_addr = ObjAddr;57  E->symfile_size = Size;58  E->prev_entry = nullptr;59 60  // Serialize rendezvous with the debugger as well as access to shared data.61  static std::mutex JITDebugLock;62  std::lock_guard<std::mutex> Lock(JITDebugLock);63 64  // Insert this entry at the head of the list.65  jit_code_entry *NextEntry = __jit_debug_descriptor.first_entry;66  E->next_entry = NextEntry;67  if (NextEntry) {68    NextEntry->prev_entry = E;69  }70 71  __jit_debug_descriptor.first_entry = E;72  __jit_debug_descriptor.relevant_entry = E;73  __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;74}75 76extern "C" orc::shared::CWrapperFunctionResult77llvm_orc_registerJITLoaderGDBAllocAction(const char *ArgData, size_t ArgSize) {78  using namespace orc::shared;79  return WrapperFunction<SPSError(SPSExecutorAddrRange, bool)>::handle(80             ArgData, ArgSize,81             [](ExecutorAddrRange R, bool AutoRegisterCode) {82               appendJITDebugDescriptor(R.Start.toPtr<const char *>(),83                                        R.size());84               // Run into the rendezvous breakpoint.85               if (AutoRegisterCode)86                 __jit_debug_register_code();87               return Error::success();88             })89      .release();90}91