//===-- 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"

#define DEBUG_TYPE "oprofile-wrapper"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/MutexGuard.h"
#include "llvm/ADT/SmallString.h"

#include <sstream>
#include <cstring>
#include <stddef.h>
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

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;

        // 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)) {
          // 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
