[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / llvm / lib / ObjCopy / MachO / MachOObject.h
blobb3303fd291c82c663b92d553bb9cfc3ad2268d8e
1 //===- MachOObject.h - Mach-O object file model -----------------*- 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 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIB_OBJCOPY_MACHO_MACHOOBJECT_H
10 #define LLVM_LIB_OBJCOPY_MACHO_MACHOOBJECT_H
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/BinaryFormat/MachO.h"
14 #include "llvm/MC/StringTableBuilder.h"
15 #include "llvm/ObjectYAML/DWARFYAML.h"
16 #include "llvm/Support/StringSaver.h"
17 #include "llvm/Support/YAMLTraits.h"
18 #include <cstdint>
19 #include <string>
20 #include <vector>
22 namespace llvm {
23 namespace objcopy {
24 namespace macho {
26 struct MachHeader {
27 uint32_t Magic;
28 uint32_t CPUType;
29 uint32_t CPUSubType;
30 uint32_t FileType;
31 uint32_t NCmds;
32 uint32_t SizeOfCmds;
33 uint32_t Flags;
34 uint32_t Reserved = 0;
37 struct RelocationInfo;
38 struct Section {
39 uint32_t Index;
40 std::string Segname;
41 std::string Sectname;
42 // CanonicalName is a string formatted as “<Segname>,<Sectname>".
43 std::string CanonicalName;
44 uint64_t Addr = 0;
45 uint64_t Size = 0;
46 // Offset in the input file.
47 std::optional<uint32_t> OriginalOffset;
48 uint32_t Offset = 0;
49 uint32_t Align = 0;
50 uint32_t RelOff = 0;
51 uint32_t NReloc = 0;
52 uint32_t Flags = 0;
53 uint32_t Reserved1 = 0;
54 uint32_t Reserved2 = 0;
55 uint32_t Reserved3 = 0;
56 StringRef Content;
57 std::vector<RelocationInfo> Relocations;
59 Section(StringRef SegName, StringRef SectName);
61 Section(StringRef SegName, StringRef SectName, StringRef Content);
63 MachO::SectionType getType() const {
64 return static_cast<MachO::SectionType>(Flags & MachO::SECTION_TYPE);
67 bool isVirtualSection() const {
68 return (getType() == MachO::S_ZEROFILL ||
69 getType() == MachO::S_GB_ZEROFILL ||
70 getType() == MachO::S_THREAD_LOCAL_ZEROFILL);
73 bool hasValidOffset() const {
74 return !(isVirtualSection() || (OriginalOffset && *OriginalOffset == 0));
78 struct LoadCommand {
79 // The type MachO::macho_load_command is defined in llvm/BinaryFormat/MachO.h
80 // and it is a union of all the structs corresponding to various load
81 // commands.
82 MachO::macho_load_command MachOLoadCommand;
84 // The raw content of the payload of the load command (located right after the
85 // corresponding struct). In some cases it is either empty or can be
86 // copied-over without digging into its structure.
87 std::vector<uint8_t> Payload;
89 // Some load commands can contain (inside the payload) an array of sections,
90 // though the contents of the sections are stored separately. The struct
91 // Section describes only sections' metadata and where to find the
92 // corresponding content inside the binary.
93 std::vector<std::unique_ptr<Section>> Sections;
95 // Returns the segment name if the load command is a segment command.
96 std::optional<StringRef> getSegmentName() const;
98 // Returns the segment vm address if the load command is a segment command.
99 std::optional<uint64_t> getSegmentVMAddr() const;
102 // A symbol information. Fields which starts with "n_" are same as them in the
103 // nlist.
104 struct SymbolEntry {
105 std::string Name;
106 bool Referenced = false;
107 uint32_t Index;
108 uint8_t n_type;
109 uint8_t n_sect;
110 uint16_t n_desc;
111 uint64_t n_value;
113 bool isExternalSymbol() const { return n_type & MachO::N_EXT; }
115 bool isLocalSymbol() const { return !isExternalSymbol(); }
117 bool isUndefinedSymbol() const {
118 return (n_type & MachO::N_TYPE) == MachO::N_UNDF;
121 bool isSwiftSymbol() const {
122 return StringRef(Name).starts_with("_$s") ||
123 StringRef(Name).starts_with("_$S");
126 std::optional<uint32_t> section() const {
127 return n_sect == MachO::NO_SECT ? std::nullopt
128 : std::optional<uint32_t>(n_sect);
132 /// The location of the symbol table inside the binary is described by LC_SYMTAB
133 /// load command.
134 struct SymbolTable {
135 std::vector<std::unique_ptr<SymbolEntry>> Symbols;
137 using iterator = pointee_iterator<
138 std::vector<std::unique_ptr<SymbolEntry>>::const_iterator>;
140 iterator begin() const { return iterator(Symbols.begin()); }
141 iterator end() const { return iterator(Symbols.end()); }
143 const SymbolEntry *getSymbolByIndex(uint32_t Index) const;
144 SymbolEntry *getSymbolByIndex(uint32_t Index);
145 void removeSymbols(
146 function_ref<bool(const std::unique_ptr<SymbolEntry> &)> ToRemove);
149 struct IndirectSymbolEntry {
150 // The original value in an indirect symbol table. Higher bits encode extra
151 // information (INDIRECT_SYMBOL_LOCAL and INDIRECT_SYMBOL_ABS).
152 uint32_t OriginalIndex;
153 /// The Symbol referenced by this entry. It's std::nullopt if the index is
154 /// INDIRECT_SYMBOL_LOCAL or INDIRECT_SYMBOL_ABS.
155 std::optional<SymbolEntry *> Symbol;
157 IndirectSymbolEntry(uint32_t OriginalIndex,
158 std::optional<SymbolEntry *> Symbol)
159 : OriginalIndex(OriginalIndex), Symbol(Symbol) {}
162 struct IndirectSymbolTable {
163 std::vector<IndirectSymbolEntry> Symbols;
166 /// The location of the string table inside the binary is described by LC_SYMTAB
167 /// load command.
168 struct StringTable {
169 std::vector<std::string> Strings;
172 struct RelocationInfo {
173 // The referenced symbol entry. Set if !Scattered && Extern.
174 std::optional<const SymbolEntry *> Symbol;
175 // The referenced section. Set if !Scattered && !Extern.
176 std::optional<const Section *> Sec;
177 // True if Info is a scattered_relocation_info.
178 bool Scattered;
179 // True if the type is an ADDEND. r_symbolnum holds the addend instead of a
180 // symbol index.
181 bool IsAddend;
182 // True if the r_symbolnum points to a section number (i.e. r_extern=0).
183 bool Extern;
184 MachO::any_relocation_info Info;
186 unsigned getPlainRelocationSymbolNum(bool IsLittleEndian) {
187 if (IsLittleEndian)
188 return Info.r_word1 & 0xffffff;
189 return Info.r_word1 >> 8;
192 void setPlainRelocationSymbolNum(unsigned SymbolNum, bool IsLittleEndian) {
193 assert(SymbolNum < (1 << 24) && "SymbolNum out of range");
194 if (IsLittleEndian)
195 Info.r_word1 = (Info.r_word1 & ~0x00ffffff) | SymbolNum;
196 else
197 Info.r_word1 = (Info.r_word1 & ~0xffffff00) | (SymbolNum << 8);
201 /// The location of the rebase info inside the binary is described by
202 /// LC_DYLD_INFO load command. Dyld rebases an image whenever dyld loads it at
203 /// an address different from its preferred address. The rebase information is
204 /// a stream of byte sized opcodes whose symbolic names start with
205 /// REBASE_OPCODE_. Conceptually the rebase information is a table of tuples:
206 /// <seg-index, seg-offset, type>
207 /// The opcodes are a compressed way to encode the table by only
208 /// encoding when a column changes. In addition simple patterns
209 /// like "every n'th offset for m times" can be encoded in a few
210 /// bytes.
211 struct RebaseInfo {
212 // At the moment we do not parse this info (and it is simply copied over),
213 // but the proper support will be added later.
214 ArrayRef<uint8_t> Opcodes;
217 /// The location of the bind info inside the binary is described by
218 /// LC_DYLD_INFO load command. Dyld binds an image during the loading process,
219 /// if the image requires any pointers to be initialized to symbols in other
220 /// images. The bind information is a stream of byte sized opcodes whose
221 /// symbolic names start with BIND_OPCODE_. Conceptually the bind information is
222 /// a table of tuples: <seg-index, seg-offset, type, symbol-library-ordinal,
223 /// symbol-name, addend> The opcodes are a compressed way to encode the table by
224 /// only encoding when a column changes. In addition simple patterns like for
225 /// runs of pointers initialized to the same value can be encoded in a few
226 /// bytes.
227 struct BindInfo {
228 // At the moment we do not parse this info (and it is simply copied over),
229 // but the proper support will be added later.
230 ArrayRef<uint8_t> Opcodes;
233 /// The location of the weak bind info inside the binary is described by
234 /// LC_DYLD_INFO load command. Some C++ programs require dyld to unique symbols
235 /// so that all images in the process use the same copy of some code/data. This
236 /// step is done after binding. The content of the weak_bind info is an opcode
237 /// stream like the bind_info. But it is sorted alphabetically by symbol name.
238 /// This enable dyld to walk all images with weak binding information in order
239 /// and look for collisions. If there are no collisions, dyld does no updating.
240 /// That means that some fixups are also encoded in the bind_info. For
241 /// instance, all calls to "operator new" are first bound to libstdc++.dylib
242 /// using the information in bind_info. Then if some image overrides operator
243 /// new that is detected when the weak_bind information is processed and the
244 /// call to operator new is then rebound.
245 struct WeakBindInfo {
246 // At the moment we do not parse this info (and it is simply copied over),
247 // but the proper support will be added later.
248 ArrayRef<uint8_t> Opcodes;
251 /// The location of the lazy bind info inside the binary is described by
252 /// LC_DYLD_INFO load command. Some uses of external symbols do not need to be
253 /// bound immediately. Instead they can be lazily bound on first use. The
254 /// lazy_bind contains a stream of BIND opcodes to bind all lazy symbols. Normal
255 /// use is that dyld ignores the lazy_bind section when loading an image.
256 /// Instead the static linker arranged for the lazy pointer to initially point
257 /// to a helper function which pushes the offset into the lazy_bind area for the
258 /// symbol needing to be bound, then jumps to dyld which simply adds the offset
259 /// to lazy_bind_off to get the information on what to bind.
260 struct LazyBindInfo {
261 ArrayRef<uint8_t> Opcodes;
264 /// The location of the export info inside the binary is described by
265 /// LC_DYLD_INFO load command. The symbols exported by a dylib are encoded in a
266 /// trie. This is a compact representation that factors out common prefixes. It
267 /// also reduces LINKEDIT pages in RAM because it encodes all information (name,
268 /// address, flags) in one small, contiguous range. The export area is a stream
269 /// of nodes. The first node sequentially is the start node for the trie. Nodes
270 /// for a symbol start with a uleb128 that is the length of the exported symbol
271 /// information for the string so far. If there is no exported symbol, the node
272 /// starts with a zero byte. If there is exported info, it follows the length.
273 /// First is a uleb128 containing flags. Normally, it is followed by
274 /// a uleb128 encoded offset which is location of the content named
275 /// by the symbol from the mach_header for the image. If the flags
276 /// is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is
277 /// a uleb128 encoded library ordinal, then a zero terminated
278 /// UTF8 string. If the string is zero length, then the symbol
279 /// is re-export from the specified dylib with the same name.
280 /// If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, then following
281 /// the flags is two uleb128s: the stub offset and the resolver offset.
282 /// The stub is used by non-lazy pointers. The resolver is used
283 /// by lazy pointers and must be called to get the actual address to use.
284 /// After the optional exported symbol information is a byte of
285 /// how many edges (0-255) that this node has leaving it,
286 /// followed by each edge.
287 /// Each edge is a zero terminated UTF8 of the addition chars
288 /// in the symbol, followed by a uleb128 offset for the node that
289 /// edge points to.
290 struct ExportInfo {
291 ArrayRef<uint8_t> Trie;
294 struct LinkData {
295 ArrayRef<uint8_t> Data;
298 struct Object {
299 MachHeader Header;
300 std::vector<LoadCommand> LoadCommands;
302 SymbolTable SymTable;
303 StringTable StrTable;
305 RebaseInfo Rebases;
306 BindInfo Binds;
307 WeakBindInfo WeakBinds;
308 LazyBindInfo LazyBinds;
309 ExportInfo Exports;
310 IndirectSymbolTable IndirectSymTable;
311 LinkData DataInCode;
312 LinkData LinkerOptimizationHint;
313 LinkData FunctionStarts;
314 LinkData ExportsTrie;
315 LinkData ChainedFixups;
316 LinkData DylibCodeSignDRs;
318 std::optional<uint32_t> SwiftVersion;
320 /// The index of LC_CODE_SIGNATURE load command if present.
321 std::optional<size_t> CodeSignatureCommandIndex;
322 /// The index of LC_DYLIB_CODE_SIGN_DRS load command if present.
323 std::optional<size_t> DylibCodeSignDRsIndex;
324 /// The index of LC_SYMTAB load command if present.
325 std::optional<size_t> SymTabCommandIndex;
326 /// The index of LC_DYLD_INFO or LC_DYLD_INFO_ONLY load command if present.
327 std::optional<size_t> DyLdInfoCommandIndex;
328 /// The index LC_DYSYMTAB load command if present.
329 std::optional<size_t> DySymTabCommandIndex;
330 /// The index LC_DATA_IN_CODE load command if present.
331 std::optional<size_t> DataInCodeCommandIndex;
332 /// The index of LC_LINKER_OPTIMIZATIN_HINT load command if present.
333 std::optional<size_t> LinkerOptimizationHintCommandIndex;
334 /// The index LC_FUNCTION_STARTS load command if present.
335 std::optional<size_t> FunctionStartsCommandIndex;
336 /// The index LC_DYLD_CHAINED_FIXUPS load command if present.
337 std::optional<size_t> ChainedFixupsCommandIndex;
338 /// The index LC_DYLD_EXPORTS_TRIE load command if present.
339 std::optional<size_t> ExportsTrieCommandIndex;
340 /// The index of the LC_SEGMENT or LC_SEGMENT_64 load command
341 /// corresponding to the __TEXT segment.
342 std::optional<size_t> TextSegmentCommandIndex;
344 BumpPtrAllocator Alloc;
345 StringSaver NewSectionsContents;
347 Object() : NewSectionsContents(Alloc) {}
349 Error
350 removeSections(function_ref<bool(const std::unique_ptr<Section> &)> ToRemove);
352 Error removeLoadCommands(function_ref<bool(const LoadCommand &)> ToRemove);
354 void updateLoadCommandIndexes();
356 /// Creates a new segment load command in the object and returns a reference
357 /// to the newly created load command. The caller should verify that SegName
358 /// is not too long (SegName.size() should be less than or equal to 16).
359 LoadCommand &addSegment(StringRef SegName, uint64_t SegVMSize);
361 bool is64Bit() const {
362 return Header.Magic == MachO::MH_MAGIC_64 ||
363 Header.Magic == MachO::MH_CIGAM_64;
366 uint64_t nextAvailableSegmentAddress() const;
369 } // end namespace macho
370 } // end namespace objcopy
371 } // end namespace llvm
373 #endif // LLVM_LIB_OBJCOPY_MACHO_MACHOOBJECT_H