1351278Sdim//===-------------- MachO.cpp - JIT linker function for MachO -------------===// 2351278Sdim// 3351278Sdim// The LLVM Compiler Infrastructure 4351278Sdim// 5351278Sdim// This file is distributed under the University of Illinois Open Source 6351278Sdim// License. See LICENSE.TXT for details. 7351278Sdim// 8351278Sdim//===----------------------------------------------------------------------===// 9351278Sdim// 10351278Sdim// MachO jit-link function. 11351278Sdim// 12351278Sdim//===----------------------------------------------------------------------===// 13351278Sdim 14351278Sdim#include "llvm/ExecutionEngine/JITLink/MachO.h" 15351278Sdim 16351278Sdim#include "llvm/BinaryFormat/MachO.h" 17360784Sdim#include "llvm/ExecutionEngine/JITLink/MachO_arm64.h" 18351278Sdim#include "llvm/ExecutionEngine/JITLink/MachO_x86_64.h" 19351278Sdim#include "llvm/Support/Endian.h" 20351278Sdim#include "llvm/Support/Format.h" 21351278Sdim#include "llvm/Support/MemoryBuffer.h" 22351278Sdim 23351278Sdimusing namespace llvm; 24351278Sdim 25351278Sdim#define DEBUG_TYPE "jitlink" 26351278Sdim 27351278Sdimnamespace llvm { 28351278Sdimnamespace jitlink { 29351278Sdim 30351278Sdimvoid jitLink_MachO(std::unique_ptr<JITLinkContext> Ctx) { 31351278Sdim 32351278Sdim // We don't want to do full MachO validation here. Just parse enough of the 33351278Sdim // header to find out what MachO linker to use. 34351278Sdim 35351278Sdim StringRef Data = Ctx->getObjectBuffer().getBuffer(); 36351278Sdim if (Data.size() < 4) { 37351278Sdim Ctx->notifyFailed(make_error<JITLinkError>("Truncated MachO buffer")); 38351278Sdim return; 39351278Sdim } 40351278Sdim 41351278Sdim uint32_t Magic; 42351278Sdim memcpy(&Magic, Data.data(), sizeof(uint32_t)); 43351278Sdim LLVM_DEBUG({ 44351278Sdim dbgs() << "jitLink_MachO: magic = " << format("0x%08" PRIx32, Magic) 45351278Sdim << ", identifier = \"" 46351278Sdim << Ctx->getObjectBuffer().getBufferIdentifier() << "\"\n"; 47351278Sdim }); 48351278Sdim 49351278Sdim if (Magic == MachO::MH_MAGIC || Magic == MachO::MH_CIGAM) { 50351278Sdim Ctx->notifyFailed( 51351278Sdim make_error<JITLinkError>("MachO 32-bit platforms not supported")); 52351278Sdim return; 53351278Sdim } else if (Magic == MachO::MH_MAGIC_64 || Magic == MachO::MH_CIGAM_64) { 54351278Sdim MachO::mach_header_64 Header; 55351278Sdim 56351278Sdim memcpy(&Header, Data.data(), sizeof(MachO::mach_header_64)); 57351278Sdim if (Magic == MachO::MH_CIGAM_64) 58351278Sdim swapStruct(Header); 59351278Sdim 60351278Sdim LLVM_DEBUG({ 61351278Sdim dbgs() << "jitLink_MachO: cputype = " 62351278Sdim << format("0x%08" PRIx32, Header.cputype) 63351278Sdim << ", cpusubtype = " << format("0x%08" PRIx32, Header.cpusubtype) 64351278Sdim << "\n"; 65351278Sdim }); 66351278Sdim 67351278Sdim switch (Header.cputype) { 68360784Sdim case MachO::CPU_TYPE_ARM64: 69360784Sdim return jitLink_MachO_arm64(std::move(Ctx)); 70351278Sdim case MachO::CPU_TYPE_X86_64: 71351278Sdim return jitLink_MachO_x86_64(std::move(Ctx)); 72351278Sdim } 73351278Sdim Ctx->notifyFailed(make_error<JITLinkError>("MachO-64 CPU type not valid")); 74351278Sdim return; 75351278Sdim } 76351278Sdim 77351278Sdim Ctx->notifyFailed(make_error<JITLinkError>("MachO magic not valid")); 78351278Sdim} 79351278Sdim 80351278Sdim} // end namespace jitlink 81351278Sdim} // end namespace llvm 82