//===-- HostInfoMacOSX.mm ---------------------------------------*- 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 "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/macosx/HostInfoMacOSX.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Timer.h"
#include "Utility/UuidCompatibility.h"

#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

// C++ Includes
#include <string>

// C inclues
#include <cstdlib>
#include <sys/sysctl.h>
#include <sys/syslimits.h>
#include <sys/types.h>

// Objective-C/C++ includes
#include <CoreFoundation/CoreFoundation.h>
#include <Foundation/Foundation.h>
#include <mach-o/dyld.h>
#if __has_include(<mach-o/dyld_introspection.h>)
#include <mach-o/dyld_introspection.h>
#define SDK_HAS_NEW_DYLD_INTROSPECTION_SPIS
#endif
#include <objc/objc-auto.h>

// These are needed when compiling on systems
// that do not yet have these definitions
#include <AvailabilityMacros.h>
#ifndef CPU_SUBTYPE_X86_64_H
#define CPU_SUBTYPE_X86_64_H ((cpu_subtype_t)8)
#endif
#ifndef CPU_TYPE_ARM64
#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64)
#endif

#ifndef CPU_TYPE_ARM64_32
#define CPU_ARCH_ABI64_32 0x02000000
#define CPU_TYPE_ARM64_32 (CPU_TYPE_ARM | CPU_ARCH_ABI64_32)
#endif

#include <TargetConditionals.h> // for TARGET_OS_TV, TARGET_OS_WATCH

using namespace lldb_private;

llvm::Optional<std::string> HostInfoMacOSX::GetOSBuildString() {
  int mib[2] = {CTL_KERN, KERN_OSVERSION};
  char cstr[PATH_MAX];
  size_t cstr_len = sizeof(cstr);
  if (::sysctl(mib, 2, cstr, &cstr_len, NULL, 0) == 0)
    return std::string(cstr, cstr_len - 1);

  return llvm::None;
}

static void ParseOSVersion(llvm::VersionTuple &version, NSString *Key) {
  @autoreleasepool {
    NSDictionary *version_info =
      [NSDictionary dictionaryWithContentsOfFile:
       @"/System/Library/CoreServices/SystemVersion.plist"];
    NSString *version_value = [version_info objectForKey: Key];
    const char *version_str = [version_value UTF8String];
    version.tryParse(version_str);
  }
}

llvm::VersionTuple HostInfoMacOSX::GetOSVersion() {
  static llvm::VersionTuple g_version;
  if (g_version.empty())
    ParseOSVersion(g_version, @"ProductVersion");
  return g_version;
}

llvm::VersionTuple HostInfoMacOSX::GetMacCatalystVersion() {
  static llvm::VersionTuple g_version;
  if (g_version.empty())
    ParseOSVersion(g_version, @"iOSSupportVersion");
  return g_version;
}


FileSpec HostInfoMacOSX::GetProgramFileSpec() {
  static FileSpec g_program_filespec;
  if (!g_program_filespec) {
    char program_fullpath[PATH_MAX];
    // If DST is NULL, then return the number of bytes needed.
    uint32_t len = sizeof(program_fullpath);
    int err = _NSGetExecutablePath(program_fullpath, &len);
    if (err == 0)
      g_program_filespec.SetFile(program_fullpath, FileSpec::Style::native);
    else if (err == -1) {
      char *large_program_fullpath = (char *)::malloc(len + 1);

      err = _NSGetExecutablePath(large_program_fullpath, &len);
      if (err == 0)
        g_program_filespec.SetFile(large_program_fullpath,
                                   FileSpec::Style::native);

      ::free(large_program_fullpath);
    }
  }
  return g_program_filespec;
}

