brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.0 KiB · 4f01c01 Raw
138 lines · cpp
1//===------- LoadLinkableFile.cpp -- Load relocatables and archives -------===//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#include "llvm/ExecutionEngine/Orc/LoadLinkableFile.h"10 11#include "llvm/ADT/ScopeExit.h"12#include "llvm/BinaryFormat/Magic.h"13#include "llvm/ExecutionEngine/Orc/MachO.h"14#include "llvm/Support/FileSystem.h"15 16#define DEBUG_TYPE "orc"17 18namespace llvm {19namespace orc {20 21static Expected<std::unique_ptr<MemoryBuffer>>22checkCOFFRelocatableObject(std::unique_ptr<MemoryBuffer> Obj,23                           const Triple &TT) {24  // TODO: Actually check the architecture of the file.25  return std::move(Obj);26}27 28static Expected<std::unique_ptr<MemoryBuffer>>29checkXCOFFRelocatableObject(std::unique_ptr<MemoryBuffer> Obj,30                            const Triple &TT) {31  // TODO: Actually check the architecture of the file.32  return std::move(Obj);33}34 35static Expected<std::unique_ptr<MemoryBuffer>>36checkELFRelocatableObject(std::unique_ptr<MemoryBuffer> Obj, const Triple &TT) {37  // TODO: Actually check the architecture of the file.38  return std::move(Obj);39}40 41Expected<std::pair<std::unique_ptr<MemoryBuffer>, LinkableFileKind>>42loadLinkableFile(StringRef Path, const Triple &TT, LoadArchives LA,43                 std::optional<StringRef> IdentifierOverride) {44  if (!IdentifierOverride)45    IdentifierOverride = Path;46 47  Expected<sys::fs::file_t> FDOrErr =48      sys::fs::openNativeFileForRead(Path, sys::fs::OF_None);49  if (!FDOrErr)50    return createFileError(Path, FDOrErr.takeError());51  sys::fs::file_t FD = *FDOrErr;52  auto CloseFile = make_scope_exit([&]() { sys::fs::closeFile(FD); });53 54  auto Buf =55      MemoryBuffer::getOpenFile(FD, *IdentifierOverride, /*FileSize=*/-1);56  if (!Buf)57    return make_error<StringError>(58        StringRef("Could not load object at path ") + Path, Buf.getError());59 60  std::optional<Triple::ObjectFormatType> RequireFormat;61  if (TT.getObjectFormat() != Triple::UnknownObjectFormat)62    RequireFormat = TT.getObjectFormat();63 64  switch (identify_magic((*Buf)->getBuffer())) {65  case file_magic::archive:66    if (LA != LoadArchives::Never)67      return std::make_pair(std::move(*Buf), LinkableFileKind::Archive);68    return make_error<StringError>(69        Path + " does not contain a relocatable object file",70        inconvertibleErrorCode());71  case file_magic::coff_object:72    if (LA == LoadArchives::Required)73      return make_error<StringError>(Path + " does not contain an archive",74                                     inconvertibleErrorCode());75 76    if (!RequireFormat || *RequireFormat == Triple::COFF) {77      auto CheckedBuf = checkCOFFRelocatableObject(std::move(*Buf), TT);78      if (!CheckedBuf)79        return CheckedBuf.takeError();80      return std::make_pair(std::move(*CheckedBuf),81                            LinkableFileKind::RelocatableObject);82    }83    break;84  case file_magic::elf_relocatable:85    if (LA == LoadArchives::Required)86      return make_error<StringError>(Path + " does not contain an archive",87                                     inconvertibleErrorCode());88 89    if (!RequireFormat || *RequireFormat == Triple::ELF) {90      auto CheckedBuf = checkELFRelocatableObject(std::move(*Buf), TT);91      if (!CheckedBuf)92        return CheckedBuf.takeError();93      return std::make_pair(std::move(*CheckedBuf),94                            LinkableFileKind::RelocatableObject);95    }96    break;97  case file_magic::macho_object:98    if (LA == LoadArchives::Required)99      return make_error<StringError>(Path + " does not contain an archive",100                                     inconvertibleErrorCode());101 102    if (!RequireFormat || *RequireFormat == Triple::MachO) {103      auto CheckedBuf = checkMachORelocatableObject(std::move(*Buf), TT, false);104      if (!CheckedBuf)105        return CheckedBuf.takeError();106      return std::make_pair(std::move(*CheckedBuf),107                            LinkableFileKind::RelocatableObject);108    }109    break;110  case file_magic::macho_universal_binary:111    if (!RequireFormat || *RequireFormat == Triple::MachO)112      return loadLinkableSliceFromMachOUniversalBinary(113          FD, std::move(*Buf), TT, LA, Path, *IdentifierOverride);114    break;115  case file_magic::xcoff_object_64:116    if (!RequireFormat || *RequireFormat == Triple::XCOFF) {117      auto CheckedBuf = checkXCOFFRelocatableObject(std::move(*Buf), TT);118      if (!CheckedBuf)119        return CheckedBuf.takeError();120      return std::make_pair(std::move(*CheckedBuf),121                            LinkableFileKind::RelocatableObject);122    }123    break;124  default:125    break;126  }127 128  return make_error<StringError>(129      Path +130          " does not contain a relocatable object file or archive compatible "131          "with " +132          TT.str(),133      inconvertibleErrorCode());134}135 136} // End namespace orc.137} // End namespace llvm.138