10b57cec5SDimitry Andric //===-------------- MachO.cpp - JIT linker function for MachO -------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // The LLVM Compiler Infrastructure 40b57cec5SDimitry Andric // 50b57cec5SDimitry Andric // This file is distributed under the University of Illinois Open Source 60b57cec5SDimitry Andric // License. See LICENSE.TXT for details. 70b57cec5SDimitry Andric // 80b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 90b57cec5SDimitry Andric // 100b57cec5SDimitry Andric // MachO jit-link function. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITLink/MachO.h" 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "llvm/BinaryFormat/MachO.h" 178bcb0991SDimitry Andric #include "llvm/ExecutionEngine/JITLink/MachO_arm64.h" 180b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITLink/MachO_x86_64.h" 190b57cec5SDimitry Andric #include "llvm/Support/Format.h" 200b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 21*5ffd83dbSDimitry Andric #include "llvm/Support/SwapByteOrder.h" 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric using namespace llvm; 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric #define DEBUG_TYPE "jitlink" 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric namespace llvm { 280b57cec5SDimitry Andric namespace jitlink { 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric void jitLink_MachO(std::unique_ptr<JITLinkContext> Ctx) { 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric // We don't want to do full MachO validation here. Just parse enough of the 330b57cec5SDimitry Andric // header to find out what MachO linker to use. 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric StringRef Data = Ctx->getObjectBuffer().getBuffer(); 360b57cec5SDimitry Andric if (Data.size() < 4) { 37*5ffd83dbSDimitry Andric StringRef BufferName = Ctx->getObjectBuffer().getBufferIdentifier(); 38*5ffd83dbSDimitry Andric Ctx->notifyFailed(make_error<JITLinkError>("Truncated MachO buffer \"" + 39*5ffd83dbSDimitry Andric BufferName + "\"")); 400b57cec5SDimitry Andric return; 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric uint32_t Magic; 440b57cec5SDimitry Andric memcpy(&Magic, Data.data(), sizeof(uint32_t)); 450b57cec5SDimitry Andric LLVM_DEBUG({ 460b57cec5SDimitry Andric dbgs() << "jitLink_MachO: magic = " << format("0x%08" PRIx32, Magic) 470b57cec5SDimitry Andric << ", identifier = \"" 480b57cec5SDimitry Andric << Ctx->getObjectBuffer().getBufferIdentifier() << "\"\n"; 490b57cec5SDimitry Andric }); 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric if (Magic == MachO::MH_MAGIC || Magic == MachO::MH_CIGAM) { 520b57cec5SDimitry Andric Ctx->notifyFailed( 530b57cec5SDimitry Andric make_error<JITLinkError>("MachO 32-bit platforms not supported")); 540b57cec5SDimitry Andric return; 550b57cec5SDimitry Andric } else if (Magic == MachO::MH_MAGIC_64 || Magic == MachO::MH_CIGAM_64) { 560b57cec5SDimitry Andric 57*5ffd83dbSDimitry Andric if (Data.size() < sizeof(MachO::mach_header_64)) { 58*5ffd83dbSDimitry Andric StringRef BufferName = Ctx->getObjectBuffer().getBufferIdentifier(); 59*5ffd83dbSDimitry Andric Ctx->notifyFailed(make_error<JITLinkError>("Truncated MachO buffer \"" + 60*5ffd83dbSDimitry Andric BufferName + "\"")); 61*5ffd83dbSDimitry Andric return; 62*5ffd83dbSDimitry Andric } 63*5ffd83dbSDimitry Andric 64*5ffd83dbSDimitry Andric // Read the CPU type from the header. 65*5ffd83dbSDimitry Andric uint32_t CPUType; 66*5ffd83dbSDimitry Andric memcpy(&CPUType, Data.data() + 4, sizeof(uint32_t)); 670b57cec5SDimitry Andric if (Magic == MachO::MH_CIGAM_64) 68*5ffd83dbSDimitry Andric CPUType = ByteSwap_32(CPUType); 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric LLVM_DEBUG({ 71*5ffd83dbSDimitry Andric dbgs() << "jitLink_MachO: cputype = " << format("0x%08" PRIx32, CPUType) 720b57cec5SDimitry Andric << "\n"; 730b57cec5SDimitry Andric }); 740b57cec5SDimitry Andric 75*5ffd83dbSDimitry Andric switch (CPUType) { 768bcb0991SDimitry Andric case MachO::CPU_TYPE_ARM64: 778bcb0991SDimitry Andric return jitLink_MachO_arm64(std::move(Ctx)); 780b57cec5SDimitry Andric case MachO::CPU_TYPE_X86_64: 790b57cec5SDimitry Andric return jitLink_MachO_x86_64(std::move(Ctx)); 800b57cec5SDimitry Andric } 810b57cec5SDimitry Andric Ctx->notifyFailed(make_error<JITLinkError>("MachO-64 CPU type not valid")); 820b57cec5SDimitry Andric return; 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric Ctx->notifyFailed(make_error<JITLinkError>("MachO magic not valid")); 860b57cec5SDimitry Andric } 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric } // end namespace jitlink 890b57cec5SDimitry Andric } // end namespace llvm 90