bool HostInfoMacOSX::ComputeSupportExeDirectory(FileSpec &file_spec) {
  FileSpec lldb_file_spec = GetShlibDir();
  if (!lldb_file_spec)
    return false;

  std::string raw_path = lldb_file_spec.GetPath();

  size_t framework_pos = raw_path.find("LLDB.framework");
  if (framework_pos != std::string::npos) {
    framework_pos += strlen("LLDB.framework");
#if TARGET_OS_IPHONE
    // Shallow bundle
    raw_path.resize(framework_pos);
#else
    // Normal bundle
    raw_path.resize(framework_pos);
    raw_path.append("/Resources");
#endif
  } else {
    // Find the bin path relative to the lib path where the cmake-based
    // OS X .dylib lives.  This is not going to work if the bin and lib
    // dir are not both in the same dir.
    //
    // It is not going to work to do it by the executable path either,
    // as in the case of a python script, the executable is python, not
    // the lldb driver.
    raw_path.append("/../bin");
    FileSpec support_dir_spec(raw_path);
    FileSystem::Instance().Resolve(support_dir_spec);
    if (!FileSystem::Instance().IsDirectory(support_dir_spec)) {
      Log *log = GetLog(LLDBLog::Host);
      LLDB_LOGF(log, "HostInfoMacOSX::%s(): failed to find support directory",
                __FUNCTION__);
      return false;
    }

    // Get normalization from support_dir_spec.  Note the FileSpec resolve
    // does not remove '..' in the path.
    char *const dir_realpath =
        realpath(support_dir_spec.GetPath().c_str(), NULL);
    if (dir_realpath) {
      raw_path = dir_realpath;
      free(dir_realpath);
    } else {
      raw_path = support_dir_spec.GetPath();
    }
  }

  file_spec.SetDirectory(raw_path);
  return (bool)file_spec.GetDirectory();
}

bool HostInfoMacOSX::ComputeHeaderDirectory(FileSpec &file_spec) {
  FileSpec lldb_file_spec = GetShlibDir();
  if (!lldb_file_spec)
    return false;

  std::string raw_path = lldb_file_spec.GetPath();

  size_t framework_pos = raw_path.find("LLDB.framework");
  if (framework_pos != std::string::npos) {
    framework_pos += strlen("LLDB.framework");
    raw_path.resize(framework_pos);
    raw_path.append("/Headers");
  }
  file_spec.SetDirectory(raw_path);
  return true;
}

bool HostInfoMacOSX::ComputeSystemPluginsDirectory(FileSpec &file_spec) {
  FileSpec lldb_file_spec = GetShlibDir();
  if (!lldb_file_spec)
    return false;

  std::string raw_path = lldb_file_spec.GetPath();

  size_t framework_pos = raw_path.find("LLDB.framework");
  if (framework_pos == std::string::npos)
    return false;

  framework_pos += strlen("LLDB.framework");
  raw_path.resize(framework_pos);
  raw_path.append("/Resources/PlugIns");
  file_spec.SetDirectory(raw_path);
  return true;
}

bool HostInfoMacOSX::ComputeUserPluginsDirectory(FileSpec &file_spec) {
  FileSpec temp_file("~/Library/Application Support/LLDB/PlugIns");
  FileSystem::Instance().Resolve(temp_file);
  file_spec.SetDirectory(temp_file.GetPathAsConstString());
  return true;
}

