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