//===- tools/dsymutil/SymbolMap.cpp ---------------------------------------===//
//
// 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 "SymbolMap.h"
#include "DebugMap.h"
#include "MachOUtils.h"

#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/WithColor.h"

#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
#include <uuid/uuid.h>
#endif

namespace llvm {
namespace dsymutil {

StringRef SymbolMapTranslator::operator()(StringRef Input) {
  if (!Input.startswith("__hidden#") && !Input.startswith("___hidden#"))
    return Input;

  bool MightNeedUnderscore = false;
  StringRef Line = Input.drop_front(sizeof("__hidden#") - 1);
  if (Line[0] == '#') {
    Line = Line.drop_front();
    MightNeedUnderscore = true;
  }

  std::size_t LineNumber = std::numeric_limits<std::size_t>::max();
  Line.split('_').first.getAsInteger(10, LineNumber);
  if (LineNumber >= UnobfuscatedStrings.size()) {
    WithColor::warning() << "reference to a unexisting unobfuscated string "
                         << Input << ": symbol map mismatch?\n"
                         << Line << '\n';
    return Input;
  }

  const std::string &Translation = UnobfuscatedStrings[LineNumber];
  if (!MightNeedUnderscore || !MangleNames)
    return Translation;

  // Objective-C symbols for the MachO symbol table start with a \1. Please see
  // `MangleContext::mangleObjCMethodName` in clang.
  if (Translation[0] == 1)
    return StringRef(Translation).drop_front();

  // We need permanent storage for the string we are about to create. Just
  // append it to the vector containing translations. This should only happen
  // during MachO symbol table translation, thus there should be no risk on
  // exponential growth.
  UnobfuscatedStrings.emplace_back("_" + Translation);
  return UnobfuscatedStrings.back();
}

SymbolMapTranslator SymbolMapLoader::Load(StringRef InputFile,
                                          const DebugMap &Map) const {
  if (SymbolMap.empty())
    return {};

  std::string SymbolMapPath = SymbolMap;

#if __APPLE__
  // Look through the UUID Map.
  if (sys::fs::is_directory(SymbolMapPath) && !Map.getUUID().empty()) {
    uuid_string_t UUIDString;
    uuid_unparse_upper((const uint8_t *)Map.getUUID().data(), UUIDString);

    SmallString<256> PlistPath(
        sys::path::parent_path(sys::path::parent_path(InputFile)));
    sys::path::append(PlistPath, StringRef(UUIDString).str() + ".plist");

    CFStringRef plistFile = CFStringCreateWithCString(
        kCFAllocatorDefault, PlistPath.c_str(), kCFStringEncodingUTF8);
    CFURLRef fileURL = CFURLCreateWithFileSystemPath(
        kCFAllocatorDefault, plistFile, kCFURLPOSIXPathStyle, false);
    CFReadStreamRef resourceData =
        CFReadStreamCreateWithFile(kCFAllocatorDefault, fileURL);
    if (resourceData) {
      CFReadStreamOpen(resourceData);
      CFDictionaryRef plist = (CFDictionaryRef)CFPropertyListCreateWithStream(
          kCFAllocatorDefault, resourceData, 0, kCFPropertyListImmutable,
          nullptr, nullptr);

      if (plist) {
        if (CFDictionaryContainsKey(plist, CFSTR("DBGOriginalUUID"))) {
          CFStringRef OldUUID = (CFStringRef)CFDictionaryGetValue(
              plist, CFSTR("DBGOriginalUUID"));

          StringRef UUID(CFStringGetCStringPtr(OldUUID, kCFStringEncodingUTF8));
          SmallString<256> BCSymbolMapPath(SymbolMapPath);
          sys::path::append(BCSymbolMapPath, UUID.str() + ".bcsymbolmap");
          SymbolMapPath = std::string(BCSymbolMapPath);
        }
        CFRelease(plist);
      }
      CFReadStreamClose(resourceData);
      CFRelease(resourceData);
    }
    CFRelease(fileURL);
    CFRelease(plistFile);
  }
#endif

  if (sys::fs::is_directory(SymbolMapPath)) {
    SymbolMapPath += (Twine("/") + sys::path::filename(InputFile) + "-" +
                      MachOUtils::getArchName(Map.getTriple().getArchName()) +
                      ".bcsymbolmap")
                         .str();
  }

  auto ErrOrMemBuffer = MemoryBuffer::getFile(SymbolMapPath);
  if (auto EC = ErrOrMemBuffer.getError()) {
    WithColor::warning() << SymbolMapPath << ": " << EC.message()
                         << ": not unobfuscating.\n";
    return {};
  }

  std::vector<std::string> UnobfuscatedStrings;
  auto &MemBuf = **ErrOrMemBuffer;
  StringRef Data(MemBuf.getBufferStart(),
                 MemBuf.getBufferEnd() - MemBuf.getBufferStart());
  StringRef LHS;
  std::tie(LHS, Data) = Data.split('\n');
  bool MangleNames = false;

  // Check version string first.
  if (!LHS.startswith("BCSymbolMap Version:")) {
    // Version string not present, warns but try to parse it.
    WithColor::warning() << SymbolMapPath
                         << " is missing version string: assuming 1.0.\n";
    UnobfuscatedStrings.emplace_back(LHS);
  } else if (LHS.equals("BCSymbolMap Version: 1.0")) {
    MangleNames = true;
  } else if (LHS.equals("BCSymbolMap Version: 2.0")) {
    MangleNames = false;
  } else {
    StringRef VersionNum;
    std::tie(LHS, VersionNum) = LHS.split(':');
    WithColor::warning() << SymbolMapPath
                         << " has unsupported symbol map version" << VersionNum
                         << ": not unobfuscating.\n";
    return {};
  }

  while (!Data.empty()) {
    std::tie(LHS, Data) = Data.split('\n');
    UnobfuscatedStrings.emplace_back(LHS);
  }

  return SymbolMapTranslator(std::move(UnobfuscatedStrings), MangleNames);
}

} // namespace dsymutil
} // namespace llvm
