[llvm] 83b52b5 - [JITLink][ELF] Route objects to their matching linker backends based on header info

Stefan Gränitz via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 8 01:56:33 PST 2020


Author: Stefan Gränitz
Date: 2020-12-08T10:56:01+01:00
New Revision: 83b52b5ba27815200e76343f2a2f1614bb1960d9

URL: https://github.com/llvm/llvm-project/commit/83b52b5ba27815200e76343f2a2f1614bb1960d9
DIFF: https://github.com/llvm/llvm-project/commit/83b52b5ba27815200e76343f2a2f1614bb1960d9.diff

LOG: [JITLink][ELF] Route objects to their matching linker backends based 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

Added: 
    

Modified: 
    llvm/lib/ExecutionEngine/JITLink/ELF.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/ExecutionEngine/JITLink/ELF.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF.cpp
index 6160583b13fe..19b878257709 100644
--- a/llvm/lib/ExecutionEngine/JITLink/ELF.cpp
+++ b/llvm/lib/ExecutionEngine/JITLink/ELF.cpp
@@ -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"
@@ -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


        


More information about the llvm-commits mailing list