blob: 192e7555b499dabc6539ce8fc5a0a75ac44ead35 [file] [log] [blame]
Eric Christopher6256b032011-04-22 03:19:48 +00001//===- 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
Owen Andersonf7c93a32011-10-11 17:32:27 +000015#include "llvm/Object/MachO.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000016#include "llvm/ADT/Triple.h"
Eric Christopher6256b032011-04-22 03:19:48 +000017#include "llvm/Object/MachOFormat.h"
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000018#include "llvm/Support/Casting.h"
Rafael Espindola8764c892013-04-07 20:01:29 +000019#include "llvm/Support/DataExtractor.h"
Owen Anderson1832f4d2011-10-26 20:42:54 +000020#include "llvm/Support/Format.h"
Eric Christopher6256b032011-04-22 03:19:48 +000021#include "llvm/Support/MemoryBuffer.h"
Eric Christopher6256b032011-04-22 03:19:48 +000022#include <cctype>
23#include <cstring>
24#include <limits>
25
26using namespace llvm;
27using namespace object;
28
29namespace llvm {
Owen Andersonf7c93a32011-10-11 17:32:27 +000030namespace object {
Eric Christopher6256b032011-04-22 03:19:48 +000031
Rafael Espindolada2a2372013-04-13 01:45:40 +000032MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object,
33 bool IsLittleEndian, bool Is64bits,
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000034 error_code &ec)
Rafael Espindolada2a2372013-04-13 01:45:40 +000035 : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object) {
Benjamin Kramer0fcab072011-09-08 20:52:17 +000036}
37
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000038bool MachOObjectFileBase::is64Bit() const {
Rafael Espindolada2a2372013-04-13 01:45:40 +000039 return isa<MachOObjectFileLE64>(this) || isa<MachOObjectFileBE64>(this);
Rafael Espindola3eff3182013-04-07 16:07:35 +000040}
41
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000042void MachOObjectFileBase::ReadULEB128s(uint64_t Index,
43 SmallVectorImpl<uint64_t> &Out) const {
Rafael Espindola8764c892013-04-07 20:01:29 +000044 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 }
Rafael Espindola3eff3182013-04-07 16:07:35 +000052}
53
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000054unsigned MachOObjectFileBase::getHeaderSize() const {
Rafael Espindolac90cc182013-04-07 19:31:49 +000055 return is64Bit() ? macho::Header64Size : macho::Header32Size;
Rafael Espindola0f08eb12013-04-07 19:05:30 +000056}
57
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000058StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const {
Rafael Espindolaf1cc8002013-04-07 19:42:15 +000059 return ObjectFile::getData().substr(Offset, Size);
Rafael Espindola0f08eb12013-04-07 19:05:30 +000060}
61
Eric Christopher6256b032011-04-22 03:19:48 +000062ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) {
Rafael Espindola9d55c092013-04-08 13:25:33 +000063 StringRef Magic = Buffer->getBuffer().slice(0, 4);
Michael J. Spencer001c9202011-06-25 17:54:50 +000064 error_code ec;
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000065 ObjectFile *Ret;
Rafael Espindolada2a2372013-04-13 01:45:40 +000066 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);
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000074 else
Rafael Espindolada2a2372013-04-13 01:45:40 +000075 return NULL;
76
Rafael Espindola6f1f3392013-04-07 16:58:48 +000077 if (ec)
Eric Christopher6256b032011-04-22 03:19:48 +000078 return NULL;
Rafael Espindola6f1f3392013-04-07 16:58:48 +000079 return Ret;
Eric Christopher6256b032011-04-22 03:19:48 +000080}
81
82/*===-- Symbols -----------------------------------------------------------===*/
83
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000084error_code MachOObjectFileBase::getSymbolValue(DataRefImpl Symb,
85 uint64_t &Val) const {
86 report_fatal_error("getSymbolValue unimplemented in MachOObjectFileBase");
Tim Northovera41dce32012-10-29 10:47:00 +000087}
Benjamin Kramerac241fe2011-09-14 01:22:52 +000088
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000089symbol_iterator MachOObjectFileBase::begin_dynamic_symbols() const {
Michael J. Spencerdfa18962012-02-28 00:40:37 +000090 // TODO: implement
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000091 report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase");
Michael J. Spencerdfa18962012-02-28 00:40:37 +000092}
93
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000094symbol_iterator MachOObjectFileBase::end_dynamic_symbols() const {
Michael J. Spencerdfa18962012-02-28 00:40:37 +000095 // TODO: implement
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000096 report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase");
Michael J. Spencerdfa18962012-02-28 00:40:37 +000097}
Eric Christopher6256b032011-04-22 03:19:48 +000098
Rafael Espindolaf6cfc152013-04-09 14:49:08 +000099library_iterator MachOObjectFileBase::begin_libraries_needed() const {
David Meyer5c2b4ea2012-03-01 01:36:50 +0000100 // TODO: implement
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000101 report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
David Meyer5c2b4ea2012-03-01 01:36:50 +0000102}
103
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000104library_iterator MachOObjectFileBase::end_libraries_needed() const {
David Meyer5c2b4ea2012-03-01 01:36:50 +0000105 // TODO: implement
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000106 report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
David Meyer5c2b4ea2012-03-01 01:36:50 +0000107}
108
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000109StringRef MachOObjectFileBase::getLoadName() const {
David Meyer97f77872012-03-01 22:19:54 +0000110 // TODO: Implement
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000111 report_fatal_error("get_load_name() unimplemented in MachOObjectFileBase");
David Meyer97f77872012-03-01 22:19:54 +0000112}
113
Eric Christopher6256b032011-04-22 03:19:48 +0000114/*===-- Sections ----------------------------------------------------------===*/
115
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000116std::size_t MachOObjectFileBase::getSectionIndex(DataRefImpl Sec) const {
Michael J. Spencer4344b1e2011-10-07 19:25:32 +0000117 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
Rafael Espindolada2a2372013-04-13 01:45:40 +0000123StringRef MachOObjectFileBase::parseSegmentOrSectionName(const char *P) const {
Rafael Espindolacef81b32012-12-21 03:47:03 +0000124 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
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000131error_code MachOObjectFileBase::isSectionData(DataRefImpl DRI,
132 bool &Result) const {
Michael J. Spencer13afc5e2011-09-28 20:57:30 +0000133 // FIXME: Unimplemented.
134 Result = false;
135 return object_error::success;
136}
137
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000138error_code MachOObjectFileBase::isSectionBSS(DataRefImpl DRI,
Andrew Kaylor30b20eb2012-10-10 01:45:52 +0000139 bool &Result) const {
140 // FIXME: Unimplemented.
Preston Gurdc68dda82012-04-12 20:13:57 +0000141 Result = false;
142 return object_error::success;
143}
144
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000145error_code
146MachOObjectFileBase::isSectionRequiredForExecution(DataRefImpl Sec,
147 bool &Result) const {
148 // FIXME: Unimplemented.
149 Result = true;
Preston Gurdc68dda82012-04-12 20:13:57 +0000150 return object_error::success;
151}
152
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000153error_code MachOObjectFileBase::isSectionVirtual(DataRefImpl Sec,
154 bool &Result) const {
155 // FIXME: Unimplemented.
156 Result = false;
157 return object_error::success;
158}
159
160error_code MachOObjectFileBase::isSectionReadOnlyData(DataRefImpl Sec,
161 bool &Result) const {
Andrew Kaylor3a129c82012-10-10 01:41:33 +0000162 // 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
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000171relocation_iterator MachOObjectFileBase::getSectionRelBegin(DataRefImpl Sec) const {
Michael J. Spencer4344b1e2011-10-07 19:25:32 +0000172 DataRefImpl ret;
Michael J. Spencer4344b1e2011-10-07 19:25:32 +0000173 ret.d.b = getSectionIndex(Sec);
174 return relocation_iterator(RelocationRef(ret, this));
175}
Rafael Espindola335f1d42013-04-08 20:45:01 +0000176
Eric Christopher6256b032011-04-22 03:19:48 +0000177
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000178/*===-- Relocations -------------------------------------------------------===*/
179
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000180error_code MachOObjectFileBase::getRelocationNext(DataRefImpl Rel,
181 RelocationRef &Res) const {
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000182 ++Rel.d.a;
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000183 Res = RelocationRef(Rel, this);
184 return object_error::success;
185}
Owen Andersond8fa76d2011-10-24 23:20:07 +0000186
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000187error_code MachOObjectFileBase::getLibraryNext(DataRefImpl LibData,
188 LibraryRef &Res) const {
189 report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
Benjamin Kramer0fcab072011-09-08 20:52:17 +0000190}
191
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000192error_code MachOObjectFileBase::getLibraryPath(DataRefImpl LibData,
193 StringRef &Res) const {
194 report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase");
David Meyer5c2b4ea2012-03-01 01:36:50 +0000195}
196
Rafael Espindola8bf80062013-04-11 02:21:31 +0000197error_code MachOObjectFileBase::getRelocationAdditionalInfo(DataRefImpl Rel,
198 int64_t &Res) const {
199 Res = 0;
200 return object_error::success;
201}
202
David Meyer5c2b4ea2012-03-01 01:36:50 +0000203
Eric Christopher6256b032011-04-22 03:19:48 +0000204/*===-- Miscellaneous -----------------------------------------------------===*/
205
Rafael Espindolaf6cfc152013-04-09 14:49:08 +0000206uint8_t MachOObjectFileBase::getBytesInAddress() const {
Rafael Espindola0f08eb12013-04-07 19:05:30 +0000207 return is64Bit() ? 8 : 4;
Eric Christopher6256b032011-04-22 03:19:48 +0000208}
209
Owen Andersonf7c93a32011-10-11 17:32:27 +0000210} // end namespace object
Eric Christopher6256b032011-04-22 03:19:48 +0000211} // end namespace llvm