void HostInfoMacOSX::ComputeHostArchitectureSupport(ArchSpec &arch_32,
                                                    ArchSpec &arch_64) {
  // All apple systems support 32 bit execution.
  uint32_t cputype, cpusubtype;
  uint32_t is_64_bit_capable = false;
  size_t len = sizeof(cputype);
  ArchSpec host_arch;
  // These will tell us about the kernel architecture, which even on a 64
  // bit machine can be 32 bit...
  if (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0) {
    len = sizeof(cpusubtype);
    if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) != 0)
      cpusubtype = CPU_TYPE_ANY;

    len = sizeof(is_64_bit_capable);
    ::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0);

    if (cputype == CPU_TYPE_ARM64 && cpusubtype == CPU_SUBTYPE_ARM64E) {
      // The arm64e architecture is a preview. Pretend the host architecture
      // is arm64.
      cpusubtype = CPU_SUBTYPE_ARM64_ALL;
    }

    if (is_64_bit_capable) {
      if (cputype & CPU_ARCH_ABI64) {
        // We have a 64 bit kernel on a 64 bit system
        arch_64.SetArchitecture(eArchTypeMachO, cputype, cpusubtype);
      } else {
        // We have a 64 bit kernel that is returning a 32 bit cputype, the
        // cpusubtype will be correct as if it were for a 64 bit architecture
        arch_64.SetArchitecture(eArchTypeMachO, cputype | CPU_ARCH_ABI64,
                                cpusubtype);
      }

      // Now we need modify the cpusubtype for the 32 bit slices.
      uint32_t cpusubtype32 = cpusubtype;
#if defined(__i386__) || defined(__x86_64__)
      if (cpusubtype == CPU_SUBTYPE_486 || cpusubtype == CPU_SUBTYPE_X86_64_H)
        cpusubtype32 = CPU_SUBTYPE_I386_ALL;
#elif defined(__arm__) || defined(__arm64__) || defined(__aarch64__)
      if (cputype == CPU_TYPE_ARM || cputype == CPU_TYPE_ARM64)
        cpusubtype32 = CPU_SUBTYPE_ARM_V7S;
#endif
      arch_32.SetArchitecture(eArchTypeMachO, cputype & ~(CPU_ARCH_MASK),
                              cpusubtype32);

      if (cputype == CPU_TYPE_ARM ||
          cputype == CPU_TYPE_ARM64 ||
          cputype == CPU_TYPE_ARM64_32) {
// When running on a watch or tv, report the host os correctly
#if defined(TARGET_OS_TV) && TARGET_OS_TV == 1
        arch_32.GetTriple().setOS(llvm::Triple::TvOS);
        arch_64.GetTriple().setOS(llvm::Triple::TvOS);
#elif defined(TARGET_OS_BRIDGE) && TARGET_OS_BRIDGE == 1
        arch_32.GetTriple().setOS(llvm::Triple::BridgeOS);
        arch_64.GetTriple().setOS(llvm::Triple::BridgeOS);
#elif defined(TARGET_OS_WATCHOS) && TARGET_OS_WATCHOS == 1
        arch_32.GetTriple().setOS(llvm::Triple::WatchOS);
        arch_64.GetTriple().setOS(llvm::Triple::WatchOS);
#elif defined(TARGET_OS_OSX) && TARGET_OS_OSX == 1
        arch_32.GetTriple().setOS(llvm::Triple::MacOSX);
        arch_64.GetTriple().setOS(llvm::Triple::MacOSX);
#else
        arch_32.GetTriple().setOS(llvm::Triple::IOS);
        arch_64.GetTriple().setOS(llvm::Triple::IOS);
#endif
      } else {
        arch_32.GetTriple().setOS(llvm::Triple::MacOSX);
        arch_64.GetTriple().setOS(llvm::Triple::MacOSX);
      }
    } else {
      // We have a 32 bit kernel on a 32 bit system
      arch_32.SetArchitecture(eArchTypeMachO, cputype, cpusubtype);
#if defined(TARGET_OS_WATCH) && TARGET_OS_WATCH == 1
      arch_32.GetTriple().setOS(llvm::Triple::WatchOS);
#else
      arch_32.GetTriple().setOS(llvm::Triple::IOS);
#endif
      arch_64.Clear();
    }
  }
}

/// Return and cache $DEVELOPER_DIR if it is set and exists.
static std::string GetEnvDeveloperDir() {
  static std::string g_env_developer_dir;
  static std::once_flag g_once_flag;
  std::call_once(g_once_flag, [&]() {
    if (const char *developer_dir_env_var = getenv("DEVELOPER_DIR")) {
      FileSpec fspec(developer_dir_env_var);
      if (FileSystem::Instance().Exists(fspec))
        g_env_developer_dir = fspec.GetPath();
    }});
  return g_env_developer_dir;
}

FileSpec HostInfoMacOSX::GetXcodeContentsDirectory() {
  static FileSpec g_xcode_contents_path;
  static std::once_flag g_once_flag;
  std::call_once(g_once_flag, [&]() {
    // Try the shlib dir first.
    if (FileSpec fspec = HostInfo::GetShlibDir()) {
      if (FileSystem::Instance().Exists(fspec)) {
        std::string xcode_contents_dir =
            XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath());
        if (!xcode_contents_dir.empty()) {
          g_xcode_contents_path = FileSpec(xcode_contents_dir);
          return;
        }
      }
    }

    llvm::SmallString<128> env_developer_dir(GetEnvDeveloperDir());
    if (!env_developer_dir.empty()) {
      llvm::sys::path::append(env_developer_dir, "Contents");
      std::string xcode_contents_dir =
          XcodeSDK::FindXcodeContentsDirectoryInPath(env_developer_dir);
      if (!xcode_contents_dir.empty()) {
        g_xcode_contents_path = FileSpec(xcode_contents_dir);
        return;
      }
    }

    FileSpec fspec(HostInfo::GetXcodeSDKPath(XcodeSDK::GetAnyMacOS()));
    if (fspec) {
      if (FileSystem::Instance().Exists(fspec)) {
        std::string xcode_contents_dir =
            XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath());
        if (!xcode_contents_dir.empty()) {
          g_xcode_contents_path = FileSpec(xcode_contents_dir);
          return;
        }
      }
    }
  });
  return g_xcode_contents_path;
}

