xref: /llvm-project/llvm/lib/ObjCopy/MachO/MachOObject.h (revision 1a830aa1fe1e88749b563fefe18382842e0cff90)
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 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_LIB_OBJCOPY_MACHO_MACHOOBJECT_H
10 #define LLVM_LIB_OBJCOPY_MACHO_MACHOOBJECT_H
11 
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>
21 
22 namespace llvm {
23 namespace objcopy {
24 namespace macho {
25 
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;
35 };
36 
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;
58 
59   Section(StringRef SegName, StringRef SectName);
60 
61   Section(StringRef SegName, StringRef SectName, StringRef Content);
62 
63   MachO::SectionType getType() const {
64     return static_cast<MachO::SectionType>(Flags & MachO::SECTION_TYPE);
65   }
66 
67   bool isVirtualSection() const {
68     return (getType() == MachO::S_ZEROFILL ||
69             getType() == MachO::S_GB_ZEROFILL ||
70             getType() == MachO::S_THREAD_LOCAL_ZEROFILL);
71   }
72 
73   bool hasValidOffset() const {
74     return !(isVirtualSection() || (OriginalOffset && *OriginalOffset == 0));
75   }
76 };
77 
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;
83 
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;
88 
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;
94 
95   // Returns the segment name if the load command is a segment command.
96   std::optional<StringRef> getSegmentName() const;
97 
98   // Returns the segment vm address if the load command is a segment command.
99   std::optional<uint64_t> getSegmentVMAddr() const;
100 };
101 
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;
112 
113   bool isExternalSymbol() const { return n_type & MachO::N_EXT; }
114 
115   bool isLocalSymbol() const { return !isExternalSymbol(); }
116 
117   bool isUndefinedSymbol() const {
118     return (n_type & MachO::N_TYPE) == MachO::N_UNDF;
119   }
120 
121   bool isSwiftSymbol() const {
122     return StringRef(Name).starts_with("_$s") ||
123            StringRef(Name).starts_with("_$S");
124   }
125 
126   std::optional<uint32_t> section() const {
127     return n_sect == MachO::NO_SECT ? std::nullopt
128                                     : std::optional<uint32_t>(n_sect);
129   }
130 };
131 
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;
136 
137   using iterator = pointee_iterator<
138       std::vector<std::unique_ptr<SymbolEntry>>::const_iterator>;
139 
140   iterator begin() const { return iterator(Symbols.begin()); }
141   iterator end() const { return iterator(Symbols.end()); }
142 
143   const SymbolEntry *getSymbolByIndex(uint32_t Index) const;
144   SymbolEntry *getSymbolByIndex(uint32_t Index);
145   void updateSymbols(function_ref<void(SymbolEntry &)> Callable);
146   void removeSymbols(
147       function_ref<bool(const std::unique_ptr<SymbolEntry> &)> ToRemove);
148 };
149 
150 struct IndirectSymbolEntry {
151   // The original value in an indirect symbol table. Higher bits encode extra
152   // information (INDIRECT_SYMBOL_LOCAL and INDIRECT_SYMBOL_ABS).
153   uint32_t OriginalIndex;
154   /// The Symbol referenced by this entry. It's std::nullopt if the index is
155   /// INDIRECT_SYMBOL_LOCAL or INDIRECT_SYMBOL_ABS.
156   std::optional<SymbolEntry *> Symbol;
157 
158   IndirectSymbolEntry(uint32_t OriginalIndex,
159                       std::optional<SymbolEntry *> Symbol)
160       : OriginalIndex(OriginalIndex), Symbol(Symbol) {}
161 };
162 
163 struct IndirectSymbolTable {
164   std::vector<IndirectSymbolEntry> Symbols;
165 };
166 
167 /// The location of the string table inside the binary is described by LC_SYMTAB
168 /// load command.
169 struct StringTable {
170   std::vector<std::string> Strings;
171 };
172 
173 struct RelocationInfo {
174   // The referenced symbol entry. Set if !Scattered && Extern.
175   std::optional<const SymbolEntry *> Symbol;
176   // The referenced section. Set if !Scattered && !Extern.
177   std::optional<const Section *> Sec;
178   // True if Info is a scattered_relocation_info.
179   bool Scattered;
180   // True if the type is an ADDEND. r_symbolnum holds the addend instead of a
181   // symbol index.
182   bool IsAddend;
183   // True if the r_symbolnum points to a section number (i.e. r_extern=0).
184   bool Extern;
185   MachO::any_relocation_info Info;
186 
187   unsigned getPlainRelocationSymbolNum(bool IsLittleEndian) {
188     if (IsLittleEndian)
189       return Info.r_word1 & 0xffffff;
190     return Info.r_word1 >> 8;
191   }
192 
193   void setPlainRelocationSymbolNum(unsigned SymbolNum, bool IsLittleEndian) {
194     assert(SymbolNum < (1 << 24) && "SymbolNum out of range");
195     if (IsLittleEndian)
196       Info.r_word1 = (Info.r_word1 & ~0x00ffffff) | SymbolNum;
197     else
198       Info.r_word1 = (Info.r_word1 & ~0xffffff00) | (SymbolNum << 8);
199   }
200 };
201 
202 /// The location of the rebase info inside the binary is described by
203 /// LC_DYLD_INFO load command. Dyld rebases an image whenever dyld loads it at
204 /// an address different from its preferred address.  The rebase information is
205 /// a stream of byte sized opcodes whose symbolic names start with
206 /// REBASE_OPCODE_. Conceptually the rebase information is a table of tuples:
207 ///   <seg-index, seg-offset, type>
208 /// The opcodes are a compressed way to encode the table by only
209 /// encoding when a column changes.  In addition simple patterns
210 /// like "every n'th offset for m times" can be encoded in a few
211 /// bytes.
212 struct RebaseInfo {
213   // At the moment we do not parse this info (and it is simply copied over),
214   // but the proper support will be added later.
215   ArrayRef<uint8_t> Opcodes;
216 };
217 
218 /// The location of the bind info inside the binary is described by
219 /// LC_DYLD_INFO load command. Dyld binds an image during the loading process,
220 /// if the image requires any pointers to be initialized to symbols in other
221 /// images. The bind information is a stream of byte sized opcodes whose
222 /// symbolic names start with BIND_OPCODE_. Conceptually the bind information is
223 /// a table of tuples: <seg-index, seg-offset, type, symbol-library-ordinal,
224 /// symbol-name, addend> The opcodes are a compressed way to encode the table by
225 /// only encoding when a column changes.  In addition simple patterns like for
226 /// runs of pointers initialized to the same value can be encoded in a few
227 /// bytes.
228 struct BindInfo {
229   // At the moment we do not parse this info (and it is simply copied over),
230   // but the proper support will be added later.
231   ArrayRef<uint8_t> Opcodes;
232 };
233 
234 /// The location of the weak bind info inside the binary is described by
235 /// LC_DYLD_INFO load command. Some C++ programs require dyld to unique symbols
236 /// so that all images in the process use the same copy of some code/data. This
237 /// step is done after binding. The content of the weak_bind info is an opcode
238 /// stream like the bind_info.  But it is sorted alphabetically by symbol name.
239 /// This enable dyld to walk all images with weak binding information in order
240 /// and look for collisions.  If there are no collisions, dyld does no updating.
241 /// That means that some fixups are also encoded in the bind_info.  For
242 /// instance, all calls to "operator new" are first bound to libstdc++.dylib
243 /// using the information in bind_info.  Then if some image overrides operator
244 /// new that is detected when the weak_bind information is processed and the
245 /// call to operator new is then rebound.
246 struct WeakBindInfo {
247   // At the moment we do not parse this info (and it is simply copied over),
248   // but the proper support will be added later.
249   ArrayRef<uint8_t> Opcodes;
250 };
251 
252 /// The location of the lazy bind info inside the binary is described by
253 /// LC_DYLD_INFO load command. Some uses of external symbols do not need to be
254 /// bound immediately. Instead they can be lazily bound on first use.  The
255 /// lazy_bind contains a stream of BIND opcodes to bind all lazy symbols. Normal
256 /// use is that dyld ignores the lazy_bind section when loading an image.
257 /// Instead the static linker arranged for the lazy pointer to initially point
258 /// to a helper function which pushes the offset into the lazy_bind area for the
259 /// symbol needing to be bound, then jumps to dyld which simply adds the offset
260 /// to lazy_bind_off to get the information on what to bind.
261 struct LazyBindInfo {
262   ArrayRef<uint8_t> Opcodes;
263 };
264 
265 /// The location of the export info inside the binary is described by
266 /// LC_DYLD_INFO load command. The symbols exported by a dylib are encoded in a
267 /// trie.  This is a compact representation that factors out common prefixes. It
268 /// also reduces LINKEDIT pages in RAM because it encodes all information (name,
269 /// address, flags) in one small, contiguous range. The export area is a stream
270 /// of nodes.  The first node sequentially is the start node for the trie. Nodes
271 /// for a symbol start with a uleb128 that is the length of the exported symbol
272 /// information for the string so far. If there is no exported symbol, the node
273 /// starts with a zero byte. If there is exported info, it follows the length.
274 /// First is a uleb128 containing flags. Normally, it is followed by
275 /// a uleb128 encoded offset which is location of the content named
276 /// by the symbol from the mach_header for the image.  If the flags
277 /// is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is
278 /// a uleb128 encoded library ordinal, then a zero terminated
279 /// UTF8 string.  If the string is zero length, then the symbol
280 /// is re-export from the specified dylib with the same name.
281 /// If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, then following
282 /// the flags is two uleb128s: the stub offset and the resolver offset.
283 /// The stub is used by non-lazy pointers.  The resolver is used
284 /// by lazy pointers and must be called to get the actual address to use.
285 /// After the optional exported symbol information is a byte of
286 /// how many edges (0-255) that this node has leaving it,
287 /// followed by each edge.
288 /// Each edge is a zero terminated UTF8 of the addition chars
289 /// in the symbol, followed by a uleb128 offset for the node that
290 /// edge points to.
291 struct ExportInfo {
292   ArrayRef<uint8_t> Trie;
293 };
294 
295 struct LinkData {
296   ArrayRef<uint8_t> Data;
297 };
298 
299 struct Object {
300   MachHeader Header;
301   std::vector<LoadCommand> LoadCommands;
302 
303   SymbolTable SymTable;
304   StringTable StrTable;
305 
306   RebaseInfo Rebases;
307   BindInfo Binds;
308   WeakBindInfo WeakBinds;
309   LazyBindInfo LazyBinds;
310   ExportInfo Exports;
311   IndirectSymbolTable IndirectSymTable;
312   LinkData DataInCode;
313   LinkData LinkerOptimizationHint;
314   LinkData FunctionStarts;
315   LinkData ExportsTrie;
316   LinkData ChainedFixups;
317   LinkData DylibCodeSignDRs;
318 
319   std::optional<uint32_t> SwiftVersion;
320 
321   /// The index of LC_CODE_SIGNATURE load command if present.
322   std::optional<size_t> CodeSignatureCommandIndex;
323   /// The index of LC_DYLIB_CODE_SIGN_DRS load command if present.
324   std::optional<size_t> DylibCodeSignDRsIndex;
325   /// The index of LC_SYMTAB load command if present.
326   std::optional<size_t> SymTabCommandIndex;
327   /// The index of LC_DYLD_INFO or LC_DYLD_INFO_ONLY load command if present.
328   std::optional<size_t> DyLdInfoCommandIndex;
329   /// The index LC_DYSYMTAB load command if present.
330   std::optional<size_t> DySymTabCommandIndex;
331   /// The index LC_DATA_IN_CODE load command if present.
332   std::optional<size_t> DataInCodeCommandIndex;
333   /// The index of LC_LINKER_OPTIMIZATIN_HINT load command if present.
334   std::optional<size_t> LinkerOptimizationHintCommandIndex;
335   /// The index LC_FUNCTION_STARTS load command if present.
336   std::optional<size_t> FunctionStartsCommandIndex;
337   /// The index LC_DYLD_CHAINED_FIXUPS load command if present.
338   std::optional<size_t> ChainedFixupsCommandIndex;
339   /// The index LC_DYLD_EXPORTS_TRIE load command if present.
340   std::optional<size_t> ExportsTrieCommandIndex;
341   /// The index of the LC_SEGMENT or LC_SEGMENT_64 load command
342   /// corresponding to the __TEXT segment.
343   std::optional<size_t> TextSegmentCommandIndex;
344   /// The index of the LC_ENCRYPTION_INFO or LC_ENCRYPTION_INFO_64 load command
345   /// if present.
346   std::optional<size_t> EncryptionInfoCommandIndex;
347 
348   BumpPtrAllocator Alloc;
349   StringSaver NewSectionsContents;
350 
351   Object() : NewSectionsContents(Alloc) {}
352 
353   Error
354   removeSections(function_ref<bool(const std::unique_ptr<Section> &)> ToRemove);
355 
356   Error removeLoadCommands(function_ref<bool(const LoadCommand &)> ToRemove);
357 
358   void updateLoadCommandIndexes();
359 
360   /// Creates a new segment load command in the object and returns a reference
361   /// to the newly created load command. The caller should verify that SegName
362   /// is not too long (SegName.size() should be less than or equal to 16).
363   LoadCommand &addSegment(StringRef SegName, uint64_t SegVMSize);
364 
365   bool is64Bit() const {
366     return Header.Magic == MachO::MH_MAGIC_64 ||
367            Header.Magic == MachO::MH_CIGAM_64;
368   }
369 
370   uint64_t nextAvailableSegmentAddress() const;
371 };
372 
373 } // end namespace macho
374 } // end namespace objcopy
375 } // end namespace llvm
376 
377 #endif // LLVM_LIB_OBJCOPY_MACHO_MACHOOBJECT_H
378