Object/Mach-O: Add header and load command information.
[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/OwningPtr.h"
15 #include "llvm/Object/MachOFormat.h"
16
17 namespace llvm {
18
19 class MemoryBuffer;
20
21 namespace object {
22
23 /// \brief Wrapper object for manipulating Mach-O object files.
24 ///
25 /// This class is designed to implement a full-featured, efficient, portable,
26 /// and robust Mach-O interface to Mach-O object files. It does not attempt to
27 /// smooth over rough edges in the Mach-O format or generalize access to object
28 /// independent features.
29 ///
30 /// The class is designed around accessing the Mach-O object which is expected
31 /// to be fully loaded into memory.
32 ///
33 /// This class is *not* suitable for concurrent use. For efficient operation,
34 /// the class uses APIs which rely on the ability to cache the results of
35 /// certain calls in internal objects which are not safe for concurrent
36 /// access. This allows the API to be zero-copy on the common paths.
37 //
38 // FIXME: It would be cool if we supported a "paged" MemoryBuffer
39 // implementation. This would allow us to implement a more sensible version of
40 // MemoryObject which can work like a MemoryBuffer, but be more efficient for
41 // objects which are in the current address space.
42 class MachOObject {
43 public:
44   struct LoadCommandInfo {
45     /// The load command information.
46     macho::LoadCommand Command;
47
48     /// The offset to the start of the load command in memory.
49     uint64_t Offset;
50   };
51
52 private:
53   OwningPtr<MemoryBuffer> Buffer;
54
55   /// Whether the object is little endian.
56   bool IsLittleEndian;
57   /// Whether the object is 64-bit.
58   bool Is64Bit;
59   /// Whether the object is swapped endianness from the host.
60   bool IsSwappedEndian;
61
62   /// The cached information on the load commands.
63   LoadCommandInfo *LoadCommands;
64   mutable unsigned NumLoadedCommands;
65
66   /// The cached copy of the header.
67   macho::Header Header;
68   macho::Header64Ext Header64Ext;
69
70 private:
71   MachOObject(MemoryBuffer *Buffer, bool IsLittleEndian, bool Is64Bit);
72
73 public:
74   ~MachOObject();
75
76   /// \brief Load a Mach-O object from a MemoryBuffer object.
77   ///
78   /// \param Buffer - The buffer to load the object from. This routine takes
79   /// exclusive ownership of the buffer (which is passed to the returned object
80   /// on success).
81   /// \param ErrorStr [out] - If given, will be set to a user readable error
82   /// message on failure.
83   /// \returns The loaded object, or null on error.
84   static MachOObject *LoadFromBuffer(MemoryBuffer *Buffer,
85                                      std::string *ErrorStr = 0);
86
87   /// @name File Information
88   /// @{
89
90   bool isLittleEndian() const { return IsLittleEndian; }
91   bool is64Bit() const { return Is64Bit; }
92
93   unsigned getHeaderSize() const {
94     return Is64Bit ? macho::Header64Size : macho::Header32Size;
95   }
96
97   /// @}
98   /// @name Object Header Access
99   /// @{
100
101   const macho::Header &getHeader() const { return Header; }
102   const macho::Header64Ext &getHeader64Ext() const {
103     assert(is64Bit() && "Invalid access!");
104     return Header64Ext;
105   }
106
107   /// @}
108   /// @name Object Structure Access
109   /// @{
110
111   /// \brief Retrieve the information for the given load command.
112   const LoadCommandInfo &getLoadCommandInfo(unsigned Index) const;
113
114   /// @}
115 };
116
117 } // end namespace object
118 } // end namespace llvm
119
120 #endif