1 //===- MachO.h - MachO object file implementation ---------------*- 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 declares the MachOObjectFile class, which implement the ObjectFile 11 // interface for MachO files. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_OBJECT_MACHO_H 16 #define LLVM_OBJECT_MACHO_H 17 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/SmallVector.h" 20 #include "llvm/ADT/Triple.h" 21 #include "llvm/Object/ObjectFile.h" 22 #include "llvm/Support/MachO.h" 23 24 namespace llvm { 25 namespace object { 26 27 /// DiceRef - This is a value type class that represents a single 28 /// data in code entry in the table in a Mach-O object file. 29 class DiceRef { 30 DataRefImpl DicePimpl; 31 const ObjectFile *OwningObject; 32 33 public: 34 DiceRef() : OwningObject(nullptr) { } 35 36 DiceRef(DataRefImpl DiceP, const ObjectFile *Owner); 37 38 bool operator==(const DiceRef &Other) const; 39 bool operator<(const DiceRef &Other) const; 40 41 void moveNext(); 42 43 std::error_code getOffset(uint32_t &Result) const; 44 std::error_code getLength(uint16_t &Result) const; 45 std::error_code getKind(uint16_t &Result) const; 46 47 DataRefImpl getRawDataRefImpl() const; 48 const ObjectFile *getObjectFile() const; 49 }; 50 typedef content_iterator<DiceRef> dice_iterator; 51 52 class MachOObjectFile : public ObjectFile { 53 public: 54 struct LoadCommandInfo { 55 const char *Ptr; // Where in memory the load command is. 56 MachO::load_command C; // The command itself. 57 }; 58 59 MachOObjectFile(std::unique_ptr<MemoryBuffer> Object, bool IsLittleEndian, 60 bool Is64Bits, std::error_code &EC); 61 62 void moveSymbolNext(DataRefImpl &Symb) const override; 63 std::error_code getSymbolName(DataRefImpl Symb, 64 StringRef &Res) const override; 65 66 // MachO specific. 67 std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const; 68 69 std::error_code getSymbolAddress(DataRefImpl Symb, 70 uint64_t &Res) const override; 71 std::error_code getSymbolAlignment(DataRefImpl Symb, 72 uint32_t &Res) const override; 73 std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; 74 std::error_code getSymbolType(DataRefImpl Symb, 75 SymbolRef::Type &Res) const override; 76 uint32_t getSymbolFlags(DataRefImpl Symb) const override; 77 std::error_code getSymbolSection(DataRefImpl Symb, 78 section_iterator &Res) const override; 79 80 void moveSectionNext(DataRefImpl &Sec) const override; 81 std::error_code getSectionName(DataRefImpl Sec, 82 StringRef &Res) const override; 83 std::error_code getSectionAddress(DataRefImpl Sec, 84 uint64_t &Res) const override; 85 std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override; 86 std::error_code getSectionContents(DataRefImpl Sec, 87 StringRef &Res) const override; 88 std::error_code getSectionAlignment(DataRefImpl Sec, 89 uint64_t &Res) const override; 90 std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override; 91 std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override; 92 std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override; 93 std::error_code isSectionRequiredForExecution(DataRefImpl Sec, 94 bool &Res) const override; 95 std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override; 96 std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override; 97 std::error_code isSectionReadOnlyData(DataRefImpl Sec, 98 bool &Res) const override; 99 std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, 100 bool &Result) const override; 101 relocation_iterator section_rel_begin(DataRefImpl Sec) const override; 102 relocation_iterator section_rel_end(DataRefImpl Sec) const override; 103 104 void moveRelocationNext(DataRefImpl &Rel) const override; 105 std::error_code getRelocationAddress(DataRefImpl Rel, 106 uint64_t &Res) const override; 107 std::error_code getRelocationOffset(DataRefImpl Rel, 108 uint64_t &Res) const override; 109 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; 110 std::error_code getRelocationType(DataRefImpl Rel, 111 uint64_t &Res) const override; 112 std::error_code 113 getRelocationTypeName(DataRefImpl Rel, 114 SmallVectorImpl<char> &Result) const override; 115 std::error_code 116 getRelocationValueString(DataRefImpl Rel, 117 SmallVectorImpl<char> &Result) const override; 118 std::error_code getRelocationHidden(DataRefImpl Rel, 119 bool &Result) const override; 120 121 std::error_code getLibraryNext(DataRefImpl LibData, 122 LibraryRef &Res) const override; 123 std::error_code getLibraryPath(DataRefImpl LibData, 124 StringRef &Res) const override; 125 126 // MachO specific. 127 std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &Res); 128 129 // TODO: Would be useful to have an iterator based version 130 // of the load command interface too. 131 132 basic_symbol_iterator symbol_begin_impl() const override; 133 basic_symbol_iterator symbol_end_impl() const override; 134 135 // MachO specific. 136 basic_symbol_iterator getSymbolByIndex(unsigned Index) const; 137 138 section_iterator section_begin() const override; 139 section_iterator section_end() const override; 140 141 library_iterator needed_library_begin() const override; 142 library_iterator needed_library_end() const override; 143 144 uint8_t getBytesInAddress() const override; 145 146 StringRef getFileFormatName() const override; 147 unsigned getArch() const override; 148 149 StringRef getLoadName() const override; 150 151 relocation_iterator section_rel_begin(unsigned Index) const; 152 relocation_iterator section_rel_end(unsigned Index) const; 153 154 dice_iterator begin_dices() const; 155 dice_iterator end_dices() const; 156 157 // In a MachO file, sections have a segment name. This is used in the .o 158 // files. They have a single segment, but this field specifies which segment 159 // a section should be put in in the final object. 160 StringRef getSectionFinalSegmentName(DataRefImpl Sec) const; 161 162 // Names are stored as 16 bytes. These returns the raw 16 bytes without 163 // interpreting them as a C string. 164 ArrayRef<char> getSectionRawName(DataRefImpl Sec) const; 165 ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const; 166 167 // MachO specific Info about relocations. 168 bool isRelocationScattered(const MachO::any_relocation_info &RE) const; 169 unsigned getPlainRelocationSymbolNum( 170 const MachO::any_relocation_info &RE) const; 171 bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const; 172 bool getScatteredRelocationScattered( 173 const MachO::any_relocation_info &RE) const; 174 uint32_t getScatteredRelocationValue( 175 const MachO::any_relocation_info &RE) const; 176 unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const; 177 unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const; 178 unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const; 179 unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const; 180 SectionRef getRelocationSection(const MachO::any_relocation_info &RE) const; 181 182 // Walk load commands. 183 LoadCommandInfo getFirstLoadCommandInfo() const; 184 LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const; 185 186 // MachO specific structures. 187 MachO::section getSection(DataRefImpl DRI) const; 188 MachO::section_64 getSection64(DataRefImpl DRI) const; 189 MachO::section getSection(const LoadCommandInfo &L, unsigned Index) const; 190 MachO::section_64 getSection64(const LoadCommandInfo &L,unsigned Index) const; 191 MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const; 192 MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const; 193 194 MachO::linkedit_data_command 195 getLinkeditDataLoadCommand(const LoadCommandInfo &L) const; 196 MachO::segment_command 197 getSegmentLoadCommand(const LoadCommandInfo &L) const; 198 MachO::segment_command_64 199 getSegment64LoadCommand(const LoadCommandInfo &L) const; 200 MachO::linker_options_command 201 getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const; 202 MachO::version_min_command 203 getVersionMinLoadCommand(const LoadCommandInfo &L) const; 204 MachO::dylib_command 205 getDylibIDLoadCommand(const LoadCommandInfo &L) const; 206 207 MachO::any_relocation_info getRelocation(DataRefImpl Rel) const; 208 MachO::data_in_code_entry getDice(DataRefImpl Rel) const; 209 MachO::mach_header getHeader() const; 210 MachO::mach_header_64 getHeader64() const; 211 uint32_t 212 getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, 213 unsigned Index) const; 214 MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, 215 unsigned Index) const; 216 MachO::symtab_command getSymtabLoadCommand() const; 217 MachO::dysymtab_command getDysymtabLoadCommand() const; 218 MachO::linkedit_data_command getDataInCodeLoadCommand() const; 219 220 StringRef getStringTableData() const; 221 bool is64Bit() const; 222 void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const; 223 224 static StringRef guessLibraryShortName(StringRef Name, bool &isFramework, 225 StringRef &Suffix); 226 227 static Triple::ArchType getArch(uint32_t CPUType); 228 static Triple getArch(uint32_t CPUType, uint32_t CPUSubType); 229 static Triple getArch(StringRef ArchFlag); 230 static Triple getHostArch(); 231 232 static bool classof(const Binary *v) { 233 return v->isMachO(); 234 } 235 236 const char *getSectionPointer(DataRefImpl Rel) const; 237 238 private: 239 typedef SmallVector<const char *, 1> SectionList; 240 SectionList Sections; 241 typedef SmallVector<const char *, 1> LibraryList; 242 LibraryList Libraries; 243 typedef SmallVector<StringRef, 1> LibraryShortName; 244 LibraryShortName LibrariesShortNames; 245 const char *SymtabLoadCmd; 246 const char *DysymtabLoadCmd; 247 const char *DataInCodeLoadCmd; 248 }; 249 250 /// DiceRef 251 inline DiceRef::DiceRef(DataRefImpl DiceP, const ObjectFile *Owner) 252 : DicePimpl(DiceP) , OwningObject(Owner) {} 253 254 inline bool DiceRef::operator==(const DiceRef &Other) const { 255 return DicePimpl == Other.DicePimpl; 256 } 257 258 inline bool DiceRef::operator<(const DiceRef &Other) const { 259 return DicePimpl < Other.DicePimpl; 260 } 261 262 inline void DiceRef::moveNext() { 263 const MachO::data_in_code_entry *P = 264 reinterpret_cast<const MachO::data_in_code_entry *>(DicePimpl.p); 265 DicePimpl.p = reinterpret_cast<uintptr_t>(P + 1); 266 } 267 268 // Since a Mach-O data in code reference, a DiceRef, can only be created when 269 // the OwningObject ObjectFile is a MachOObjectFile a static_cast<> is used for 270 // the methods that get the values of the fields of the reference. 271 272 inline std::error_code DiceRef::getOffset(uint32_t &Result) const { 273 const MachOObjectFile *MachOOF = 274 static_cast<const MachOObjectFile *>(OwningObject); 275 MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); 276 Result = Dice.offset; 277 return object_error::success; 278 } 279 280 inline std::error_code DiceRef::getLength(uint16_t &Result) const { 281 const MachOObjectFile *MachOOF = 282 static_cast<const MachOObjectFile *>(OwningObject); 283 MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); 284 Result = Dice.length; 285 return object_error::success; 286 } 287 288 inline std::error_code DiceRef::getKind(uint16_t &Result) const { 289 const MachOObjectFile *MachOOF = 290 static_cast<const MachOObjectFile *>(OwningObject); 291 MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); 292 Result = Dice.kind; 293 return object_error::success; 294 } 295 296 inline DataRefImpl DiceRef::getRawDataRefImpl() const { 297 return DicePimpl; 298 } 299 300 inline const ObjectFile *DiceRef::getObjectFile() const { 301 return OwningObject; 302 } 303 304 } 305 } 306 307 #endif 308 309