xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/JITLink/MachO.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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