Home | History | Annotate | Line # | Download | only in MachO
      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 
     60   Section(StringRef SegName, StringRef SectName)
     61       : Segname(std::string(SegName)), Sectname(std::string(SectName)),
     62         CanonicalName((Twine(SegName) + Twine(',') + SectName).str()) {}
     63 
     64   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 
     69   MachO::SectionType getType() const {
     70     return static_cast<MachO::SectionType>(Flags & MachO::SECTION_TYPE);
     71   }
     72 
     73   bool isVirtualSection() const {
     74     return (getType() == MachO::S_ZEROFILL ||
     75             getType() == MachO::S_GB_ZEROFILL ||
     76             getType() == MachO::S_THREAD_LOCAL_ZEROFILL);
     77   }
     78 
     79   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 
    119   bool isExternalSymbol() const { return n_type & MachO::N_EXT; }
    120 
    121   bool isLocalSymbol() const { return !isExternalSymbol(); }
    122 
    123   bool isUndefinedSymbol() const {
    124     return (n_type & MachO::N_TYPE) == MachO::N_UNDF;
    125   }
    126 
    127   bool isSwiftSymbol() const {
    128     return StringRef(Name).startswith("_$s") ||
    129            StringRef(Name).startswith("_$S");
    130   }
    131 
    132   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 
    145   iterator begin() const { return iterator(Symbols.begin()); }
    146   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 
    162   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 
    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 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 
    334   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 
    348   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