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-exception
6//
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
22#define DEBUG_TYPE "bolt-rtlib"
23
24using namespace llvm;
25using namespace bolt;
26
27void RuntimeLibrary::anchor() {}
28
29std::string RuntimeLibrary::getLibPath(StringRef ToolPath,
30 StringRef LibFileName) {
31 StringRef Dir = llvm::sys::path::parent_path(path: ToolPath);
32 SmallString<128> LibPath = llvm::sys::path::parent_path(path: Dir);
33 llvm::sys::path::append(path&: LibPath, a: "lib" LLVM_LIBDIR_SUFFIX);
34 if (!llvm::sys::fs::exists(Path: LibPath)) {
35 // In some cases we install bolt binary into one level deeper in bin/,
36 // we need to go back one more level to find lib directory.
37 LibPath = llvm::sys::path::parent_path(path: llvm::sys::path::parent_path(path: Dir));
38 llvm::sys::path::append(path&: LibPath, a: "lib" LLVM_LIBDIR_SUFFIX);
39 }
40 llvm::sys::path::append(path&: LibPath, a: LibFileName);
41 if (!llvm::sys::fs::exists(Path: LibPath)) {
42 errs() << "BOLT-ERROR: library not found: " << LibPath << "\n";
43 exit(status: 1);
44 }
45 return std::string(LibPath);
46}
47
48void RuntimeLibrary::loadLibrary(StringRef LibPath, BOLTLinker &Linker,
49 BOLTLinker::SectionsMapper MapSections) {
50 ErrorOr<std::unique_ptr<MemoryBuffer>> MaybeBuf =
51 MemoryBuffer::getFile(Filename: LibPath, IsText: false, RequiresNullTerminator: false);
52 check_error(EC: MaybeBuf.getError(), Message: LibPath);
53 std::unique_ptr<MemoryBuffer> B = std::move(MaybeBuf.get());
54 file_magic Magic = identify_magic(magic: B->getBuffer());
55
56 if (Magic == file_magic::archive) {
57 Error Err = Error::success();
58 object::Archive Archive(B.get()->getMemBufferRef(), Err);
59 for (const object::Archive::Child &C : Archive.children(Err)) {
60 std::unique_ptr<object::Binary> Bin = cantFail(ValOrErr: C.getAsBinary());
61 if (object::ObjectFile *Obj = dyn_cast<object::ObjectFile>(Val: &*Bin))
62 Linker.loadObject(Obj: Obj->getMemoryBufferRef(), MapSections);
63 }
64 check_error(E: std::move(Err), Message: B->getBufferIdentifier());
65 } else if (Magic == file_magic::elf_relocatable ||
66 Magic == file_magic::elf_shared_object) {
67 std::unique_ptr<object::ObjectFile> Obj = cantFail(
68 ValOrErr: object::ObjectFile::createObjectFile(Object: B.get()->getMemBufferRef()),
69 Msg: "error creating in-memory object");
70 Linker.loadObject(Obj: Obj->getMemoryBufferRef(), MapSections);
71 } else {
72 errs() << "BOLT-ERROR: unrecognized library format: " << LibPath << "\n";
73 exit(status: 1);
74 }
75}
76

source code of bolt/lib/RuntimeLibs/RuntimeLibrary.cpp