lldb_private::FileSpec HostInfoMacOSX::GetXcodeDeveloperDirectory() {
  static lldb_private::FileSpec g_developer_directory;
  static llvm::once_flag g_once_flag;
  llvm::call_once(g_once_flag, []() {
    if (FileSpec fspec = GetXcodeContentsDirectory()) {
      fspec.AppendPathComponent("Developer");
      if (FileSystem::Instance().Exists(fspec))
        g_developer_directory = fspec;
    }
  });
  return g_developer_directory;
}

static std::string GetXcodeSDK(XcodeSDK sdk) {
  XcodeSDK::Info info = sdk.Parse();
  std::string sdk_name = XcodeSDK::GetCanonicalName(info);

  auto xcrun = [](const std::string &sdk,
                  llvm::StringRef developer_dir = "") -> std::string {
    Args args;
    if (!developer_dir.empty()) {
      args.AppendArgument("/usr/bin/env");
      args.AppendArgument("DEVELOPER_DIR=" + developer_dir.str());
    }
    args.AppendArgument("/usr/bin/xcrun");
    args.AppendArgument("--show-sdk-path");
    args.AppendArgument("--sdk");
    args.AppendArgument(sdk);

    Log *log = GetLog(LLDBLog::Host);
    if (log) {
      std::string cmdstr;
      args.GetCommandString(cmdstr);
      log->Printf("GetXcodeSDK() running shell cmd '%s'", cmdstr.c_str());
    }

    int status = 0;
    int signo = 0;
    std::string output_str;
    lldb_private::Status error =
        Host::RunShellCommand(args, FileSpec(), &status, &signo, &output_str,
                              std::chrono::seconds(15));

    // Check that xcrun return something useful.
    if (status != 0 || output_str.empty())
      return {};

    // Convert to a StringRef so we can manipulate the string without modifying
    // the underlying data.
    llvm::StringRef output(output_str);

    // Remove any trailing newline characters.
    output = output.rtrim();

    // Strip any leading newline characters and everything before them.
    const size_t last_newline = output.rfind('\n');
    if (last_newline != llvm::StringRef::npos)
      output = output.substr(last_newline + 1);

    return output.str();
  };

  auto find_sdk = [&xcrun](const std::string &sdk_name) -> std::string {
    // Invoke xcrun with the developer dir specified in the environment.
    std::string developer_dir = GetEnvDeveloperDir();
    if (!developer_dir.empty()) {
      // Don't fallback if DEVELOPER_DIR was set.
      return xcrun(sdk_name, developer_dir);
    }

    // Invoke xcrun with the shlib dir.
    if (FileSpec fspec = HostInfo::GetShlibDir()) {
      if (FileSystem::Instance().Exists(fspec)) {
        std::string contents_dir =
            XcodeSDK::FindXcodeContentsDirectoryInPath(fspec.GetPath());
        llvm::StringRef shlib_developer_dir =
            llvm::sys::path::parent_path(contents_dir);
        if (!shlib_developer_dir.empty()) {
          std::string sdk = xcrun(sdk_name, std::move(shlib_developer_dir));
          if (!sdk.empty())
            return sdk;
        }
      }
    }

    // Invoke xcrun without a developer dir as a last resort.
    return xcrun(sdk_name);
  };

  std::string path = find_sdk(sdk_name);
  while (path.empty()) {
    // Try an alternate spelling of the name ("macosx10.9internal").
    if (info.type == XcodeSDK::Type::MacOSX && !info.version.empty() &&
        info.internal) {
      llvm::StringRef fixed(sdk_name);
      if (fixed.consume_back(".internal"))
        sdk_name = fixed.str() + "internal";
      path = find_sdk(sdk_name);
      if (!path.empty())
        break;
    }
    Log *log = GetLog(LLDBLog::Host);
    LLDB_LOGF(log, "Couldn't find SDK %s on host", sdk_name.c_str());

    // Try without the version.
    if (!info.version.empty()) {
      info.version = {};
      sdk_name = XcodeSDK::GetCanonicalName(info);
      path = find_sdk(sdk_name);
      if (!path.empty())
        break;
    }

    LLDB_LOGF(log, "Couldn't find any matching SDK on host");
    return {};
  }

  // Whatever is left in output should be a valid path.
  if (!FileSystem::Instance().Exists(path))
    return {};
  return path;
}

