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