1*0b57cec5SDimitry Andric //===-------------- MachO.cpp - JIT linker function for MachO -------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // The LLVM Compiler Infrastructure 4*0b57cec5SDimitry Andric // 5*0b57cec5SDimitry Andric // This file is distributed under the University of Illinois Open Source 6*0b57cec5SDimitry Andric // License. See LICENSE.TXT for details. 7*0b57cec5SDimitry Andric // 8*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 9*0b57cec5SDimitry Andric // 10*0b57cec5SDimitry Andric // MachO jit-link function. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITLink/MachO.h" 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "llvm/BinaryFormat/MachO.h" 17*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITLink/MachO_x86_64.h" 18*0b57cec5SDimitry Andric #include "llvm/Support/Endian.h" 19*0b57cec5SDimitry Andric #include "llvm/Support/Format.h" 20*0b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric using namespace llvm; 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric #define DEBUG_TYPE "jitlink" 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric namespace llvm { 27*0b57cec5SDimitry Andric namespace jitlink { 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric void jitLink_MachO(std::unique_ptr<JITLinkContext> Ctx) { 30*0b57cec5SDimitry Andric 31*0b57cec5SDimitry Andric // We don't want to do full MachO validation here. Just parse enough of the 32*0b57cec5SDimitry Andric // header to find out what MachO linker to use. 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric StringRef Data = Ctx->getObjectBuffer().getBuffer(); 35*0b57cec5SDimitry Andric if (Data.size() < 4) { 36*0b57cec5SDimitry Andric Ctx->notifyFailed(make_error<JITLinkError>("Truncated MachO buffer")); 37*0b57cec5SDimitry Andric return; 38*0b57cec5SDimitry Andric } 39*0b57cec5SDimitry Andric 40*0b57cec5SDimitry Andric uint32_t Magic; 41*0b57cec5SDimitry Andric memcpy(&Magic, Data.data(), sizeof(uint32_t)); 42*0b57cec5SDimitry Andric LLVM_DEBUG({ 43*0b57cec5SDimitry Andric dbgs() << "jitLink_MachO: magic = " << format("0x%08" PRIx32, Magic) 44*0b57cec5SDimitry Andric << ", identifier = \"" 45*0b57cec5SDimitry Andric << Ctx->getObjectBuffer().getBufferIdentifier() << "\"\n"; 46*0b57cec5SDimitry Andric }); 47*0b57cec5SDimitry Andric 48*0b57cec5SDimitry Andric if (Magic == MachO::MH_MAGIC || Magic == MachO::MH_CIGAM) { 49*0b57cec5SDimitry Andric Ctx->notifyFailed( 50*0b57cec5SDimitry Andric make_error<JITLinkError>("MachO 32-bit platforms not supported")); 51*0b57cec5SDimitry Andric return; 52*0b57cec5SDimitry Andric } else if (Magic == MachO::MH_MAGIC_64 || Magic == MachO::MH_CIGAM_64) { 53*0b57cec5SDimitry Andric MachO::mach_header_64 Header; 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric memcpy(&Header, Data.data(), sizeof(MachO::mach_header_64)); 56*0b57cec5SDimitry Andric if (Magic == MachO::MH_CIGAM_64) 57*0b57cec5SDimitry Andric swapStruct(Header); 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric LLVM_DEBUG({ 60*0b57cec5SDimitry Andric dbgs() << "jitLink_MachO: cputype = " 61*0b57cec5SDimitry Andric << format("0x%08" PRIx32, Header.cputype) 62*0b57cec5SDimitry Andric << ", cpusubtype = " << format("0x%08" PRIx32, Header.cpusubtype) 63*0b57cec5SDimitry Andric << "\n"; 64*0b57cec5SDimitry Andric }); 65*0b57cec5SDimitry Andric 66*0b57cec5SDimitry Andric switch (Header.cputype) { 67*0b57cec5SDimitry Andric case MachO::CPU_TYPE_X86_64: 68*0b57cec5SDimitry Andric return jitLink_MachO_x86_64(std::move(Ctx)); 69*0b57cec5SDimitry Andric } 70*0b57cec5SDimitry Andric Ctx->notifyFailed(make_error<JITLinkError>("MachO-64 CPU type not valid")); 71*0b57cec5SDimitry Andric return; 72*0b57cec5SDimitry Andric } 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric Ctx->notifyFailed(make_error<JITLinkError>("MachO magic not valid")); 75*0b57cec5SDimitry Andric } 76*0b57cec5SDimitry Andric 77*0b57cec5SDimitry Andric } // end namespace jitlink 78*0b57cec5SDimitry Andric } // end namespace llvm 79