llvm::StringRef HostInfoMacOSX::GetXcodeSDKPath(XcodeSDK sdk) {
  static llvm::StringMap<std::string> g_sdk_path;
  static std::mutex g_sdk_path_mutex;

  std::lock_guard<std::mutex> guard(g_sdk_path_mutex);
  LLDB_SCOPED_TIMER();

  auto it = g_sdk_path.find(sdk.GetString());
  if (it != g_sdk_path.end())
    return it->second;
  auto it_new = g_sdk_path.insert({sdk.GetString(), GetXcodeSDK(sdk)});
  return it_new.first->second;
}

namespace {
struct dyld_shared_cache_dylib_text_info {
  uint64_t version; // current version 1
  // following fields all exist in version 1
  uint64_t loadAddressUnslid;
  uint64_t textSegmentSize;
  uuid_t dylibUuid;
  const char *path; // pointer invalid at end of iterations
  // following fields all exist in version 2
  uint64_t textSegmentOffset; // offset from start of cache
};
typedef struct dyld_shared_cache_dylib_text_info
    dyld_shared_cache_dylib_text_info;
}

extern "C" int dyld_shared_cache_iterate_text(
    const uuid_t cacheUuid,
    void (^callback)(const dyld_shared_cache_dylib_text_info *info));
extern "C" uint8_t *_dyld_get_shared_cache_range(size_t *length);
extern "C" bool _dyld_get_shared_cache_uuid(uuid_t uuid);

namespace {
class SharedCacheInfo {
public:
  const UUID &GetUUID() const { return m_uuid; }
  const llvm::StringMap<SharedCacheImageInfo> &GetImages() const {
    return m_images;
  }

  SharedCacheInfo();

private:
  llvm::StringMap<SharedCacheImageInfo> m_images;
  UUID m_uuid;
};
}

SharedCacheInfo::SharedCacheInfo() {
#if defined(SDK_HAS_NEW_DYLD_INTROSPECTION_SPIS)
  if (__builtin_available(macOS 12, *)) {
    if (dyld_process_create_for_current_task) {
      auto dyld_process = dyld_process_create_for_current_task();
      auto snapshot =
          dyld_process_snapshot_create_for_process(dyld_process, nullptr);
      auto shared_cache = dyld_process_snapshot_get_shared_cache(snapshot);
      assert(dyld_process && snapshot && shared_cache);

      dyld_shared_cache_for_each_image(shared_cache, ^(dyld_image_t image) {
        __block uint64_t minVmAddr = UINT64_MAX;
        __block uint64_t maxVmAddr = 0;
        uuid_t uuidStore;
        __block uuid_t *uuid = &uuidStore;

        dyld_image_for_each_segment_info(image, ^(const char *segmentName,
                                                  uint64_t vmAddr,
                                                  uint64_t vmSize, int perm) {
          minVmAddr = std::min(minVmAddr, vmAddr);
          maxVmAddr = std::max(maxVmAddr, vmAddr + vmSize);
          dyld_image_copy_uuid(image, uuid);
        });
        assert(minVmAddr != UINT_MAX);
        assert(maxVmAddr != 0);
        m_images[dyld_image_get_installname(image)] = SharedCacheImageInfo{
            UUID::fromData(uuid, 16),
            std::make_shared<DataBufferUnowned>((uint8_t *)minVmAddr,
                                                maxVmAddr - minVmAddr)};
      });
      dyld_process_snapshot_dispose(snapshot);
      return;
    }
  }
#endif

  size_t shared_cache_size;
  uint8_t *shared_cache_start =
      _dyld_get_shared_cache_range(&shared_cache_size);
  uuid_t dsc_uuid;
  _dyld_get_shared_cache_uuid(dsc_uuid);
  m_uuid = UUID::fromData(dsc_uuid);

  dyld_shared_cache_iterate_text(
      dsc_uuid, ^(const dyld_shared_cache_dylib_text_info *info) {
        m_images[info->path] = SharedCacheImageInfo{
            UUID::fromData(info->dylibUuid, 16),
            std::make_shared<DataBufferUnowned>(
                shared_cache_start + info->textSegmentOffset,
                shared_cache_size - info->textSegmentOffset)};
      });
}

SharedCacheImageInfo
HostInfoMacOSX::GetSharedCacheImageInfo(llvm::StringRef image_name) {
  static SharedCacheInfo g_shared_cache_info;
  return g_shared_cache_info.GetImages().lookup(image_name);
}
