Skip to content

Commit

Permalink
[JITLink][ELF] Route objects to their matching linker backends based …
Browse files Browse the repository at this point in the history
…on header info

Distinguish objects by target properties address size, endian and machine architecture. So far we only
support x86-64 (ELFCLASS64, ELFDATA2LSB, EM_X86_64).

Reviewed By: lhames

Differential Revision: https://reviews.llvm.org/D90860
  • Loading branch information
weliveindetail committed Dec 8, 2020
1 parent 2d1b024 commit 83b52b5
Showing 1 changed file with 43 additions and 10 deletions.
53 changes: 43 additions & 10 deletions llvm/lib/ExecutionEngine/JITLink/ELF.cpp
Expand Up @@ -15,6 +15,7 @@

#include "llvm/BinaryFormat/ELF.h"
#include "llvm/ExecutionEngine/JITLink/ELF_x86_64.h"
#include "llvm/Object/ELF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
Expand All @@ -27,24 +28,56 @@ using namespace llvm;
namespace llvm {
namespace jitlink {

void jitLink_ELF(std::unique_ptr<JITLinkContext> Ctx) {
Expected<uint16_t> readTargetMachineArch(StringRef Buffer) {
const char *Data = Buffer.data();

// We don't want to do full ELF validation here. We just verify it is elf'ish.
// Probably should parse into an elf header when we support more than x86 :)
if (Data[ELF::EI_DATA] == ELF::ELFDATA2LSB) {
if (Data[ELF::EI_CLASS] == ELF::ELFCLASS64) {
if (auto File = llvm::object::ELF64LEFile::create(Buffer)) {
return File->getHeader().e_machine;
} else {
return File.takeError();
}
} else if (Data[ELF::EI_CLASS] == ELF::ELFCLASS32) {
if (auto File = llvm::object::ELF32LEFile::create(Buffer)) {
return File->getHeader().e_machine;
} else {
return File.takeError();
}
}
}

StringRef Data = Ctx->getObjectBuffer().getBuffer();
if (Data.size() < llvm::ELF::EI_MAG3 + 1) {
return ELF::EM_NONE;
}

void jitLink_ELF(std::unique_ptr<JITLinkContext> Ctx) {
StringRef Buffer = Ctx->getObjectBuffer().getBuffer();
if (Buffer.size() < ELF::EI_MAG3 + 1) {
Ctx->notifyFailed(make_error<JITLinkError>("Truncated ELF buffer"));
return;
}

if (!memcmp(Data.data(), llvm::ELF::ElfMagic, strlen(llvm::ELF::ElfMagic))) {
if (Data.data()[llvm::ELF::EI_CLASS] == ELF::ELFCLASS64) {
return jitLink_ELF_x86_64(std::move(Ctx));
}
if (memcmp(Buffer.data(), ELF::ElfMagic, strlen(ELF::ElfMagic)) != 0) {
Ctx->notifyFailed(make_error<JITLinkError>("ELF magic not valid"));
return;
}

Expected<uint16_t> TargetMachineArch = readTargetMachineArch(Buffer);
if (!TargetMachineArch) {
Ctx->notifyFailed(TargetMachineArch.takeError());
return;
}

Ctx->notifyFailed(make_error<JITLinkError>("ELF magic not valid"));
switch (*TargetMachineArch) {
case ELF::EM_X86_64:
jitLink_ELF_x86_64(std::move(Ctx));
return;
default:
Ctx->notifyFailed(make_error<JITLinkError>(
"Unsupported target machine architecture in ELF object " +
Ctx->getObjectBuffer().getBufferIdentifier()));
return;
}
}

} // end namespace jitlink
Expand Down

0 comments on commit 83b52b5

Please sign in to comment.