1226584Sdim//===- MachO.h - MachO object file implementation ---------------*- C++ -*-===// 2226584Sdim// 3226584Sdim// The LLVM Compiler Infrastructure 4226584Sdim// 5226584Sdim// This file is distributed under the University of Illinois Open Source 6226584Sdim// License. See LICENSE.TXT for details. 7226584Sdim// 8226584Sdim//===----------------------------------------------------------------------===// 9226584Sdim// 10252723Sdim// This file declares the MachOObjectFile class, which implement the ObjectFile 11252723Sdim// interface for MachO files. 12226584Sdim// 13226584Sdim//===----------------------------------------------------------------------===// 14226584Sdim 15226584Sdim#ifndef LLVM_OBJECT_MACHO_H 16226584Sdim#define LLVM_OBJECT_MACHO_H 17226584Sdim 18252723Sdim#include "llvm/ADT/ArrayRef.h" 19252723Sdim#include "llvm/ADT/SmallVector.h" 20263509Sdim#include "llvm/ADT/Triple.h" 21226584Sdim#include "llvm/Object/ObjectFile.h" 22226584Sdim#include "llvm/Support/MachO.h" 23226584Sdim 24226584Sdimnamespace llvm { 25226584Sdimnamespace object { 26226584Sdim 27263509Sdim/// DiceRef - This is a value type class that represents a single 28263509Sdim/// data in code entry in the table in a Mach-O object file. 29263509Sdimclass DiceRef { 30263509Sdim DataRefImpl DicePimpl; 31263509Sdim const ObjectFile *OwningObject; 32263509Sdim 33263509Sdimpublic: 34263509Sdim DiceRef() : OwningObject(NULL) { } 35263509Sdim 36263509Sdim DiceRef(DataRefImpl DiceP, const ObjectFile *Owner); 37263509Sdim 38263509Sdim bool operator==(const DiceRef &Other) const; 39263509Sdim bool operator<(const DiceRef &Other) const; 40263509Sdim 41263509Sdim error_code getNext(DiceRef &Result) const; 42263509Sdim 43263509Sdim error_code getOffset(uint32_t &Result) const; 44263509Sdim error_code getLength(uint16_t &Result) const; 45263509Sdim error_code getKind(uint16_t &Result) const; 46263509Sdim 47263509Sdim DataRefImpl getRawDataRefImpl() const; 48263509Sdim const ObjectFile *getObjectFile() const; 49263509Sdim}; 50263509Sdimtypedef content_iterator<DiceRef> dice_iterator; 51263509Sdim 52226584Sdimclass MachOObjectFile : public ObjectFile { 53226584Sdimpublic: 54252723Sdim struct LoadCommandInfo { 55252723Sdim const char *Ptr; // Where in memory the load command is. 56263509Sdim MachO::load_command C; // The command itself. 57252723Sdim }; 58226584Sdim 59252723Sdim MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits, 60252723Sdim error_code &ec); 61226584Sdim 62226584Sdim virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; 63226584Sdim virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; 64252723Sdim virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; 65235633Sdim virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const; 66252723Sdim virtual error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const; 67226584Sdim virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; 68252723Sdim virtual error_code getSymbolType(DataRefImpl Symb, 69252723Sdim SymbolRef::Type &Res) const; 70235633Sdim virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; 71235633Sdim virtual error_code getSymbolSection(DataRefImpl Symb, 72235633Sdim section_iterator &Res) const; 73245431Sdim virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; 74226584Sdim 75226584Sdim virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; 76226584Sdim virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; 77226584Sdim virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; 78226584Sdim virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; 79226584Sdim virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; 80226584Sdim virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const; 81226584Sdim virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; 82226584Sdim virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; 83226584Sdim virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; 84235633Sdim virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, 85235633Sdim bool &Res) const; 86235633Sdim virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; 87235633Sdim virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; 88245431Sdim virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const; 89252723Sdim virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, 90226584Sdim bool &Result) const; 91263509Sdim virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const; 92263509Sdim virtual relocation_iterator section_rel_end(DataRefImpl Sec) const; 93226584Sdim 94226584Sdim virtual error_code getRelocationNext(DataRefImpl Rel, 95226584Sdim RelocationRef &Res) const; 96252723Sdim virtual error_code getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const; 97252723Sdim virtual error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const; 98263509Sdim virtual symbol_iterator getRelocationSymbol(DataRefImpl Rel) const; 99252723Sdim virtual error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const; 100226584Sdim virtual error_code getRelocationTypeName(DataRefImpl Rel, 101226584Sdim SmallVectorImpl<char> &Result) const; 102226584Sdim virtual error_code getRelocationValueString(DataRefImpl Rel, 103226584Sdim SmallVectorImpl<char> &Result) const; 104235633Sdim virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const; 105226584Sdim 106235633Sdim virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const; 107235633Sdim virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const; 108235633Sdim 109252723Sdim // TODO: Would be useful to have an iterator based version 110252723Sdim // of the load command interface too. 111226584Sdim 112252723Sdim virtual symbol_iterator begin_symbols() const; 113252723Sdim virtual symbol_iterator end_symbols() const; 114226584Sdim 115252723Sdim virtual symbol_iterator begin_dynamic_symbols() const; 116252723Sdim virtual symbol_iterator end_dynamic_symbols() const; 117235633Sdim 118252723Sdim virtual section_iterator begin_sections() const; 119252723Sdim virtual section_iterator end_sections() const; 120252723Sdim 121252723Sdim virtual library_iterator begin_libraries_needed() const; 122252723Sdim virtual library_iterator end_libraries_needed() const; 123252723Sdim 124252723Sdim virtual uint8_t getBytesInAddress() const; 125252723Sdim 126252723Sdim virtual StringRef getFileFormatName() const; 127252723Sdim virtual unsigned getArch() const; 128252723Sdim 129252723Sdim virtual StringRef getLoadName() const; 130252723Sdim 131263509Sdim relocation_iterator section_rel_begin(unsigned Index) const; 132263509Sdim relocation_iterator section_rel_end(unsigned Index) const; 133252723Sdim 134263509Sdim dice_iterator begin_dices() const; 135263509Sdim dice_iterator end_dices() const; 136263509Sdim 137252723Sdim // In a MachO file, sections have a segment name. This is used in the .o 138252723Sdim // files. They have a single segment, but this field specifies which segment 139252723Sdim // a section should be put in in the final object. 140252723Sdim StringRef getSectionFinalSegmentName(DataRefImpl Sec) const; 141252723Sdim 142252723Sdim // Names are stored as 16 bytes. These returns the raw 16 bytes without 143252723Sdim // interpreting them as a C string. 144252723Sdim ArrayRef<char> getSectionRawName(DataRefImpl Sec) const; 145252723Sdim ArrayRef<char> getSectionRawFinalSegmentName(DataRefImpl Sec) const; 146252723Sdim 147252723Sdim // MachO specific Info about relocations. 148263509Sdim bool isRelocationScattered(const MachO::any_relocation_info &RE) const; 149263509Sdim unsigned getPlainRelocationSymbolNum( 150263509Sdim const MachO::any_relocation_info &RE) const; 151263509Sdim bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const; 152263509Sdim bool getScatteredRelocationScattered( 153263509Sdim const MachO::any_relocation_info &RE) const; 154263509Sdim uint32_t getScatteredRelocationValue( 155263509Sdim const MachO::any_relocation_info &RE) const; 156263509Sdim unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const; 157263509Sdim unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const; 158263509Sdim unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const; 159263509Sdim unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const; 160263509Sdim SectionRef getRelocationSection(const MachO::any_relocation_info &RE) const; 161252723Sdim 162252723Sdim // Walk load commands. 163252723Sdim LoadCommandInfo getFirstLoadCommandInfo() const; 164252723Sdim LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const; 165252723Sdim 166252723Sdim // MachO specific structures. 167263509Sdim MachO::section getSection(DataRefImpl DRI) const; 168263509Sdim MachO::section_64 getSection64(DataRefImpl DRI) const; 169263509Sdim MachO::section getSection(const LoadCommandInfo &L, unsigned Index) const; 170263509Sdim MachO::section_64 getSection64(const LoadCommandInfo &L,unsigned Index) const; 171263509Sdim MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const; 172263509Sdim MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const; 173252723Sdim 174263509Sdim MachO::linkedit_data_command 175252723Sdim getLinkeditDataLoadCommand(const LoadCommandInfo &L) const; 176263509Sdim MachO::segment_command 177252723Sdim getSegmentLoadCommand(const LoadCommandInfo &L) const; 178263509Sdim MachO::segment_command_64 179252723Sdim getSegment64LoadCommand(const LoadCommandInfo &L) const; 180263509Sdim MachO::linker_options_command 181252723Sdim getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const; 182252723Sdim 183263509Sdim MachO::any_relocation_info getRelocation(DataRefImpl Rel) const; 184263509Sdim MachO::data_in_code_entry getDice(DataRefImpl Rel) const; 185263509Sdim MachO::mach_header getHeader() const; 186263509Sdim MachO::mach_header_64 getHeader64() const; 187263509Sdim uint32_t 188263509Sdim getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, 189252723Sdim unsigned Index) const; 190263509Sdim MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, 191263509Sdim unsigned Index) const; 192263509Sdim MachO::symtab_command getSymtabLoadCommand() const; 193263509Sdim MachO::dysymtab_command getDysymtabLoadCommand() const; 194263509Sdim MachO::linkedit_data_command getDataInCodeLoadCommand() const; 195252723Sdim 196252723Sdim StringRef getStringTableData() const; 197252723Sdim bool is64Bit() const; 198252723Sdim void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const; 199252723Sdim 200263509Sdim static Triple::ArchType getArch(uint32_t CPUType); 201263509Sdim 202252723Sdim static bool classof(const Binary *v) { 203252723Sdim return v->isMachO(); 204252723Sdim } 205252723Sdim 206252723Sdimprivate: 207252723Sdim typedef SmallVector<const char*, 1> SectionList; 208252723Sdim SectionList Sections; 209252723Sdim const char *SymtabLoadCmd; 210252723Sdim const char *DysymtabLoadCmd; 211263509Sdim const char *DataInCodeLoadCmd; 212226584Sdim}; 213226584Sdim 214263509Sdim/// DiceRef 215263509Sdiminline DiceRef::DiceRef(DataRefImpl DiceP, const ObjectFile *Owner) 216263509Sdim : DicePimpl(DiceP) , OwningObject(Owner) {} 217263509Sdim 218263509Sdiminline bool DiceRef::operator==(const DiceRef &Other) const { 219263509Sdim return DicePimpl == Other.DicePimpl; 220226584Sdim} 221263509Sdim 222263509Sdiminline bool DiceRef::operator<(const DiceRef &Other) const { 223263509Sdim return DicePimpl < Other.DicePimpl; 224226584Sdim} 225226584Sdim 226263509Sdiminline error_code DiceRef::getNext(DiceRef &Result) const { 227263509Sdim DataRefImpl Rel = DicePimpl; 228263509Sdim const MachO::data_in_code_entry *P = 229263509Sdim reinterpret_cast<const MachO::data_in_code_entry *>(Rel.p); 230263509Sdim Rel.p = reinterpret_cast<uintptr_t>(P + 1); 231263509Sdim Result = DiceRef(Rel, OwningObject); 232263509Sdim return object_error::success; 233263509Sdim} 234263509Sdim 235263509Sdim// Since a Mach-O data in code reference, a DiceRef, can only be created when 236263509Sdim// the OwningObject ObjectFile is a MachOObjectFile a static_cast<> is used for 237263509Sdim// the methods that get the values of the fields of the reference. 238263509Sdim 239263509Sdiminline error_code DiceRef::getOffset(uint32_t &Result) const { 240263509Sdim const MachOObjectFile *MachOOF = 241263509Sdim static_cast<const MachOObjectFile *>(OwningObject); 242263509Sdim MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); 243263509Sdim Result = Dice.offset; 244263509Sdim return object_error::success; 245263509Sdim} 246263509Sdim 247263509Sdiminline error_code DiceRef::getLength(uint16_t &Result) const { 248263509Sdim const MachOObjectFile *MachOOF = 249263509Sdim static_cast<const MachOObjectFile *>(OwningObject); 250263509Sdim MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); 251263509Sdim Result = Dice.length; 252263509Sdim return object_error::success; 253263509Sdim} 254263509Sdim 255263509Sdiminline error_code DiceRef::getKind(uint16_t &Result) const { 256263509Sdim const MachOObjectFile *MachOOF = 257263509Sdim static_cast<const MachOObjectFile *>(OwningObject); 258263509Sdim MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); 259263509Sdim Result = Dice.kind; 260263509Sdim return object_error::success; 261263509Sdim} 262263509Sdim 263263509Sdiminline DataRefImpl DiceRef::getRawDataRefImpl() const { 264263509Sdim return DicePimpl; 265263509Sdim} 266263509Sdim 267263509Sdiminline const ObjectFile *DiceRef::getObjectFile() const { 268263509Sdim return OwningObject; 269263509Sdim} 270263509Sdim 271263509Sdim} 272263509Sdim} 273263509Sdim 274226584Sdim#endif 275226584Sdim 276