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 212