macho-dump: Add support for dumping string table data.
[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   /// @}
106   /// @name String Table Data
107   /// @{
108
109   StringRef getStringTableData() const {
110     assert(HasStringTable && "String table has not been registered!");
111     return StringTable;
112   }
113
114   void RegisterStringTable(macho::SymtabLoadCommand &SLC);
115
116   /// @}
117   /// @name Object Header Access
118   /// @{
119
120   const macho::Header &getHeader() const { return Header; }
121   const macho::Header64Ext &getHeader64Ext() const {
122     assert(is64Bit() && "Invalid access!");
123     return Header64Ext;
124   }
125
126   /// @}
127   /// @name Object Structure Access
128   /// @{
129
130   /// \brief Retrieve the information for the given load command.
131   const LoadCommandInfo &getLoadCommandInfo(unsigned Index) const;
132
133   void ReadSegmentLoadCommand(
134     const LoadCommandInfo &LCI,
135     InMemoryStruct<macho::SegmentLoadCommand> &Res) const;
136   void ReadSegment64LoadCommand(
137     const LoadCommandInfo &LCI,
138     InMemoryStruct<macho::Segment64LoadCommand> &Res) const;
139   void ReadSymtabLoadCommand(
140     const LoadCommandInfo &LCI,
141     InMemoryStruct<macho::SymtabLoadCommand> &Res) const;
142   void ReadDysymtabLoadCommand(
143     const LoadCommandInfo &LCI,
144     InMemoryStruct<macho::DysymtabLoadCommand> &Res) const;
145   void ReadIndirectSymbolTableEntry(
146     const macho::DysymtabLoadCommand &DLC,
147     unsigned Index,
148     InMemoryStruct<macho::IndirectSymbolTableEntry> &Res) const;
149   void ReadSection(
150     const LoadCommandInfo &LCI,
151     unsigned Index,
152     InMemoryStruct<macho::Section> &Res) const;
153   void ReadSection64(
154     const LoadCommandInfo &LCI,
155     unsigned Index,
156     InMemoryStruct<macho::Section64> &Res) const;
157   void ReadRelocationEntry(
158     uint64_t RelocationTableOffset, unsigned Index,
159     InMemoryStruct<macho::RelocationEntry> &Res) const;
160
161   /// @}
162 };
163
164 } // end namespace object
165 } // end namespace llvm
166
167 #endif