Home | History | Annotate | Download | only in Object
      1 //===- MachO.h - MachO object file implementation ---------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file declares the MachOObjectFile class, which implement the ObjectFile
     11 // interface for MachO files.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_OBJECT_MACHO_H
     16 #define LLVM_OBJECT_MACHO_H
     17 
     18 #include "llvm/ADT/ArrayRef.h"
     19 #include "llvm/ADT/SmallString.h"
     20 #include "llvm/ADT/SmallVector.h"
     21 #include "llvm/ADT/StringExtras.h"
     22 #include "llvm/ADT/StringRef.h"
     23 #include "llvm/ADT/Triple.h"
     24 #include "llvm/ADT/iterator_range.h"
     25 #include "llvm/BinaryFormat/MachO.h"
     26 #include "llvm/MC/SubtargetFeature.h"
     27 #include "llvm/Object/Binary.h"
     28 #include "llvm/Object/ObjectFile.h"
     29 #include "llvm/Object/SymbolicFile.h"
     30 #include "llvm/Support/Error.h"
     31 #include "llvm/Support/Format.h"
     32 #include "llvm/Support/MemoryBuffer.h"
     33 #include "llvm/Support/raw_ostream.h"
     34 #include <cstdint>
     35 #include <memory>
     36 #include <string>
     37 #include <system_error>
     38 
     39 namespace llvm {
     40 namespace object {
     41 
     42 /// DiceRef - This is a value type class that represents a single
     43 /// data in code entry in the table in a Mach-O object file.
     44 class DiceRef {
     45   DataRefImpl DicePimpl;
     46   const ObjectFile *OwningObject = nullptr;
     47 
     48 public:
     49   DiceRef() = default;
     50   DiceRef(DataRefImpl DiceP, const ObjectFile *Owner);
     51 
     52   bool operator==(const DiceRef &Other) const;
     53   bool operator<(const DiceRef &Other) const;
     54 
     55   void moveNext();
     56 
     57   std::error_code getOffset(uint32_t &Result) const;
     58   std::error_code getLength(uint16_t &Result) const;
     59   std::error_code getKind(uint16_t &Result) const;
     60 
     61   DataRefImpl getRawDataRefImpl() const;
     62   const ObjectFile *getObjectFile() const;
     63 };
     64 using dice_iterator = content_iterator<DiceRef>;
     65 
     66 /// ExportEntry encapsulates the current-state-of-the-walk used when doing a
     67 /// non-recursive walk of the trie data structure.  This allows you to iterate
     68 /// across all exported symbols using:
     69 ///      Error Err;
     70 ///      for (const llvm::object::ExportEntry &AnExport : Obj->exports(&Err)) {
     71 ///      }
     72 ///      if (Err) { report error ...
     73 class ExportEntry {
     74 public:
     75   ExportEntry(Error *Err, const MachOObjectFile *O, ArrayRef<uint8_t> Trie);
     76 
     77   StringRef name() const;
     78   uint64_t flags() const;
     79   uint64_t address() const;
     80   uint64_t other() const;
     81   StringRef otherName() const;
     82   uint32_t nodeOffset() const;
     83 
     84   bool operator==(const ExportEntry &) const;
     85 
     86   void moveNext();
     87 
     88 private:
     89   friend class MachOObjectFile;
     90 
     91   void moveToFirst();
     92   void moveToEnd();
     93   uint64_t readULEB128(const uint8_t *&p, const char **error);
     94   void pushDownUntilBottom();
     95   void pushNode(uint64_t Offset);
     96 
     97   // Represents a node in the mach-o exports trie.
     98   struct NodeState {
     99     NodeState(const uint8_t *Ptr);
    100 
    101     const uint8_t *Start;
    102     const uint8_t *Current;
    103     uint64_t Flags = 0;
    104     uint64_t Address = 0;
    105     uint64_t Other = 0;
    106     const char *ImportName = nullptr;
    107     unsigned ChildCount = 0;
    108     unsigned NextChildIndex = 0;
    109     unsigned ParentStringLength = 0;
    110     bool IsExportNode = false;
    111   };
    112   using NodeList = SmallVector<NodeState, 16>;
    113   using node_iterator = NodeList::const_iterator;
    114 
    115   Error *E;
    116   const MachOObjectFile *O;
    117   ArrayRef<uint8_t> Trie;
    118   SmallString<256> CumulativeString;
    119   NodeList Stack;
    120   bool Done = false;
    121 
    122   iterator_range<node_iterator> nodes() const {
    123     return make_range(Stack.begin(), Stack.end());
    124   }
    125 };
    126 using export_iterator = content_iterator<ExportEntry>;
    127 
    128 // Segment info so SegIndex/SegOffset pairs in a Mach-O Bind or Rebase entry
    129 // can be checked and translated.  Only the SegIndex/SegOffset pairs from
    130 // checked entries are to be used with the segmentName(), sectionName() and
    131 // address() methods below.
    132 class BindRebaseSegInfo {
    133 public:
    134   BindRebaseSegInfo(const MachOObjectFile *Obj);
    135 
    136   // Used to check a Mach-O Bind or Rebase entry for errors when iterating.
    137   const char *checkSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
    138                                 bool endInvalid);
    139   const char *checkCountAndSkip(uint32_t Count, uint32_t Skip,
    140                                 uint8_t PointerSize, int32_t SegIndex,
    141                                 uint64_t SegOffset);
    142   // Used with valid SegIndex/SegOffset values from checked entries.
    143   StringRef segmentName(int32_t SegIndex);
    144   StringRef sectionName(int32_t SegIndex, uint64_t SegOffset);
    145   uint64_t address(uint32_t SegIndex, uint64_t SegOffset);
    146 
    147 private:
    148   struct SectionInfo {
    149     uint64_t Address;
    150     uint64_t Size;
    151     StringRef SectionName;
    152     StringRef SegmentName;
    153     uint64_t OffsetInSegment;
    154     uint64_t SegmentStartAddress;
    155     int32_t SegmentIndex;
    156   };
    157   const SectionInfo &findSection(int32_t SegIndex, uint64_t SegOffset);
    158 
    159   SmallVector<SectionInfo, 32> Sections;
    160   int32_t MaxSegIndex;
    161 };
    162 
    163 /// MachORebaseEntry encapsulates the current state in the decompression of
    164 /// rebasing opcodes. This allows you to iterate through the compressed table of
    165 /// rebasing using:
    166 ///    Error Err;
    167 ///    for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable(&Err)) {
    168 ///    }
    169 ///    if (Err) { report error ...
    170 class MachORebaseEntry {
    171 public:
    172   MachORebaseEntry(Error *Err, const MachOObjectFile *O,
    173                    ArrayRef<uint8_t> opcodes, bool is64Bit);
    174 
    175   int32_t segmentIndex() const;
    176   uint64_t segmentOffset() const;
    177   StringRef typeName() const;
    178   StringRef segmentName() const;
    179   StringRef sectionName() const;
    180   uint64_t address() const;
    181 
    182   bool operator==(const MachORebaseEntry &) const;
    183 
    184   void moveNext();
    185 
    186 private:
    187   friend class MachOObjectFile;
    188 
    189   void moveToFirst();
    190   void moveToEnd();
    191   uint64_t readULEB128(const char **error);
    192 
    193   Error *E;
    194   const MachOObjectFile *O;
    195   ArrayRef<uint8_t> Opcodes;
    196   const uint8_t *Ptr;
    197   uint64_t SegmentOffset = 0;
    198   int32_t SegmentIndex = -1;
    199   uint64_t RemainingLoopCount = 0;
    200   uint64_t AdvanceAmount = 0;
    201   uint8_t  RebaseType = 0;
    202   uint8_t  PointerSize;
    203   bool     Done = false;
    204 };
    205 using rebase_iterator = content_iterator<MachORebaseEntry>;
    206 
    207 /// MachOBindEntry encapsulates the current state in the decompression of
    208 /// binding opcodes. This allows you to iterate through the compressed table of
    209 /// bindings using:
    210 ///    Error Err;
    211 ///    for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable(&Err)) {
    212 ///    }
    213 ///    if (Err) { report error ...
    214 class MachOBindEntry {
    215 public:
    216   enum class Kind { Regular, Lazy, Weak };
    217 
    218   MachOBindEntry(Error *Err, const MachOObjectFile *O,
    219                  ArrayRef<uint8_t> Opcodes, bool is64Bit, MachOBindEntry::Kind);
    220 
    221   int32_t segmentIndex() const;
    222   uint64_t segmentOffset() const;
    223   StringRef typeName() const;
    224   StringRef symbolName() const;
    225   uint32_t flags() const;
    226   int64_t addend() const;
    227   int ordinal() const;
    228 
    229   StringRef segmentName() const;
    230   StringRef sectionName() const;
    231   uint64_t address() const;
    232 
    233   bool operator==(const MachOBindEntry &) const;
    234 
    235   void moveNext();
    236 
    237 private:
    238   friend class MachOObjectFile;
    239 
    240   void moveToFirst();
    241   void moveToEnd();
    242   uint64_t readULEB128(const char **error);
    243   int64_t readSLEB128(const char **error);
    244 
    245   Error *E;
    246   const MachOObjectFile *O;
    247   ArrayRef<uint8_t> Opcodes;
    248   const uint8_t *Ptr;
    249   uint64_t SegmentOffset = 0;
    250   int32_t  SegmentIndex = -1;
    251   StringRef SymbolName;
    252   bool     LibraryOrdinalSet = false;
    253   int      Ordinal = 0;
    254   uint32_t Flags = 0;
    255   int64_t  Addend = 0;
    256   uint64_t RemainingLoopCount = 0;
    257   uint64_t AdvanceAmount = 0;
    258   uint8_t  BindType = 0;
    259   uint8_t  PointerSize;
    260   Kind     TableKind;
    261   bool     Done = false;
    262 };
    263 using bind_iterator = content_iterator<MachOBindEntry>;
    264 
    265 class MachOObjectFile : public ObjectFile {
    266 public:
    267   struct LoadCommandInfo {
    268     const char *Ptr;      // Where in memory the load command is.
    269     MachO::load_command C; // The command itself.
    270   };
    271   using LoadCommandList = SmallVector<LoadCommandInfo, 4>;
    272   using load_command_iterator = LoadCommandList::const_iterator;
    273 
    274   static Expected<std::unique_ptr<MachOObjectFile>>
    275   create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
    276          uint32_t UniversalCputype = 0, uint32_t UniversalIndex = 0);
    277 
    278   void moveSymbolNext(DataRefImpl &Symb) const override;
    279 
    280   uint64_t getNValue(DataRefImpl Sym) const;
    281   Expected<StringRef> getSymbolName(DataRefImpl Symb) const override;
    282 
    283   // MachO specific.
    284   Error checkSymbolTable() const;
    285 
    286   std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const;
    287   unsigned getSectionType(SectionRef Sec) const;
    288 
    289   Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override;
    290   uint32_t getSymbolAlignment(DataRefImpl Symb) const override;
    291   uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override;
    292   Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override;
    293   uint32_t getSymbolFlags(DataRefImpl Symb) const override;
    294   Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override;
    295   unsigned getSymbolSectionID(SymbolRef Symb) const;
    296   unsigned getSectionID(SectionRef Sec) const;
    297 
    298   void moveSectionNext(DataRefImpl &Sec) const override;
    299   std::error_code getSectionName(DataRefImpl Sec,
    300                                  StringRef &Res) const override;
    301   uint64_t getSectionAddress(DataRefImpl Sec) const override;
    302   uint64_t getSectionIndex(DataRefImpl Sec) const override;
    303   uint64_t getSectionSize(DataRefImpl Sec) const override;
    304   std::error_code getSectionContents(DataRefImpl Sec,
    305                                      StringRef &Res) const override;
    306   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
    307   bool isSectionCompressed(DataRefImpl Sec) const override;
    308   bool isSectionText(DataRefImpl Sec) const override;
    309   bool isSectionData(DataRefImpl Sec) const override;
    310   bool isSectionBSS(DataRefImpl Sec) const override;
    311   bool isSectionVirtual(DataRefImpl Sec) const override;
    312   bool isSectionBitcode(DataRefImpl Sec) const override;
    313 
    314   /// When dsymutil generates the companion file, it strips all unnecessary
    315   /// sections (e.g. everything in the _TEXT segment) by omitting their body
    316   /// and setting the offset in their corresponding load command to zero.
    317   ///
    318   /// While the load command itself is valid, reading the section corresponds
    319   /// to reading the number of bytes specified in the load command, starting
    320   /// from offset 0 (i.e. the Mach-O header at the beginning of the file).
    321   bool isSectionStripped(DataRefImpl Sec) const override;
    322 
    323   relocation_iterator section_rel_begin(DataRefImpl Sec) const override;
    324   relocation_iterator section_rel_end(DataRefImpl Sec) const override;
    325 
    326   relocation_iterator extrel_begin() const;
    327   relocation_iterator extrel_end() const;
    328   iterator_range<relocation_iterator> external_relocations() const {
    329     return make_range(extrel_begin(), extrel_end());
    330   }
    331 
    332   void moveRelocationNext(DataRefImpl &Rel) const override;
    333   uint64_t getRelocationOffset(DataRefImpl Rel) const override;
    334   symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override;
    335   section_iterator getRelocationSection(DataRefImpl Rel) const;
    336   uint64_t getRelocationType(DataRefImpl Rel) const override;
    337   void getRelocationTypeName(DataRefImpl Rel,
    338                              SmallVectorImpl<char> &Result) const override;
    339   uint8_t getRelocationLength(DataRefImpl Rel) const;
    340 
    341   // MachO specific.
    342   std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const;
    343   uint32_t getLibraryCount() const;
    344 
    345   section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const;
    346 
    347   // TODO: Would be useful to have an iterator based version
    348   // of the load command interface too.
    349 
    350   basic_symbol_iterator symbol_begin() const override;
    351   basic_symbol_iterator symbol_end() const override;
    352 
    353   // MachO specific.
    354   basic_symbol_iterator getSymbolByIndex(unsigned Index) const;
    355   uint64_t getSymbolIndex(DataRefImpl Symb) const;
    356 
    357   section_iterator section_begin() const override;
    358   section_iterator section_end() const override;
    359 
    360   uint8_t getBytesInAddress() const override;
    361 
    362   StringRef getFileFormatName() const override;
    363   unsigned getArch() const override;
    364   SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); }
    365   Triple getArchTriple(const char **McpuDefault = nullptr) const;
    366 
    367   relocation_iterator section_rel_begin(unsigned Index) const;
    368   relocation_iterator section_rel_end(unsigned Index) const;
    369 
    370   dice_iterator begin_dices() const;
    371   dice_iterator end_dices() const;
    372 
    373   load_command_iterator begin_load_commands() const;
    374   load_command_iterator end_load_commands() const;
    375   iterator_range<load_command_iterator> load_commands() const;
    376 
    377   /// For use iterating over all exported symbols.
    378   iterator_range<export_iterator> exports(Error &Err) const;
    379 
    380   /// For use examining a trie not in a MachOObjectFile.
    381   static iterator_range<export_iterator> exports(Error &Err,
    382                                                  ArrayRef<uint8_t> Trie,
    383                                                  const MachOObjectFile *O =
    384                                                                       nullptr);
    385 
    386   /// For use iterating over all rebase table entries.
    387   iterator_range<rebase_iterator> rebaseTable(Error &Err);
    388 
    389   /// For use examining rebase opcodes in a MachOObjectFile.
    390   static iterator_range<rebase_iterator> rebaseTable(Error &Err,
    391                                                      MachOObjectFile *O,
    392                                                      ArrayRef<uint8_t> Opcodes,
    393                                                      bool is64);
    394 
    395   /// For use iterating over all bind table entries.
    396   iterator_range<bind_iterator> bindTable(Error &Err);
    397 
    398   /// For use iterating over all lazy bind table entries.
    399   iterator_range<bind_iterator> lazyBindTable(Error &Err);
    400 
    401   /// For use iterating over all weak bind table entries.
    402   iterator_range<bind_iterator> weakBindTable(Error &Err);
    403 
    404   /// For use examining bind opcodes in a MachOObjectFile.
    405   static iterator_range<bind_iterator> bindTable(Error &Err,
    406                                                  MachOObjectFile *O,
    407                                                  ArrayRef<uint8_t> Opcodes,
    408                                                  bool is64,
    409                                                  MachOBindEntry::Kind);
    410 
    411   /// For use with a SegIndex,SegOffset pair in MachOBindEntry::moveNext() to
    412   /// validate a MachOBindEntry.
    413   const char *BindEntryCheckSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
    414                                          bool endInvalid) const {
    415     return BindRebaseSectionTable->checkSegAndOffset(SegIndex, SegOffset,
    416                                                      endInvalid);
    417   }
    418   /// For use in MachOBindEntry::moveNext() to validate a MachOBindEntry for
    419   /// the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode.
    420   const char *BindEntryCheckCountAndSkip(uint32_t Count, uint32_t Skip,
    421                                          uint8_t PointerSize, int32_t SegIndex,
    422                                          uint64_t SegOffset) const {
    423     return BindRebaseSectionTable->checkCountAndSkip(Count, Skip, PointerSize,
    424                                                      SegIndex, SegOffset);
    425   }
    426 
    427   /// For use with a SegIndex,SegOffset pair in MachORebaseEntry::moveNext() to
    428   /// validate a MachORebaseEntry.
    429   const char *RebaseEntryCheckSegAndOffset(int32_t SegIndex, uint64_t SegOffset,
    430                                            bool endInvalid) const {
    431     return BindRebaseSectionTable->checkSegAndOffset(SegIndex, SegOffset,
    432                                                      endInvalid);
    433   }
    434   /// For use in MachORebaseEntry::moveNext() to validate a MachORebaseEntry for
    435   /// the REBASE_OPCODE_DO_*_TIMES* opcodes.
    436   const char *RebaseEntryCheckCountAndSkip(uint32_t Count, uint32_t Skip,
    437                                          uint8_t PointerSize, int32_t SegIndex,
    438                                          uint64_t SegOffset) const {
    439     return BindRebaseSectionTable->checkCountAndSkip(Count, Skip, PointerSize,
    440                                                      SegIndex, SegOffset);
    441   }
    442 
    443   /// For use with the SegIndex of a checked Mach-O Bind or Rebase entry to
    444   /// get the segment name.
    445   StringRef BindRebaseSegmentName(int32_t SegIndex) const {
    446     return BindRebaseSectionTable->segmentName(SegIndex);
    447   }
    448 
    449   /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or
    450   /// Rebase entry to get the section name.
    451   StringRef BindRebaseSectionName(uint32_t SegIndex, uint64_t SegOffset) const {
    452     return BindRebaseSectionTable->sectionName(SegIndex, SegOffset);
    453   }
    454 
    455   /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or
    456   /// Rebase entry to get the address.
    457   uint64_t BindRebaseAddress(uint32_t SegIndex, uint64_t SegOffset) const {
    458     return BindRebaseSectionTable->address(SegIndex, SegOffset);
    459   }
    460 
    461   // In a MachO file, sections have a segment name. This is used in the .o
    462   // files. They have a single segment, but this field specifies which segment
    463   // a section should be put in in the final object.
    464   StringRef getSectionFinalSegmentName(DataRefImpl Sec) const;
    465 
    466   // Names are stored as 16 bytes. These returns the raw 16 bytes without
    467   // interpreting them as a C string.
    468   ArrayRef<char> getSectionRawName(DataRefImpl Sec) const;
    469   ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const;
    470 
    471   // MachO specific Info about relocations.
    472   bool isRelocationScattered(const MachO::any_relocation_info &RE) const;
    473   unsigned getPlainRelocationSymbolNum(
    474                                     const MachO::any_relocation_info &RE) const;
    475   bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const;
    476   bool getScatteredRelocationScattered(
    477                                     const MachO::any_relocation_info &RE) const;
    478   uint32_t getScatteredRelocationValue(
    479                                     const MachO::any_relocation_info &RE) const;
    480   uint32_t getScatteredRelocationType(
    481                                     const MachO::any_relocation_info &RE) const;
    482   unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const;
    483   unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const;
    484   unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const;
    485   unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const;
    486   SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const;
    487 
    488   // MachO specific structures.
    489   MachO::section getSection(DataRefImpl DRI) const;
    490   MachO::section_64 getSection64(DataRefImpl DRI) const;
    491   MachO::section getSection(const LoadCommandInfo &L, unsigned Index) const;
    492   MachO::section_64 getSection64(const LoadCommandInfo &L,unsigned Index) const;
    493   MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const;
    494   MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const;
    495 
    496   MachO::linkedit_data_command
    497   getLinkeditDataLoadCommand(const LoadCommandInfo &L) const;
    498   MachO::segment_command
    499   getSegmentLoadCommand(const LoadCommandInfo &L) const;
    500   MachO::segment_command_64
    501   getSegment64LoadCommand(const LoadCommandInfo &L) const;
    502   MachO::linker_option_command
    503   getLinkerOptionLoadCommand(const LoadCommandInfo &L) const;
    504   MachO::version_min_command
    505   getVersionMinLoadCommand(const LoadCommandInfo &L) const;
    506   MachO::note_command
    507   getNoteLoadCommand(const LoadCommandInfo &L) const;
    508   MachO::build_version_command
    509   getBuildVersionLoadCommand(const LoadCommandInfo &L) const;
    510   MachO::build_tool_version
    511   getBuildToolVersion(unsigned index) const;
    512   MachO::dylib_command
    513   getDylibIDLoadCommand(const LoadCommandInfo &L) const;
    514   MachO::dyld_info_command
    515   getDyldInfoLoadCommand(const LoadCommandInfo &L) const;
    516   MachO::dylinker_command
    517   getDylinkerCommand(const LoadCommandInfo &L) const;
    518   MachO::uuid_command
    519   getUuidCommand(const LoadCommandInfo &L) const;
    520   MachO::rpath_command
    521   getRpathCommand(const LoadCommandInfo &L) const;
    522   MachO::source_version_command
    523   getSourceVersionCommand(const LoadCommandInfo &L) const;
    524   MachO::entry_point_command
    525   getEntryPointCommand(const LoadCommandInfo &L) const;
    526   MachO::encryption_info_command
    527   getEncryptionInfoCommand(const LoadCommandInfo &L) const;
    528   MachO::encryption_info_command_64
    529   getEncryptionInfoCommand64(const LoadCommandInfo &L) const;
    530   MachO::sub_framework_command
    531   getSubFrameworkCommand(const LoadCommandInfo &L) const;
    532   MachO::sub_umbrella_command
    533   getSubUmbrellaCommand(const LoadCommandInfo &L) const;
    534   MachO::sub_library_command
    535   getSubLibraryCommand(const LoadCommandInfo &L) const;
    536   MachO::sub_client_command
    537   getSubClientCommand(const LoadCommandInfo &L) const;
    538   MachO::routines_command
    539   getRoutinesCommand(const LoadCommandInfo &L) const;
    540   MachO::routines_command_64
    541   getRoutinesCommand64(const LoadCommandInfo &L) const;
    542   MachO::thread_command
    543   getThreadCommand(const LoadCommandInfo &L) const;
    544 
    545   MachO::any_relocation_info getRelocation(DataRefImpl Rel) const;
    546   MachO::data_in_code_entry getDice(DataRefImpl Rel) const;
    547   const MachO::mach_header &getHeader() const;
    548   const MachO::mach_header_64 &getHeader64() const;
    549   uint32_t
    550   getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC,
    551                               unsigned Index) const;
    552   MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset,
    553                                                     unsigned Index) const;
    554   MachO::symtab_command getSymtabLoadCommand() const;
    555   MachO::dysymtab_command getDysymtabLoadCommand() const;
    556   MachO::linkedit_data_command getDataInCodeLoadCommand() const;
    557   MachO::linkedit_data_command getLinkOptHintsLoadCommand() const;
    558   ArrayRef<uint8_t> getDyldInfoRebaseOpcodes() const;
    559   ArrayRef<uint8_t> getDyldInfoBindOpcodes() const;
    560   ArrayRef<uint8_t> getDyldInfoWeakBindOpcodes() const;
    561   ArrayRef<uint8_t> getDyldInfoLazyBindOpcodes() const;
    562   ArrayRef<uint8_t> getDyldInfoExportsTrie() const;
    563   ArrayRef<uint8_t> getUuid() const;
    564 
    565   StringRef getStringTableData() const;
    566   bool is64Bit() const;
    567   void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
    568 
    569   static StringRef guessLibraryShortName(StringRef Name, bool &isFramework,
    570                                          StringRef &Suffix);
    571 
    572   static Triple::ArchType getArch(uint32_t CPUType);
    573   static Triple getArchTriple(uint32_t CPUType, uint32_t CPUSubType,
    574                               const char **McpuDefault = nullptr,
    575                               const char **ArchFlag = nullptr);
    576   static bool isValidArch(StringRef ArchFlag);
    577   static Triple getHostArch();
    578 
    579   bool isRelocatableObject() const override;
    580 
    581   StringRef mapDebugSectionName(StringRef Name) const override;
    582 
    583   bool hasPageZeroSegment() const { return HasPageZeroSegment; }
    584 
    585   static bool classof(const Binary *v) {
    586     return v->isMachO();
    587   }
    588 
    589   static uint32_t
    590   getVersionMinMajor(MachO::version_min_command &C, bool SDK) {
    591     uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
    592     return (VersionOrSDK >> 16) & 0xffff;
    593   }
    594 
    595   static uint32_t
    596   getVersionMinMinor(MachO::version_min_command &C, bool SDK) {
    597     uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
    598     return (VersionOrSDK >> 8) & 0xff;
    599   }
    600 
    601   static uint32_t
    602   getVersionMinUpdate(MachO::version_min_command &C, bool SDK) {
    603     uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version;
    604     return VersionOrSDK & 0xff;
    605   }
    606 
    607   static std::string getBuildPlatform(uint32_t platform) {
    608     switch (platform) {
    609     case MachO::PLATFORM_MACOS: return "macos";
    610     case MachO::PLATFORM_IOS: return "ios";
    611     case MachO::PLATFORM_TVOS: return "tvos";
    612     case MachO::PLATFORM_WATCHOS: return "watchos";
    613     case MachO::PLATFORM_BRIDGEOS: return "bridgeos";
    614     default:
    615       std::string ret;
    616       raw_string_ostream ss(ret);
    617       ss << format_hex(platform, 8, true);
    618       return ss.str();
    619     }
    620   }
    621 
    622   static std::string getBuildTool(uint32_t tools) {
    623     switch (tools) {
    624     case MachO::TOOL_CLANG: return "clang";
    625     case MachO::TOOL_SWIFT: return "swift";
    626     case MachO::TOOL_LD: return "ld";
    627     default:
    628       std::string ret;
    629       raw_string_ostream ss(ret);
    630       ss << format_hex(tools, 8, true);
    631       return ss.str();
    632     }
    633   }
    634 
    635   static std::string getVersionString(uint32_t version) {
    636     uint32_t major = (version >> 16) & 0xffff;
    637     uint32_t minor = (version >> 8) & 0xff;
    638     uint32_t update = version & 0xff;
    639 
    640     SmallString<32> Version;
    641     Version = utostr(major) + "." + utostr(minor);
    642     if (update != 0)
    643       Version += "." + utostr(update);
    644     return Version.str();
    645   }
    646 
    647 private:
    648   MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits,
    649                   Error &Err, uint32_t UniversalCputype = 0,
    650                   uint32_t UniversalIndex = 0);
    651 
    652   uint64_t getSymbolValueImpl(DataRefImpl Symb) const override;
    653 
    654   union {
    655     MachO::mach_header_64 Header64;
    656     MachO::mach_header Header;
    657   };
    658   using SectionList = SmallVector<const char*, 1>;
    659   SectionList Sections;
    660   using LibraryList = SmallVector<const char*, 1>;
    661   LibraryList Libraries;
    662   LoadCommandList LoadCommands;
    663   using LibraryShortName = SmallVector<StringRef, 1>;
    664   using BuildToolList = SmallVector<const char*, 1>;
    665   BuildToolList BuildTools;
    666   mutable LibraryShortName LibrariesShortNames;
    667   std::unique_ptr<BindRebaseSegInfo> BindRebaseSectionTable;
    668   const char *SymtabLoadCmd = nullptr;
    669   const char *DysymtabLoadCmd = nullptr;
    670   const char *DataInCodeLoadCmd = nullptr;
    671   const char *LinkOptHintsLoadCmd = nullptr;
    672   const char *DyldInfoLoadCmd = nullptr;
    673   const char *UuidLoadCmd = nullptr;
    674   bool HasPageZeroSegment = false;
    675 };
    676 
    677 /// DiceRef
    678 inline DiceRef::DiceRef(DataRefImpl DiceP, const ObjectFile *Owner)
    679   : DicePimpl(DiceP) , OwningObject(Owner) {}
    680 
    681 inline bool DiceRef::operator==(const DiceRef &Other) const {
    682   return DicePimpl == Other.DicePimpl;
    683 }
    684 
    685 inline bool DiceRef::operator<(const DiceRef &Other) const {
    686   return DicePimpl < Other.DicePimpl;
    687 }
    688 
    689 inline void DiceRef::moveNext() {
    690   const MachO::data_in_code_entry *P =
    691     reinterpret_cast<const MachO::data_in_code_entry *>(DicePimpl.p);
    692   DicePimpl.p = reinterpret_cast<uintptr_t>(P + 1);
    693 }
    694 
    695 // Since a Mach-O data in code reference, a DiceRef, can only be created when
    696 // the OwningObject ObjectFile is a MachOObjectFile a static_cast<> is used for
    697 // the methods that get the values of the fields of the reference.
    698 
    699 inline std::error_code DiceRef::getOffset(uint32_t &Result) const {
    700   const MachOObjectFile *MachOOF =
    701     static_cast<const MachOObjectFile *>(OwningObject);
    702   MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
    703   Result = Dice.offset;
    704   return std::error_code();
    705 }
    706 
    707 inline std::error_code DiceRef::getLength(uint16_t &Result) const {
    708   const MachOObjectFile *MachOOF =
    709     static_cast<const MachOObjectFile *>(OwningObject);
    710   MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
    711   Result = Dice.length;
    712   return std::error_code();
    713 }
    714 
    715 inline std::error_code DiceRef::getKind(uint16_t &Result) const {
    716   const MachOObjectFile *MachOOF =
    717     static_cast<const MachOObjectFile *>(OwningObject);
    718   MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl);
    719   Result = Dice.kind;
    720   return std::error_code();
    721 }
    722 
    723 inline DataRefImpl DiceRef::getRawDataRefImpl() const {
    724   return DicePimpl;
    725 }
    726 
    727 inline const ObjectFile *DiceRef::getObjectFile() const {
    728   return OwningObject;
    729 }
    730 
    731 } // end namespace object
    732 } // end namespace llvm
    733 
    734 #endif // LLVM_OBJECT_MACHO_H
    735