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