Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
6.5 KiB

  1. //===- MachOObject.h - Mach-O Object File Wrapper ---------------*- 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. #ifndef LLVM_OBJECT_MACHOOBJECT_H
  10. #define LLVM_OBJECT_MACHOOBJECT_H
  11. #include "llvm/ADT/InMemoryStruct.h"
  12. #include "llvm/ADT/OwningPtr.h"
  13. #include "llvm/ADT/StringRef.h"
  14. #include "llvm/Object/MachOFormat.h"
  15. #include <string>
  16. namespace llvm {
  17. class MemoryBuffer;
  18. class raw_ostream;
  19. namespace object {
  20. /// \brief Wrapper object for manipulating Mach-O object files.
  21. ///
  22. /// This class is designed to implement a full-featured, efficient, portable,
  23. /// and robust Mach-O interface to Mach-O object files. It does not attempt to
  24. /// smooth over rough edges in the Mach-O format or generalize access to object
  25. /// independent features.
  26. ///
  27. /// The class is designed around accessing the Mach-O object which is expected
  28. /// to be fully loaded into memory.
  29. ///
  30. /// This class is *not* suitable for concurrent use. For efficient operation,
  31. /// the class uses APIs which rely on the ability to cache the results of
  32. /// certain calls in internal objects which are not safe for concurrent
  33. /// access. This allows the API to be zero-copy on the common paths.
  34. //
  35. // FIXME: It would be cool if we supported a "paged" MemoryBuffer
  36. // implementation. This would allow us to implement a more sensible version of
  37. // MemoryObject which can work like a MemoryBuffer, but be more efficient for
  38. // objects which are in the current address space.
  39. class MachOObject {
  40. public:
  41. struct LoadCommandInfo {
  42. /// The load command information.
  43. macho::LoadCommand Command;
  44. /// The offset to the start of the load command in memory.
  45. uint64_t Offset;
  46. };
  47. private:
  48. OwningPtr<MemoryBuffer> Buffer;
  49. /// Whether the object is little endian.
  50. bool IsLittleEndian;
  51. /// Whether the object is 64-bit.
  52. bool Is64Bit;
  53. /// Whether the object is swapped endianness from the host.
  54. bool IsSwappedEndian;
  55. /// Whether the string table has been registered.
  56. bool HasStringTable;
  57. /// The cached information on the load commands.
  58. LoadCommandInfo *LoadCommands;
  59. mutable unsigned NumLoadedCommands;
  60. /// The cached copy of the header.
  61. macho::Header Header;
  62. macho::Header64Ext Header64Ext;
  63. /// Cache string table information.
  64. StringRef StringTable;
  65. private:
  66. MachOObject(MemoryBuffer *Buffer, bool IsLittleEndian, bool Is64Bit);
  67. public:
  68. ~MachOObject();
  69. /// \brief Load a Mach-O object from a MemoryBuffer object.
  70. ///
  71. /// \param Buffer - The buffer to load the object from. This routine takes
  72. /// exclusive ownership of the buffer (which is passed to the returned object
  73. /// on success).
  74. /// \param ErrorStr [out] - If given, will be set to a user readable error
  75. /// message on failure.
  76. /// \returns The loaded object, or null on error.
  77. static MachOObject *LoadFromBuffer(MemoryBuffer *Buffer,
  78. std::string *ErrorStr = 0);
  79. /// @name File Information
  80. /// @{
  81. bool isLittleEndian() const { return IsLittleEndian; }
  82. bool isSwappedEndian() const { return IsSwappedEndian; }
  83. bool is64Bit() const { return Is64Bit; }
  84. unsigned getHeaderSize() const {
  85. return Is64Bit ? macho::Header64Size : macho::Header32Size;
  86. }
  87. StringRef getData(size_t Offset, size_t Size) const;
  88. /// @}
  89. /// @name String Table Data
  90. /// @{
  91. StringRef getStringTableData() const {
  92. assert(HasStringTable && "String table has not been registered!");
  93. return StringTable;
  94. }
  95. StringRef getStringAtIndex(unsigned Index) const {
  96. size_t End = getStringTableData().find('\0', Index);
  97. return getStringTableData().slice(Index, End);
  98. }
  99. void RegisterStringTable(macho::SymtabLoadCommand &SLC);
  100. /// @}
  101. /// @name Object Header Access
  102. /// @{
  103. const macho::Header &getHeader() const { return Header; }
  104. const macho::Header64Ext &getHeader64Ext() const {
  105. assert(is64Bit() && "Invalid access!");
  106. return Header64Ext;
  107. }
  108. /// @}
  109. /// @name Object Structure Access
  110. /// @{
  111. // TODO: Would be useful to have an iterator based version
  112. // of this.
  113. /// \brief Retrieve the information for the given load command.
  114. const LoadCommandInfo &getLoadCommandInfo(unsigned Index) const;
  115. void ReadSegmentLoadCommand(
  116. const LoadCommandInfo &LCI,
  117. InMemoryStruct<macho::SegmentLoadCommand> &Res) const;
  118. void ReadSegment64LoadCommand(
  119. const LoadCommandInfo &LCI,
  120. InMemoryStruct<macho::Segment64LoadCommand> &Res) const;
  121. void ReadSymtabLoadCommand(
  122. const LoadCommandInfo &LCI,
  123. InMemoryStruct<macho::SymtabLoadCommand> &Res) const;
  124. void ReadDysymtabLoadCommand(
  125. const LoadCommandInfo &LCI,
  126. InMemoryStruct<macho::DysymtabLoadCommand> &Res) const;
  127. void ReadLinkeditDataLoadCommand(
  128. const LoadCommandInfo &LCI,
  129. InMemoryStruct<macho::LinkeditDataLoadCommand> &Res) const;
  130. void ReadLinkerOptionsLoadCommand(
  131. const LoadCommandInfo &LCI,
  132. InMemoryStruct<macho::LinkerOptionsLoadCommand> &Res) const;
  133. void ReadIndirectSymbolTableEntry(
  134. const macho::DysymtabLoadCommand &DLC,
  135. unsigned Index,
  136. InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const;
  137. void ReadSection(
  138. const LoadCommandInfo &LCI,
  139. unsigned Index,
  140. InMemoryStruct<macho::Section> &Res) const;
  141. void ReadSection64(
  142. const LoadCommandInfo &LCI,
  143. unsigned Index,
  144. InMemoryStruct<macho::Section64> &Res) const;
  145. void ReadRelocationEntry(
  146. uint64_t RelocationTableOffset, unsigned Index,
  147. InMemoryStruct<macho::RelocationEntry> &Res) const;
  148. void ReadSymbolTableEntry(
  149. uint64_t SymbolTableOffset, unsigned Index,
  150. InMemoryStruct<macho::SymbolTableEntry> &Res) const;
  151. void ReadSymbol64TableEntry(
  152. uint64_t SymbolTableOffset, unsigned Index,
  153. InMemoryStruct<macho::Symbol64TableEntry> &Res) const;
  154. void ReadDataInCodeTableEntry(
  155. uint64_t TableOffset, unsigned Index,
  156. InMemoryStruct<macho::DataInCodeTableEntry> &Res) const;
  157. void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const;
  158. /// @}
  159. /// @name Object Dump Facilities
  160. /// @{
  161. /// dump - Support for debugging, callable in GDB: V->dump()
  162. //
  163. void dump() const;
  164. void dumpHeader() const;
  165. /// print - Implement operator<< on Value.
  166. ///
  167. void print(raw_ostream &O) const;
  168. void printHeader(raw_ostream &O) const;
  169. /// @}
  170. };
  171. inline raw_ostream &operator<<(raw_ostream &OS, const MachOObject &V) {
  172. V.print(OS);
  173. return OS;
  174. }
  175. } // end namespace object
  176. } // end namespace llvm
  177. #endif