X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FObject%2FMachO.h;h=073e8b7baa4497286e9d02c492d87e6be4bce28c;hb=4266ae806798f1e8982a53bb9babe1e508adfc68;hp=41484485e442472db35c78a7c31257881311f6d7;hpb=305b826f92e0dc7b670238e7caa35ab6e1cf341a;p=oota-llvm.git diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 41484485e44..073e8b7baa4 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file declares the MachOObjectFile class, which binds the MachOObject -// class to the generic ObjectFile wrapper. +// This file declares the MachOObjectFile class, which implement the ObjectFile +// interface for MachO files. // //===----------------------------------------------------------------------===// @@ -17,130 +17,118 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/Object/MachOObject.h" +#include "llvm/ADT/Triple.h" #include "llvm/Object/ObjectFile.h" -#include "llvm/Support/Endian.h" #include "llvm/Support/MachO.h" -#include "llvm/Support/raw_ostream.h" namespace llvm { namespace object { -namespace MachOFormat { - struct Section { - char Name[16]; - char SegmentName[16]; - support::ulittle32_t Address; - support::ulittle32_t Size; - support::ulittle32_t Offset; - support::ulittle32_t Align; - support::ulittle32_t RelocationTableOffset; - support::ulittle32_t NumRelocationTableEntries; - support::ulittle32_t Flags; - support::ulittle32_t Reserved1; - support::ulittle32_t Reserved2; - }; +/// DiceRef - This is a value type class that represents a single +/// data in code entry in the table in a Mach-O object file. +class DiceRef { + DataRefImpl DicePimpl; + const ObjectFile *OwningObject; - struct Section64 { - char Name[16]; - char SegmentName[16]; - support::ulittle64_t Address; - support::ulittle64_t Size; - support::ulittle32_t Offset; - support::ulittle32_t Align; - support::ulittle32_t RelocationTableOffset; - support::ulittle32_t NumRelocationTableEntries; - support::ulittle32_t Flags; - support::ulittle32_t Reserved1; - support::ulittle32_t Reserved2; - support::ulittle32_t Reserved3; - }; +public: + DiceRef() : OwningObject(nullptr) { } - struct RelocationEntry { - support::ulittle32_t Word0; - support::ulittle32_t Word1; - }; + DiceRef(DataRefImpl DiceP, const ObjectFile *Owner); - struct SymbolTableEntry { - support::ulittle32_t StringIndex; - uint8_t Type; - uint8_t SectionIndex; - support::ulittle16_t Flags; - support::ulittle32_t Value; - }; + bool operator==(const DiceRef &Other) const; + bool operator<(const DiceRef &Other) const; - struct Symbol64TableEntry { - support::ulittle32_t StringIndex; - uint8_t Type; - uint8_t SectionIndex; - support::ulittle16_t Flags; - support::ulittle64_t Value; - }; - - struct SymtabLoadCommand { - support::ulittle32_t Type; - support::ulittle32_t Size; - support::ulittle32_t SymbolTableOffset; - support::ulittle32_t NumSymbolTableEntries; - support::ulittle32_t StringTableOffset; - support::ulittle32_t StringTableSize; - }; + void moveNext(); - struct SegmentLoadCommand { - support::ulittle32_t Type; - support::ulittle32_t Size; - char Name[16]; - support::ulittle32_t VMAddress; - support::ulittle32_t VMSize; - support::ulittle32_t FileOffset; - support::ulittle32_t FileSize; - support::ulittle32_t MaxVMProtection; - support::ulittle32_t InitialVMProtection; - support::ulittle32_t NumSections; - support::ulittle32_t Flags; - }; + error_code getOffset(uint32_t &Result) const; + error_code getLength(uint16_t &Result) const; + error_code getKind(uint16_t &Result) const; - struct Segment64LoadCommand { - support::ulittle32_t Type; - support::ulittle32_t Size; - char Name[16]; - support::ulittle64_t VMAddress; - support::ulittle64_t VMSize; - support::ulittle64_t FileOffset; - support::ulittle64_t FileSize; - support::ulittle32_t MaxVMProtection; - support::ulittle32_t InitialVMProtection; - support::ulittle32_t NumSections; - support::ulittle32_t Flags; - }; - - struct LinkeditDataLoadCommand { - support::ulittle32_t Type; - support::ulittle32_t Size; - support::ulittle32_t DataOffset; - support::ulittle32_t DataSize; - }; -} - -typedef MachOObject::LoadCommandInfo LoadCommandInfo; + DataRefImpl getRawDataRefImpl() const; + const ObjectFile *getObjectFile() const; +}; +typedef content_iterator dice_iterator; class MachOObjectFile : public ObjectFile { public: - MachOObjectFile(MemoryBuffer *Object, MachOObject *MOO, error_code &ec); - - virtual symbol_iterator begin_symbols() const; - virtual symbol_iterator end_symbols() const; - virtual symbol_iterator begin_dynamic_symbols() const; - virtual symbol_iterator end_dynamic_symbols() const; - virtual library_iterator begin_libraries_needed() const; - virtual library_iterator end_libraries_needed() const; - virtual section_iterator begin_sections() const; - virtual section_iterator end_sections() const; - - virtual uint8_t getBytesInAddress() const; - virtual StringRef getFileFormatName() const; - virtual unsigned getArch() const; - virtual StringRef getLoadName() const; + struct LoadCommandInfo { + const char *Ptr; // Where in memory the load command is. + MachO::load_command C; // The command itself. + }; + + MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64Bits, + error_code &EC, bool BufferOwned = true); + + void moveSymbolNext(DataRefImpl &Symb) const override; + error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const override; + error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; + error_code getSymbolAlignment(DataRefImpl Symb, uint32_t &Res) const override; + error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; + error_code getSymbolType(DataRefImpl Symb, + SymbolRef::Type &Res) const override; + uint32_t getSymbolFlags(DataRefImpl Symb) const override; + error_code getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const override; + + void moveSectionNext(DataRefImpl &Sec) const override; + error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override; + error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const override; + error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const override; + error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override; + error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const override; + error_code isSectionText(DataRefImpl Sec, bool &Res) const override; + error_code isSectionData(DataRefImpl Sec, bool &Res) const override; + error_code isSectionBSS(DataRefImpl Sec, bool &Res) const override; + error_code isSectionRequiredForExecution(DataRefImpl Sec, + bool &Res) const override; + error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const override; + error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const override; + error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const override; + error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, + bool &Result) const override; + relocation_iterator section_rel_begin(DataRefImpl Sec) const override; + relocation_iterator section_rel_end(DataRefImpl Sec) const override; + + void moveRelocationNext(DataRefImpl &Rel) const override; + error_code getRelocationAddress(DataRefImpl Rel, + uint64_t &Res) const override; + error_code getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const override; + symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override; + error_code getRelocationType(DataRefImpl Rel, uint64_t &Res) const override; + error_code getRelocationTypeName(DataRefImpl Rel, + SmallVectorImpl &Result) const override; + error_code getRelocationValueString(DataRefImpl Rel, + SmallVectorImpl &Result) const override; + error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const override; + + error_code getLibraryNext(DataRefImpl LibData, + LibraryRef &Res) const override; + error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const override; + + // TODO: Would be useful to have an iterator based version + // of the load command interface too. + + basic_symbol_iterator symbol_begin_impl() const override; + basic_symbol_iterator symbol_end_impl() const override; + + section_iterator section_begin() const override; + section_iterator section_end() const override; + + library_iterator needed_library_begin() const override; + library_iterator needed_library_end() const override; + + uint8_t getBytesInAddress() const override; + + StringRef getFileFormatName() const override; + unsigned getArch() const override; + + StringRef getLoadName() const override; + + relocation_iterator section_rel_begin(unsigned Index) const; + relocation_iterator section_rel_end(unsigned Index) const; + + dice_iterator begin_dices() const; + dice_iterator end_dices() const; // In a MachO file, sections have a segment name. This is used in the .o // files. They have a single segment, but this field specifies which segment @@ -150,107 +138,130 @@ public: // Names are stored as 16 bytes. These returns the raw 16 bytes without // interpreting them as a C string. ArrayRef getSectionRawName(DataRefImpl Sec) const; - ArrayRefgetSectionRawFinalSegmentName(DataRefImpl Sec) const; - - const MachOFormat::LinkeditDataLoadCommand * - getLinkeditDataLoadCommand(LoadCommandInfo LCI) const; - - const MachOObject *getObject() const { return MachOObj.get(); } - - static inline bool classof(const Binary *v) { + ArrayRef getSectionRawFinalSegmentName(DataRefImpl Sec) const; + + // MachO specific Info about relocations. + bool isRelocationScattered(const MachO::any_relocation_info &RE) const; + unsigned getPlainRelocationSymbolNum( + const MachO::any_relocation_info &RE) const; + bool getPlainRelocationExternal(const MachO::any_relocation_info &RE) const; + bool getScatteredRelocationScattered( + const MachO::any_relocation_info &RE) const; + uint32_t getScatteredRelocationValue( + const MachO::any_relocation_info &RE) const; + unsigned getAnyRelocationAddress(const MachO::any_relocation_info &RE) const; + unsigned getAnyRelocationPCRel(const MachO::any_relocation_info &RE) const; + unsigned getAnyRelocationLength(const MachO::any_relocation_info &RE) const; + unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const; + SectionRef getRelocationSection(const MachO::any_relocation_info &RE) const; + + // Walk load commands. + LoadCommandInfo getFirstLoadCommandInfo() const; + LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const; + + // MachO specific structures. + MachO::section getSection(DataRefImpl DRI) const; + MachO::section_64 getSection64(DataRefImpl DRI) const; + MachO::section getSection(const LoadCommandInfo &L, unsigned Index) const; + MachO::section_64 getSection64(const LoadCommandInfo &L,unsigned Index) const; + MachO::nlist getSymbolTableEntry(DataRefImpl DRI) const; + MachO::nlist_64 getSymbol64TableEntry(DataRefImpl DRI) const; + + MachO::linkedit_data_command + getLinkeditDataLoadCommand(const LoadCommandInfo &L) const; + MachO::segment_command + getSegmentLoadCommand(const LoadCommandInfo &L) const; + MachO::segment_command_64 + getSegment64LoadCommand(const LoadCommandInfo &L) const; + MachO::linker_options_command + getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const; + MachO::version_min_command + getVersionMinLoadCommand(const LoadCommandInfo &L) const; + + MachO::any_relocation_info getRelocation(DataRefImpl Rel) const; + MachO::data_in_code_entry getDice(DataRefImpl Rel) const; + MachO::mach_header getHeader() const; + MachO::mach_header_64 getHeader64() const; + uint32_t + getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, + unsigned Index) const; + MachO::data_in_code_entry getDataInCodeTableEntry(uint32_t DataOffset, + unsigned Index) const; + MachO::symtab_command getSymtabLoadCommand() const; + MachO::dysymtab_command getDysymtabLoadCommand() const; + MachO::linkedit_data_command getDataInCodeLoadCommand() const; + + StringRef getStringTableData() const; + bool is64Bit() const; + void ReadULEB128s(uint64_t Index, SmallVectorImpl &Out) const; + + static Triple::ArchType getArch(uint32_t CPUType); + + static bool classof(const Binary *v) { return v->isMachO(); } -protected: - virtual error_code getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const; - virtual error_code getSymbolName(DataRefImpl Symb, StringRef &Res) const; - virtual error_code getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const; - virtual error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const; - virtual error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const; - virtual error_code getSymbolNMTypeChar(DataRefImpl Symb, char &Res) const; - virtual error_code getSymbolFlags(DataRefImpl Symb, uint32_t &Res) const; - virtual error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const; - virtual error_code getSymbolSection(DataRefImpl Symb, - section_iterator &Res) const; - virtual error_code getSymbolValue(DataRefImpl Symb, uint64_t &Val) const; - - virtual error_code getSectionNext(DataRefImpl Sec, SectionRef &Res) const; - virtual error_code getSectionName(DataRefImpl Sec, StringRef &Res) const; - virtual error_code getSectionAddress(DataRefImpl Sec, uint64_t &Res) const; - virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; - virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; - virtual error_code getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const; - virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; - virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; - virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; - virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, - bool &Res) const; - virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; - virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; - virtual error_code isSectionReadOnlyData(DataRefImpl Sec, bool &Res) const; - virtual error_code sectionContainsSymbol(DataRefImpl DRI, DataRefImpl S, - bool &Result) const; - virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; - virtual relocation_iterator getSectionRelEnd(DataRefImpl Sec) const; - - virtual error_code getRelocationNext(DataRefImpl Rel, - RelocationRef &Res) const; - virtual error_code getRelocationAddress(DataRefImpl Rel, - uint64_t &Res) const; - virtual error_code getRelocationOffset(DataRefImpl Rel, - uint64_t &Res) const; - virtual error_code getRelocationSymbol(DataRefImpl Rel, - SymbolRef &Res) const; - virtual error_code getRelocationType(DataRefImpl Rel, - uint64_t &Res) const; - virtual error_code getRelocationTypeName(DataRefImpl Rel, - SmallVectorImpl &Result) const; - virtual error_code getRelocationAdditionalInfo(DataRefImpl Rel, - int64_t &Res) const; - virtual error_code getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl &Result) const; - virtual error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const; - - virtual error_code getLibraryNext(DataRefImpl LibData, LibraryRef &Res) const; - virtual error_code getLibraryPath(DataRefImpl LibData, StringRef &Res) const; - private: - OwningPtr MachOObj; - typedef SmallVector SectionList; + typedef SmallVector SectionList; SectionList Sections; + const char *SymtabLoadCmd; + const char *DysymtabLoadCmd; + const char *DataInCodeLoadCmd; +}; + +/// DiceRef +inline DiceRef::DiceRef(DataRefImpl DiceP, const ObjectFile *Owner) + : DicePimpl(DiceP) , OwningObject(Owner) {} + +inline bool DiceRef::operator==(const DiceRef &Other) const { + return DicePimpl == Other.DicePimpl; +} +inline bool DiceRef::operator<(const DiceRef &Other) const { + return DicePimpl < Other.DicePimpl; +} - void moveToNextSection(DataRefImpl &DRI) const; +inline void DiceRef::moveNext() { + const MachO::data_in_code_entry *P = + reinterpret_cast(DicePimpl.p); + DicePimpl.p = reinterpret_cast(P + 1); +} - const MachOFormat::SymbolTableEntry * - getSymbolTableEntry(DataRefImpl DRI) const; +// Since a Mach-O data in code reference, a DiceRef, can only be created when +// the OwningObject ObjectFile is a MachOObjectFile a static_cast<> is used for +// the methods that get the values of the fields of the reference. - const MachOFormat::SymbolTableEntry * - getSymbolTableEntry(DataRefImpl DRI, - const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const; +inline error_code DiceRef::getOffset(uint32_t &Result) const { + const MachOObjectFile *MachOOF = + static_cast(OwningObject); + MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); + Result = Dice.offset; + return object_error::success; +} - const MachOFormat::Symbol64TableEntry * - getSymbol64TableEntry(DataRefImpl DRI) const; +inline error_code DiceRef::getLength(uint16_t &Result) const { + const MachOObjectFile *MachOOF = + static_cast(OwningObject); + MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); + Result = Dice.length; + return object_error::success; +} - const MachOFormat::Symbol64TableEntry * - getSymbol64TableEntry(DataRefImpl DRI, - const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const; +inline error_code DiceRef::getKind(uint16_t &Result) const { + const MachOObjectFile *MachOOF = + static_cast(OwningObject); + MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); + Result = Dice.kind; + return object_error::success; +} - void moveToNextSymbol(DataRefImpl &DRI) const; - const MachOFormat::Section *getSection(DataRefImpl DRI) const; - const MachOFormat::Section64 *getSection64(DataRefImpl DRI) const; - const MachOFormat::RelocationEntry *getRelocation(DataRefImpl Rel) const; - const MachOFormat::SymtabLoadCommand * - getSymtabLoadCommand(LoadCommandInfo LCI) const; - const MachOFormat::SegmentLoadCommand * - getSegmentLoadCommand(LoadCommandInfo LCI) const; - const MachOFormat::Segment64LoadCommand * - getSegment64LoadCommand(LoadCommandInfo LCI) const; - std::size_t getSectionIndex(DataRefImpl Sec) const; +inline DataRefImpl DiceRef::getRawDataRefImpl() const { + return DicePimpl; +} - void printRelocationTargetName(const MachOFormat::RelocationEntry *RE, - raw_string_ostream &fmt) const; -}; +inline const ObjectFile *DiceRef::getObjectFile() const { + return OwningObject; +} } }