LLVM 19.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"
15#include "llvm/MC/MCExpr.h"
17#include "llvm/MC/MCSection.h"
20#include <cstdint>
21#include <memory>
22#include <string>
23#include <vector>
24
25namespace llvm {
26
27class MachObjectWriter;
28
30 const unsigned Is64Bit : 1;
31 const uint32_t CPUType;
32protected:
34public:
35 unsigned LocalDifference_RIT = 0;
36
37protected:
38 MCMachObjectTargetWriter(bool Is64Bit_, uint32_t CPUType_,
39 uint32_t CPUSubtype_);
40
43 }
44
45public:
47
49 static bool classof(const MCObjectTargetWriter *W) {
50 return W->getFormat() == Triple::MachO;
51 }
52
53 /// \name Lifetime Management
54 /// @{
55
56 virtual void reset() {}
57
58 /// @}
59
60 /// \name Accessors
61 /// @{
62
63 bool is64Bit() const { return Is64Bit; }
64 uint32_t getCPUType() const { return CPUType; }
65 uint32_t getCPUSubtype() const { return CPUSubtype; }
68 }
69
70 /// @}
71
72 /// \name API
73 /// @{
74
75 virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm,
76 const MCAsmLayout &Layout,
77 const MCFragment *Fragment,
79 uint64_t &FixedValue) = 0;
80
81 /// @}
82};
83
85 /// Helper struct for containing some precomputed information on symbols.
86 struct MachSymbolData {
87 const MCSymbol *Symbol;
88 uint64_t StringIndex;
89 uint8_t SectionIndex;
90
91 // Support lexicographic sorting.
92 bool operator<(const MachSymbolData &RHS) const;
93 };
94
95 /// The target specific Mach-O writer instance.
96 std::unique_ptr<MCMachObjectTargetWriter> TargetObjectWriter;
97
98 /// \name Relocation Data
99 /// @{
100
101 struct RelAndSymbol {
102 const MCSymbol *Sym;
104 RelAndSymbol(const MCSymbol *Sym, const MachO::any_relocation_info &MRE)
105 : Sym(Sym), MRE(MRE) {}
106 };
107
110
111 SectionAddrMap SectionAddress;
112
113 /// @}
114 /// \name Symbol Table Data
115 /// @{
116
117 StringTableBuilder StringTable;
118 std::vector<MachSymbolData> LocalSymbolData;
119 std::vector<MachSymbolData> ExternalSymbolData;
120 std::vector<MachSymbolData> UndefinedSymbolData;
121
122 /// @}
123
124 MachSymbolData *findSymbolData(const MCSymbol &Sym);
125
126 void writeWithPadding(StringRef Str, uint64_t Size);
127
128public:
129 MachObjectWriter(std::unique_ptr<MCMachObjectTargetWriter> MOTW,
130 raw_pwrite_stream &OS, bool IsLittleEndian)
131 : TargetObjectWriter(std::move(MOTW)),
132 StringTable(TargetObjectWriter->is64Bit() ? StringTableBuilder::MachO64
133 : StringTableBuilder::MachO),
134 W(OS,
135 IsLittleEndian ? llvm::endianness::little : llvm::endianness::big) {}
136
138
139 const MCSymbol &findAliasedSymbol(const MCSymbol &Sym) const;
140
141 /// \name Lifetime management Methods
142 /// @{
143
144 void reset() override;
145
146 /// @}
147
148 /// \name Utility Methods
149 /// @{
150
151 bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind);
152
153 SectionAddrMap &getSectionAddressMap() { return SectionAddress; }
154
156 return SectionAddress.lookup(Sec);
157 }
158 uint64_t getSymbolAddress(const MCSymbol &S, const MCAsmLayout &Layout) const;
159
160 uint64_t getFragmentAddress(const MCFragment *Fragment,
161 const MCAsmLayout &Layout) const;
162
163 uint64_t getPaddingSize(const MCSection *SD, const MCAsmLayout &Layout) const;
164
166
167 /// @}
168
169 /// \name Target Writer Proxy Accessors
170 /// @{
171
172 bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
173 bool isX86_64() const {
174 uint32_t CPUType = TargetObjectWriter->getCPUType();
175 return CPUType == MachO::CPU_TYPE_X86_64;
176 }
177
178 /// @}
179
180 void writeHeader(MachO::HeaderFileType Type, unsigned NumLoadCommands,
181 unsigned LoadCommandsSize, bool SubsectionsViaSymbols);
182
183 /// Write a segment load command.
184 ///
185 /// \param NumSections The number of sections in this segment.
186 /// \param SectionDataSize The total size of the sections.
187 void writeSegmentLoadCommand(StringRef Name, unsigned NumSections,
188 uint64_t VMAddr, uint64_t VMSize,
189 uint64_t SectionDataStartOffset,
190 uint64_t SectionDataSize, uint32_t MaxProt,
191 uint32_t InitProt);
192
193 void writeSection(const MCAsmLayout &Layout, const MCSection &Sec,
194 uint64_t VMAddr, uint64_t FileOffset, unsigned Flags,
195 uint64_t RelocationsStart, unsigned NumRelocations);
196
197 void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols,
198 uint32_t StringTableOffset,
199 uint32_t StringTableSize);
200
202 uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols,
203 uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols,
204 uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols,
205 uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols);
206
207 void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout);
208
210 uint32_t DataSize);
211
212 void writeLinkerOptionsLoadCommand(const std::vector<std::string> &Options);
213
214 // FIXME: We really need to improve the relocation validation. Basically, we
215 // want to implement a separate computation which evaluates the relocation
216 // entry as the linker would, and verifies that the resultant fixup value is
217 // exactly what the encoder wanted. This will catch several classes of
218 // problems:
219 //
220 // - Relocation entry bugs, the two algorithms are unlikely to have the same
221 // exact bug.
222 //
223 // - Relaxation issues, where we forget to relax something.
224 //
225 // - Input errors, where something cannot be correctly encoded. 'as' allows
226 // these through in many cases.
227
228 // Add a relocation to be output in the object file. At the time this is
229 // called, the symbol indexes are not know, so if the relocation refers
230 // to a symbol it should be passed as \p RelSymbol so that it can be updated
231 // afterwards. If the relocation doesn't refer to a symbol, nullptr should be
232 // used.
233 void addRelocation(const MCSymbol *RelSymbol, const MCSection *Sec,
235 RelAndSymbol P(RelSymbol, MRE);
236 Relocations[Sec].push_back(P);
237 }
238
239 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
240 const MCFragment *Fragment, const MCFixup &Fixup,
241 MCValue Target, uint64_t &FixedValue) override;
242
244
245 /// Compute the symbol table data.
247 std::vector<MachSymbolData> &LocalSymbolData,
248 std::vector<MachSymbolData> &ExternalSymbolData,
249 std::vector<MachSymbolData> &UndefinedSymbolData);
250
251 void computeSectionAddresses(const MCAssembler &Asm,
252 const MCAsmLayout &Layout);
253
255 const MCAsmLayout &Layout) override;
256
258 const MCSymbol &A,
259 const MCSymbol &B,
260 bool InSet) const override;
261
263 const MCSymbol &SymA,
264 const MCFragment &FB, bool InSet,
265 bool IsPCRel) const override;
266
268
269 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
270};
271
272/// Construct a new Mach-O writer instance.
273///
274/// This routine takes ownership of the target writer subclass.
275///
276/// \param MOTW - The target specific Mach-O writer subclass.
277/// \param OS - The stream to write to.
278/// \returns The constructed object writer.
279std::unique_ptr<MCObjectWriter>
280createMachObjectWriter(std::unique_ptr<MCMachObjectTargetWriter> MOTW,
281 raw_pwrite_stream &OS, bool IsLittleEndian);
282
283} // end namespace llvm
284
285#endif // LLVM_MC_MCMACHOBJECTWRITER_H
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
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
#define P(N)
PowerPC TLS Dynamic Call Fixup
raw_pwrite_stream & OS
Value * RHS
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:202
Encapsulates the layout of an assembly file at a particular point in time.
Definition: MCAsmLayout.h:28
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition: MCFixup.h:71
void setLocalDifferenceRelocationType(unsigned Type)
static bool classof(const MCObjectTargetWriter *W)
virtual void recordRelocation(MachObjectWriter *Writer, MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue)=0
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...
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:40
This represents an "assembler immediate".
Definition: MCValue.h:36
bool doesSymbolRequireExternRelocation(const MCSymbol &S)
uint64_t getSymbolAddress(const MCSymbol &S, const MCAsmLayout &Layout) const
SectionAddrMap & getSectionAddressMap()
void computeSymbolTable(MCAssembler &Asm, std::vector< MachSymbolData > &LocalSymbolData, std::vector< MachSymbolData > &ExternalSymbolData, std::vector< MachSymbolData > &UndefinedSymbolData)
Compute the symbol table data.
uint64_t getSectionAddress(const MCSection *Sec) const
void addRelocation(const MCSymbol *RelSymbol, const MCSection *Sec, MachO::any_relocation_info &MRE)
uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override
Write the object file and returns the number of bytes written.
void populateAddrSigSection(MCAssembler &Asm)
bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind)
support::endian::Writer W
void executePostLayoutBinding(MCAssembler &Asm, const MCAsmLayout &Layout) override
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
void writeLinkerOptionsLoadCommand(const std::vector< std::string > &Options)
void writeDysymtabLoadCommand(uint32_t FirstLocalSymbol, uint32_t NumLocalSymbols, uint32_t FirstExternalSymbol, uint32_t NumExternalSymbols, uint32_t FirstUndefinedSymbol, uint32_t NumUndefinedSymbols, uint32_t IndirectSymbolOffset, uint32_t NumIndirectSymbols)
void writeNlist(MachSymbolData &MSD, const MCAsmLayout &Layout)
const MCSymbol & findAliasedSymbol(const MCSymbol &Sym) const
bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, const MCSymbol &A, const MCSymbol &B, bool InSet) const override
void writeSection(const MCAsmLayout &Layout, const MCSection &Sec, uint64_t VMAddr, uint64_t FileOffset, unsigned Flags, uint64_t RelocationsStart, unsigned NumRelocations)
void writeSegmentLoadCommand(StringRef Name, unsigned NumSections, uint64_t VMAddr, uint64_t VMSize, uint64_t SectionDataStartOffset, uint64_t SectionDataSize, uint32_t MaxProt, uint32_t InitProt)
Write a segment load command.
void writeLinkeditLoadCommand(uint32_t Type, uint32_t DataOffset, uint32_t DataSize)
void writeHeader(MachO::HeaderFileType Type, unsigned NumLoadCommands, unsigned LoadCommandsSize, bool SubsectionsViaSymbols)
uint64_t getFragmentAddress(const MCFragment *Fragment, const MCAsmLayout &Layout) const
void reset() override
lifetime management
void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, const MCFragment *Fragment, const MCFixup &Fixup, MCValue Target, uint64_t &FixedValue) override
Record a relocation entry.
void computeSectionAddresses(const MCAssembler &Asm, const MCAsmLayout &Layout)
void writeSymtabLoadCommand(uint32_t SymbolOffset, uint32_t NumSymbols, uint32_t StringTableOffset, uint32_t StringTableSize)
void bindIndirectSymbols(MCAssembler &Asm)
uint64_t getPaddingSize(const MCSection *SD, const MCAsmLayout &Layout) const
MachObjectWriter(std::unique_ptr< MCMachObjectTargetWriter > MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Utility for building string tables with deduplicated suffixes.
Target - Wrapper for Target specific information.
ObjectFormatType
Definition: Triple.h:285
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
An abstract base class for streams implementations that also support a pwrite operation.
Definition: raw_ostream.h:444
HeaderFileType
Definition: MachO.h:40
@ CPU_TYPE_X86_64
Definition: MachO.h:1566
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:361
std::unique_ptr< MCObjectWriter > createMachObjectWriter(std::unique_ptr< MCMachObjectTargetWriter > MOTW, raw_pwrite_stream &OS, bool IsLittleEndian)
Construct a new Mach-O writer instance.
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:1858
endianness
Definition: bit.h:70
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:67