brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · 98852ee Raw
117 lines · cpp
1//===- bolt/RuntimeLibs/RuntimeLibrary.cpp - Runtime Library --------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the RuntimeLibrary class.10//11//===----------------------------------------------------------------------===//12 13#include "bolt/RuntimeLibs/RuntimeLibrary.h"14#include "bolt/Core/Linker.h"15#include "bolt/RuntimeLibs/RuntimeLibraryVariables.inc"16#include "bolt/Utils/Utils.h"17#include "llvm/BinaryFormat/Magic.h"18#include "llvm/Object/Archive.h"19#include "llvm/Object/ObjectFile.h"20#include "llvm/Support/Path.h"21#include "llvm/Support/Program.h"22 23#define DEBUG_TYPE "bolt-rtlib"24 25using namespace llvm;26using namespace bolt;27 28void RuntimeLibrary::anchor() {}29 30std::string RuntimeLibrary::getLibPathByToolPath(StringRef ToolPath,31                                                 StringRef LibFileName) {32  StringRef Dir = llvm::sys::path::parent_path(ToolPath);33  SmallString<128> LibPath = llvm::sys::path::parent_path(Dir);34  llvm::sys::path::append(LibPath, "lib" LLVM_LIBDIR_SUFFIX);35  if (!llvm::sys::fs::exists(LibPath)) {36    // In some cases we install bolt binary into one level deeper in bin/,37    // we need to go back one more level to find lib directory.38    LibPath = llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir));39    llvm::sys::path::append(LibPath, "lib" LLVM_LIBDIR_SUFFIX);40  }41  llvm::sys::path::append(LibPath, LibFileName);42  if (!llvm::sys::fs::exists(LibPath)) {43    // If it is a symlink, check the directory that the symlink points to.44    if (llvm::sys::fs::is_symlink_file(ToolPath)) {45      SmallString<256> RealPath;46      llvm::sys::fs::real_path(ToolPath, RealPath);47      if (llvm::ErrorOr<std::string> P =48              llvm::sys::findProgramByName(RealPath)) {49        outs() << "BOLT-INFO: library not found: " << LibPath << "\n"50               << "BOLT-INFO: " << ToolPath << " is a symlink; will look up "51               << LibFileName52               << " at the target directory that the symlink points to\n";53        return getLibPath(*P, LibFileName);54      }55    }56    errs() << "BOLT-ERROR: library not found: " << LibPath << "\n";57    exit(1);58  }59  return std::string(LibPath);60}61 62std::string RuntimeLibrary::getLibPathByInstalled(StringRef LibFileName) {63  SmallString<128> LibPath(CMAKE_INSTALL_FULL_LIBDIR);64  llvm::sys::path::append(LibPath, LibFileName);65  return std::string(LibPath);66}67 68std::string RuntimeLibrary::getLibPath(StringRef ToolPath,69                                       StringRef LibFileName) {70  if (llvm::sys::fs::exists(LibFileName)) {71    return std::string(LibFileName);72  }73 74  std::string ByTool = getLibPathByToolPath(ToolPath, LibFileName);75  if (llvm::sys::fs::exists(ByTool)) {76    return ByTool;77  }78 79  std::string ByInstalled = getLibPathByInstalled(LibFileName);80  if (llvm::sys::fs::exists(ByInstalled)) {81    return ByInstalled;82  }83 84  errs() << "BOLT-ERROR: library not found: " << ByTool << ", " << ByInstalled85         << ", or " << LibFileName << "\n";86  exit(1);87}88 89void RuntimeLibrary::loadLibrary(StringRef LibPath, BOLTLinker &Linker,90                                 BOLTLinker::SectionsMapper MapSections) {91  ErrorOr<std::unique_ptr<MemoryBuffer>> MaybeBuf =92      MemoryBuffer::getFile(LibPath, false, false);93  check_error(MaybeBuf.getError(), LibPath);94  std::unique_ptr<MemoryBuffer> B = std::move(MaybeBuf.get());95  file_magic Magic = identify_magic(B->getBuffer());96 97  if (Magic == file_magic::archive) {98    Error Err = Error::success();99    object::Archive Archive(B->getMemBufferRef(), Err);100    for (const object::Archive::Child &C : Archive.children(Err)) {101      std::unique_ptr<object::Binary> Bin = cantFail(C.getAsBinary());102      if (object::ObjectFile *Obj = dyn_cast<object::ObjectFile>(&*Bin))103        Linker.loadObject(Obj->getMemoryBufferRef(), MapSections);104    }105    check_error(std::move(Err), B->getBufferIdentifier());106  } else if (Magic == file_magic::elf_relocatable ||107             Magic == file_magic::elf_shared_object) {108    std::unique_ptr<object::ObjectFile> Obj =109        cantFail(object::ObjectFile::createObjectFile(B->getMemBufferRef()),110                 "error creating in-memory object");111    Linker.loadObject(Obj->getMemoryBufferRef(), MapSections);112  } else {113    errs() << "BOLT-ERROR: unrecognized library format: " << LibPath << "\n";114    exit(1);115  }116}117