diff options
Diffstat (limited to 'include/llvm/Object/MachO.h')
-rw-r--r-- | include/llvm/Object/MachO.h | 249 |
1 files changed, 213 insertions, 36 deletions
diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index e93ebb8..768cda6 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -49,6 +49,141 @@ public: }; typedef content_iterator<DiceRef> dice_iterator; +/// ExportEntry encapsulates the current-state-of-the-walk used when doing a +/// non-recursive walk of the trie data structure. This allows you to iterate +/// across all exported symbols using: +/// for (const llvm::object::ExportEntry &AnExport : Obj->exports()) { +/// } +class ExportEntry { +public: + ExportEntry(ArrayRef<uint8_t> Trie); + + StringRef name() const; + uint64_t flags() const; + uint64_t address() const; + uint64_t other() const; + StringRef otherName() const; + uint32_t nodeOffset() const; + + bool operator==(const ExportEntry &) const; + + void moveNext(); + +private: + friend class MachOObjectFile; + void moveToFirst(); + void moveToEnd(); + uint64_t readULEB128(const uint8_t *&p); + void pushDownUntilBottom(); + void pushNode(uint64_t Offset); + + // Represents a node in the mach-o exports trie. + struct NodeState { + NodeState(const uint8_t *Ptr); + const uint8_t *Start; + const uint8_t *Current; + uint64_t Flags; + uint64_t Address; + uint64_t Other; + const char *ImportName; + unsigned ChildCount; + unsigned NextChildIndex; + unsigned ParentStringLength; + bool IsExportNode; + }; + + ArrayRef<uint8_t> Trie; + SmallString<256> CumulativeString; + SmallVector<NodeState, 16> Stack; + bool Malformed; + bool Done; +}; +typedef content_iterator<ExportEntry> export_iterator; + +/// MachORebaseEntry encapsulates the current state in the decompression of +/// rebasing opcodes. This allows you to iterate through the compressed table of +/// rebasing using: +/// for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable()) { +/// } +class MachORebaseEntry { +public: + MachORebaseEntry(ArrayRef<uint8_t> opcodes, bool is64Bit); + + uint32_t segmentIndex() const; + uint64_t segmentOffset() const; + StringRef typeName() const; + + bool operator==(const MachORebaseEntry &) const; + + void moveNext(); + +private: + friend class MachOObjectFile; + void moveToFirst(); + void moveToEnd(); + uint64_t readULEB128(); + + ArrayRef<uint8_t> Opcodes; + const uint8_t *Ptr; + uint64_t SegmentOffset; + uint32_t SegmentIndex; + uint64_t RemainingLoopCount; + uint64_t AdvanceAmount; + uint8_t RebaseType; + uint8_t PointerSize; + bool Malformed; + bool Done; +}; +typedef content_iterator<MachORebaseEntry> rebase_iterator; + +/// MachOBindEntry encapsulates the current state in the decompression of +/// binding opcodes. This allows you to iterate through the compressed table of +/// bindings using: +/// for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable()) { +/// } +class MachOBindEntry { +public: + enum class Kind { Regular, Lazy, Weak }; + + MachOBindEntry(ArrayRef<uint8_t> Opcodes, bool is64Bit, MachOBindEntry::Kind); + + uint32_t segmentIndex() const; + uint64_t segmentOffset() const; + StringRef typeName() const; + StringRef symbolName() const; + uint32_t flags() const; + int64_t addend() const; + int ordinal() const; + + bool operator==(const MachOBindEntry &) const; + + void moveNext(); + +private: + friend class MachOObjectFile; + void moveToFirst(); + void moveToEnd(); + uint64_t readULEB128(); + int64_t readSLEB128(); + + ArrayRef<uint8_t> Opcodes; + const uint8_t *Ptr; + uint64_t SegmentOffset; + uint32_t SegmentIndex; + StringRef SymbolName; + int Ordinal; + uint32_t Flags; + int64_t Addend; + uint64_t RemainingLoopCount; + uint64_t AdvanceAmount; + uint8_t BindType; + uint8_t PointerSize; + Kind TableKind; + bool Malformed; + bool Done; +}; +typedef content_iterator<MachOBindEntry> bind_iterator; + class MachOObjectFile : public ObjectFile { public: struct LoadCommandInfo { @@ -56,8 +191,8 @@ public: MachO::load_command C; // The command itself. }; - MachOObjectFile(std::unique_ptr<MemoryBuffer> Object, bool IsLittleEndian, - bool Is64Bits, std::error_code &EC); + MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, + std::error_code &EC); void moveSymbolNext(DataRefImpl &Symb) const override; std::error_code getSymbolName(DataRefImpl Symb, @@ -80,24 +215,19 @@ public: void moveSectionNext(DataRefImpl &Sec) const override; std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override; - std::error_code getSectionAddress(DataRefImpl Sec, - uint64_t &Res) const override; - std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override; + uint64_t getSectionAddress(DataRefImpl Sec) const override; + uint64_t getSectionSize(DataRefImpl Sec) const override; std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override; - std::error_code getSectionAlignment(DataRefImpl Sec, - uint64_t &Res) const override; - std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override; - std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override; - std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override; - std::error_code isSectionRequiredForExecution(DataRefImpl Sec, - bool &Res) const override; - std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override; - std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override; - std::error_code isSectionReadOnlyData(DataRefImpl Sec, - bool &Res) const override; - std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, - bool &Result) const override; + uint64_t getSectionAlignment(DataRefImpl Sec) const override; + bool isSectionText(DataRefImpl Sec) const override; + bool isSectionData(DataRefImpl Sec) const override; + bool isSectionBSS(DataRefImpl Sec) const override; + bool isSectionRequiredForExecution(DataRefImpl Sec) const override; + bool isSectionVirtual(DataRefImpl Sec) const override; + bool isSectionZeroInit(DataRefImpl Sec) const override; + bool isSectionReadOnlyData(DataRefImpl Sec) const override; + bool sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; @@ -118,13 +248,8 @@ public: std::error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const override; - std::error_code getLibraryNext(DataRefImpl LibData, - LibraryRef &Res) const override; - std::error_code getLibraryPath(DataRefImpl LibData, - StringRef &Res) const override; - // MachO specific. - std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &Res); + std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const; // TODO: Would be useful to have an iterator based version // of the load command interface too. @@ -138,21 +263,45 @@ public: section_iterator section_begin() const override; section_iterator section_end() const override; - library_iterator needed_library_begin() const override; - library_iterator needed_library_end() const override; - uint8_t getBytesInAddress() const override; StringRef getFileFormatName() const override; unsigned getArch() const override; - - StringRef getLoadName() const override; + Triple getArch(const char **McpuDefault, Triple *ThumbTriple) const; relocation_iterator section_rel_begin(unsigned Index) const; relocation_iterator section_rel_end(unsigned Index) const; dice_iterator begin_dices() const; dice_iterator end_dices() const; + + /// For use iterating over all exported symbols. + iterator_range<export_iterator> exports() const; + + /// For use examining a trie not in a MachOObjectFile. + static iterator_range<export_iterator> exports(ArrayRef<uint8_t> Trie); + + /// For use iterating over all rebase table entries. + iterator_range<rebase_iterator> rebaseTable() const; + + /// For use examining rebase opcodes not in a MachOObjectFile. + static iterator_range<rebase_iterator> rebaseTable(ArrayRef<uint8_t> Opcodes, + bool is64); + + /// For use iterating over all bind table entries. + iterator_range<bind_iterator> bindTable() const; + + /// For use iterating over all lazy bind table entries. + iterator_range<bind_iterator> lazyBindTable() const; + + /// For use iterating over all lazy bind table entries. + iterator_range<bind_iterator> weakBindTable() const; + + /// For use examining bind opcodes not in a MachOObjectFile. + static iterator_range<bind_iterator> bindTable(ArrayRef<uint8_t> Opcodes, + bool is64, + MachOBindEntry::Kind); + // In a MachO file, sections have a segment name. This is used in the .o // files. They have a single segment, but this field specifies which segment @@ -173,6 +322,8 @@ public: const MachO::any_relocation_info &RE) const; uint32_t getScatteredRelocationValue( const MachO::any_relocation_info &RE) const; + uint32_t getScatteredRelocationType( + const MachO::any_relocation_info &RE) const; unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const; unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const; unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const; @@ -203,6 +354,16 @@ public: getVersionMinLoadCommand(const LoadCommandInfo &L) const; MachO::dylib_command getDylibIDLoadCommand(const LoadCommandInfo &L) const; + MachO::dyld_info_command + getDyldInfoLoadCommand(const LoadCommandInfo &L) const; + MachO::dylinker_command + getDylinkerCommand(const LoadCommandInfo &L) const; + MachO::uuid_command + getUuidCommand(const LoadCommandInfo &L) const; + MachO::source_version_command + getSourceVersionCommand(const LoadCommandInfo &L) const; + MachO::entry_point_command + getEntryPointCommand(const LoadCommandInfo &L) const; MachO::any_relocation_info getRelocation(DataRefImpl Rel) const; MachO::data_in_code_entry getDice(DataRefImpl Rel) const; @@ -216,6 +377,12 @@ public: MachO::symtab_command getSymtabLoadCommand() const; MachO::dysymtab_command getDysymtabLoadCommand() const; MachO::linkedit_data_command getDataInCodeLoadCommand() const; + ArrayRef<uint8_t> getDyldInfoRebaseOpcodes() const; + ArrayRef<uint8_t> getDyldInfoBindOpcodes() const; + ArrayRef<uint8_t> getDyldInfoWeakBindOpcodes() const; + ArrayRef<uint8_t> getDyldInfoLazyBindOpcodes() const; + ArrayRef<uint8_t> getDyldInfoExportsTrie() const; + ArrayRef<uint8_t> getUuid() const; StringRef getStringTableData() const; bool is64Bit() const; @@ -225,26 +392,36 @@ public: StringRef &Suffix); static Triple::ArchType getArch(uint32_t CPUType); - static Triple getArch(uint32_t CPUType, uint32_t CPUSubType); - static Triple getArch(StringRef ArchFlag); + static Triple getArch(uint32_t CPUType, uint32_t CPUSubType, + const char **McpuDefault = nullptr); + static Triple getThumbArch(uint32_t CPUType, uint32_t CPUSubType, + const char **McpuDefault = nullptr); + static Triple getArch(uint32_t CPUType, uint32_t CPUSubType, + const char **McpuDefault, Triple *ThumbTriple); + static bool isValidArch(StringRef ArchFlag); static Triple getHostArch(); + bool isRelocatableObject() const override; + + bool hasPageZeroSegment() const { return HasPageZeroSegment; } + static bool classof(const Binary *v) { return v->isMachO(); } - const char *getSectionPointer(DataRefImpl Rel) const; - private: - typedef SmallVector<const char *, 1> SectionList; + typedef SmallVector<const char*, 1> SectionList; SectionList Sections; - typedef SmallVector<const char *, 1> LibraryList; + typedef SmallVector<const char*, 1> LibraryList; LibraryList Libraries; typedef SmallVector<StringRef, 1> LibraryShortName; - LibraryShortName LibrariesShortNames; + mutable LibraryShortName LibrariesShortNames; const char *SymtabLoadCmd; const char *DysymtabLoadCmd; const char *DataInCodeLoadCmd; + const char *DyldInfoLoadCmd; + const char *UuidLoadCmd; + bool HasPageZeroSegment; }; /// DiceRef |