//===-- SubprocessMemory.cpp ------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "SubprocessMemory.h"
#include "Error.h"
#include "llvm/Support/Error.h"
#include <cerrno>

#ifdef __linux__
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>
#endif

namespace llvm {
namespace exegesis {

#if defined(__linux__) && !defined(__ANDROID__)

Error SubprocessMemory::initializeSubprocessMemory(pid_t ProcessID) {
  // Add the PID to the shared memory name so that if we're running multiple
  // processes at the same time, they won't interfere with each other.
  // This comes up particularly often when running the exegesis tests with
  // llvm-lit
  std::string AuxiliaryMemoryName = "/auxmem" + std::to_string(ProcessID);
  int AuxiliaryMemoryFD = shm_open(AuxiliaryMemoryName.c_str(),
                                   O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
  if (AuxiliaryMemoryFD == -1)
    return make_error<Failure>(
        "Failed to create shared memory object for auxiliary memory: " +
        Twine(strerror(errno)));
  if (ftruncate(AuxiliaryMemoryFD, AuxiliaryMemorySize) != 0) {
    return make_error<Failure>("Truncating the auxiliary memory failed: " +
                               Twine(strerror(errno)));
  }
  SharedMemoryNames.push_back(AuxiliaryMemoryName);
  return Error::success();
}

Error SubprocessMemory::addMemoryDefinition(
    std::unordered_map<std::string, MemoryValue> MemoryDefinitions,
    pid_t ProcessPID) {
  SharedMemoryNames.reserve(MemoryDefinitions.size());
  for (auto &[Name, MemVal] : MemoryDefinitions) {
    std::string SharedMemoryName = "/" + std::to_string(ProcessPID) + "memdef" +
                                   std::to_string(MemVal.Index);
    SharedMemoryNames.push_back(SharedMemoryName);
    int SharedMemoryFD =
        shm_open(SharedMemoryName.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
    if (ftruncate(SharedMemoryFD, MemVal.SizeBytes) != 0) {
      return make_error<Failure>("Truncating a memory definiton failed: " +
                                 Twine(strerror(errno)));
    }

    char *SharedMemoryMapping =
        (char *)mmap(NULL, MemVal.SizeBytes, PROT_READ | PROT_WRITE, MAP_SHARED,
                     SharedMemoryFD, 0);
    // fill the buffer with the specified value
    size_t CurrentByte = 0;
    const size_t ValueWidthBytes = MemVal.Value.getBitWidth() / 8;
    while (CurrentByte < MemVal.SizeBytes - ValueWidthBytes) {
      memcpy(SharedMemoryMapping + CurrentByte, MemVal.Value.getRawData(),
             ValueWidthBytes);
      CurrentByte += ValueWidthBytes;
    }
    // fill the last section
    memcpy(SharedMemoryMapping + CurrentByte, MemVal.Value.getRawData(),
           MemVal.SizeBytes - CurrentByte);
    if (munmap(SharedMemoryMapping, MemVal.SizeBytes) != 0) {
      return make_error<Failure>(
          "Unmapping a memory definition in the parent failed: " +
          Twine(strerror(errno)));
    }
  }
  return Error::success();
}

Expected<int> SubprocessMemory::setupAuxiliaryMemoryInSubprocess(
    std::unordered_map<std::string, MemoryValue> MemoryDefinitions,
    pid_t ParentPID, int CounterFileDescriptor) {
  std::string AuxiliaryMemoryName = "/auxmem" + std::to_string(ParentPID);
  int AuxiliaryMemoryFileDescriptor =
      shm_open(AuxiliaryMemoryName.c_str(), O_RDWR, S_IRUSR | S_IWUSR);
  if (AuxiliaryMemoryFileDescriptor == -1)
    return make_error<Failure>(
        "Getting file descriptor for auxiliary memory failed");
  // set up memory value file descriptors
  int *AuxiliaryMemoryMapping =
      (int *)mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED,
                  AuxiliaryMemoryFileDescriptor, 0);
  if ((intptr_t)AuxiliaryMemoryMapping == -1)
    return make_error<Failure>("Mapping auxiliary memory failed");
  AuxiliaryMemoryMapping[0] = CounterFileDescriptor;
  for (auto &[Name, MemVal] : MemoryDefinitions) {
    std::string MemoryValueName = "/" + std::to_string(ParentPID) + "memdef" +
                                  std::to_string(MemVal.Index);
    AuxiliaryMemoryMapping[AuxiliaryMemoryOffset + MemVal.Index] =
        shm_open(MemoryValueName.c_str(), O_RDWR, S_IRUSR | S_IWUSR);
    if (AuxiliaryMemoryMapping[AuxiliaryMemoryOffset + MemVal.Index] == -1)
      return make_error<Failure>("Mapping shared memory failed");
  }
  if (munmap(AuxiliaryMemoryMapping, 4096) == -1)
    return make_error<Failure>("Unmapping auxiliary memory failed");
  return AuxiliaryMemoryFileDescriptor;
}

SubprocessMemory::~SubprocessMemory() {
  for (std::string SharedMemoryName : SharedMemoryNames) {
    if (shm_unlink(SharedMemoryName.c_str()) != 0) {
      errs() << "Failed to unlink shared memory section: " << strerror(errno)
             << "\n";
    }
  }
}

#else

Error SubprocessMemory::initializeSubprocessMemory(pid_t ProcessPID) {
  return make_error<Failure>(
      "initializeSubprocessMemory is only supported on Linux");
}

Error SubprocessMemory::addMemoryDefinition(
    std::unordered_map<std::string, MemoryValue> MemoryDefinitions,
    pid_t ProcessPID) {
  return make_error<Failure>("addMemoryDefinitions is only supported on Linux");
}

Expected<int> SubprocessMemory::setupAuxiliaryMemoryInSubprocess(
    std::unordered_map<std::string, MemoryValue> MemoryDefinitions,
    pid_t ParentPID, int CounterFileDescriptor) {
  return make_error<Failure>(
      "setupAuxiliaryMemoryInSubprocess is only supported on Linux");
}

SubprocessMemory::~SubprocessMemory() {}

#endif // defined(__linux__) && !defined(__ANDROID__)

} // namespace exegesis
} // namespace llvm
