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).startswith("_$s") || 123 StringRef(Name).startswith("_$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 removeSymbols( 146 function_ref<bool(const std::unique_ptr<SymbolEntry> &)> ToRemove); 147 }; 148 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; 156 157 IndirectSymbolEntry(uint32_t OriginalIndex, 158 std::optional<SymbolEntry *> Symbol) 159 : OriginalIndex(OriginalIndex), Symbol(Symbol) {} 160 }; 161 162 struct IndirectSymbolTable { 163 std::vector<IndirectSymbolEntry> Symbols; 164 }; 165 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; 170 }; 171 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; 185 186 unsigned getPlainRelocationSymbolNum(bool IsLittleEndian) { 187 if (IsLittleEndian) 188 return Info.r_word1 & 0xffffff; 189 return Info.r_word1 >> 8; 190 } 191 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); 198 } 199 }; 200 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; 215 }; 216 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; 231 }; 232 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; 249 }; 250 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; 262 }; 263 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; 292 }; 293 294 struct LinkData { 295 ArrayRef<uint8_t> Data; 296 }; 297 298 struct Object { 299 MachHeader Header; 300 std::vector<LoadCommand> LoadCommands; 301 302 SymbolTable SymTable; 303 StringTable StrTable; 304 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; 317 318 std::optional<uint32_t> SwiftVersion; 319 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; 343 344 BumpPtrAllocator Alloc; 345 StringSaver NewSectionsContents; 346 347 Object() : NewSectionsContents(Alloc) {} 348 349 Error 350 removeSections(function_ref<bool(const std::unique_ptr<Section> &)> ToRemove); 351 352 Error removeLoadCommands(function_ref<bool(const LoadCommand &)> ToRemove); 353 354 void updateLoadCommandIndexes(); 355 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); 360 361 bool is64Bit() const { 362 return Header.Magic == MachO::MH_MAGIC_64 || 363 Header.Magic == MachO::MH_CIGAM_64; 364 } 365 366 uint64_t nextAvailableSegmentAddress() const; 367 }; 368 369 } // end namespace macho 370 } // end namespace objcopy 371 } // end namespace llvm 372 373 #endif // LLVM_LIB_OBJCOPY_MACHO_MACHOOBJECT_H 374