LLVM 24.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
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
49
50public:
52
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; }
73 }
74
75 /// @}
76
77 /// \name API
78 /// @{
79
81 const MCFragment *Fragment,
82 const MCFixup &Fixup, MCValue Target,
83 uint64_t &FixedValue) = 0;
84
85 /// @}
86};
87
89public:
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.
108 VersionTuple SDKVersion;
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 /// Offset of each section's data from the start of all section data.
147 DenseMap<const MCSection *, uint64_t> SectionDataOffset;
148
149 // List of sections in layout order. Virtual sections are after non-virtual
150 // sections.
151 SmallVector<MCSection *, 0> SectionOrder;
152
153 /// @}
154 /// \name Symbol Table Data
155 /// @{
156
157 StringTableBuilder StringTable;
158 std::vector<MachSymbolData> LocalSymbolData;
159 std::vector<MachSymbolData> ExternalSymbolData;
160 std::vector<MachSymbolData> UndefinedSymbolData;
161
162 /// @}
163
164 // Used to communicate Linker Optimization Hint information.
165 MCLOHContainer LOHContainer;
166
167 VersionInfoType VersionInfo{};
168 VersionInfoType TargetVariantVersionInfo{};
169
170 std::optional<std::string> TargetTriple;
171
172 // The list of linker options for LC_LINKER_OPTION.
173 std::vector<std::vector<std::string>> LinkerOptions;
174
175 MachSymbolData *findSymbolData(const MCSymbol &Sym);
176
177 void writeWithPadding(StringRef Str, uint64_t Size);
178
179public:
180 MachObjectWriter(std::unique_ptr<MCMachObjectTargetWriter> MOTW,
181 raw_pwrite_stream &OS, bool IsLittleEndian)
182 : TargetObjectWriter(std::move(MOTW)),
183 StringTable(TargetObjectWriter->is64Bit() ? StringTableBuilder::MachO64
185 W(OS,
186 IsLittleEndian ? llvm::endianness::little : llvm::endianness::big) {}
187
189
190 const MCSymbol &findAliasedSymbol(const MCSymbol &Sym) const;
191
192 void reset() override;
193 void setAssembler(MCAssembler *Asm) override;
194
195 /// \name Utility Methods
196 /// @{
197
198 std::vector<IndirectSymbolData> &getIndirectSymbols() {
199 return IndirectSymbols;
200 }
201 std::vector<DataRegionData> &getDataRegions() { return DataRegions; }
203 return SectionOrder;
204 }
205 MCLOHContainer &getLOHContainer() { return LOHContainer; }
206
207 uint64_t getSectionAddress(const MCSection *Sec) const;
208 uint64_t getSymbolAddress(const MCSymbol &S) const;
209
210 uint64_t getFragmentAddress(const MCAssembler &Asm,
211 const MCFragment *Fragment) const;
212
213 uint64_t getPaddingSize(const MCAssembler &Asm, const MCSection *SD) const;
214
215 const MCSymbol *getAtom(const MCSymbol &S) const;
216
217 bool doesSymbolRequireExternRelocation(const MCSymbol &S);
218
219 /// Mach-O deployment target version information.
220 void setVersionMin(MCVersionMinType Type, unsigned Major, unsigned Minor,
221 unsigned Update,
222 VersionTuple SDKVersion = VersionTuple()) {
223 VersionInfo.EmitBuildVersion = false;
224 VersionInfo.TypeOrPlatform.Type = Type;
225 VersionInfo.Major = Major;
226 VersionInfo.Minor = Minor;
227 VersionInfo.Update = Update;
228 VersionInfo.SDKVersion = SDKVersion;
229 }
230 void setBuildVersion(MachO::PlatformType Platform, unsigned Major,
231 unsigned Minor, unsigned Update,
232 VersionTuple SDKVersion = VersionTuple()) {
233 VersionInfo.EmitBuildVersion = true;
234 VersionInfo.TypeOrPlatform.Platform = Platform;
235 VersionInfo.Major = Major;
236 VersionInfo.Minor = Minor;
237 VersionInfo.Update = Update;
238 VersionInfo.SDKVersion = SDKVersion;
239 }
241 unsigned Major, unsigned Minor,
242 unsigned Update, VersionTuple SDKVersion) {
243 TargetVariantVersionInfo.EmitBuildVersion = true;
244 TargetVariantVersionInfo.TypeOrPlatform.Platform = Platform;
245 TargetVariantVersionInfo.Major = Major;
246 TargetVariantVersionInfo.Minor = Minor;
247 TargetVariantVersionInfo.Update = Update;
248 TargetVariantVersionInfo.SDKVersion = SDKVersion;
249 }
250
251 void setTargetTriple(StringRef Triple) { TargetTriple = Triple; }
252
253 std::vector<std::vector<std::string>> &getLinkerOptions() {
254 return LinkerOptions;
255 }
256
257 /// @}
258
259 /// \name Target Writer Proxy Accessors
260 /// @{
261
262 bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
263 bool isX86_64() const {
264 uint32_t CPUType = TargetObjectWriter->getCPUType();
265 return CPUType == MachO::CPU_TYPE_X86_64;
266 }
267
268 /// @}
269
270 void writeHeader(MachO::HeaderFileType Type, unsigned NumLoadCommands,
271 unsigned LoadCommandsSize, bool SubsectionsViaSymbols);
272
273 /// Write a segment load command.
274 ///
275 /// \param NumSections The number of sections in this segment.
276 /// \param SectionDataSize The total size of the sections.
277 void writeSegmentLoadCommand(StringRef Name, unsigned NumSections,
278 uint64_t VMAddr, uint64_t VMSize,
279 uint64_t SectionDataStartOffset,
280 uint64_t SectionDataSize, uint32_t MaxProt,
281 uint32_t InitProt);
282
283 void writeSection(const MCAssembler &Asm, const MCSectionMachO &Sec,
284 uint64_t VMAddr, uint64_t FileOffset, unsigned Flags,
285 uint64_t RelocationsStart, unsigned NumRelocations);
286
287 void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
288 uint32_t StringTableOffset,
289 uint32_t StringTableSize);
290
291 void writeDysymtabLoadCommand(
292 uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols,
293 uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols,
294 uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols,
295 uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols);
296
297 void writeNlist(MachSymbolData &MSD, const MCAssembler &Asm);
298
299 void writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset,
300 uint32_t DataSize);
301
302 void writeLinkerOptionsLoadCommand(const std::vector<std::string> &Options);
303
304 // FIXME: We really need to improve the relocation validation. Basically, we
305 // want to implement a separate computation which evaluates the relocation
306 // entry as the linker would, and verifies that the resultant fixup value is
307 // exactly what the encoder wanted. This will catch several classes of
308 // problems:
309 //
310 // - Relocation entry bugs, the two algorithms are unlikely to have the same
311 // exact bug.
312 //
313 // - Relaxation issues, where we forget to relax something.
314 //
315 // - Input errors, where something cannot be correctly encoded. 'as' allows
316 // these through in many cases.
317
318 // Add a relocation to be output in the object file. At the time this is
319 // called, the symbol indexes are not know, so if the relocation refers
320 // to a symbol it should be passed as \p RelSymbol so that it can be updated
321 // afterwards. If the relocation doesn't refer to a symbol, nullptr should be
322 // used.
323 void addRelocation(const MCSymbol *RelSymbol, const MCSection *Sec,
325 RelAndSymbol P(RelSymbol, MRE);
326 Relocations[Sec].push_back(P);
327 }
328
329 void recordRelocation(const MCFragment &F, const MCFixup &Fixup,
330 MCValue Target, uint64_t &FixedValue) override;
331
332 void bindIndirectSymbols(MCAssembler &Asm);
333
334 /// Compute the symbol table data.
335 void computeSymbolTable(MCAssembler &Asm,
336 std::vector<MachSymbolData> &LocalSymbolData,
337 std::vector<MachSymbolData> &ExternalSymbolData,
338 std::vector<MachSymbolData> &UndefinedSymbolData);
339
340 void computeSectionAddresses(const MCAssembler &Asm);
341
342 void executePostLayoutBinding() override;
343
344 bool isSymbolRefDifferenceFullyResolvedImpl(const MCSymbol &SymA,
345 const MCFragment &FB, bool InSet,
346 bool IsPCRel) const override;
347
348 void populateAddrSigSection(MCAssembler &Asm);
349
350 uint64_t writeObject() override;
351};
352} // end namespace llvm
353
354#endif // LLVM_MC_MCMACHOBJECTWRITER_H
uint64_t uint64_t
#define LLVM_ABI
Definition Compiler.h:211
This file defines the DenseMap class.
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:54
#define P(N)
Defines the llvm::VersionTuple class, which represents a version in the form major[....
Value * RHS
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition MCFixup.h:65
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
MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_, uint32_t CPUSubtype_)
unsigned getLocalDifferenceRelocationType() const
Base class for classes that define behaviour that is specific to both the target and the object forma...
MCObjectWriter()=default
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:580
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()
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
const MCSymbol & findAliasedSymbol(const MCSymbol &Sym) const
std::vector< IndirectSymbolData > & getIndirectSymbols()
void setAssembler(MCAssembler *Asm) override
void setTargetTriple(StringRef Triple)
void reset() override
lifetime management
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()
struct { bool EmitBuildVersion; union { MCVersionMinType Type; MachO::PlatformType Platform; } TypeOrPlatform; unsigned Major; unsigned Minor; unsigned Update; VersionTuple SDKVersion; } VersionInfoType
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Utility for building string tables with deduplicated suffixes.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
Represents a version number in the form major[.minor[.subminor[.build]]].
An abstract base class for streams implementations that also support a pwrite operation.
HeaderFileType
Definition MachO.h:40
@ CPU_TYPE_X86_64
Definition MachO.h:1699
This is an optimization pass for GlobalISel generic memory operations.
MCVersionMinType
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:1933
endianness
Definition bit.h:71
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:879
Adapter to write values to a stream in a particular byte order.