LLVM  14.0.0git
MachO.cpp
Go to the documentation of this file.
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 
14 
18 #include "llvm/Support/Format.h"
21 
22 using namespace llvm;
23 
24 #define DEBUG_TYPE "jitlink"
25 
26 namespace llvm {
27 namespace jitlink {
28 
31  StringRef Data = ObjectBuffer.getBuffer();
32  if (Data.size() < 4)
33  return make_error<JITLinkError>("Truncated MachO buffer \"" +
34  ObjectBuffer.getBufferIdentifier() + "\"");
35 
37  memcpy(&Magic, Data.data(), sizeof(uint32_t));
38  LLVM_DEBUG({
39  dbgs() << "jitLink_MachO: magic = " << format("0x%08" PRIx32, Magic)
40  << ", identifier = \"" << ObjectBuffer.getBufferIdentifier()
41  << "\"\n";
42  });
43 
45  return make_error<JITLinkError>("MachO 32-bit platforms not supported");
47 
48  if (Data.size() < sizeof(MachO::mach_header_64))
49  return make_error<JITLinkError>("Truncated MachO buffer \"" +
50  ObjectBuffer.getBufferIdentifier() +
51  "\"");
52 
53  // Read the CPU type from the header.
55  memcpy(&CPUType, Data.data() + 4, sizeof(uint32_t));
58 
59  LLVM_DEBUG({
60  dbgs() << "jitLink_MachO: cputype = " << format("0x%08" PRIx32, CPUType)
61  << "\n";
62  });
63 
64  switch (CPUType) {
66  return createLinkGraphFromMachOObject_arm64(ObjectBuffer);
68  return createLinkGraphFromMachOObject_x86_64(ObjectBuffer);
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
MemoryBuffer.h
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::MachO::MH_CIGAM
@ MH_CIGAM
Definition: MachO.h:31
SwapByteOrder.h
llvm::Triple::x86_64
@ x86_64
Definition: Triple.h:84
llvm::MachO::CPUType
CPUType
Definition: MachO.h:1418
llvm::MachO::MH_CIGAM_64
@ MH_CIGAM_64
Definition: MachO.h:33
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
Format.h
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::MachO::CPU_TYPE_X86_64
@ CPU_TYPE_X86_64
Definition: MachO.h:1422
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
MachO_x86_64.h
llvm::MachO::mach_header_64
Definition: MachO.h:519
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
Magic
const char Magic[]
Definition: Archive.cpp:41
llvm::MachO::CPU_TYPE_ARM64
@ CPU_TYPE_ARM64
Definition: MachO.h:1426
memcpy
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
MachO_arm64.h
llvm::MemoryBufferRef::getBuffer
StringRef getBuffer() const
Definition: MemoryBufferRef.h:32
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
uint32_t
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::MachO::MH_MAGIC
@ MH_MAGIC
Definition: MachO.h:30
llvm::MemoryBufferRef::getBufferIdentifier
StringRef getBufferIdentifier() const
Definition: MemoryBufferRef.h:33
MachO.h
llvm::ByteSwap_32
uint32_t ByteSwap_32(uint32_t value)
This function returns a byte-swapped representation of the 32-bit argument.
Definition: SwapByteOrder.h:66
llvm::MachO::MH_MAGIC_64
@ MH_MAGIC_64
Definition: MachO.h:32
llvm::Triple::aarch64
@ aarch64
Definition: Triple.h:52