LLVM API Documentation
00001 //===- MachO.h - MachO object file implementation ---------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file declares the MachOObjectFile class, which implement the ObjectFile 00011 // interface for MachO files. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_OBJECT_MACHO_H 00016 #define LLVM_OBJECT_MACHO_H 00017 00018 #include "llvm/ADT/ArrayRef.h" 00019 #include "llvm/ADT/SmallVector.h" 00020 #include "llvm/ADT/Triple.h" 00021 #include "llvm/Object/ObjectFile.h" 00022 #include "llvm/Support/MachO.h" 00023 00024 namespace llvm { 00025 namespace object { 00026 00027 /// DiceRef - This is a value type class that represents a single 00028 /// data in code entry in the table in a Mach-O object file. 00029 class DiceRef { 00030 DataRefImpl DicePimpl; 00031 const ObjectFile *OwningObject; 00032 00033 public: 00034 DiceRef() : OwningObject(nullptr) { } 00035 00036 DiceRef(DataRefImpl DiceP, const ObjectFile *Owner); 00037 00038 bool operator==(const DiceRef &Other) const; 00039 bool operator<(const DiceRef &Other) const; 00040 00041 void moveNext(); 00042 00043 std::error_code getOffset(uint32_t &Result) const; 00044 std::error_code getLength(uint16_t &Result) const; 00045 std::error_code getKind(uint16_t &Result) const; 00046 00047 DataRefImpl getRawDataRefImpl() const; 00048 const ObjectFile *getObjectFile() const; 00049 }; 00050 typedef content_iterator<DiceRef> dice_iterator; 00051 00052 /// ExportEntry encapsulates the current-state-of-the-walk used when doing a 00053 /// non-recursive walk of the trie data structure. This allows you to iterate 00054 /// across all exported symbols using: 00055 /// for (const llvm::object::ExportEntry &AnExport : Obj->exports()) { 00056 /// } 00057 class ExportEntry { 00058 public: 00059 ExportEntry(ArrayRef<uint8_t> Trie); 00060 00061 StringRef name() const; 00062 uint64_t flags() const; 00063 uint64_t address() const; 00064 uint64_t other() const; 00065 StringRef otherName() const; 00066 uint32_t nodeOffset() const; 00067 00068 bool operator==(const ExportEntry &) const; 00069 00070 void moveNext(); 00071 00072 private: 00073 friend class MachOObjectFile; 00074 void moveToFirst(); 00075 void moveToEnd(); 00076 uint64_t readULEB128(const uint8_t *&p); 00077 void pushDownUntilBottom(); 00078 void pushNode(uint64_t Offset); 00079 00080 // Represents a node in the mach-o exports trie. 00081 struct NodeState { 00082 NodeState(const uint8_t *Ptr); 00083 const uint8_t *Start; 00084 const uint8_t *Current; 00085 uint64_t Flags; 00086 uint64_t Address; 00087 uint64_t Other; 00088 const char *ImportName; 00089 unsigned ChildCount; 00090 unsigned NextChildIndex; 00091 unsigned ParentStringLength; 00092 bool IsExportNode; 00093 }; 00094 00095 ArrayRef<uint8_t> Trie; 00096 SmallString<256> CumulativeString; 00097 SmallVector<NodeState, 16> Stack; 00098 bool Malformed; 00099 bool Done; 00100 }; 00101 typedef content_iterator<ExportEntry> export_iterator; 00102 00103 /// MachORebaseEntry encapsulates the current state in the decompression of 00104 /// rebasing opcodes. This allows you to iterate through the compressed table of 00105 /// rebasing using: 00106 /// for (const llvm::object::MachORebaseEntry &Entry : Obj->rebaseTable()) { 00107 /// } 00108 class MachORebaseEntry { 00109 public: 00110 MachORebaseEntry(ArrayRef<uint8_t> opcodes, bool is64Bit); 00111 00112 uint32_t segmentIndex() const; 00113 uint64_t segmentOffset() const; 00114 StringRef typeName() const; 00115 00116 bool operator==(const MachORebaseEntry &) const; 00117 00118 void moveNext(); 00119 00120 private: 00121 friend class MachOObjectFile; 00122 void moveToFirst(); 00123 void moveToEnd(); 00124 uint64_t readULEB128(); 00125 00126 ArrayRef<uint8_t> Opcodes; 00127 const uint8_t *Ptr; 00128 uint64_t SegmentOffset; 00129 uint32_t SegmentIndex; 00130 uint64_t RemainingLoopCount; 00131 uint64_t AdvanceAmount; 00132 uint8_t RebaseType; 00133 uint8_t PointerSize; 00134 bool Malformed; 00135 bool Done; 00136 }; 00137 typedef content_iterator<MachORebaseEntry> rebase_iterator; 00138 00139 /// MachOBindEntry encapsulates the current state in the decompression of 00140 /// binding opcodes. This allows you to iterate through the compressed table of 00141 /// bindings using: 00142 /// for (const llvm::object::MachOBindEntry &Entry : Obj->bindTable()) { 00143 /// } 00144 class MachOBindEntry { 00145 public: 00146 enum class Kind { Regular, Lazy, Weak }; 00147 00148 MachOBindEntry(ArrayRef<uint8_t> Opcodes, bool is64Bit, MachOBindEntry::Kind); 00149 00150 uint32_t segmentIndex() const; 00151 uint64_t segmentOffset() const; 00152 StringRef typeName() const; 00153 StringRef symbolName() const; 00154 uint32_t flags() const; 00155 int64_t addend() const; 00156 int ordinal() const; 00157 00158 bool operator==(const MachOBindEntry &) const; 00159 00160 void moveNext(); 00161 00162 private: 00163 friend class MachOObjectFile; 00164 void moveToFirst(); 00165 void moveToEnd(); 00166 uint64_t readULEB128(); 00167 int64_t readSLEB128(); 00168 00169 ArrayRef<uint8_t> Opcodes; 00170 const uint8_t *Ptr; 00171 uint64_t SegmentOffset; 00172 uint32_t SegmentIndex; 00173 StringRef SymbolName; 00174 int Ordinal; 00175 uint32_t Flags; 00176 int64_t Addend; 00177 uint64_t RemainingLoopCount; 00178 uint64_t AdvanceAmount; 00179 uint8_t BindType; 00180 uint8_t PointerSize; 00181 Kind TableKind; 00182 bool Malformed; 00183 bool Done; 00184 }; 00185 typedef content_iterator<MachOBindEntry> bind_iterator; 00186 00187 class MachOObjectFile : public ObjectFile { 00188 public: 00189 struct LoadCommandInfo { 00190 const char *Ptr; // Where in memory the load command is. 00191 MachO::load_command C; // The command itself. 00192 }; 00193 00194 MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, 00195 std::error_code &EC); 00196 00197 void moveSymbolNext(DataRefImpl &Symb) const override; 00198 std::error_code getSymbolName(DataRefImpl Symb, 00199 StringRef &Res) const override; 00200 00201 // MachO specific. 00202 std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const; 00203 00204 std::error_code getSymbolAddress(DataRefImpl Symb, 00205 uint64_t &Res) const override; 00206 std::error_code getSymbolAlignment(DataRefImpl Symb, 00207 uint32_t &Res) const override; 00208 std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; 00209 std::error_code getSymbolType(DataRefImpl Symb, 00210 SymbolRef::Type &Res) const override; 00211 uint32_t getSymbolFlags(DataRefImpl Symb) const override; 00212 std::error_code getSymbolSection(DataRefImpl Symb, 00213 section_iterator &Res) const override; 00214 00215 void moveSectionNext(DataRefImpl &Sec) const override; 00216 std::error_code getSectionName(DataRefImpl Sec, 00217 StringRef &Res) const override; 00218 std::error_code getSectionAddress(DataRefImpl Sec, 00219 uint64_t &Res) const override; 00220 std::error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override; 00221 std::error_code getSectionContents(DataRefImpl Sec, 00222 StringRef &Res) const override; 00223 std::error_code getSectionAlignment(DataRefImpl Sec, 00224 uint64_t &Res) const override; 00225 std::error_code isSectionText(DataRefImpl Sec, bool &Res) const override; 00226 std::error_code isSectionData(DataRefImpl Sec, bool &Res) const override; 00227 std::error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override; 00228 std::error_code isSectionRequiredForExecution(DataRefImpl Sec, 00229 bool &Res) const override; 00230 std::error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override; 00231 std::error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override; 00232 std::error_code isSectionReadOnlyData(DataRefImpl Sec, 00233 bool &Res) const override; 00234 std::error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, 00235 bool &Result) const override; 00236 relocation_iterator section_rel_begin(DataRefImpl Sec) const override; 00237 relocation_iterator section_rel_end(DataRefImpl Sec) const override; 00238 00239 void moveRelocationNext(DataRefImpl &Rel) const override; 00240 std::error_code getRelocationAddress(DataRefImpl Rel, 00241 uint64_t &Res) const override; 00242 std::error_code getRelocationOffset(DataRefImpl Rel, 00243 uint64_t &Res) const override; 00244 symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; 00245 std::error_code getRelocationType(DataRefImpl Rel, 00246 uint64_t &Res) const override; 00247 std::error_code 00248 getRelocationTypeName(DataRefImpl Rel, 00249 SmallVectorImpl<char> &Result) const override; 00250 std::error_code 00251 getRelocationValueString(DataRefImpl Rel, 00252 SmallVectorImpl<char> &Result) const override; 00253 std::error_code getRelocationHidden(DataRefImpl Rel, 00254 bool &Result) const override; 00255 00256 // MachO specific. 00257 std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const; 00258 00259 // TODO: Would be useful to have an iterator based version 00260 // of the load command interface too. 00261 00262 basic_symbol_iterator symbol_begin_impl() const override; 00263 basic_symbol_iterator symbol_end_impl() const override; 00264 00265 // MachO specific. 00266 basic_symbol_iterator getSymbolByIndex(unsigned Index) const; 00267 00268 section_iterator section_begin() const override; 00269 section_iterator section_end() const override; 00270 00271 uint8_t getBytesInAddress() const override; 00272 00273 StringRef getFileFormatName() const override; 00274 unsigned getArch() const override; 00275 Triple getArch(const char **McpuDefault, Triple *ThumbTriple) const; 00276 00277 relocation_iterator section_rel_begin(unsigned Index) const; 00278 relocation_iterator section_rel_end(unsigned Index) const; 00279 00280 dice_iterator begin_dices() const; 00281 dice_iterator end_dices() const; 00282 00283 /// For use iterating over all exported symbols. 00284 iterator_range<export_iterator> exports() const; 00285 00286 /// For use examining a trie not in a MachOObjectFile. 00287 static iterator_range<export_iterator> exports(ArrayRef<uint8_t> Trie); 00288 00289 /// For use iterating over all rebase table entries. 00290 iterator_range<rebase_iterator> rebaseTable() const; 00291 00292 /// For use examining rebase opcodes not in a MachOObjectFile. 00293 static iterator_range<rebase_iterator> rebaseTable(ArrayRef<uint8_t> Opcodes, 00294 bool is64); 00295 00296 /// For use iterating over all bind table entries. 00297 iterator_range<bind_iterator> bindTable() const; 00298 00299 /// For use iterating over all lazy bind table entries. 00300 iterator_range<bind_iterator> lazyBindTable() const; 00301 00302 /// For use iterating over all lazy bind table entries. 00303 iterator_range<bind_iterator> weakBindTable() const; 00304 00305 /// For use examining bind opcodes not in a MachOObjectFile. 00306 static iterator_range<bind_iterator> bindTable(ArrayRef<uint8_t> Opcodes, 00307 bool is64, 00308 MachOBindEntry::Kind); 00309 00310 00311 // In a MachO file, sections have a segment name. This is used in the .o 00312 // files. They have a single segment, but this field specifies which segment 00313 // a section should be put in in the final object. 00314 StringRef getSectionFinalSegmentName(DataRefImpl Sec) const; 00315 00316 // Names are stored as 16 bytes. These returns the raw 16 bytes without 00317 // interpreting them as a C string. 00318 ArrayRef<char> getSectionRawName(DataRefImpl Sec) const; 00319 ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const; 00320 00321 // MachO specific Info about relocations. 00322 bool isRelocationScattered(const MachO::any_relocation_info &RE) const; 00323 unsigned getPlainRelocationSymbolNum( 00324 const MachO::any_relocation_info &RE) const; 00325 bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const; 00326 bool getScatteredRelocationScattered( 00327 const MachO::any_relocation_info &RE) const; 00328 uint32_t getScatteredRelocationValue( 00329 const MachO::any_relocation_info &RE) const; 00330 unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const; 00331 unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const; 00332 unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const; 00333 unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const; 00334 SectionRef getRelocationSection(const MachO::any_relocation_info &RE) const; 00335 00336 // Walk load commands. 00337 LoadCommandInfo getFirstLoadCommandInfo() const; 00338 LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const; 00339 00340 // MachO specific structures. 00341 MachO::section getSection(DataRefImpl DRI) const; 00342 MachO::section_64 getSection64(DataRefImpl DRI) const; 00343 MachO::section getSection(const LoadCommandInfo &L, unsigned Index) const; 00344 MachO::section_64 getSection64(const LoadCommandInfo &L,unsigned Index) const; 00345 MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const; 00346 MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const; 00347 00348 MachO::linkedit_data_command 00349 getLinkeditDataLoadCommand(const LoadCommandInfo &L) const; 00350 MachO::segment_command 00351 getSegmentLoadCommand(const LoadCommandInfo &L) const; 00352 MachO::segment_command_64 00353 getSegment64LoadCommand(const LoadCommandInfo &L) const; 00354 MachO::linker_options_command 00355 getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const; 00356 MachO::version_min_command 00357 getVersionMinLoadCommand(const LoadCommandInfo &L) const; 00358 MachO::dylib_command 00359 getDylibIDLoadCommand(const LoadCommandInfo &L) const; 00360 MachO::dyld_info_command 00361 getDyldInfoLoadCommand(const LoadCommandInfo &L) const; 00362 MachO::dylinker_command 00363 getDylinkerCommand(const LoadCommandInfo &L) const; 00364 MachO::uuid_command 00365 getUuidCommand(const LoadCommandInfo &L) const; 00366 MachO::source_version_command 00367 getSourceVersionCommand(const LoadCommandInfo &L) const; 00368 MachO::entry_point_command 00369 getEntryPointCommand(const LoadCommandInfo &L) const; 00370 00371 MachO::any_relocation_info getRelocation(DataRefImpl Rel) const; 00372 MachO::data_in_code_entry getDice(DataRefImpl Rel) const; 00373 MachO::mach_header getHeader() const; 00374 MachO::mach_header_64 getHeader64() const; 00375 uint32_t 00376 getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, 00377 unsigned Index) const; 00378 MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, 00379 unsigned Index) const; 00380 MachO::symtab_command getSymtabLoadCommand() const; 00381 MachO::dysymtab_command getDysymtabLoadCommand() const; 00382 MachO::linkedit_data_command getDataInCodeLoadCommand() const; 00383 ArrayRef<uint8_t> getDyldInfoRebaseOpcodes() const; 00384 ArrayRef<uint8_t> getDyldInfoBindOpcodes() const; 00385 ArrayRef<uint8_t> getDyldInfoWeakBindOpcodes() const; 00386 ArrayRef<uint8_t> getDyldInfoLazyBindOpcodes() const; 00387 ArrayRef<uint8_t> getDyldInfoExportsTrie() const; 00388 00389 StringRef getStringTableData() const; 00390 bool is64Bit() const; 00391 void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const; 00392 00393 static StringRef guessLibraryShortName(StringRef Name, bool &isFramework, 00394 StringRef &Suffix); 00395 00396 static Triple::ArchType getArch(uint32_t CPUType); 00397 static Triple getArch(uint32_t CPUType, uint32_t CPUSubType, 00398 const char **McpuDefault = nullptr); 00399 static Triple getThumbArch(uint32_t CPUType, uint32_t CPUSubType, 00400 const char **McpuDefault = nullptr); 00401 static Triple getArch(uint32_t CPUType, uint32_t CPUSubType, 00402 const char **McpuDefault, Triple *ThumbTriple); 00403 static bool isValidArch(StringRef ArchFlag); 00404 static Triple getHostArch(); 00405 00406 bool isRelocatableObject() const override; 00407 00408 bool hasPageZeroSegment() const { return HasPageZeroSegment; } 00409 00410 static bool classof(const Binary *v) { 00411 return v->isMachO(); 00412 } 00413 00414 private: 00415 typedef SmallVector<const char*, 1> SectionList; 00416 SectionList Sections; 00417 typedef SmallVector<const char*, 1> LibraryList; 00418 LibraryList Libraries; 00419 typedef SmallVector<StringRef, 1> LibraryShortName; 00420 mutable LibraryShortName LibrariesShortNames; 00421 const char *SymtabLoadCmd; 00422 const char *DysymtabLoadCmd; 00423 const char *DataInCodeLoadCmd; 00424 const char *DyldInfoLoadCmd; 00425 bool HasPageZeroSegment; 00426 }; 00427 00428 /// DiceRef 00429 inline DiceRef::DiceRef(DataRefImpl DiceP, const ObjectFile *Owner) 00430 : DicePimpl(DiceP) , OwningObject(Owner) {} 00431 00432 inline bool DiceRef::operator==(const DiceRef &Other) const { 00433 return DicePimpl == Other.DicePimpl; 00434 } 00435 00436 inline bool DiceRef::operator<(const DiceRef &Other) const { 00437 return DicePimpl < Other.DicePimpl; 00438 } 00439 00440 inline void DiceRef::moveNext() { 00441 const MachO::data_in_code_entry *P = 00442 reinterpret_cast<const MachO::data_in_code_entry *>(DicePimpl.p); 00443 DicePimpl.p = reinterpret_cast<uintptr_t>(P + 1); 00444 } 00445 00446 // Since a Mach-O data in code reference, a DiceRef, can only be created when 00447 // the OwningObject ObjectFile is a MachOObjectFile a static_cast<> is used for 00448 // the methods that get the values of the fields of the reference. 00449 00450 inline std::error_code DiceRef::getOffset(uint32_t &Result) const { 00451 const MachOObjectFile *MachOOF = 00452 static_cast<const MachOObjectFile *>(OwningObject); 00453 MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); 00454 Result = Dice.offset; 00455 return object_error::success; 00456 } 00457 00458 inline std::error_code DiceRef::getLength(uint16_t &Result) const { 00459 const MachOObjectFile *MachOOF = 00460 static_cast<const MachOObjectFile *>(OwningObject); 00461 MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); 00462 Result = Dice.length; 00463 return object_error::success; 00464 } 00465 00466 inline std::error_code DiceRef::getKind(uint16_t &Result) const { 00467 const MachOObjectFile *MachOOF = 00468 static_cast<const MachOObjectFile *>(OwningObject); 00469 MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); 00470 Result = Dice.kind; 00471 return object_error::success; 00472 } 00473 00474 inline DataRefImpl DiceRef::getRawDataRefImpl() const { 00475 return DicePimpl; 00476 } 00477 00478 inline const ObjectFile *DiceRef::getObjectFile() const { 00479 return OwningObject; 00480 } 00481 00482 } 00483 } 00484 00485 #endif 00486