Finish templating MachObjectFile over endianness.
[oota-llvm.git] / lib / Object / MachOObjectFile.cpp
1 //===- MachOObjectFile.cpp - Mach-O object file binding ---------*- 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 // This file defines the MachOObjectFile class, which binds the MachOObject
11 // class to the generic ObjectFile wrapper.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Object/MachO.h"
16 #include "llvm/ADT/Triple.h"
17 #include "llvm/Object/MachOFormat.h"
18 #include "llvm/Support/Casting.h"
19 #include "llvm/Support/DataExtractor.h"
20 #include "llvm/Support/Format.h"
21 #include "llvm/Support/MemoryBuffer.h"
22 #include <cctype>
23 #include <cstring>
24 #include <limits>
25
26 using namespace llvm;
27 using namespace object;
28
29 namespace llvm {
30 namespace object {
31
32 MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object,
33                                          bool IsLittleEndian, bool Is64bits,
34                                          error_code &ec)
35     : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) {
36 }
37
38 bool MachOObjectFileBase::is64Bit() const {
39   return isa<MachOObjectFileLE64>(this) || isa<MachOObjectFileBE64>(this);
40 }
41
42 void MachOObjectFileBase::ReadULEB128s(uint64_t Index,
43                                        SmallVectorImpl<uint64_t> &Out) const {
44   DataExtractor extractor(ObjectFile::getData(), true, 0);
45
46   uint32_t offset = Index;
47   uint64_t data = 0;
48   while (uint64_t delta = extractor.getULEB128(&offset)) {
49     data += delta;
50     Out.push_back(data);
51   }
52 }
53
54 unsigned MachOObjectFileBase::getHeaderSize() const {
55   return is64Bit() ? macho::Header64Size : macho::Header32Size;
56 }
57
58 StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const {
59   return ObjectFile::getData().substr(Offset, Size);
60 }
61
62 ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
63   StringRef Magic = Buffer->getBuffer().slice(0, 4);
64   error_code ec;
65   ObjectFile *Ret;
66   if (Magic == "\xFE\xED\xFA\xCE")
67     Ret = new MachOObjectFileBE32(Buffer, ec);
68   else if (Magic == "\xCE\xFA\xED\xFE")
69     Ret = new MachOObjectFileLE32(Buffer, ec);
70   else if (Magic == "\xFE\xED\xFA\xCF")
71     Ret = new MachOObjectFileBE64(Buffer, ec);
72   else if (Magic == "\xCF\xFA\xED\xFE")
73     Ret = new MachOObjectFileLE64(Buffer, ec);
74   else
75     return NULL;
76
77   if (ec)
78     return NULL;
79   return Ret;
80 }
81
82 /*===-- Symbols -----------------------------------------------------------===*/
83
84 error_code MachOObjectFileBase::getSymbolValue(DataRefImpl Symb,
85                                                uint64_t &Val) const {
86   report_fatal_error("getSymbolValue unimplemented in MachOObjectFileBase");
87 }
88
89 symbol_iterator MachOObjectFileBase::begin_dynamic_symbols() const {
90   // TODO: implement
91   report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase");
92 }
93
94 symbol_iterator MachOObjectFileBase::end_dynamic_symbols() const {
95   // TODO: implement
96   report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase");
97 }
98
99 library_iterator MachOObjectFileBase::begin_libraries_needed() const {
100   // TODO: implement
101   report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
102 }
103
104 library_iterator MachOObjectFileBase::end_libraries_needed() const {
105   // TODO: implement
106   report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
107 }
108
109 StringRef MachOObjectFileBase::getLoadName() const {
110   // TODO: Implement
111   report_fatal_error("get_load_name() unimplemented in MachOObjectFileBase");
112 }
113
114 /*===-- Sections ----------------------------------------------------------===*/
115
116 std::size_t MachOObjectFileBase::getSectionIndex(DataRefImpl Sec) const {
117   SectionList::const_iterator loc =
118     std::find(Sections.begin(), Sections.end(), Sec);
119   assert(loc != Sections.end() && "Sec is not a valid section!");
120   return std::distance(Sections.begin(), loc);
121 }
122
123 StringRef MachOObjectFileBase::parseSegmentOrSectionName(const char *P) const {
124   if (P[15] == 0)
125     // Null terminated.
126     return P;
127   // Not null terminated, so this is a 16 char string.
128   return StringRef(P, 16);
129 }
130
131 error_code MachOObjectFileBase::isSectionData(DataRefImpl DRI,
132                                               bool &Result) const {
133   // FIXME: Unimplemented.
134   Result = false;
135   return object_error::success;
136 }
137
138 error_code MachOObjectFileBase::isSectionBSS(DataRefImpl DRI,
139                                              bool &Result) const {
140   // FIXME: Unimplemented.
141   Result = false;
142   return object_error::success;
143 }
144
145 error_code
146 MachOObjectFileBase::isSectionRequiredForExecution(DataRefImpl Sec,
147                                                    bool &Result) const {
148   // FIXME: Unimplemented.
149   Result = true;
150   return object_error::success;
151 }
152
153 error_code MachOObjectFileBase::isSectionVirtual(DataRefImpl Sec,
154                                                  bool &Result) const {
155   // FIXME: Unimplemented.
156   Result = false;
157   return object_error::success;
158 }
159
160 error_code MachOObjectFileBase::isSectionReadOnlyData(DataRefImpl Sec,
161                                                       bool &Result) const {
162   // Consider using the code from isSectionText to look for __const sections.
163   // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS
164   // to use section attributes to distinguish code from data.
165
166   // FIXME: Unimplemented.
167   Result = false;
168   return object_error::success;
169 }
170
171 relocation_iterator MachOObjectFileBase::getSectionRelBegin(DataRefImpl Sec) const {
172   DataRefImpl ret;
173   ret.d.b = getSectionIndex(Sec);
174   return relocation_iterator(RelocationRef(ret, this));
175 }
176
177
178 /*===-- Relocations -------------------------------------------------------===*/
179
180 error_code MachOObjectFileBase::getRelocationNext(DataRefImpl Rel,
181                                                   RelocationRef &Res) const {
182   ++Rel.d.a;
183   Res = RelocationRef(Rel, this);
184   return object_error::success;
185 }
186
187 error_code MachOObjectFileBase::getLibraryNext(DataRefImpl LibData,
188                                                LibraryRef &Res) const {
189   report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
190 }
191
192 error_code MachOObjectFileBase::getLibraryPath(DataRefImpl LibData,
193                                                StringRef &Res) const {
194   report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
195 }
196
197 error_code MachOObjectFileBase::getRelocationAdditionalInfo(DataRefImpl Rel,
198                                                            int64_t &Res) const {
199   Res = 0;
200   return object_error::success;
201 }
202
203
204 /*===-- Miscellaneous -----------------------------------------------------===*/
205
206 uint8_t MachOObjectFileBase::getBytesInAddress() const {
207   return is64Bit() ? 8 : 4;
208 }
209
210 } // end namespace object
211 } // end namespace llvm