LLVM 22.0.0git
MCMachObjectWriter.h
Go to the documentation of this file.
1//===- llvm/MC/MCMachObjectWriter.h - Mach Object Writer --------*- 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 LLVM_MC_MCMACHOBJECTWRITER_H
10#define LLVM_MC_MCMACHOBJECTWRITER_H
11
12#include "llvm/ADT/DenseMap.h"
13#include "llvm/ADT/StringRef.h"
16#include "llvm/MC/MCExpr.h"
25#include <cstdint>
26#include <memory>
27#include <string>
28#include <vector>
29
30namespace llvm {
31
32class MachObjectWriter;
33
35 const unsigned Is64Bit : 1;
36 const uint32_t CPUType;
37protected:
39public:
40 unsigned LocalDifference_RIT = 0;
41
42protected:
43 MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_,
44 uint32_t CPUSubtype_);
45
47 LocalDifference_RIT = Type;
48 }
49
50public:
52
53 Triple::ObjectFormatType getFormat() const override { return Triple::MachO; }
54 static bool classof(const MCObjectTargetWriter *W) {
55 return W->getFormat() == Triple::MachO;
56 }
57
58 /// \name Lifetime Management
59 /// @{
60
61 virtual void reset() {}
62
63 /// @}
64
65 /// \name Accessors
66 /// @{
67
68 bool is64Bit() const { return Is64Bit; }
69 uint32_t getCPUType() const { return CPUType; }
70 uint32_t getCPUSubtype() const { return CPUSubtype; }
72 return LocalDifference_RIT;
73 }
74
75 /// @}
76
77 /// \name API
78 /// @{
79
80 virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
81 const MCFragment *Fragment,
83 uint64_t &FixedValue) = 0;
84
85 /// @}
86};
87
89public:
94 };
95
96 // A Major version of 0 indicates that no version information was supplied
97 // and so the corresponding load command should not be emitted.
98 using VersionInfoType = struct {
99 bool EmitBuildVersion;
100 union {
101 MCVersionMinType Type; ///< Used when EmitBuildVersion==false.
102 MachO::PlatformType Platform; ///< Used when EmitBuildVersion==true.
103 } TypeOrPlatform;
104 unsigned Major;
105 unsigned Minor;
106 unsigned Update;
107 /// An optional version of the SDK that was used to build the source.
109 };
110
111private:
112 /// Helper struct for containing some precomputed information on symbols.
113 struct MachSymbolData {
114 const MCSymbolMachO *Symbol;
115 uint64_t StringIndex;
116 uint8_t SectionIndex;
117
118 // Support lexicographic sorting.
119 LLVM_ABI bool operator<(const MachSymbolData &RHS) const;
120 };
121
122 struct IndirectSymbolData {
123 MCSymbolMachO *Symbol;
124 MCSection *Section;
125 };
126
127 /// The target specific Mach-O writer instance.
128 std::unique_ptr<MCMachObjectTargetWriter> TargetObjectWriter;
129
130 /// \name Relocation Data
131 /// @{
132
133 struct RelAndSymbol {
134 const MCSymbol *Sym;
135 MachO::any_relocation_info MRE;
136 RelAndSymbol(const MCSymbol *Sym, const MachO::any_relocation_info &MRE)
137 : Sym(Sym), MRE(MRE) {}
138 };
139
140 DenseMap<const MCSection *, std::vector<RelAndSymbol>> Relocations;
141 std::vector<IndirectSymbolData> IndirectSymbols;
142 DenseMap<const MCSection *, unsigned> IndirectSymBase;
143
144 std::vector<DataRegionData> DataRegions;
145
146 DenseMap<const MCSection *, uint64_t> SectionAddress;
147
148 // List of sections in layout order. Virtual sections are after non-virtual
149 // sections.
150 SmallVector<MCSection *, 0> SectionOrder;
151
152 /// @}
153 /// \name Symbol Table Data
154 /// @{
155
156 StringTableBuilder StringTable;
157 std::vector<MachSymbolData> LocalSymbolData;
158 std::vector<MachSymbolData> ExternalSymbolData;
159 std::vector<MachSymbolData> UndefinedSymbolData;
160
161 /// @}
162
163 // Used to communicate Linker Optimization Hint information.
164 MCLOHContainer LOHContainer;
165
166 VersionInfoType VersionInfo{};
167 VersionInfoType TargetVariantVersionInfo{};
168
169 // The list of linker options for LC_LINKER_OPTION.
170 std::vector<std::vector<std::string>> LinkerOptions;
171
172 MachSymbolData *findSymbolData(const MCSymbol &Sym);
173
174 void writeWithPadding(StringRef Str, uint64_t Size);
175
176public:
177 MachObjectWriter(std::unique_ptr<MCMachObjectTargetWriter> MOTW,
178 raw_pwrite_stream &OS, bool IsLittleEndian)
179 : TargetObjectWriter(std::move(MOTW)),
180 StringTable(TargetObjectWriter->is64Bit() ? StringTableBuilder::MachO64
181 : StringTableBuilder::MachO),
182 W(OS,
183 IsLittleEndian ? llvm::endianness::little : llvm::endianness::big) {}
184
186
187 const MCSymbol &findAliasedSymbol(const MCSymbol &Sym) const;
188
189 void reset() override;
190 void setAssembler(MCAssembler *Asm) override;
191
192 /// \name Utility Methods
193 /// @{
194
195 std::vector<IndirectSymbolData> &getIndirectSymbols() {
196 return IndirectSymbols;
197 }
198 std::vector<DataRegionData> &getDataRegions() { return DataRegions; }
200 return SectionOrder;
201 }
202 MCLOHContainer &getLOHContainer() { return LOHContainer; }
203
205 return SectionAddress.lookup(Sec);
206 }
207 uint64_t getSymbolAddress(const MCSymbol &S) const;
208
209 uint64_t getFragmentAddress(const MCAssembler &Asm,
210 const MCFragment *Fragment) const;
211
212 uint64_t getPaddingSize(const MCAssembler &Asm, const MCSection *SD) const;
213
214 const MCSymbol *getAtom(const MCSymbol &S) const;
215
216 bool doesSymbolRequireExternRelocation(const MCSymbol &S);
217
218 /// Mach-O deployment target version information.
219 void setVersionMin(MCVersionMinType Type, unsigned Major, unsigned Minor,
220 unsigned Update,
221 VersionTuple SDKVersion = VersionTuple()) {
222 VersionInfo.EmitBuildVersion = false;
223 VersionInfo.TypeOrPlatform.Type = Type;
224 VersionInfo.Major = Major;
225 VersionInfo.Minor = Minor;
226 VersionInfo.Update = Update;
227 VersionInfo.SDKVersion = SDKVersion;
228 }
229 void setBuildVersion(MachO::PlatformType Platform, unsigned Major,
230 unsigned Minor, unsigned Update,
231 VersionTuple SDKVersion = VersionTuple()) {
232 VersionInfo.EmitBuildVersion = true;
233 VersionInfo.TypeOrPlatform.Platform = Platform;
234 VersionInfo.Major = Major;
235 VersionInfo.Minor = Minor;
236 VersionInfo.Update = Update;
237 VersionInfo.SDKVersion = SDKVersion;
238 }
240 unsigned Major, unsigned Minor,
241 unsigned Update, VersionTuple SDKVersion) {
242 TargetVariantVersionInfo.EmitBuildVersion = true;
243 TargetVariantVersionInfo.TypeOrPlatform.Platform = Platform;
244 TargetVariantVersionInfo.Major = Major;
245 TargetVariantVersionInfo.Minor = Minor;
246 TargetVariantVersionInfo.Update = Update;
247 TargetVariantVersionInfo.SDKVersion = SDKVersion;
248 }
249
250 std::vector<std::vector<std::string>> &getLinkerOptions() {
251 return LinkerOptions;
252 }
253
254 /// @}
255
256 /// \name Target Writer Proxy Accessors
257 /// @{
258
259 bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
260 bool isX86_64() const {
261 uint32_t CPUType = TargetObjectWriter->getCPUType();
262 return CPUType == MachO::CPU_TYPE_X86_64;
263 }
264
265 /// @}
266
267 void writeHeader(MachO::HeaderFileType Type, unsigned NumLoadCommands,
268 unsigned LoadCommandsSize, bool SubsectionsViaSymbols);
269
270 /// Write a segment load command.
271 ///
272 /// \param NumSections The number of sections in this segment.
273 /// \param SectionDataSize The total size of the sections.
274 void writeSegmentLoadCommand(StringRef Name, unsigned NumSections,
275 uint64_t VMAddr, uint64_t VMSize,
276 uint64_t SectionDataStartOffset,
277 uint64_t SectionDataSize, uint32_t MaxProt,
278 uint32_t InitProt);
279
280 void writeSection(const MCAssembler &Asm, const MCSectionMachO &Sec,
281 uint64_t VMAddr, uint64_t FileOffset, unsigned Flags,
282 uint64_t RelocationsStart, unsigned NumRelocations);
283
284 void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
285 uint32_t StringTableOffset,
286 uint32_t StringTableSize);
287
288 void writeDysymtabLoadCommand(
289 uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols,
290 uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols,
291 uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols,
292 uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols);
293
294 void writeNlist(MachSymbolData &MSD, const MCAssembler &Asm);
295
296 void writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,
297 uint32_t DataSize);
298
299 void writeLinkerOptionsLoadCommand(const std::vector<std::string> &Options);
300
301 // FIXME: We really need to improve the relocation validation. Basically, we
302 // want to implement a separate computation which evaluates the relocation
303 // entry as the linker would, and verifies that the resultant fixup value is
304 // exactly what the encoder wanted. This will catch several classes of
305 // problems:
306 //
307 // - Relocation entry bugs, the two algorithms are unlikely to have the same
308 // exact bug.
309 //
310 // - Relaxation issues, where we forget to relax something.
311 //
312 // - Input errors, where something cannot be correctly encoded. 'as' allows
313 // these through in many cases.
314
315 // Add a relocation to be output in the object file. At the time this is
316 // called, the symbol indexes are not know, so if the relocation refers
317 // to a symbol it should be passed as \p RelSymbol so that it can be updated
318 // afterwards. If the relocation doesn't refer to a symbol, nullptr should be
319 // used.
320 void addRelocation(const MCSymbol *RelSymbol, const MCSection *Sec,
322 RelAndSymbol P(RelSymbol, MRE);
323 Relocations[Sec].push_back(P);
324 }
325
326 void recordRelocation(const MCFragment &F, const MCFixup &Fixup,
327 MCValue Target, uint64_t &FixedValue) override;
328
329 void bindIndirectSymbols(MCAssembler &Asm);
330
331 /// Compute the symbol table data.
332 void computeSymbolTable(MCAssembler &Asm,
333 std::vector<MachSymbolData> &LocalSymbolData,
334 std::vector<MachSymbolData> &ExternalSymbolData,
335 std::vector<MachSymbolData> &UndefinedSymbolData);
336
337 void computeSectionAddresses(const MCAssembler &Asm);
338
339 void executePostLayoutBinding() override;
340
341 bool isSymbolRefDifferenceFullyResolvedImpl(const MCSymbol &SymA,
342 const MCFragment &FB, bool InSet,
343 bool IsPCRel) const override;
344
345 void populateAddrSigSection(MCAssembler &Asm);
346
347 uint64_t writeObject() override;
348};
349} // end namespace llvm
350
351#endif // LLVM_MC_MCMACHOBJECTWRITER_H
RelocType Type
Definition: COFFYAML.cpp:410
#define LLVM_ABI
Definition: Compiler.h:213
This file defines the DenseMap class.
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
static LVOptions Options
Definition: LVOptions.cpp:25
bool operator<(const DeltaInfo &LHS, int64_t Delta)
Definition: LineTable.cpp:30
#define F(x, y, z)
Definition: MD5.cpp:55
#define P(N)
PowerPC TLS Dynamic Call Fixup
raw_pwrite_stream & OS
Defines the llvm::VersionTuple class, which represents a version in the form major[....
static bool is64Bit(const char *name)
Value * RHS
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:61
virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)=0
void setLocalDifferenceRelocationType(unsigned Type)
static bool classof(const MCObjectTargetWriter *W)
Triple::ObjectFormatType getFormat() const override
unsigned getLocalDifferenceRelocationType() const
Base class for classes that define behaviour that is specific to both the target and the object forma...
Defines the object file and target independent interfaces used by the assembler backend to write nati...
This represents a section on a Mach-O system (used by Mac OS X).
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:496
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
void setTargetVariantBuildVersion(MachO::PlatformType Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion)
MCLOHContainer & getLOHContainer()
MachO::PlatformType Platform
Used when EmitBuildVersion==true.
{ bool EmitBuildVersion VersionInfoType
uint64_t getSectionAddress(const MCSection *Sec) const
void addRelocation(const MCSymbol *RelSymbol, const MCSection *Sec, MachO::any_relocation_info &MRE)
const llvm::SmallVectorImpl< MCSection * > & getSectionOrder() const
std::vector< DataRegionData > & getDataRegions()
support::endian::Writer W
VersionTuple SDKVersion
An optional version of the SDK that was used to build the source.
std::vector< IndirectSymbolData > & getIndirectSymbols()
MCVersionMinType Type
Used when EmitBuildVersion==false.
void setVersionMin(MCVersionMinType Type, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion=VersionTuple())
Mach-O deployment target version information.
void setBuildVersion(MachO::PlatformType Platform, unsigned Major, unsigned Minor, unsigned Update, VersionTuple SDKVersion=VersionTuple())
MachObjectWriter(std::unique_ptr< MCMachObjectTargetWriter > MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
std::vector< std::vector< std::string > > & getLinkerOptions()
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
Utility for building string tables with deduplicated suffixes.
A table of densely packed, null-terminated strings indexed by offset.
Definition: StringTable.h:33
Target - Wrapper for Target specific information.
ObjectFormatType
Definition: Triple.h:314
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:30
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:435
PlatformType
Definition: MachO.h:500
HeaderFileType
Definition: MachO.h:40
DataRegionType
Definition: MachO.h:225
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MCVersionMinType
Definition: MCDirectives.h:61
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1886
endianness
Definition: bit.h:71
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:67