Path: blob/main/contrib/llvm-project/llvm/lib/Object/BuildID.cpp
35232 views
//===- llvm/Object/BuildID.cpp - Build ID ---------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file9/// This file defines a library for handling Build IDs and using them to find10/// debug info.11///12//===----------------------------------------------------------------------===//1314#include "llvm/Object/BuildID.h"1516#include "llvm/Object/ELFObjectFile.h"17#include "llvm/Support/FileSystem.h"18#include "llvm/Support/Path.h"1920using namespace llvm;21using namespace llvm::object;2223namespace {2425template <typename ELFT> BuildIDRef getBuildID(const ELFFile<ELFT> &Obj) {26auto PhdrsOrErr = Obj.program_headers();27if (!PhdrsOrErr) {28consumeError(PhdrsOrErr.takeError());29return {};30}31for (const auto &P : *PhdrsOrErr) {32if (P.p_type != ELF::PT_NOTE)33continue;34Error Err = Error::success();35for (auto N : Obj.notes(P, Err))36if (N.getType() == ELF::NT_GNU_BUILD_ID &&37N.getName() == ELF::ELF_NOTE_GNU)38return N.getDesc(P.p_align);39consumeError(std::move(Err));40}41return {};42}4344} // namespace4546BuildID llvm::object::parseBuildID(StringRef Str) {47std::string Bytes;48if (!tryGetFromHex(Str, Bytes))49return {};50ArrayRef<uint8_t> BuildID(reinterpret_cast<const uint8_t *>(Bytes.data()),51Bytes.size());52return SmallVector<uint8_t>(BuildID.begin(), BuildID.end());53}5455BuildIDRef llvm::object::getBuildID(const ObjectFile *Obj) {56if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(Obj))57return ::getBuildID(O->getELFFile());58if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(Obj))59return ::getBuildID(O->getELFFile());60if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(Obj))61return ::getBuildID(O->getELFFile());62if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(Obj))63return ::getBuildID(O->getELFFile());64return std::nullopt;65}6667std::optional<std::string> BuildIDFetcher::fetch(BuildIDRef BuildID) const {68auto GetDebugPath = [&](StringRef Directory) {69SmallString<128> Path{Directory};70sys::path::append(Path, ".build-id",71llvm::toHex(BuildID[0], /*LowerCase=*/true),72llvm::toHex(BuildID.slice(1), /*LowerCase=*/true));73Path += ".debug";74return Path;75};76if (DebugFileDirectories.empty()) {77SmallString<128> Path = GetDebugPath(78#if defined(__NetBSD__)79// Try /usr/libdata/debug/.build-id/../...80"/usr/libdata/debug"81#else82// Try /usr/lib/debug/.build-id/../...83"/usr/lib/debug"84#endif85);86if (llvm::sys::fs::exists(Path))87return std::string(Path);88} else {89for (const auto &Directory : DebugFileDirectories) {90// Try <debug-file-directory>/.build-id/../...91SmallString<128> Path = GetDebugPath(Directory);92if (llvm::sys::fs::exists(Path))93return std::string(Path);94}95}96return std::nullopt;97}9899100