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