1 //===- Object.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_OBJCOPY_MACHO_OBJECT_H 10 #define LLVM_OBJCOPY_MACHO_OBJECT_H 11 12 #include "llvm/ADT/Optional.h" 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/BinaryFormat/MachO.h" 15 #include "llvm/MC/StringTableBuilder.h" 16 #include "llvm/ObjectYAML/DWARFYAML.h" 17 #include "llvm/Support/StringSaver.h" 18 #include "llvm/Support/YAMLTraits.h" 19 #include <cstdint> 20 #include <string> 21 #include <vector> 22 23 namespace llvm { 24 namespace objcopy { 25 namespace macho { 26 27 struct MachHeader { 28 uint32_t Magic; 29 uint32_t CPUType; 30 uint32_t CPUSubType; 31 uint32_t FileType; 32 uint32_t NCmds; 33 uint32_t SizeOfCmds; 34 uint32_t Flags; 35 uint32_t Reserved = 0; 36 }; 37 38 struct RelocationInfo; 39 struct Section { 40 uint32_t Index; 41 std::string Segname; 42 std::string Sectname; 43 // CanonicalName is a string formatted as “<Segname>,<Sectname>". 44 std::string CanonicalName; 45 uint64_t Addr = 0; 46 uint64_t Size = 0; 47 // Offset in the input file. 48 Optional<uint32_t> OriginalOffset; 49 uint32_t Offset = 0; 50 uint32_t Align = 0; 51 uint32_t RelOff = 0; 52 uint32_t NReloc = 0; 53 uint32_t Flags = 0; 54 uint32_t Reserved1 = 0; 55 uint32_t Reserved2 = 0; 56 uint32_t Reserved3 = 0; 57 StringRef Content; 58 std::vector<RelocationInfo> Relocations; 59 SectionSection60 Section(StringRef SegName, StringRef SectName) 61 : Segname(std::string(SegName)), Sectname(std::string(SectName)), 62 CanonicalName((Twine(SegName) + Twine(',') + SectName).str()) {} 63 SectionSection64 Section(StringRef SegName, StringRef SectName, StringRef Content) 65 : Segname(std::string(SegName)), Sectname(std::string(SectName)), 66 CanonicalName((Twine(SegName) + Twine(',') + SectName).str()), 67 Content(Content) {} 68 getTypeSection69 MachO::SectionType getType() const { 70 return static_cast<MachO::SectionType>(Flags & MachO::SECTION_TYPE); 71 } 72 isVirtualSectionSection73 bool isVirtualSection() const { 74 return (getType() == MachO::S_ZEROFILL || 75 getType() == MachO::S_GB_ZEROFILL || 76 getType() == MachO::S_THREAD_LOCAL_ZEROFILL); 77 } 78 hasValidOffsetSection79 bool hasValidOffset() const { 80 return !(isVirtualSection() || (OriginalOffset && *OriginalOffset == 0)); 81 } 82 }; 83 84 struct LoadCommand { 85 // The type MachO::macho_load_command is defined in llvm/BinaryFormat/MachO.h 86 // and it is a union of all the structs corresponding to various load 87 // commands. 88 MachO::macho_load_command MachOLoadCommand; 89 90 // The raw content of the payload of the load command (located right after the 91 // corresponding struct). In some cases it is either empty or can be 92 // copied-over without digging into its structure. 93 std::vector<uint8_t> Payload; 94 95 // Some load commands can contain (inside the payload) an array of sections, 96 // though the contents of the sections are stored separately. The struct 97 // Section describes only sections' metadata and where to find the 98 // corresponding content inside the binary. 99 std::vector<std::unique_ptr<Section>> Sections; 100 101 // Returns the segment name if the load command is a segment command. 102 Optional<StringRef> getSegmentName() const; 103 104 // Returns the segment vm address if the load command is a segment command. 105 Optional<uint64_t> getSegmentVMAddr() const; 106 }; 107 108 // A symbol information. Fields which starts with "n_" are same as them in the 109 // nlist. 110 struct SymbolEntry { 111 std::string Name; 112 bool Referenced = false; 113 uint32_t Index; 114 uint8_t n_type; 115 uint8_t n_sect; 116 uint16_t n_desc; 117 uint64_t n_value; 118 isExternalSymbolSymbolEntry119 bool isExternalSymbol() const { return n_type & MachO::N_EXT; } 120 isLocalSymbolSymbolEntry121 bool isLocalSymbol() const { return !isExternalSymbol(); } 122 isUndefinedSymbolSymbolEntry123 bool isUndefinedSymbol() const { 124 return (n_type & MachO::N_TYPE) == MachO::N_UNDF; 125 } 126 isSwiftSymbolSymbolEntry127 bool isSwiftSymbol() const { 128 return StringRef(Name).startswith("_$s") || 129 StringRef(Name).startswith("_$S"); 130 } 131 sectionSymbolEntry132 Optional<uint32_t> section() const { 133 return n_sect == MachO::NO_SECT ? None : Optional<uint32_t>(n_sect); 134 } 135 }; 136 137 /// The location of the symbol table inside the binary is described by LC_SYMTAB 138 /// load command. 139 struct SymbolTable { 140 std::vector<std::unique_ptr<SymbolEntry>> Symbols; 141 142 using iterator = pointee_iterator< 143 std::vector<std::unique_ptr<SymbolEntry>>::const_iterator>; 144 beginSymbolTable145 iterator begin() const { return iterator(Symbols.begin()); } endSymbolTable146 iterator end() const { return iterator(Symbols.end()); } 147 148 const SymbolEntry *getSymbolByIndex(uint32_t Index) const; 149 SymbolEntry *getSymbolByIndex(uint32_t Index); 150 void removeSymbols( 151 function_ref<bool(const std::unique_ptr<SymbolEntry> &)> ToRemove); 152 }; 153 154 struct IndirectSymbolEntry { 155 // The original value in an indirect symbol table. Higher bits encode extra 156 // information (INDIRECT_SYMBOL_LOCAL and INDIRECT_SYMBOL_ABS). 157 uint32_t OriginalIndex; 158 /// The Symbol referenced by this entry. It's None if the index is 159 /// INDIRECT_SYMBOL_LOCAL or INDIRECT_SYMBOL_ABS. 160 Optional<SymbolEntry *> Symbol; 161 IndirectSymbolEntryIndirectSymbolEntry162 IndirectSymbolEntry(uint32_t OriginalIndex, Optional<SymbolEntry *> Symbol) 163 : OriginalIndex(OriginalIndex), Symbol(Symbol) {} 164 }; 165 166 struct IndirectSymbolTable { 167 std::vector<IndirectSymbolEntry> Symbols; 168 }; 169 170 /// The location of the string table inside the binary is described by LC_SYMTAB 171 /// load command. 172 struct StringTable { 173 std::vector<std::string> Strings; 174 }; 175 176 struct RelocationInfo { 177 // The referenced symbol entry. Set if !Scattered && Extern. 178 Optional<const SymbolEntry *> Symbol; 179 // The referenced section. Set if !Scattered && !Extern. 180 Optional<const Section *> Sec; 181 // True if Info is a scattered_relocation_info. 182 bool Scattered; 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 getPlainRelocationSymbolNumRelocationInfo187 unsigned getPlainRelocationSymbolNum(bool IsLittleEndian) { 188 if (IsLittleEndian) 189 return Info.r_word1 & 0xffffff; 190 return Info.r_word1 >> 8; 191 } 192 setPlainRelocationSymbolNumRelocationInfo193 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 FunctionStarts; 314 LinkData CodeSignature; 315 316 Optional<uint32_t> SwiftVersion; 317 318 /// The index of LC_CODE_SIGNATURE load command if present. 319 Optional<size_t> CodeSignatureCommandIndex; 320 /// The index of LC_SYMTAB load command if present. 321 Optional<size_t> SymTabCommandIndex; 322 /// The index of LC_DYLD_INFO or LC_DYLD_INFO_ONLY load command if present. 323 Optional<size_t> DyLdInfoCommandIndex; 324 /// The index LC_DYSYMTAB load comamnd if present. 325 Optional<size_t> DySymTabCommandIndex; 326 /// The index LC_DATA_IN_CODE load comamnd if present. 327 Optional<size_t> DataInCodeCommandIndex; 328 /// The index LC_FUNCTION_STARTS load comamnd if present. 329 Optional<size_t> FunctionStartsCommandIndex; 330 331 BumpPtrAllocator Alloc; 332 StringSaver NewSectionsContents; 333 ObjectObject334 Object() : NewSectionsContents(Alloc) {} 335 336 Error 337 removeSections(function_ref<bool(const std::unique_ptr<Section> &)> ToRemove); 338 339 Error removeLoadCommands(function_ref<bool(const LoadCommand &)> ToRemove); 340 341 void updateLoadCommandIndexes(); 342 343 /// Creates a new segment load command in the object and returns a reference 344 /// to the newly created load command. The caller should verify that SegName 345 /// is not too long (SegName.size() should be less than or equal to 16). 346 LoadCommand &addSegment(StringRef SegName, uint64_t SegVMSize); 347 is64BitObject348 bool is64Bit() const { 349 return Header.Magic == MachO::MH_MAGIC_64 || 350 Header.Magic == MachO::MH_CIGAM_64; 351 } 352 353 uint64_t nextAvailableSegmentAddress() const; 354 }; 355 356 } // end namespace macho 357 } // end namespace objcopy 358 } // end namespace llvm 359 360 #endif // LLVM_OBJCOPY_MACHO_OBJECT_H 361