15
15
16
16
#include " llvm/BinaryFormat/ELF.h"
17
17
#include " llvm/ExecutionEngine/JITLink/ELF_x86_64.h"
18
+ #include " llvm/Object/ELF.h"
18
19
#include " llvm/Support/Endian.h"
19
20
#include " llvm/Support/Format.h"
20
21
#include " llvm/Support/MemoryBuffer.h"
@@ -27,24 +28,56 @@ using namespace llvm;
27
28
namespace llvm {
28
29
namespace jitlink {
29
30
30
- void jitLink_ELF (std::unique_ptr<JITLinkContext> Ctx) {
31
+ Expected<uint16_t > readTargetMachineArch (StringRef Buffer) {
32
+ const char *Data = Buffer.data ();
31
33
32
- // We don't want to do full ELF validation here. We just verify it is elf'ish.
33
- // Probably should parse into an elf header when we support more than x86 :)
34
+ if (Data[ELF::EI_DATA] == ELF::ELFDATA2LSB) {
35
+ if (Data[ELF::EI_CLASS] == ELF::ELFCLASS64) {
36
+ if (auto File = llvm::object::ELF64LEFile::create (Buffer)) {
37
+ return File->getHeader ().e_machine ;
38
+ } else {
39
+ return File.takeError ();
40
+ }
41
+ } else if (Data[ELF::EI_CLASS] == ELF::ELFCLASS32) {
42
+ if (auto File = llvm::object::ELF32LEFile::create (Buffer)) {
43
+ return File->getHeader ().e_machine ;
44
+ } else {
45
+ return File.takeError ();
46
+ }
47
+ }
48
+ }
34
49
35
- StringRef Data = Ctx->getObjectBuffer ().getBuffer ();
36
- if (Data.size () < llvm::ELF::EI_MAG3 + 1 ) {
50
+ return ELF::EM_NONE;
51
+ }
52
+
53
+ void jitLink_ELF (std::unique_ptr<JITLinkContext> Ctx) {
54
+ StringRef Buffer = Ctx->getObjectBuffer ().getBuffer ();
55
+ if (Buffer.size () < ELF::EI_MAG3 + 1 ) {
37
56
Ctx->notifyFailed (make_error<JITLinkError>(" Truncated ELF buffer" ));
38
57
return ;
39
58
}
40
59
41
- if (!memcmp (Data.data (), llvm::ELF::ElfMagic, strlen (llvm::ELF::ElfMagic))) {
42
- if (Data.data ()[llvm::ELF::EI_CLASS] == ELF::ELFCLASS64) {
43
- return jitLink_ELF_x86_64 (std::move (Ctx));
44
- }
60
+ if (memcmp (Buffer.data (), ELF::ElfMagic, strlen (ELF::ElfMagic)) != 0 ) {
61
+ Ctx->notifyFailed (make_error<JITLinkError>(" ELF magic not valid" ));
62
+ return ;
63
+ }
64
+
65
+ Expected<uint16_t > TargetMachineArch = readTargetMachineArch (Buffer);
66
+ if (!TargetMachineArch) {
67
+ Ctx->notifyFailed (TargetMachineArch.takeError ());
68
+ return ;
45
69
}
46
70
47
- Ctx->notifyFailed (make_error<JITLinkError>(" ELF magic not valid" ));
71
+ switch (*TargetMachineArch) {
72
+ case ELF::EM_X86_64:
73
+ jitLink_ELF_x86_64 (std::move (Ctx));
74
+ return ;
75
+ default :
76
+ Ctx->notifyFailed (make_error<JITLinkError>(
77
+ " Unsupported target machine architecture in ELF object " +
78
+ Ctx->getObjectBuffer ().getBufferIdentifier ()));
79
+ return ;
80
+ }
48
81
}
49
82
50
83
} // end namespace jitlink
0 commit comments