brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.2 KiB · 42f42ee Raw
160 lines · cpp
1//===-------------- ELF.cpp - JIT linker function for ELF -------------===//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// ELF jit-link function.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/ExecutionEngine/JITLink/ELF.h"14 15#include "llvm/BinaryFormat/ELF.h"16#include "llvm/ExecutionEngine/JITLink/ELF_aarch32.h"17#include "llvm/ExecutionEngine/JITLink/ELF_aarch64.h"18#include "llvm/ExecutionEngine/JITLink/ELF_loongarch.h"19#include "llvm/ExecutionEngine/JITLink/ELF_ppc64.h"20#include "llvm/ExecutionEngine/JITLink/ELF_riscv.h"21#include "llvm/ExecutionEngine/JITLink/ELF_systemz.h"22#include "llvm/ExecutionEngine/JITLink/ELF_x86.h"23#include "llvm/ExecutionEngine/JITLink/ELF_x86_64.h"24#include "llvm/Object/ELF.h"25#include <cstring>26 27using namespace llvm;28 29#define DEBUG_TYPE "jitlink"30 31namespace llvm {32namespace jitlink {33 34Expected<uint16_t> readTargetMachineArch(StringRef Buffer) {35  const char *Data = Buffer.data();36 37  if (Data[ELF::EI_DATA] == ELF::ELFDATA2LSB) {38    if (Data[ELF::EI_CLASS] == ELF::ELFCLASS64) {39      if (auto File = llvm::object::ELF64LEFile::create(Buffer)) {40        return File->getHeader().e_machine;41      } else {42        return File.takeError();43      }44    } else if (Data[ELF::EI_CLASS] == ELF::ELFCLASS32) {45      if (auto File = llvm::object::ELF32LEFile::create(Buffer)) {46        return File->getHeader().e_machine;47      } else {48        return File.takeError();49      }50    }51  }52 53  if (Data[ELF::EI_DATA] == ELF::ELFDATA2MSB) {54    if (Data[ELF::EI_CLASS] == ELF::ELFCLASS64) {55      if (auto File = llvm::object::ELF64BEFile::create(Buffer)) {56        return File->getHeader().e_machine;57      } else {58        return File.takeError();59      }60    } else if (Data[ELF::EI_CLASS] == ELF::ELFCLASS32) {61      if (auto File = llvm::object::ELF32BEFile::create(Buffer)) {62        return File->getHeader().e_machine;63      } else {64        return File.takeError();65      }66    }67  }68 69  return ELF::EM_NONE;70}71 72Expected<std::unique_ptr<LinkGraph>>73createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer,74                             std::shared_ptr<orc::SymbolStringPool> SSP) {75  StringRef Buffer = ObjectBuffer.getBuffer();76  if (Buffer.size() < ELF::EI_NIDENT)77    return make_error<JITLinkError>("Truncated ELF buffer");78 79  if (memcmp(Buffer.data(), ELF::ElfMagic, strlen(ELF::ElfMagic)) != 0)80    return make_error<JITLinkError>("ELF magic not valid");81 82  uint8_t DataEncoding = Buffer.data()[ELF::EI_DATA];83  Expected<uint16_t> TargetMachineArch = readTargetMachineArch(Buffer);84  if (!TargetMachineArch)85    return TargetMachineArch.takeError();86 87  switch (*TargetMachineArch) {88  case ELF::EM_AARCH64:89    return createLinkGraphFromELFObject_aarch64(ObjectBuffer, std::move(SSP));90  case ELF::EM_ARM:91    return createLinkGraphFromELFObject_aarch32(ObjectBuffer, std::move(SSP));92  case ELF::EM_PPC64: {93    if (DataEncoding == ELF::ELFDATA2LSB)94      return createLinkGraphFromELFObject_ppc64le(ObjectBuffer, std::move(SSP));95    else96      return createLinkGraphFromELFObject_ppc64(ObjectBuffer, std::move(SSP));97  }98  case ELF::EM_LOONGARCH:99    return createLinkGraphFromELFObject_loongarch(ObjectBuffer, std::move(SSP));100  case ELF::EM_RISCV:101    return createLinkGraphFromELFObject_riscv(ObjectBuffer, std::move(SSP));102  case ELF::EM_S390:103    return createLinkGraphFromELFObject_systemz(ObjectBuffer, std::move(SSP));104  case ELF::EM_X86_64:105    return createLinkGraphFromELFObject_x86_64(ObjectBuffer, std::move(SSP));106  case ELF::EM_386:107    return createLinkGraphFromELFObject_x86(ObjectBuffer, std::move(SSP));108  default:109    return make_error<JITLinkError>(110        "Unsupported target machine architecture in ELF object " +111        ObjectBuffer.getBufferIdentifier());112  }113}114 115void link_ELF(std::unique_ptr<LinkGraph> G,116              std::unique_ptr<JITLinkContext> Ctx) {117  switch (G->getTargetTriple().getArch()) {118  case Triple::aarch64:119    link_ELF_aarch64(std::move(G), std::move(Ctx));120    return;121  case Triple::arm:122  case Triple::armeb:123  case Triple::thumb:124  case Triple::thumbeb:125    link_ELF_aarch32(std::move(G), std::move(Ctx));126    return;127  case Triple::loongarch32:128  case Triple::loongarch64:129    link_ELF_loongarch(std::move(G), std::move(Ctx));130    return;131  case Triple::ppc64:132    link_ELF_ppc64(std::move(G), std::move(Ctx));133    return;134  case Triple::ppc64le:135    link_ELF_ppc64le(std::move(G), std::move(Ctx));136    return;137  case Triple::riscv32:138  case Triple::riscv64:139    link_ELF_riscv(std::move(G), std::move(Ctx));140    return;141  case Triple::systemz:142    link_ELF_systemz(std::move(G), std::move(Ctx));143    return;144  case Triple::x86_64:145    link_ELF_x86_64(std::move(G), std::move(Ctx));146    return;147  case Triple::x86:148    link_ELF_x86(std::move(G), std::move(Ctx));149    return;150  default:151    Ctx->notifyFailed(make_error<JITLinkError>(152        "Unsupported target machine architecture in ELF link graph " +153        G->getName()));154    return;155  }156}157 158} // end namespace jitlink159} // end namespace llvm160