1 //===- Target.h -------------------------------------------------*- C++ -*-===//
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 #ifndef LLD_MACHO_TARGET_H
10 #define LLD_MACHO_TARGET_H
11 
12 #include "llvm/BinaryFormat/MachO.h"
13 #include "llvm/Support/MemoryBuffer.h"
14 
15 #include <cstddef>
16 #include <cstdint>
17 
18 namespace lld {
19 namespace macho {
20 
21 class Symbol;
22 class DylibSymbol;
23 class InputSection;
24 struct Reloc;
25 
26 enum : uint64_t {
27   // We are currently only supporting 64-bit targets since macOS and iOS are
28   // deprecating 32-bit apps.
29   WordSize = 8,
30   PageSize = 4096,
31   PageZeroSize = 1ull << 32, // XXX should be 4096 for 32-bit targets
32   MaxAlignmentPowerOf2 = 32,
33 };
34 
35 class TargetInfo {
36 public:
37   virtual ~TargetInfo() = default;
38 
39   // Validate the relocation structure and get its addend.
40   virtual uint64_t getAddend(llvm::MemoryBufferRef,
41                              const llvm::MachO::section_64 &,
42                              llvm::MachO::relocation_info,
43                              llvm::MachO::relocation_info) const = 0;
44   virtual bool isPairedReloc(llvm::MachO::relocation_info) const = 0;
45   virtual void relocateOne(uint8_t *loc, const Reloc &, uint64_t val) const = 0;
46 
47   // Write code for lazy binding. See the comments on StubsSection for more
48   // details.
49   virtual void writeStub(uint8_t *buf, const Symbol &) const = 0;
50   virtual void writeStubHelperHeader(uint8_t *buf) const = 0;
51   virtual void writeStubHelperEntry(uint8_t *buf, const DylibSymbol &,
52                                     uint64_t entryAddr) const = 0;
53 
54   // Symbols may be referenced via either the GOT or the stubs section,
55   // depending on the relocation type. prepareSymbolRelocation() will set up the
56   // GOT/stubs entries, and resolveSymbolVA() will return the addresses of those
57   // entries. resolveSymbolVA() may also relax the target instructions to save
58   // on a level of address indirection.
59   virtual void prepareSymbolRelocation(Symbol *, const InputSection *,
60                                        const Reloc &) = 0;
61   virtual uint64_t resolveSymbolVA(uint8_t *buf, const Symbol &,
62                                    uint8_t type) const = 0;
63 
64   uint32_t cpuType;
65   uint32_t cpuSubtype;
66 
67   size_t stubSize;
68   size_t stubHelperHeaderSize;
69   size_t stubHelperEntrySize;
70 };
71 
72 TargetInfo *createX86_64TargetInfo();
73 
74 extern TargetInfo *target;
75 
76 } // namespace macho
77 } // namespace lld
78 
79 #endif
80