Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lld/MachO/Target.h
34878 views
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 "MachOStructs.h"
13
#include "Relocations.h"
14
15
#include "llvm/ADT/BitmaskEnum.h"
16
#include "llvm/BinaryFormat/MachO.h"
17
#include "llvm/Support/MathExtras.h"
18
#include "llvm/Support/MemoryBuffer.h"
19
20
#include <cstddef>
21
#include <cstdint>
22
23
#include "mach-o/compact_unwind_encoding.h"
24
25
namespace lld::macho {
26
LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
27
28
class Symbol;
29
class Defined;
30
class DylibSymbol;
31
class InputSection;
32
class ObjFile;
33
34
static_assert(static_cast<uint32_t>(UNWIND_X86_64_MODE_MASK) ==
35
static_cast<uint32_t>(UNWIND_X86_MODE_MASK) &&
36
static_cast<uint32_t>(UNWIND_ARM64_MODE_MASK) ==
37
static_cast<uint32_t>(UNWIND_X86_64_MODE_MASK));
38
39
// Since the mode masks have the same value on all targets, define
40
// a common one for convenience.
41
constexpr uint32_t UNWIND_MODE_MASK = UNWIND_X86_64_MODE_MASK;
42
43
class TargetInfo {
44
public:
45
template <class LP> TargetInfo(LP) {
46
// Having these values available in TargetInfo allows us to access them
47
// without having to resort to templates.
48
magic = LP::magic;
49
pageZeroSize = LP::pageZeroSize;
50
headerSize = sizeof(typename LP::mach_header);
51
wordSize = LP::wordSize;
52
p2WordSize = llvm::CTLog2<LP::wordSize>();
53
}
54
55
virtual ~TargetInfo() = default;
56
57
// Validate the relocation structure and get its addend.
58
virtual int64_t
59
getEmbeddedAddend(llvm::MemoryBufferRef, uint64_t offset,
60
const llvm::MachO::relocation_info) const = 0;
61
virtual void relocateOne(uint8_t *loc, const Reloc &, uint64_t va,
62
uint64_t relocVA) const = 0;
63
64
// Write code for lazy binding. See the comments on StubsSection for more
65
// details.
66
virtual void writeStub(uint8_t *buf, const Symbol &,
67
uint64_t pointerVA) const = 0;
68
virtual void writeStubHelperHeader(uint8_t *buf) const = 0;
69
virtual void writeStubHelperEntry(uint8_t *buf, const Symbol &,
70
uint64_t entryAddr) const = 0;
71
72
virtual void writeObjCMsgSendStub(uint8_t *buf, Symbol *sym,
73
uint64_t stubsAddr, uint64_t &stubOffset,
74
uint64_t selrefVA,
75
Symbol *objcMsgSend) const = 0;
76
77
// Symbols may be referenced via either the GOT or the stubs section,
78
// depending on the relocation type. prepareSymbolRelocation() will set up the
79
// GOT/stubs entries, and resolveSymbolVA() will return the addresses of those
80
// entries. resolveSymbolVA() may also relax the target instructions to save
81
// on a level of address indirection.
82
virtual void relaxGotLoad(uint8_t *loc, uint8_t type) const = 0;
83
84
virtual uint64_t getPageSize() const = 0;
85
86
virtual void populateThunk(InputSection *thunk, Symbol *funcSym) {
87
llvm_unreachable("target does not use thunks");
88
}
89
90
const RelocAttrs &getRelocAttrs(uint8_t type) const {
91
assert(type < relocAttrs.size() && "invalid relocation type");
92
if (type >= relocAttrs.size())
93
return invalidRelocAttrs;
94
return relocAttrs[type];
95
}
96
97
bool hasAttr(uint8_t type, RelocAttrBits bit) const {
98
return getRelocAttrs(type).hasAttr(bit);
99
}
100
101
bool usesThunks() const { return thunkSize > 0; }
102
103
// For now, handleDtraceReloc only implements -no_dtrace_dof, and ensures
104
// that the linking would not fail even when there are user-provided dtrace
105
// symbols. However, unlike ld64, lld currently does not emit __dof sections.
106
virtual void handleDtraceReloc(const Symbol *sym, const Reloc &r,
107
uint8_t *loc) const {
108
llvm_unreachable("Unsupported architecture for dtrace symbols");
109
}
110
111
virtual void applyOptimizationHints(uint8_t *, const ObjFile &) const {};
112
113
uint32_t magic;
114
llvm::MachO::CPUType cpuType;
115
uint32_t cpuSubtype;
116
117
uint64_t pageZeroSize;
118
size_t headerSize;
119
size_t stubSize;
120
size_t stubHelperHeaderSize;
121
size_t stubHelperEntrySize;
122
size_t objcStubsFastSize;
123
size_t objcStubsSmallSize;
124
size_t objcStubsFastAlignment;
125
size_t objcStubsSmallAlignment;
126
uint8_t p2WordSize;
127
size_t wordSize;
128
129
size_t thunkSize = 0;
130
uint64_t forwardBranchRange = 0;
131
uint64_t backwardBranchRange = 0;
132
133
uint32_t modeDwarfEncoding;
134
uint8_t subtractorRelocType;
135
uint8_t unsignedRelocType;
136
137
llvm::ArrayRef<RelocAttrs> relocAttrs;
138
139
// We contrive this value as sufficiently far from any valid address that it
140
// will always be out-of-range for any architecture. UINT64_MAX is not a
141
// good choice because it is (a) only 1 away from wrapping to 0, and (b) the
142
// tombstone value for DenseMap<> and caused weird assertions for me.
143
static constexpr uint64_t outOfRangeVA = 0xfull << 60;
144
};
145
146
TargetInfo *createX86_64TargetInfo();
147
TargetInfo *createARM64TargetInfo();
148
TargetInfo *createARM64_32TargetInfo();
149
150
struct LP64 {
151
using mach_header = llvm::MachO::mach_header_64;
152
using nlist = structs::nlist_64;
153
using segment_command = llvm::MachO::segment_command_64;
154
using section = llvm::MachO::section_64;
155
using encryption_info_command = llvm::MachO::encryption_info_command_64;
156
157
static constexpr uint32_t magic = llvm::MachO::MH_MAGIC_64;
158
static constexpr uint32_t segmentLCType = llvm::MachO::LC_SEGMENT_64;
159
static constexpr uint32_t encryptionInfoLCType =
160
llvm::MachO::LC_ENCRYPTION_INFO_64;
161
162
static constexpr uint64_t pageZeroSize = 1ull << 32;
163
static constexpr size_t wordSize = 8;
164
};
165
166
struct ILP32 {
167
using mach_header = llvm::MachO::mach_header;
168
using nlist = structs::nlist;
169
using segment_command = llvm::MachO::segment_command;
170
using section = llvm::MachO::section;
171
using encryption_info_command = llvm::MachO::encryption_info_command;
172
173
static constexpr uint32_t magic = llvm::MachO::MH_MAGIC;
174
static constexpr uint32_t segmentLCType = llvm::MachO::LC_SEGMENT;
175
static constexpr uint32_t encryptionInfoLCType =
176
llvm::MachO::LC_ENCRYPTION_INFO;
177
178
static constexpr uint64_t pageZeroSize = 1ull << 12;
179
static constexpr size_t wordSize = 4;
180
};
181
182
extern TargetInfo *target;
183
184
} // namespace lld::macho
185
186
#endif
187
188