//===-- JITDebugRegisterer.cpp - Register debug symbols for JIT -----------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines a JITDebugRegisterer object that is used by the JIT to
// register debug info with debuggers like GDB.
//
//===----------------------------------------------------------------------===//

#include "JITDebugRegisterer.h"
#include "../../CodeGen/ELF.h"
#include "../../CodeGen/ELFWriter.h"
#include "llvm/LLVMContext.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Mutex.h"
#include <string>
#include <vector>

namespace llvm {

// This must be kept in sync with gdb/gdb/jit.h .
extern "C" {

  // Debuggers puts a breakpoint in this function.
  DISABLE_INLINE void __jit_debug_register_code() { }

  // We put information about the JITed function in this global, which the
  // debugger reads.  Make sure to specify the version statically, because the
  // debugger checks the version before we can set it during runtime.
  struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };

}

namespace {

  /// JITDebugLock - Used to serialize all code registration events, since they
  /// modify global variables.
  sys::Mutex JITDebugLock;

}

JITDebugRegisterer::JITDebugRegisterer(TargetMachine &tm) : TM(tm), FnMap() { }

JITDebugRegisterer::~JITDebugRegisterer() {
  // Free all ELF memory.
  for (RegisteredFunctionsMap::iterator I = FnMap.begin(), E = FnMap.end();
       I != E; ++I) {
    // Call the private method that doesn't update the map so our iterator
    // doesn't break.
    UnregisterFunctionInternal(I);
  }
  FnMap.clear();
}

std::string JITDebugRegisterer::MakeELF(const Function *F, DebugInfo &I) {
  // Stack allocate an empty module with an empty LLVMContext for the ELFWriter
  // API.  We don't use the real module because then the ELFWriter would write
  // out unnecessary GlobalValues during finalization.
  LLVMContext Context;
  Module M("", Context);

  // Make a buffer for the ELF in memory.
  std::string Buffer;
  raw_string_ostream O(Buffer);
  ELFWriter EW(O, TM);
  EW.doInitialization(M);

  // Copy the binary into the .text section.  This isn't necessary, but it's
  // useful to be able to disassemble the ELF by hand.
  ELFSection &Text = EW.getTextSection(const_cast<Function *>(F));
  Text.Addr = (uint64_t)I.FnStart;
  // TODO: We could eliminate this copy if we somehow used a pointer/size pair
  // instead of a vector.
  Text.getData().assign(I.FnStart, I.FnEnd);

  // Copy the exception handling call frame information into the .eh_frame
  // section.  This allows GDB to get a good stack trace, particularly on
  // linux x86_64.  Mark this as a PROGBITS section that needs to be loaded
  // into memory at runtime.
  ELFSection &EH = EW.getSection(".eh_frame", ELF::SHT_PROGBITS,
                                 ELF::SHF_ALLOC);
  // Pointers in the DWARF EH info are all relative to the EH frame start,
  // which is stored here.
  EH.Addr = (uint64_t)I.EhStart;
  // TODO: We could eliminate this copy if we somehow used a pointer/size pair
  // instead of a vector.
  EH.getData().assign(I.EhStart, I.EhEnd);

  // Add this single function to the symbol table, so the debugger prints the
  // name instead of '???'.  We give the symbol default global visibility.
  ELFSym *FnSym = ELFSym::getGV(F,
                                ELF::STB_GLOBAL,
                                ELF::STT_FUNC,
                                ELF::STV_DEFAULT);
  FnSym->SectionIdx = Text.SectionIdx;
  FnSym->Size = I.FnEnd - I.FnStart;
  FnSym->Value = 0;  // Offset from start of section.
  EW.SymbolList.push_back(FnSym);

  EW.doFinalization(M);
  O.flush();

  // When trying to debug why GDB isn't getting the debug info right, it's
  // awfully helpful to write the object file to disk so that it can be
  // inspected with readelf and objdump.
  if (JITEmitDebugInfoToDisk) {
    std::string Filename;
    raw_string_ostream O2(Filename);
    O2 << "/tmp/llvm_function_" << I.FnStart << "_" << F->getNameStr() << ".o";
    O2.flush();
    std::string Errors;
    raw_fd_ostream O3(Filename.c_str(), Errors);
    O3 << Buffer;
    O3.close();
  }

  return Buffer;
}

void JITDebugRegisterer::RegisterFunction(const Function *F, DebugInfo &I) {
  // TODO: Support non-ELF platforms.
  if (!TM.getELFWriterInfo())
    return;

  std::string Buffer = MakeELF(F, I);

  jit_code_entry *JITCodeEntry = new jit_code_entry();
  JITCodeEntry->symfile_addr = Buffer.c_str();
  JITCodeEntry->symfile_size = Buffer.size();

  // Add a mapping from F to the entry and buffer, so we can delete this
  // info later.
  FnMap[F] = std::make_pair<std::string, jit_code_entry*>(Buffer, JITCodeEntry);

  // Acquire the lock and do the registration.
  {
    MutexGuard locked(JITDebugLock);
    __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;

    // Insert this entry at the head of the list.
    JITCodeEntry->prev_entry = NULL;
    jit_code_entry *NextEntry = __jit_debug_descriptor.first_entry;
    JITCodeEntry->next_entry = NextEntry;
    if (NextEntry != NULL) {
      NextEntry->prev_entry = JITCodeEntry;
    }
    __jit_debug_descriptor.first_entry = JITCodeEntry;
    __jit_debug_descriptor.relevant_entry = JITCodeEntry;
    __jit_debug_register_code();
  }
}

void JITDebugRegisterer::UnregisterFunctionInternal(
    RegisteredFunctionsMap::iterator I) {
  jit_code_entry *&JITCodeEntry = I->second.second;

  // Acquire the lock and do the unregistration.
  {
    MutexGuard locked(JITDebugLock);
    __jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN;

    // Remove the jit_code_entry from the linked list.
    jit_code_entry *PrevEntry = JITCodeEntry->prev_entry;
    jit_code_entry *NextEntry = JITCodeEntry->next_entry;
    if (NextEntry) {
      NextEntry->prev_entry = PrevEntry;
    }
    if (PrevEntry) {
      PrevEntry->next_entry = NextEntry;
    } else {
      assert(__jit_debug_descriptor.first_entry == JITCodeEntry);
      __jit_debug_descriptor.first_entry = NextEntry;
    }

    // Tell GDB which entry we removed, and unregister the code.
    __jit_debug_descriptor.relevant_entry = JITCodeEntry;
    __jit_debug_register_code();
  }

  delete JITCodeEntry;
  JITCodeEntry = NULL;

  // Free the ELF file in memory.
  std::string &Buffer = I->second.first;
  Buffer.clear();
}

void JITDebugRegisterer::UnregisterFunction(const Function *F) {
  // TODO: Support non-ELF platforms.
  if (!TM.getELFWriterInfo())
    return;

  RegisteredFunctionsMap::iterator I = FnMap.find(F);
  if (I == FnMap.end()) return;
  UnregisterFunctionInternal(I);
  FnMap.erase(I);
}

} // end namespace llvm
