Path: blob/main/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/ELF.cpp
35271 views
//===-------------- ELF.cpp - JIT linker function for ELF -------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// ELF jit-link function.9//10//===----------------------------------------------------------------------===//1112#include "llvm/ExecutionEngine/JITLink/ELF.h"1314#include "llvm/BinaryFormat/ELF.h"15#include "llvm/ExecutionEngine/JITLink/ELF_aarch32.h"16#include "llvm/ExecutionEngine/JITLink/ELF_aarch64.h"17#include "llvm/ExecutionEngine/JITLink/ELF_i386.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_x86_64.h"22#include "llvm/Object/ELF.h"23#include "llvm/Support/Format.h"24#include "llvm/Support/MemoryBuffer.h"25#include <cstring>2627using namespace llvm;2829#define DEBUG_TYPE "jitlink"3031namespace llvm {32namespace jitlink {3334Expected<uint16_t> readTargetMachineArch(StringRef Buffer) {35const char *Data = Buffer.data();3637if (Data[ELF::EI_DATA] == ELF::ELFDATA2LSB) {38if (Data[ELF::EI_CLASS] == ELF::ELFCLASS64) {39if (auto File = llvm::object::ELF64LEFile::create(Buffer)) {40return File->getHeader().e_machine;41} else {42return File.takeError();43}44} else if (Data[ELF::EI_CLASS] == ELF::ELFCLASS32) {45if (auto File = llvm::object::ELF32LEFile::create(Buffer)) {46return File->getHeader().e_machine;47} else {48return File.takeError();49}50}51}5253if (Data[ELF::EI_DATA] == ELF::ELFDATA2MSB) {54if (Data[ELF::EI_CLASS] == ELF::ELFCLASS64) {55if (auto File = llvm::object::ELF64BEFile::create(Buffer)) {56return File->getHeader().e_machine;57} else {58return File.takeError();59}60} else if (Data[ELF::EI_CLASS] == ELF::ELFCLASS32) {61if (auto File = llvm::object::ELF32BEFile::create(Buffer)) {62return File->getHeader().e_machine;63} else {64return File.takeError();65}66}67}6869return ELF::EM_NONE;70}7172Expected<std::unique_ptr<LinkGraph>>73createLinkGraphFromELFObject(MemoryBufferRef ObjectBuffer) {74StringRef Buffer = ObjectBuffer.getBuffer();75if (Buffer.size() < ELF::EI_NIDENT)76return make_error<JITLinkError>("Truncated ELF buffer");7778if (memcmp(Buffer.data(), ELF::ElfMagic, strlen(ELF::ElfMagic)) != 0)79return make_error<JITLinkError>("ELF magic not valid");8081uint8_t DataEncoding = Buffer.data()[ELF::EI_DATA];82Expected<uint16_t> TargetMachineArch = readTargetMachineArch(Buffer);83if (!TargetMachineArch)84return TargetMachineArch.takeError();8586switch (*TargetMachineArch) {87case ELF::EM_AARCH64:88return createLinkGraphFromELFObject_aarch64(ObjectBuffer);89case ELF::EM_ARM:90return createLinkGraphFromELFObject_aarch32(ObjectBuffer);91case ELF::EM_LOONGARCH:92return createLinkGraphFromELFObject_loongarch(ObjectBuffer);93case ELF::EM_PPC64: {94if (DataEncoding == ELF::ELFDATA2LSB)95return createLinkGraphFromELFObject_ppc64le(ObjectBuffer);96else97return createLinkGraphFromELFObject_ppc64(ObjectBuffer);98}99case ELF::EM_RISCV:100return createLinkGraphFromELFObject_riscv(ObjectBuffer);101case ELF::EM_X86_64:102return createLinkGraphFromELFObject_x86_64(ObjectBuffer);103case ELF::EM_386:104return createLinkGraphFromELFObject_i386(ObjectBuffer);105default:106return make_error<JITLinkError>(107"Unsupported target machine architecture in ELF object " +108ObjectBuffer.getBufferIdentifier());109}110}111112void link_ELF(std::unique_ptr<LinkGraph> G,113std::unique_ptr<JITLinkContext> Ctx) {114switch (G->getTargetTriple().getArch()) {115case Triple::aarch64:116link_ELF_aarch64(std::move(G), std::move(Ctx));117return;118case Triple::arm:119case Triple::armeb:120case Triple::thumb:121case Triple::thumbeb:122link_ELF_aarch32(std::move(G), std::move(Ctx));123return;124case Triple::loongarch32:125case Triple::loongarch64:126link_ELF_loongarch(std::move(G), std::move(Ctx));127return;128case Triple::ppc64:129link_ELF_ppc64(std::move(G), std::move(Ctx));130return;131case Triple::ppc64le:132link_ELF_ppc64le(std::move(G), std::move(Ctx));133return;134case Triple::riscv32:135case Triple::riscv64:136link_ELF_riscv(std::move(G), std::move(Ctx));137return;138case Triple::x86_64:139link_ELF_x86_64(std::move(G), std::move(Ctx));140return;141case Triple::x86:142link_ELF_i386(std::move(G), std::move(Ctx));143return;144default:145Ctx->notifyFailed(make_error<JITLinkError>(146"Unsupported target machine architecture in ELF link graph " +147G->getName()));148return;149}150}151152} // end namespace jitlink153} // end namespace llvm154155156