1 //===-------------- MachO.cpp - JIT linker function for MachO -------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // MachO jit-link function. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/ExecutionEngine/JITLink/MachO.h" 15 16 #include "llvm/BinaryFormat/MachO.h" 17 #include "llvm/ExecutionEngine/JITLink/MachO_arm64.h" 18 #include "llvm/ExecutionEngine/JITLink/MachO_x86_64.h" 19 #include "llvm/Support/Format.h" 20 #include "llvm/Support/MemoryBuffer.h" 21 #include "llvm/Support/SwapByteOrder.h" 22 23 using namespace llvm; 24 25 #define DEBUG_TYPE "jitlink" 26 27 namespace llvm { 28 namespace jitlink { 29 30 Expected<std::unique_ptr<LinkGraph>> 31 createLinkGraphFromMachOObject(MemoryBufferRef ObjectBuffer) { 32 StringRef Data = ObjectBuffer.getBuffer(); 33 if (Data.size() < 4) 34 return make_error<JITLinkError>("Truncated MachO buffer \"" + 35 ObjectBuffer.getBufferIdentifier() + "\""); 36 37 uint32_t Magic; 38 memcpy(&Magic, Data.data(), sizeof(uint32_t)); 39 LLVM_DEBUG({ 40 dbgs() << "jitLink_MachO: magic = " << format("0x%08" PRIx32, Magic) 41 << ", identifier = \"" << ObjectBuffer.getBufferIdentifier() 42 << "\"\n"; 43 }); 44 45 if (Magic == MachO::MH_MAGIC || Magic == MachO::MH_CIGAM) 46 return make_error<JITLinkError>("MachO 32-bit platforms not supported"); 47 else if (Magic == MachO::MH_MAGIC_64 || Magic == MachO::MH_CIGAM_64) { 48 49 if (Data.size() < sizeof(MachO::mach_header_64)) 50 return make_error<JITLinkError>("Truncated MachO buffer \"" + 51 ObjectBuffer.getBufferIdentifier() + 52 "\""); 53 54 // Read the CPU type from the header. 55 uint32_t CPUType; 56 memcpy(&CPUType, Data.data() + 4, sizeof(uint32_t)); 57 if (Magic == MachO::MH_CIGAM_64) 58 CPUType = ByteSwap_32(CPUType); 59 60 LLVM_DEBUG({ 61 dbgs() << "jitLink_MachO: cputype = " << format("0x%08" PRIx32, CPUType) 62 << "\n"; 63 }); 64 65 switch (CPUType) { 66 case MachO::CPU_TYPE_ARM64: 67 return createLinkGraphFromMachOObject_arm64(ObjectBuffer); 68 case MachO::CPU_TYPE_X86_64: 69 return createLinkGraphFromMachOObject_x86_64(ObjectBuffer); 70 } 71 return make_error<JITLinkError>("MachO-64 CPU type not valid"); 72 } else 73 return make_error<JITLinkError>("Unrecognized MachO magic value"); 74 } 75 76 void link_MachO(std::unique_ptr<LinkGraph> G, 77 std::unique_ptr<JITLinkContext> Ctx) { 78 79 switch (G->getTargetTriple().getArch()) { 80 case Triple::aarch64: 81 return link_MachO_arm64(std::move(G), std::move(Ctx)); 82 case Triple::x86_64: 83 return link_MachO_x86_64(std::move(G), std::move(Ctx)); 84 default: 85 Ctx->notifyFailed(make_error<JITLinkError>("MachO-64 CPU type not valid")); 86 return; 87 } 88 } 89 90 } // end namespace jitlink 91 } // end namespace llvm 92