//===- llvm/Object/BuildID.cpp - Build ID ---------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file defines a library for handling Build IDs and using them to find
/// debug info.
///
//===----------------------------------------------------------------------===//

#include "llvm/Object/BuildID.h"

#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"

using namespace llvm;
using namespace llvm::object;

namespace {

template <typename ELFT> BuildIDRef getBuildID(const ELFFile<ELFT> &Obj) {
  auto findBuildID = [&Obj](const auto &ShdrOrPhdr,
                            uint64_t Alignment) -> std::optional<BuildIDRef> {
    Error Err = Error::success();
    for (auto N : Obj.notes(ShdrOrPhdr, Err))
      if (N.getType() == ELF::NT_GNU_BUILD_ID &&
          N.getName() == ELF::ELF_NOTE_GNU)
        return N.getDesc(Alignment);
    consumeError(std::move(Err));
    return std::nullopt;
  };

  auto Sections = cantFail(Obj.sections());
  for (const auto &S : Sections) {
    if (S.sh_type != ELF::SHT_NOTE)
      continue;
    if (std::optional<BuildIDRef> ShdrRes = findBuildID(S, S.sh_addralign))
      return ShdrRes.value();
  }
  auto PhdrsOrErr = Obj.program_headers();
  if (!PhdrsOrErr) {
    consumeError(PhdrsOrErr.takeError());
    return {};
  }
  for (const auto &P : *PhdrsOrErr) {
    if (P.p_type != ELF::PT_NOTE)
      continue;
    if (std::optional<BuildIDRef> PhdrRes = findBuildID(P, P.p_align))
      return PhdrRes.value();
  }
  return {};
}

} // namespace

BuildID llvm::object::parseBuildID(StringRef Str) {
  std::string Bytes;
  if (!tryGetFromHex(Str, Bytes))
    return {};
  ArrayRef<uint8_t> BuildID(reinterpret_cast<const uint8_t *>(Bytes.data()),
                            Bytes.size());
  return SmallVector<uint8_t>(BuildID);
}

BuildIDRef llvm::object::getBuildID(const ObjectFile *Obj) {
  if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(Obj))
    return ::getBuildID(O->getELFFile());
  if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(Obj))
    return ::getBuildID(O->getELFFile());
  if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(Obj))
    return ::getBuildID(O->getELFFile());
  if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(Obj))
    return ::getBuildID(O->getELFFile());
  return {};
}

std::optional<std::string> BuildIDFetcher::fetch(BuildIDRef BuildID) const {
  auto GetDebugPath = [&](StringRef Directory) {
    SmallString<128> Path{Directory};
    sys::path::append(Path, ".build-id",
                      llvm::toHex(BuildID[0], /*LowerCase=*/true),
                      llvm::toHex(BuildID.slice(1), /*LowerCase=*/true));
    Path += ".debug";
    return Path;
  };
  if (DebugFileDirectories.empty()) {
    SmallString<128> Path = GetDebugPath(
#if defined(__NetBSD__)
        // Try /usr/libdata/debug/.build-id/../...
        "/usr/libdata/debug"
#else
        // Try /usr/lib/debug/.build-id/../...
        "/usr/lib/debug"
#endif
    );
    if (llvm::sys::fs::exists(Path))
      return std::string(Path);
  } else {
    for (const auto &Directory : DebugFileDirectories) {
      // Try <debug-file-directory>/.build-id/../...
      SmallString<128> Path = GetDebugPath(Directory);
      if (llvm::sys::fs::exists(Path))
        return std::string(Path);
    }
  }
  return std::nullopt;
}
