//===-- OProfileWrapper.cpp - OProfile JIT API Wrapper implementation -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the interface in OProfileWrapper.h. It is responsible
// for loading the opagent dynamic library when the first call to an op_
// function occurs.
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/OProfileWrapper.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/Support/raw_ostream.h"
#include <cstring>
#include <dirent.h>
#include <fcntl.h>
#include <stddef.h>
#include <sys/stat.h>
#include <unistd.h>

#define DEBUG_TYPE "oprofile-wrapper"

namespace {

// Global mutex to ensure a single thread initializes oprofile agent.
llvm::sys::Mutex OProfileInitializationMutex;

} // anonymous namespace

namespace llvm {

OProfileWrapper::OProfileWrapper()
: Agent(0),
  OpenAgentFunc(0),
  CloseAgentFunc(0),
  WriteNativeCodeFunc(0),
  WriteDebugLineInfoFunc(0),
  UnloadNativeCodeFunc(0),
  MajorVersionFunc(0),
  MinorVersionFunc(0),
  IsOProfileRunningFunc(0),
  Initialized(false) {
}

bool OProfileWrapper::initialize() {
  using namespace llvm;
  using namespace llvm::sys;

  MutexGuard Guard(OProfileInitializationMutex);

  if (Initialized)
    return OpenAgentFunc != 0;

  Initialized = true;

  // If the oprofile daemon is not running, don't load the opagent library
  if (!isOProfileRunning()) {
    DEBUG(dbgs() << "OProfile daemon is not detected.\n");
    return false;
  }

  std::string error;
  if(!DynamicLibrary::LoadLibraryPermanently("libopagent.so", &error)) {
    DEBUG(dbgs()
            << "OProfile connector library libopagent.so could not be loaded: "
            << error << "\n");
  }

  // Get the addresses of the opagent functions
  OpenAgentFunc = (op_open_agent_ptr_t)(intptr_t)
          DynamicLibrary::SearchForAddressOfSymbol("op_open_agent");
  CloseAgentFunc = (op_close_agent_ptr_t)(intptr_t)
          DynamicLibrary::SearchForAddressOfSymbol("op_close_agent");
  WriteNativeCodeFunc = (op_write_native_code_ptr_t)(intptr_t)
          DynamicLibrary::SearchForAddressOfSymbol("op_write_native_code");
  WriteDebugLineInfoFunc = (op_write_debug_line_info_ptr_t)(intptr_t)
          DynamicLibrary::SearchForAddressOfSymbol("op_write_debug_line_info");
  UnloadNativeCodeFunc = (op_unload_native_code_ptr_t)(intptr_t)
          DynamicLibrary::SearchForAddressOfSymbol("op_unload_native_code");
  MajorVersionFunc = (op_major_version_ptr_t)(intptr_t)
          DynamicLibrary::SearchForAddressOfSymbol("op_major_version");
  MinorVersionFunc = (op_major_version_ptr_t)(intptr_t)
          DynamicLibrary::SearchForAddressOfSymbol("op_minor_version");

  // With missing functions, we can do nothing
  if (!OpenAgentFunc
      || !CloseAgentFunc
      || !WriteNativeCodeFunc
      || !WriteDebugLineInfoFunc
      || !UnloadNativeCodeFunc) {
    OpenAgentFunc = 0;
    CloseAgentFunc = 0;
    WriteNativeCodeFunc = 0;
    WriteDebugLineInfoFunc = 0;
    UnloadNativeCodeFunc = 0;
    return false;
  }

  return true;
}

bool OProfileWrapper::isOProfileRunning() {
  if (IsOProfileRunningFunc != 0)
    return IsOProfileRunningFunc();
  return checkForOProfileProcEntry();
}

bool OProfileWrapper::checkForOProfileProcEntry() {
  DIR* ProcDir;

  ProcDir = opendir("/proc");
  if (!ProcDir)
    return false;

  // Walk the /proc tree looking for the oprofile daemon
  struct dirent* Entry;
  while (0 != (Entry = readdir(ProcDir))) {
    if (Entry->d_type == DT_DIR) {
      // Build a path from the current entry name
      SmallString<256> CmdLineFName;
      raw_svector_ostream(CmdLineFName) << "/proc/" << Entry->d_name
                                        << "/cmdline";

      // Open the cmdline file
      int CmdLineFD = open(CmdLineFName.c_str(), S_IRUSR);
      if (CmdLineFD != -1) {
        char    ExeName[PATH_MAX+1];
        char*   BaseName = 0;

        // Read the cmdline file
        ssize_t NumRead = read(CmdLineFD, ExeName, PATH_MAX+1);
        close(CmdLineFD);
        ssize_t Idx = 0;

        if (ExeName[0] != '/') {
          BaseName = ExeName;
        }

        // Find the terminator for the first string
        while (Idx < NumRead-1 && ExeName[Idx] != 0) {
          Idx++;
        }

        // Go back to the last non-null character
        Idx--;

        // Find the last path separator in the first string
        while (Idx > 0) {
          if (ExeName[Idx] == '/') {
            BaseName = ExeName + Idx + 1;
            break;
          }
          Idx--;
        }

        // Test this to see if it is the oprofile daemon
        if (BaseName != 0 && (!strcmp("oprofiled", BaseName) ||
                              !strcmp("operf", BaseName))) {
          // If it is, we're done
          closedir(ProcDir);
          return true;
        }
      }
    }
  }

  // We've looked through all the files and didn't find the daemon
  closedir(ProcDir);
  return false;
}

bool OProfileWrapper::op_open_agent() {
  if (!Initialized)
    initialize();

  if (OpenAgentFunc != 0) {
    Agent = OpenAgentFunc();
    return Agent != 0;
  }

  return false;
}

int OProfileWrapper::op_close_agent() {
  if (!Initialized)
    initialize();

  int ret = -1;
  if (Agent && CloseAgentFunc) {
    ret = CloseAgentFunc(Agent);
    if (ret == 0) {
      Agent = 0;
    }
  }
  return ret;
}

bool OProfileWrapper::isAgentAvailable() {
  return Agent != 0;
}

int OProfileWrapper::op_write_native_code(const char* Name,
                                          uint64_t Addr,
                                          void const* Code,
                                          const unsigned int Size) {
  if (!Initialized)
    initialize();

  if (Agent && WriteNativeCodeFunc)
    return WriteNativeCodeFunc(Agent, Name, Addr, Code, Size);

  return -1;
}

int OProfileWrapper::op_write_debug_line_info(
  void const* Code,
  size_t NumEntries,
  struct debug_line_info const* Info) {
  if (!Initialized)
    initialize();

  if (Agent && WriteDebugLineInfoFunc)
    return WriteDebugLineInfoFunc(Agent, Code, NumEntries, Info);

  return -1;
}

int OProfileWrapper::op_major_version() {
  if (!Initialized)
    initialize();

  if (Agent && MajorVersionFunc)
    return MajorVersionFunc();

  return -1;
}

int OProfileWrapper::op_minor_version() {
  if (!Initialized)
    initialize();

  if (Agent && MinorVersionFunc)
    return MinorVersionFunc();

  return -1;
}

int  OProfileWrapper::op_unload_native_code(uint64_t Addr) {
  if (!Initialized)
    initialize();

  if (Agent && UnloadNativeCodeFunc)
    return UnloadNativeCodeFunc(Agent, Addr);

  return -1;
}

} // namespace llvm
