10b57cec5SDimitry Andric //===- MachO.h - MachO object file implementation ---------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file declares the MachOObjectFile class, which implement the ObjectFile 100b57cec5SDimitry Andric // interface for MachO files. 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #ifndef LLVM_OBJECT_MACHO_H 150b57cec5SDimitry Andric #define LLVM_OBJECT_MACHO_H 160b57cec5SDimitry Andric 170b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 180b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 190b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 200b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h" 210b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 220b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 230b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h" 240b57cec5SDimitry Andric #include "llvm/BinaryFormat/MachO.h" 250b57cec5SDimitry Andric #include "llvm/MC/SubtargetFeature.h" 260b57cec5SDimitry Andric #include "llvm/Object/Binary.h" 270b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h" 280b57cec5SDimitry Andric #include "llvm/Object/SymbolicFile.h" 290b57cec5SDimitry Andric #include "llvm/Support/Error.h" 300b57cec5SDimitry Andric #include "llvm/Support/Format.h" 310b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 320b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 330b57cec5SDimitry Andric #include <cstdint> 340b57cec5SDimitry Andric #include <memory> 350b57cec5SDimitry Andric #include <string> 360b57cec5SDimitry Andric #include <system_error> 370b57cec5SDimitry Andric 380b57cec5SDimitry Andric namespace llvm { 390b57cec5SDimitry Andric namespace object { 400b57cec5SDimitry Andric 410b57cec5SDimitry Andric /// DiceRef - This is a value type class that represents a single 420b57cec5SDimitry Andric /// data in code entry in the table in a Mach-O object file. 430b57cec5SDimitry Andric class DiceRef { 440b57cec5SDimitry Andric DataRefImpl DicePimpl; 450b57cec5SDimitry Andric const ObjectFile *OwningObject = nullptr; 460b57cec5SDimitry Andric 470b57cec5SDimitry Andric public: 480b57cec5SDimitry Andric DiceRef() = default; 490b57cec5SDimitry Andric DiceRef(DataRefImpl DiceP, const ObjectFile *Owner); 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric bool operator==(const DiceRef &Other) const; 520b57cec5SDimitry Andric bool operator<(const DiceRef &Other) const; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric void moveNext(); 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric std::error_code getOffset(uint32_t &Result) const; 570b57cec5SDimitry Andric std::error_code getLength(uint16_t &Result) const; 580b57cec5SDimitry Andric std::error_code getKind(uint16_t &Result) const; 590b57cec5SDimitry Andric 600b57cec5SDimitry Andric DataRefImpl getRawDataRefImpl() const; 610b57cec5SDimitry Andric const ObjectFile *getObjectFile() const; 620b57cec5SDimitry Andric }; 630b57cec5SDimitry Andric using dice_iterator = content_iterator<DiceRef>; 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric /// ExportEntry encapsulates the current-state-of-the-walk used when doing a 660b57cec5SDimitry Andric /// non-recursive walk of the trie data structure. This allows you to iterate 670b57cec5SDimitry Andric /// across all exported symbols using: 685ffd83dbSDimitry Andric /// Error Err = Error::success(); 690b57cec5SDimitry Andric /// for (const llvm::object::ExportEntry &AnExport : Obj->exports(&Err)) { 700b57cec5SDimitry Andric /// } 710b57cec5SDimitry Andric /// if (Err) { report error ... 720b57cec5SDimitry Andric class ExportEntry { 730b57cec5SDimitry Andric public: 740b57cec5SDimitry Andric ExportEntry(Error *Err, const MachOObjectFile *O, ArrayRef<uint8_t> Trie); 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric StringRef name() const; 770b57cec5SDimitry Andric uint64_t flags() const; 780b57cec5SDimitry Andric uint64_t address() const; 790b57cec5SDimitry Andric uint64_t other() const; 800b57cec5SDimitry Andric StringRef otherName() const; 810b57cec5SDimitry Andric uint32_t nodeOffset() const; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric bool operator==(const ExportEntry &) const; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric void moveNext(); 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric private: 880b57cec5SDimitry Andric friend class MachOObjectFile; 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric void moveToFirst(); 910b57cec5SDimitry Andric void moveToEnd(); 920b57cec5SDimitry Andric uint64_t readULEB128(const uint8_t *&p, const char **error); 930b57cec5SDimitry Andric void pushDownUntilBottom(); 940b57cec5SDimitry Andric void pushNode(uint64_t Offset); 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric // Represents a node in the mach-o exports trie. 970b57cec5SDimitry Andric struct NodeState { 980b57cec5SDimitry Andric NodeState(const uint8_t *Ptr); 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric const uint8_t *Start; 1010b57cec5SDimitry Andric const uint8_t *Current; 1020b57cec5SDimitry Andric uint64_t Flags = 0; 1030b57cec5SDimitry Andric uint64_t Address = 0; 1040b57cec5SDimitry Andric uint64_t Other = 0; 1050b57cec5SDimitry Andric const char *ImportName = nullptr; 1060b57cec5SDimitry Andric unsigned ChildCount = 0; 1070b57cec5SDimitry Andric unsigned NextChildIndex = 0; 1080b57cec5SDimitry Andric unsigned ParentStringLength = 0; 1090b57cec5SDimitry Andric bool IsExportNode = false; 1100b57cec5SDimitry Andric }; 1110b57cec5SDimitry Andric using NodeList = SmallVector<NodeState, 16>; 1120b57cec5SDimitry Andric using node_iterator = NodeList::const_iterator; 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric Error *E; 1150b57cec5SDimitry Andric const MachOObjectFile *O; 1160b57cec5SDimitry Andric ArrayRef<uint8_t> Trie; 1170b57cec5SDimitry Andric SmallString<256> CumulativeString; 1180b57cec5SDimitry Andric NodeList Stack; 1190b57cec5SDimitry Andric bool Done = false; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric iterator_range<node_iterator> nodes() const { 1220b57cec5SDimitry Andric return make_range(Stack.begin(), Stack.end()); 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric }; 1250b57cec5SDimitry Andric using export_iterator = content_iterator<ExportEntry>; 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric // Segment info so SegIndex/SegOffset pairs in a Mach-O Bind or Rebase entry 1280b57cec5SDimitry Andric // can be checked and translated. Only the SegIndex/SegOffset pairs from 1290b57cec5SDimitry Andric // checked entries are to be used with the segmentName(), sectionName() and 1300b57cec5SDimitry Andric // address() methods below. 1310b57cec5SDimitry Andric class BindRebaseSegInfo { 1320b57cec5SDimitry Andric public: 1330b57cec5SDimitry Andric BindRebaseSegInfo(const MachOObjectFile *Obj); 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric // Used to check a Mach-O Bind or Rebase entry for errors when iterating. 1360b57cec5SDimitry Andric const char* checkSegAndOffsets(int32_t SegIndex, uint64_t SegOffset, 1370b57cec5SDimitry Andric uint8_t PointerSize, uint32_t Count=1, 1380b57cec5SDimitry Andric uint32_t Skip=0); 1390b57cec5SDimitry Andric // Used with valid SegIndex/SegOffset values from checked entries. 1400b57cec5SDimitry Andric StringRef segmentName(int32_t SegIndex); 1410b57cec5SDimitry Andric StringRef sectionName(int32_t SegIndex, uint64_t SegOffset); 1420b57cec5SDimitry Andric uint64_t address(uint32_t SegIndex, uint64_t SegOffset); 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric private: 1450b57cec5SDimitry Andric struct SectionInfo { 1460b57cec5SDimitry Andric uint64_t Address; 1470b57cec5SDimitry Andric uint64_t Size; 1480b57cec5SDimitry Andric StringRef SectionName; 1490b57cec5SDimitry Andric StringRef SegmentName; 1500b57cec5SDimitry Andric uint64_t OffsetInSegment; 1510b57cec5SDimitry Andric uint64_t SegmentStartAddress; 1520b57cec5SDimitry Andric int32_t SegmentIndex; 1530b57cec5SDimitry Andric }; 1540b57cec5SDimitry Andric const SectionInfo &findSection(int32_t SegIndex, uint64_t SegOffset); 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric SmallVector<SectionInfo, 32> Sections; 1570b57cec5SDimitry Andric int32_t MaxSegIndex; 1580b57cec5SDimitry Andric }; 1590b57cec5SDimitry Andric 1600b57cec5SDimitry Andric /// MachORebaseEntry encapsulates the current state in the decompression of 1610b57cec5SDimitry Andric /// rebasing opcodes. This allows you to iterate through the compressed table of 1620b57cec5SDimitry Andric /// rebasing using: 1635ffd83dbSDimitry Andric /// Error Err = Error::success(); 1640b57cec5SDimitry Andric /// for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable(&Err)) { 1650b57cec5SDimitry Andric /// } 1660b57cec5SDimitry Andric /// if (Err) { report error ... 1670b57cec5SDimitry Andric class MachORebaseEntry { 1680b57cec5SDimitry Andric public: 1690b57cec5SDimitry Andric MachORebaseEntry(Error *Err, const MachOObjectFile *O, 1700b57cec5SDimitry Andric ArrayRef<uint8_t> opcodes, bool is64Bit); 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric int32_t segmentIndex() const; 1730b57cec5SDimitry Andric uint64_t segmentOffset() const; 1740b57cec5SDimitry Andric StringRef typeName() const; 1750b57cec5SDimitry Andric StringRef segmentName() const; 1760b57cec5SDimitry Andric StringRef sectionName() const; 1770b57cec5SDimitry Andric uint64_t address() const; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andric bool operator==(const MachORebaseEntry &) const; 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric void moveNext(); 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric private: 1840b57cec5SDimitry Andric friend class MachOObjectFile; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric void moveToFirst(); 1870b57cec5SDimitry Andric void moveToEnd(); 1880b57cec5SDimitry Andric uint64_t readULEB128(const char **error); 1890b57cec5SDimitry Andric 1900b57cec5SDimitry Andric Error *E; 1910b57cec5SDimitry Andric const MachOObjectFile *O; 1920b57cec5SDimitry Andric ArrayRef<uint8_t> Opcodes; 1930b57cec5SDimitry Andric const uint8_t *Ptr; 1940b57cec5SDimitry Andric uint64_t SegmentOffset = 0; 1950b57cec5SDimitry Andric int32_t SegmentIndex = -1; 1960b57cec5SDimitry Andric uint64_t RemainingLoopCount = 0; 1970b57cec5SDimitry Andric uint64_t AdvanceAmount = 0; 1980b57cec5SDimitry Andric uint8_t RebaseType = 0; 1990b57cec5SDimitry Andric uint8_t PointerSize; 2000b57cec5SDimitry Andric bool Done = false; 2010b57cec5SDimitry Andric }; 2020b57cec5SDimitry Andric using rebase_iterator = content_iterator<MachORebaseEntry>; 2030b57cec5SDimitry Andric 2040b57cec5SDimitry Andric /// MachOBindEntry encapsulates the current state in the decompression of 2050b57cec5SDimitry Andric /// binding opcodes. This allows you to iterate through the compressed table of 2060b57cec5SDimitry Andric /// bindings using: 2075ffd83dbSDimitry Andric /// Error Err = Error::success(); 2080b57cec5SDimitry Andric /// for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable(&Err)) { 2090b57cec5SDimitry Andric /// } 2100b57cec5SDimitry Andric /// if (Err) { report error ... 2110b57cec5SDimitry Andric class MachOBindEntry { 2120b57cec5SDimitry Andric public: 2130b57cec5SDimitry Andric enum class Kind { Regular, Lazy, Weak }; 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric MachOBindEntry(Error *Err, const MachOObjectFile *O, 2160b57cec5SDimitry Andric ArrayRef<uint8_t> Opcodes, bool is64Bit, MachOBindEntry::Kind); 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric int32_t segmentIndex() const; 2190b57cec5SDimitry Andric uint64_t segmentOffset() const; 2200b57cec5SDimitry Andric StringRef typeName() const; 2210b57cec5SDimitry Andric StringRef symbolName() const; 2220b57cec5SDimitry Andric uint32_t flags() const; 2230b57cec5SDimitry Andric int64_t addend() const; 2240b57cec5SDimitry Andric int ordinal() const; 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric StringRef segmentName() const; 2270b57cec5SDimitry Andric StringRef sectionName() const; 2280b57cec5SDimitry Andric uint64_t address() const; 2290b57cec5SDimitry Andric 2300b57cec5SDimitry Andric bool operator==(const MachOBindEntry &) const; 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric void moveNext(); 2330b57cec5SDimitry Andric 2340b57cec5SDimitry Andric private: 2350b57cec5SDimitry Andric friend class MachOObjectFile; 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric void moveToFirst(); 2380b57cec5SDimitry Andric void moveToEnd(); 2390b57cec5SDimitry Andric uint64_t readULEB128(const char **error); 2400b57cec5SDimitry Andric int64_t readSLEB128(const char **error); 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric Error *E; 2430b57cec5SDimitry Andric const MachOObjectFile *O; 2440b57cec5SDimitry Andric ArrayRef<uint8_t> Opcodes; 2450b57cec5SDimitry Andric const uint8_t *Ptr; 2460b57cec5SDimitry Andric uint64_t SegmentOffset = 0; 2470b57cec5SDimitry Andric int32_t SegmentIndex = -1; 2480b57cec5SDimitry Andric StringRef SymbolName; 2490b57cec5SDimitry Andric bool LibraryOrdinalSet = false; 2500b57cec5SDimitry Andric int Ordinal = 0; 2510b57cec5SDimitry Andric uint32_t Flags = 0; 2520b57cec5SDimitry Andric int64_t Addend = 0; 2530b57cec5SDimitry Andric uint64_t RemainingLoopCount = 0; 2540b57cec5SDimitry Andric uint64_t AdvanceAmount = 0; 2550b57cec5SDimitry Andric uint8_t BindType = 0; 2560b57cec5SDimitry Andric uint8_t PointerSize; 2570b57cec5SDimitry Andric Kind TableKind; 2580b57cec5SDimitry Andric bool Done = false; 2590b57cec5SDimitry Andric }; 2600b57cec5SDimitry Andric using bind_iterator = content_iterator<MachOBindEntry>; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric class MachOObjectFile : public ObjectFile { 2630b57cec5SDimitry Andric public: 2640b57cec5SDimitry Andric struct LoadCommandInfo { 2650b57cec5SDimitry Andric const char *Ptr; // Where in memory the load command is. 2660b57cec5SDimitry Andric MachO::load_command C; // The command itself. 2670b57cec5SDimitry Andric }; 2680b57cec5SDimitry Andric using LoadCommandList = SmallVector<LoadCommandInfo, 4>; 2690b57cec5SDimitry Andric using load_command_iterator = LoadCommandList::const_iterator; 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric static Expected<std::unique_ptr<MachOObjectFile>> 2720b57cec5SDimitry Andric create(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, 2730b57cec5SDimitry Andric uint32_t UniversalCputype = 0, uint32_t UniversalIndex = 0); 2740b57cec5SDimitry Andric 2750b57cec5SDimitry Andric void moveSymbolNext(DataRefImpl &Symb) const override; 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric uint64_t getNValue(DataRefImpl Sym) const; 2780b57cec5SDimitry Andric Expected<StringRef> getSymbolName(DataRefImpl Symb) const override; 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric // MachO specific. 2810b57cec5SDimitry Andric Error checkSymbolTable() const; 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const; 2840b57cec5SDimitry Andric unsigned getSectionType(SectionRef Sec) const; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric Expected<uint64_t> getSymbolAddress(DataRefImpl Symb) const override; 2870b57cec5SDimitry Andric uint32_t getSymbolAlignment(DataRefImpl Symb) const override; 2880b57cec5SDimitry Andric uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override; 2890b57cec5SDimitry Andric Expected<SymbolRef::Type> getSymbolType(DataRefImpl Symb) const override; 2905ffd83dbSDimitry Andric Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override; 2910b57cec5SDimitry Andric Expected<section_iterator> getSymbolSection(DataRefImpl Symb) const override; 2920b57cec5SDimitry Andric unsigned getSymbolSectionID(SymbolRef Symb) const; 2930b57cec5SDimitry Andric unsigned getSectionID(SectionRef Sec) const; 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric void moveSectionNext(DataRefImpl &Sec) const override; 2960b57cec5SDimitry Andric Expected<StringRef> getSectionName(DataRefImpl Sec) const override; 2970b57cec5SDimitry Andric uint64_t getSectionAddress(DataRefImpl Sec) const override; 2980b57cec5SDimitry Andric uint64_t getSectionIndex(DataRefImpl Sec) const override; 2990b57cec5SDimitry Andric uint64_t getSectionSize(DataRefImpl Sec) const override; 3008bcb0991SDimitry Andric ArrayRef<uint8_t> getSectionContents(uint32_t Offset, uint64_t Size) const; 3010b57cec5SDimitry Andric Expected<ArrayRef<uint8_t>> 3020b57cec5SDimitry Andric getSectionContents(DataRefImpl Sec) const override; 3030b57cec5SDimitry Andric uint64_t getSectionAlignment(DataRefImpl Sec) const override; 3040b57cec5SDimitry Andric Expected<SectionRef> getSection(unsigned SectionIndex) const; 3050b57cec5SDimitry Andric Expected<SectionRef> getSection(StringRef SectionName) const; 3060b57cec5SDimitry Andric bool isSectionCompressed(DataRefImpl Sec) const override; 3070b57cec5SDimitry Andric bool isSectionText(DataRefImpl Sec) const override; 3080b57cec5SDimitry Andric bool isSectionData(DataRefImpl Sec) const override; 3090b57cec5SDimitry Andric bool isSectionBSS(DataRefImpl Sec) const override; 3100b57cec5SDimitry Andric bool isSectionVirtual(DataRefImpl Sec) const override; 3110b57cec5SDimitry Andric bool isSectionBitcode(DataRefImpl Sec) const override; 312fe6060f1SDimitry Andric bool isDebugSection(DataRefImpl Sec) const override; 3130b57cec5SDimitry Andric 314349cc55cSDimitry Andric /// Return the raw contents of an entire segment. 315349cc55cSDimitry Andric ArrayRef<uint8_t> getSegmentContents(StringRef SegmentName) const; 316349cc55cSDimitry Andric 3170b57cec5SDimitry Andric /// When dsymutil generates the companion file, it strips all unnecessary 3180b57cec5SDimitry Andric /// sections (e.g. everything in the _TEXT segment) by omitting their body 3190b57cec5SDimitry Andric /// and setting the offset in their corresponding load command to zero. 3200b57cec5SDimitry Andric /// 3210b57cec5SDimitry Andric /// While the load command itself is valid, reading the section corresponds 3220b57cec5SDimitry Andric /// to reading the number of bytes specified in the load command, starting 3230b57cec5SDimitry Andric /// from offset 0 (i.e. the Mach-O header at the beginning of the file). 3240b57cec5SDimitry Andric bool isSectionStripped(DataRefImpl Sec) const override; 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric relocation_iterator section_rel_begin(DataRefImpl Sec) const override; 3270b57cec5SDimitry Andric relocation_iterator section_rel_end(DataRefImpl Sec) const override; 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric relocation_iterator extrel_begin() const; 3300b57cec5SDimitry Andric relocation_iterator extrel_end() const; 3310b57cec5SDimitry Andric iterator_range<relocation_iterator> external_relocations() const { 3320b57cec5SDimitry Andric return make_range(extrel_begin(), extrel_end()); 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric relocation_iterator locrel_begin() const; 3360b57cec5SDimitry Andric relocation_iterator locrel_end() const; 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric void moveRelocationNext(DataRefImpl &Rel) const override; 3390b57cec5SDimitry Andric uint64_t getRelocationOffset(DataRefImpl Rel) const override; 3400b57cec5SDimitry Andric symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; 3410b57cec5SDimitry Andric section_iterator getRelocationSection(DataRefImpl Rel) const; 3420b57cec5SDimitry Andric uint64_t getRelocationType(DataRefImpl Rel) const override; 3430b57cec5SDimitry Andric void getRelocationTypeName(DataRefImpl Rel, 3440b57cec5SDimitry Andric SmallVectorImpl<char> &Result) const override; 3450b57cec5SDimitry Andric uint8_t getRelocationLength(DataRefImpl Rel) const; 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric // MachO specific. 3480b57cec5SDimitry Andric std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const; 3490b57cec5SDimitry Andric uint32_t getLibraryCount() const; 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric section_iterator getRelocationRelocatedSection(relocation_iterator Rel) const; 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric // TODO: Would be useful to have an iterator based version 3540b57cec5SDimitry Andric // of the load command interface too. 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric basic_symbol_iterator symbol_begin() const override; 3570b57cec5SDimitry Andric basic_symbol_iterator symbol_end() const override; 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric // MachO specific. 3600b57cec5SDimitry Andric symbol_iterator getSymbolByIndex(unsigned Index) const; 3610b57cec5SDimitry Andric uint64_t getSymbolIndex(DataRefImpl Symb) const; 3620b57cec5SDimitry Andric 3630b57cec5SDimitry Andric section_iterator section_begin() const override; 3640b57cec5SDimitry Andric section_iterator section_end() const override; 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andric uint8_t getBytesInAddress() const override; 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric StringRef getFileFormatName() const override; 3690b57cec5SDimitry Andric Triple::ArchType getArch() const override; 3700b57cec5SDimitry Andric SubtargetFeatures getFeatures() const override { return SubtargetFeatures(); } 3710b57cec5SDimitry Andric Triple getArchTriple(const char **McpuDefault = nullptr) const; 3720b57cec5SDimitry Andric 3730b57cec5SDimitry Andric relocation_iterator section_rel_begin(unsigned Index) const; 3740b57cec5SDimitry Andric relocation_iterator section_rel_end(unsigned Index) const; 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric dice_iterator begin_dices() const; 3770b57cec5SDimitry Andric dice_iterator end_dices() const; 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric load_command_iterator begin_load_commands() const; 3800b57cec5SDimitry Andric load_command_iterator end_load_commands() const; 3810b57cec5SDimitry Andric iterator_range<load_command_iterator> load_commands() const; 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric /// For use iterating over all exported symbols. 3840b57cec5SDimitry Andric iterator_range<export_iterator> exports(Error &Err) const; 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric /// For use examining a trie not in a MachOObjectFile. 3870b57cec5SDimitry Andric static iterator_range<export_iterator> exports(Error &Err, 3880b57cec5SDimitry Andric ArrayRef<uint8_t> Trie, 3890b57cec5SDimitry Andric const MachOObjectFile *O = 3900b57cec5SDimitry Andric nullptr); 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric /// For use iterating over all rebase table entries. 3930b57cec5SDimitry Andric iterator_range<rebase_iterator> rebaseTable(Error &Err); 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric /// For use examining rebase opcodes in a MachOObjectFile. 3960b57cec5SDimitry Andric static iterator_range<rebase_iterator> rebaseTable(Error &Err, 3970b57cec5SDimitry Andric MachOObjectFile *O, 3980b57cec5SDimitry Andric ArrayRef<uint8_t> Opcodes, 3990b57cec5SDimitry Andric bool is64); 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric /// For use iterating over all bind table entries. 4020b57cec5SDimitry Andric iterator_range<bind_iterator> bindTable(Error &Err); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric /// For use iterating over all lazy bind table entries. 4050b57cec5SDimitry Andric iterator_range<bind_iterator> lazyBindTable(Error &Err); 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric /// For use iterating over all weak bind table entries. 4080b57cec5SDimitry Andric iterator_range<bind_iterator> weakBindTable(Error &Err); 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric /// For use examining bind opcodes in a MachOObjectFile. 4110b57cec5SDimitry Andric static iterator_range<bind_iterator> bindTable(Error &Err, 4120b57cec5SDimitry Andric MachOObjectFile *O, 4130b57cec5SDimitry Andric ArrayRef<uint8_t> Opcodes, 4140b57cec5SDimitry Andric bool is64, 4150b57cec5SDimitry Andric MachOBindEntry::Kind); 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists 4180b57cec5SDimitry Andric // that fully contains a pointer at that location. Multiple fixups in a bind 4190b57cec5SDimitry Andric // (such as with the BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB opcode) can 4200b57cec5SDimitry Andric // be tested via the Count and Skip parameters. 4210b57cec5SDimitry Andric // 4220b57cec5SDimitry Andric // This is used by MachOBindEntry::moveNext() to validate a MachOBindEntry. 4230b57cec5SDimitry Andric const char *BindEntryCheckSegAndOffsets(int32_t SegIndex, uint64_t SegOffset, 4240b57cec5SDimitry Andric uint8_t PointerSize, uint32_t Count=1, 4250b57cec5SDimitry Andric uint32_t Skip=0) const { 4260b57cec5SDimitry Andric return BindRebaseSectionTable->checkSegAndOffsets(SegIndex, SegOffset, 4270b57cec5SDimitry Andric PointerSize, Count, Skip); 4280b57cec5SDimitry Andric } 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric // Given a SegIndex, SegOffset, and PointerSize, verify a valid section exists 4310b57cec5SDimitry Andric // that fully contains a pointer at that location. Multiple fixups in a rebase 4320b57cec5SDimitry Andric // (such as with the REBASE_OPCODE_DO_*_TIMES* opcodes) can be tested via the 4330b57cec5SDimitry Andric // Count and Skip parameters. 4340b57cec5SDimitry Andric // 4350b57cec5SDimitry Andric // This is used by MachORebaseEntry::moveNext() to validate a MachORebaseEntry 4360b57cec5SDimitry Andric const char *RebaseEntryCheckSegAndOffsets(int32_t SegIndex, 4370b57cec5SDimitry Andric uint64_t SegOffset, 4380b57cec5SDimitry Andric uint8_t PointerSize, 4390b57cec5SDimitry Andric uint32_t Count=1, 4400b57cec5SDimitry Andric uint32_t Skip=0) const { 4410b57cec5SDimitry Andric return BindRebaseSectionTable->checkSegAndOffsets(SegIndex, SegOffset, 4420b57cec5SDimitry Andric PointerSize, Count, Skip); 4430b57cec5SDimitry Andric } 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric /// For use with the SegIndex of a checked Mach-O Bind or Rebase entry to 4460b57cec5SDimitry Andric /// get the segment name. 4470b57cec5SDimitry Andric StringRef BindRebaseSegmentName(int32_t SegIndex) const { 4480b57cec5SDimitry Andric return BindRebaseSectionTable->segmentName(SegIndex); 4490b57cec5SDimitry Andric } 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or 4520b57cec5SDimitry Andric /// Rebase entry to get the section name. 4530b57cec5SDimitry Andric StringRef BindRebaseSectionName(uint32_t SegIndex, uint64_t SegOffset) const { 4540b57cec5SDimitry Andric return BindRebaseSectionTable->sectionName(SegIndex, SegOffset); 4550b57cec5SDimitry Andric } 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric /// For use with a SegIndex,SegOffset pair from a checked Mach-O Bind or 4580b57cec5SDimitry Andric /// Rebase entry to get the address. 4590b57cec5SDimitry Andric uint64_t BindRebaseAddress(uint32_t SegIndex, uint64_t SegOffset) const { 4600b57cec5SDimitry Andric return BindRebaseSectionTable->address(SegIndex, SegOffset); 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 4630b57cec5SDimitry Andric // In a MachO file, sections have a segment name. This is used in the .o 4640b57cec5SDimitry Andric // files. They have a single segment, but this field specifies which segment 4650b57cec5SDimitry Andric // a section should be put in the final object. 4660b57cec5SDimitry Andric StringRef getSectionFinalSegmentName(DataRefImpl Sec) const; 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric // Names are stored as 16 bytes. These returns the raw 16 bytes without 4690b57cec5SDimitry Andric // interpreting them as a C string. 4700b57cec5SDimitry Andric ArrayRef<char> getSectionRawName(DataRefImpl Sec) const; 4710b57cec5SDimitry Andric ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const; 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric // MachO specific Info about relocations. 4740b57cec5SDimitry Andric bool isRelocationScattered(const MachO::any_relocation_info &RE) const; 4750b57cec5SDimitry Andric unsigned getPlainRelocationSymbolNum( 4760b57cec5SDimitry Andric const MachO::any_relocation_info &RE) const; 4770b57cec5SDimitry Andric bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const; 4780b57cec5SDimitry Andric bool getScatteredRelocationScattered( 4790b57cec5SDimitry Andric const MachO::any_relocation_info &RE) const; 4800b57cec5SDimitry Andric uint32_t getScatteredRelocationValue( 4810b57cec5SDimitry Andric const MachO::any_relocation_info &RE) const; 4820b57cec5SDimitry Andric uint32_t getScatteredRelocationType( 4830b57cec5SDimitry Andric const MachO::any_relocation_info &RE) const; 4840b57cec5SDimitry Andric unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const; 4850b57cec5SDimitry Andric unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const; 4860b57cec5SDimitry Andric unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const; 4870b57cec5SDimitry Andric unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const; 4880b57cec5SDimitry Andric SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const; 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric // MachO specific structures. 4910b57cec5SDimitry Andric MachO::section getSection(DataRefImpl DRI) const; 4920b57cec5SDimitry Andric MachO::section_64 getSection64(DataRefImpl DRI) const; 4930b57cec5SDimitry Andric MachO::section getSection(const LoadCommandInfo &L, unsigned Index) const; 4940b57cec5SDimitry Andric MachO::section_64 getSection64(const LoadCommandInfo &L,unsigned Index) const; 4950b57cec5SDimitry Andric MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const; 4960b57cec5SDimitry Andric MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const; 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric MachO::linkedit_data_command 4990b57cec5SDimitry Andric getLinkeditDataLoadCommand(const LoadCommandInfo &L) const; 5000b57cec5SDimitry Andric MachO::segment_command 5010b57cec5SDimitry Andric getSegmentLoadCommand(const LoadCommandInfo &L) const; 5020b57cec5SDimitry Andric MachO::segment_command_64 5030b57cec5SDimitry Andric getSegment64LoadCommand(const LoadCommandInfo &L) const; 5040b57cec5SDimitry Andric MachO::linker_option_command 5050b57cec5SDimitry Andric getLinkerOptionLoadCommand(const LoadCommandInfo &L) const; 5060b57cec5SDimitry Andric MachO::version_min_command 5070b57cec5SDimitry Andric getVersionMinLoadCommand(const LoadCommandInfo &L) const; 5080b57cec5SDimitry Andric MachO::note_command 5090b57cec5SDimitry Andric getNoteLoadCommand(const LoadCommandInfo &L) const; 5100b57cec5SDimitry Andric MachO::build_version_command 5110b57cec5SDimitry Andric getBuildVersionLoadCommand(const LoadCommandInfo &L) const; 5120b57cec5SDimitry Andric MachO::build_tool_version 5130b57cec5SDimitry Andric getBuildToolVersion(unsigned index) const; 5140b57cec5SDimitry Andric MachO::dylib_command 5150b57cec5SDimitry Andric getDylibIDLoadCommand(const LoadCommandInfo &L) const; 5160b57cec5SDimitry Andric MachO::dyld_info_command 5170b57cec5SDimitry Andric getDyldInfoLoadCommand(const LoadCommandInfo &L) const; 5180b57cec5SDimitry Andric MachO::dylinker_command 5190b57cec5SDimitry Andric getDylinkerCommand(const LoadCommandInfo &L) const; 5200b57cec5SDimitry Andric MachO::uuid_command 5210b57cec5SDimitry Andric getUuidCommand(const LoadCommandInfo &L) const; 5220b57cec5SDimitry Andric MachO::rpath_command 5230b57cec5SDimitry Andric getRpathCommand(const LoadCommandInfo &L) const; 5240b57cec5SDimitry Andric MachO::source_version_command 5250b57cec5SDimitry Andric getSourceVersionCommand(const LoadCommandInfo &L) const; 5260b57cec5SDimitry Andric MachO::entry_point_command 5270b57cec5SDimitry Andric getEntryPointCommand(const LoadCommandInfo &L) const; 5280b57cec5SDimitry Andric MachO::encryption_info_command 5290b57cec5SDimitry Andric getEncryptionInfoCommand(const LoadCommandInfo &L) const; 5300b57cec5SDimitry Andric MachO::encryption_info_command_64 5310b57cec5SDimitry Andric getEncryptionInfoCommand64(const LoadCommandInfo &L) const; 5320b57cec5SDimitry Andric MachO::sub_framework_command 5330b57cec5SDimitry Andric getSubFrameworkCommand(const LoadCommandInfo &L) const; 5340b57cec5SDimitry Andric MachO::sub_umbrella_command 5350b57cec5SDimitry Andric getSubUmbrellaCommand(const LoadCommandInfo &L) const; 5360b57cec5SDimitry Andric MachO::sub_library_command 5370b57cec5SDimitry Andric getSubLibraryCommand(const LoadCommandInfo &L) const; 5380b57cec5SDimitry Andric MachO::sub_client_command 5390b57cec5SDimitry Andric getSubClientCommand(const LoadCommandInfo &L) const; 5400b57cec5SDimitry Andric MachO::routines_command 5410b57cec5SDimitry Andric getRoutinesCommand(const LoadCommandInfo &L) const; 5420b57cec5SDimitry Andric MachO::routines_command_64 5430b57cec5SDimitry Andric getRoutinesCommand64(const LoadCommandInfo &L) const; 5440b57cec5SDimitry Andric MachO::thread_command 5450b57cec5SDimitry Andric getThreadCommand(const LoadCommandInfo &L) const; 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric MachO::any_relocation_info getRelocation(DataRefImpl Rel) const; 5480b57cec5SDimitry Andric MachO::data_in_code_entry getDice(DataRefImpl Rel) const; 5490b57cec5SDimitry Andric const MachO::mach_header &getHeader() const; 5500b57cec5SDimitry Andric const MachO::mach_header_64 &getHeader64() const; 5510b57cec5SDimitry Andric uint32_t 5520b57cec5SDimitry Andric getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, 5530b57cec5SDimitry Andric unsigned Index) const; 5540b57cec5SDimitry Andric MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, 5550b57cec5SDimitry Andric unsigned Index) const; 5560b57cec5SDimitry Andric MachO::symtab_command getSymtabLoadCommand() const; 5570b57cec5SDimitry Andric MachO::dysymtab_command getDysymtabLoadCommand() const; 5580b57cec5SDimitry Andric MachO::linkedit_data_command getDataInCodeLoadCommand() const; 5590b57cec5SDimitry Andric MachO::linkedit_data_command getLinkOptHintsLoadCommand() const; 5600b57cec5SDimitry Andric ArrayRef<uint8_t> getDyldInfoRebaseOpcodes() const; 5610b57cec5SDimitry Andric ArrayRef<uint8_t> getDyldInfoBindOpcodes() const; 5620b57cec5SDimitry Andric ArrayRef<uint8_t> getDyldInfoWeakBindOpcodes() const; 5630b57cec5SDimitry Andric ArrayRef<uint8_t> getDyldInfoLazyBindOpcodes() const; 5640b57cec5SDimitry Andric ArrayRef<uint8_t> getDyldInfoExportsTrie() const; 5650b57cec5SDimitry Andric ArrayRef<uint8_t> getUuid() const; 5660b57cec5SDimitry Andric 5670b57cec5SDimitry Andric StringRef getStringTableData() const; 5680b57cec5SDimitry Andric bool is64Bit() const; 5690b57cec5SDimitry Andric void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const; 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric static StringRef guessLibraryShortName(StringRef Name, bool &isFramework, 5720b57cec5SDimitry Andric StringRef &Suffix); 5730b57cec5SDimitry Andric 574480093f4SDimitry Andric static Triple::ArchType getArch(uint32_t CPUType, uint32_t CPUSubType); 5750b57cec5SDimitry Andric static Triple getArchTriple(uint32_t CPUType, uint32_t CPUSubType, 5760b57cec5SDimitry Andric const char **McpuDefault = nullptr, 5770b57cec5SDimitry Andric const char **ArchFlag = nullptr); 5780b57cec5SDimitry Andric static bool isValidArch(StringRef ArchFlag); 5790b57cec5SDimitry Andric static ArrayRef<StringRef> getValidArchs(); 5800b57cec5SDimitry Andric static Triple getHostArch(); 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andric bool isRelocatableObject() const override; 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andric StringRef mapDebugSectionName(StringRef Name) const override; 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric bool hasPageZeroSegment() const { return HasPageZeroSegment; } 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric static bool classof(const Binary *v) { 5890b57cec5SDimitry Andric return v->isMachO(); 5900b57cec5SDimitry Andric } 5910b57cec5SDimitry Andric 5920b57cec5SDimitry Andric static uint32_t 5930b57cec5SDimitry Andric getVersionMinMajor(MachO::version_min_command &C, bool SDK) { 5940b57cec5SDimitry Andric uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version; 5950b57cec5SDimitry Andric return (VersionOrSDK >> 16) & 0xffff; 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric static uint32_t 5990b57cec5SDimitry Andric getVersionMinMinor(MachO::version_min_command &C, bool SDK) { 6000b57cec5SDimitry Andric uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version; 6010b57cec5SDimitry Andric return (VersionOrSDK >> 8) & 0xff; 6020b57cec5SDimitry Andric } 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andric static uint32_t 6050b57cec5SDimitry Andric getVersionMinUpdate(MachO::version_min_command &C, bool SDK) { 6060b57cec5SDimitry Andric uint32_t VersionOrSDK = (SDK) ? C.sdk : C.version; 6070b57cec5SDimitry Andric return VersionOrSDK & 0xff; 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric static std::string getBuildPlatform(uint32_t platform) { 6110b57cec5SDimitry Andric switch (platform) { 6120b57cec5SDimitry Andric case MachO::PLATFORM_MACOS: return "macos"; 6130b57cec5SDimitry Andric case MachO::PLATFORM_IOS: return "ios"; 6140b57cec5SDimitry Andric case MachO::PLATFORM_TVOS: return "tvos"; 6150b57cec5SDimitry Andric case MachO::PLATFORM_WATCHOS: return "watchos"; 6160b57cec5SDimitry Andric case MachO::PLATFORM_BRIDGEOS: return "bridgeos"; 6170b57cec5SDimitry Andric case MachO::PLATFORM_MACCATALYST: return "macCatalyst"; 6180b57cec5SDimitry Andric case MachO::PLATFORM_IOSSIMULATOR: return "iossimulator"; 6190b57cec5SDimitry Andric case MachO::PLATFORM_TVOSSIMULATOR: return "tvossimulator"; 6200b57cec5SDimitry Andric case MachO::PLATFORM_WATCHOSSIMULATOR: return "watchossimulator"; 621e8d8bef9SDimitry Andric case MachO::PLATFORM_DRIVERKIT: return "driverkit"; 6220b57cec5SDimitry Andric default: 6230b57cec5SDimitry Andric std::string ret; 6240b57cec5SDimitry Andric raw_string_ostream ss(ret); 6250b57cec5SDimitry Andric ss << format_hex(platform, 8, true); 6260b57cec5SDimitry Andric return ss.str(); 6270b57cec5SDimitry Andric } 6280b57cec5SDimitry Andric } 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric static std::string getBuildTool(uint32_t tools) { 6310b57cec5SDimitry Andric switch (tools) { 6320b57cec5SDimitry Andric case MachO::TOOL_CLANG: return "clang"; 6330b57cec5SDimitry Andric case MachO::TOOL_SWIFT: return "swift"; 6340b57cec5SDimitry Andric case MachO::TOOL_LD: return "ld"; 6350b57cec5SDimitry Andric default: 6360b57cec5SDimitry Andric std::string ret; 6370b57cec5SDimitry Andric raw_string_ostream ss(ret); 6380b57cec5SDimitry Andric ss << format_hex(tools, 8, true); 6390b57cec5SDimitry Andric return ss.str(); 6400b57cec5SDimitry Andric } 6410b57cec5SDimitry Andric } 6420b57cec5SDimitry Andric 6430b57cec5SDimitry Andric static std::string getVersionString(uint32_t version) { 6440b57cec5SDimitry Andric uint32_t major = (version >> 16) & 0xffff; 6450b57cec5SDimitry Andric uint32_t minor = (version >> 8) & 0xff; 6460b57cec5SDimitry Andric uint32_t update = version & 0xff; 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric SmallString<32> Version; 6490b57cec5SDimitry Andric Version = utostr(major) + "." + utostr(minor); 6500b57cec5SDimitry Andric if (update != 0) 6510b57cec5SDimitry Andric Version += "." + utostr(update); 6525ffd83dbSDimitry Andric return std::string(std::string(Version.str())); 6530b57cec5SDimitry Andric } 6540b57cec5SDimitry Andric 6550eae32dcSDimitry Andric /// If the input path is a .dSYM bundle (as created by the dsymutil tool), 6560eae32dcSDimitry Andric /// return the paths to the object files found in the bundle, otherwise return 6570eae32dcSDimitry Andric /// an empty vector. If the path appears to be a .dSYM bundle but no objects 6580eae32dcSDimitry Andric /// were found or there was a filesystem error, then return an error. 6590eae32dcSDimitry Andric static Expected<std::vector<std::string>> 6600eae32dcSDimitry Andric findDsymObjectMembers(StringRef Path); 6610eae32dcSDimitry Andric 6620b57cec5SDimitry Andric private: 6630b57cec5SDimitry Andric MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, 6640b57cec5SDimitry Andric Error &Err, uint32_t UniversalCputype = 0, 6650b57cec5SDimitry Andric uint32_t UniversalIndex = 0); 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric uint64_t getSymbolValueImpl(DataRefImpl Symb) const override; 6680b57cec5SDimitry Andric 6690b57cec5SDimitry Andric union { 6700b57cec5SDimitry Andric MachO::mach_header_64 Header64; 6710b57cec5SDimitry Andric MachO::mach_header Header; 6720b57cec5SDimitry Andric }; 6730b57cec5SDimitry Andric using SectionList = SmallVector<const char*, 1>; 6740b57cec5SDimitry Andric SectionList Sections; 6750b57cec5SDimitry Andric using LibraryList = SmallVector<const char*, 1>; 6760b57cec5SDimitry Andric LibraryList Libraries; 6770b57cec5SDimitry Andric LoadCommandList LoadCommands; 6780b57cec5SDimitry Andric using LibraryShortName = SmallVector<StringRef, 1>; 6790b57cec5SDimitry Andric using BuildToolList = SmallVector<const char*, 1>; 6800b57cec5SDimitry Andric BuildToolList BuildTools; 6810b57cec5SDimitry Andric mutable LibraryShortName LibrariesShortNames; 6820b57cec5SDimitry Andric std::unique_ptr<BindRebaseSegInfo> BindRebaseSectionTable; 6830b57cec5SDimitry Andric const char *SymtabLoadCmd = nullptr; 6840b57cec5SDimitry Andric const char *DysymtabLoadCmd = nullptr; 6850b57cec5SDimitry Andric const char *DataInCodeLoadCmd = nullptr; 6860b57cec5SDimitry Andric const char *LinkOptHintsLoadCmd = nullptr; 6870b57cec5SDimitry Andric const char *DyldInfoLoadCmd = nullptr; 6880b57cec5SDimitry Andric const char *UuidLoadCmd = nullptr; 6890b57cec5SDimitry Andric bool HasPageZeroSegment = false; 6900b57cec5SDimitry Andric }; 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric /// DiceRef 6930b57cec5SDimitry Andric inline DiceRef::DiceRef(DataRefImpl DiceP, const ObjectFile *Owner) 6940b57cec5SDimitry Andric : DicePimpl(DiceP) , OwningObject(Owner) {} 6950b57cec5SDimitry Andric 6960b57cec5SDimitry Andric inline bool DiceRef::operator==(const DiceRef &Other) const { 6970b57cec5SDimitry Andric return DicePimpl == Other.DicePimpl; 6980b57cec5SDimitry Andric } 6990b57cec5SDimitry Andric 7000b57cec5SDimitry Andric inline bool DiceRef::operator<(const DiceRef &Other) const { 7010b57cec5SDimitry Andric return DicePimpl < Other.DicePimpl; 7020b57cec5SDimitry Andric } 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric inline void DiceRef::moveNext() { 7050b57cec5SDimitry Andric const MachO::data_in_code_entry *P = 7060b57cec5SDimitry Andric reinterpret_cast<const MachO::data_in_code_entry *>(DicePimpl.p); 7070b57cec5SDimitry Andric DicePimpl.p = reinterpret_cast<uintptr_t>(P + 1); 7080b57cec5SDimitry Andric } 7090b57cec5SDimitry Andric 7100b57cec5SDimitry Andric // Since a Mach-O data in code reference, a DiceRef, can only be created when 7110b57cec5SDimitry Andric // the OwningObject ObjectFile is a MachOObjectFile a static_cast<> is used for 7120b57cec5SDimitry Andric // the methods that get the values of the fields of the reference. 7130b57cec5SDimitry Andric 7140b57cec5SDimitry Andric inline std::error_code DiceRef::getOffset(uint32_t &Result) const { 7150b57cec5SDimitry Andric const MachOObjectFile *MachOOF = 7160b57cec5SDimitry Andric static_cast<const MachOObjectFile *>(OwningObject); 7170b57cec5SDimitry Andric MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); 7180b57cec5SDimitry Andric Result = Dice.offset; 7190b57cec5SDimitry Andric return std::error_code(); 7200b57cec5SDimitry Andric } 7210b57cec5SDimitry Andric 7220b57cec5SDimitry Andric inline std::error_code DiceRef::getLength(uint16_t &Result) const { 7230b57cec5SDimitry Andric const MachOObjectFile *MachOOF = 7240b57cec5SDimitry Andric static_cast<const MachOObjectFile *>(OwningObject); 7250b57cec5SDimitry Andric MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); 7260b57cec5SDimitry Andric Result = Dice.length; 7270b57cec5SDimitry Andric return std::error_code(); 7280b57cec5SDimitry Andric } 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andric inline std::error_code DiceRef::getKind(uint16_t &Result) const { 7310b57cec5SDimitry Andric const MachOObjectFile *MachOOF = 7320b57cec5SDimitry Andric static_cast<const MachOObjectFile *>(OwningObject); 7330b57cec5SDimitry Andric MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); 7340b57cec5SDimitry Andric Result = Dice.kind; 7350b57cec5SDimitry Andric return std::error_code(); 7360b57cec5SDimitry Andric } 7370b57cec5SDimitry Andric 7380b57cec5SDimitry Andric inline DataRefImpl DiceRef::getRawDataRefImpl() const { 7390b57cec5SDimitry Andric return DicePimpl; 7400b57cec5SDimitry Andric } 7410b57cec5SDimitry Andric 7420b57cec5SDimitry Andric inline const ObjectFile *DiceRef::getObjectFile() const { 7430b57cec5SDimitry Andric return OwningObject; 7440b57cec5SDimitry Andric } 7450b57cec5SDimitry Andric 7460b57cec5SDimitry Andric } // end namespace object 7470b57cec5SDimitry Andric } // end namespace llvm 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andric #endif // LLVM_OBJECT_MACHO_H 750