1 //===--- RuntimeLibrary.cpp - The 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 //===----------------------------------------------------------------------===// 10 11 #include "bolt/RuntimeLibs/RuntimeLibrary.h" 12 #include "bolt/Utils/Utils.h" 13 #include "llvm/BinaryFormat/Magic.h" 14 #include "llvm/ExecutionEngine/RuntimeDyld.h" 15 #include "llvm/Object/Archive.h" 16 #include "llvm/Support/Path.h" 17 18 #undef DEBUG_TYPE 19 #define DEBUG_TYPE "bolt-rtlib" 20 21 using namespace llvm; 22 using namespace bolt; 23 24 void RuntimeLibrary::anchor() {} 25 26 std::string RuntimeLibrary::getLibPath(StringRef ToolPath, 27 StringRef LibFileName) { 28 StringRef Dir = llvm::sys::path::parent_path(ToolPath); 29 SmallString<128> LibPath = llvm::sys::path::parent_path(Dir); 30 llvm::sys::path::append(LibPath, "lib"); 31 if (!llvm::sys::fs::exists(LibPath)) { 32 // In some cases we install bolt binary into one level deeper in bin/, 33 // we need to go back one more level to find lib directory. 34 LibPath = 35 llvm::sys::path::parent_path(llvm::sys::path::parent_path(Dir)); 36 llvm::sys::path::append(LibPath, "lib"); 37 } 38 llvm::sys::path::append(LibPath, LibFileName); 39 if (!llvm::sys::fs::exists(LibPath)) { 40 errs() << "BOLT-ERROR: library not found: " << LibPath << "\n"; 41 exit(1); 42 } 43 return std::string(LibPath.str()); 44 } 45 46 void RuntimeLibrary::loadLibrary(StringRef LibPath, RuntimeDyld &RTDyld) { 47 ErrorOr<std::unique_ptr<MemoryBuffer>> MaybeBuf = 48 MemoryBuffer::getFile(LibPath, -1, false); 49 check_error(MaybeBuf.getError(), LibPath); 50 std::unique_ptr<MemoryBuffer> B = std::move(MaybeBuf.get()); 51 file_magic Magic = identify_magic(B->getBuffer()); 52 53 if (Magic == file_magic::archive) { 54 Error Err = Error::success(); 55 object::Archive Archive(B.get()->getMemBufferRef(), Err); 56 for (const object::Archive::Child &C : Archive.children(Err)) { 57 std::unique_ptr<object::Binary> Bin = cantFail(C.getAsBinary()); 58 if (object::ObjectFile *Obj = dyn_cast<object::ObjectFile>(&*Bin)) { 59 RTDyld.loadObject(*Obj); 60 } 61 } 62 check_error(std::move(Err), B->getBufferIdentifier()); 63 } else if (Magic == file_magic::elf_relocatable || 64 Magic == file_magic::elf_shared_object) { 65 std::unique_ptr<object::ObjectFile> Obj = cantFail( 66 object::ObjectFile::createObjectFile(B.get()->getMemBufferRef()), 67 "error creating in-memory object"); 68 RTDyld.loadObject(*Obj); 69 } else { 70 errs() << "BOLT-ERROR: unrecognized library format: " << LibPath << "\n"; 71 exit(1); 72 } 73 } 74