X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FObject%2FMachOObjectFile.cpp;h=a930117019e7edbfc87228b6f83a373cbe17a5ce;hb=bb96dfcf4f58ae7152f4be92254a0bb1c0995e6d;hp=38198b17938d1af0f9f80abba13597b64d0b3d51;hpb=e5330f77cf420d71cfd46c960387eb06edeccbf8;p=oota-llvm.git diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 38198b17938..a930117019e 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -14,11 +14,11 @@ #include "llvm/Object/MachO.h" #include "llvm/ADT/Triple.h" -#include "llvm/Object/MachOFormat.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Format.h" #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" #include #include #include @@ -29,16 +29,16 @@ using namespace object; namespace llvm { namespace object { -struct SymbolTableEntryBase { - uint32_t StringIndex; - uint8_t Type; - uint8_t SectionIndex; - uint16_t Flags; +struct nlist_base { + uint32_t n_strx; + uint8_t n_type; + uint8_t n_sect; + uint16_t n_desc; }; -struct SectionBase { - char Name[16]; - char SegmentName[16]; +struct section_base { + char sectname[16]; + char segname[16]; }; template @@ -50,119 +50,174 @@ template static void SwapStruct(T &Value); template<> -void SwapStruct(macho::RelocationEntry &H) { - SwapValue(H.Word0); - SwapValue(H.Word1); +void SwapStruct(MachO::any_relocation_info &H) { + SwapValue(H.r_word0); + SwapValue(H.r_word1); +} + +template<> +void SwapStruct(MachO::load_command &L) { + SwapValue(L.cmd); + SwapValue(L.cmdsize); +} + +template<> +void SwapStruct(nlist_base &S) { + SwapValue(S.n_strx); + SwapValue(S.n_desc); } template<> -void SwapStruct(macho::LoadCommand &L) { - SwapValue(L.Type); - SwapValue(L.Size); +void SwapStruct(MachO::section &S) { + SwapValue(S.addr); + SwapValue(S.size); + SwapValue(S.offset); + SwapValue(S.align); + SwapValue(S.reloff); + SwapValue(S.nreloc); + SwapValue(S.flags); + SwapValue(S.reserved1); + SwapValue(S.reserved2); } template<> -void SwapStruct(SymbolTableEntryBase &S) { - SwapValue(S.StringIndex); - SwapValue(S.Flags); +void SwapStruct(MachO::section_64 &S) { + SwapValue(S.addr); + SwapValue(S.size); + SwapValue(S.offset); + SwapValue(S.align); + SwapValue(S.reloff); + SwapValue(S.nreloc); + SwapValue(S.flags); + SwapValue(S.reserved1); + SwapValue(S.reserved2); + SwapValue(S.reserved3); } template<> -void SwapStruct(macho::Section &S) { - SwapValue(S.Address); - SwapValue(S.Size); - SwapValue(S.Offset); - SwapValue(S.Align); - SwapValue(S.RelocationTableOffset); - SwapValue(S.NumRelocationTableEntries); - SwapValue(S.Flags); - SwapValue(S.Reserved1); - SwapValue(S.Reserved2); +void SwapStruct(MachO::nlist &S) { + SwapValue(S.n_strx); + SwapValue(S.n_desc); + SwapValue(S.n_value); } template<> -void SwapStruct(macho::Section64 &S) { - SwapValue(S.Address); - SwapValue(S.Size); - SwapValue(S.Offset); - SwapValue(S.Align); - SwapValue(S.RelocationTableOffset); - SwapValue(S.NumRelocationTableEntries); - SwapValue(S.Flags); - SwapValue(S.Reserved1); - SwapValue(S.Reserved2); - SwapValue(S.Reserved3); +void SwapStruct(MachO::nlist_64 &S) { + SwapValue(S.n_strx); + SwapValue(S.n_desc); + SwapValue(S.n_value); } template<> -void SwapStruct(macho::SymbolTableEntry &S) { - SwapValue(S.StringIndex); - SwapValue(S.Flags); - SwapValue(S.Value); +void SwapStruct(MachO::mach_header &H) { + SwapValue(H.magic); + SwapValue(H.cputype); + SwapValue(H.cpusubtype); + SwapValue(H.filetype); + SwapValue(H.ncmds); + SwapValue(H.sizeofcmds); + SwapValue(H.flags); } template<> -void SwapStruct(macho::Symbol64TableEntry &S) { - SwapValue(S.StringIndex); - SwapValue(S.Flags); - SwapValue(S.Value); +void SwapStruct(MachO::mach_header_64 &H) { + SwapValue(H.magic); + SwapValue(H.cputype); + SwapValue(H.cpusubtype); + SwapValue(H.filetype); + SwapValue(H.ncmds); + SwapValue(H.sizeofcmds); + SwapValue(H.flags); + SwapValue(H.reserved); } template<> -void SwapStruct(macho::Header &H) { - SwapValue(H.Magic); - SwapValue(H.CPUType); - SwapValue(H.CPUSubtype); - SwapValue(H.FileType); - SwapValue(H.NumLoadCommands); - SwapValue(H.SizeOfLoadCommands); - SwapValue(H.Flags); +void SwapStruct(MachO::symtab_command &C) { + SwapValue(C.cmd); + SwapValue(C.cmdsize); + SwapValue(C.symoff); + SwapValue(C.nsyms); + SwapValue(C.stroff); + SwapValue(C.strsize); } template<> -void SwapStruct(macho::SymtabLoadCommand &C) { - SwapValue(C.Type); - SwapValue(C.Size); - SwapValue(C.SymbolTableOffset); - SwapValue(C.NumSymbolTableEntries); - SwapValue(C.StringTableOffset); - SwapValue(C.StringTableSize); +void SwapStruct(MachO::dysymtab_command &C) { + SwapValue(C.cmd); + SwapValue(C.cmdsize); + SwapValue(C.ilocalsym); + SwapValue(C.nlocalsym); + SwapValue(C.iextdefsym); + SwapValue(C.nextdefsym); + SwapValue(C.iundefsym); + SwapValue(C.nundefsym); + SwapValue(C.tocoff); + SwapValue(C.ntoc); + SwapValue(C.modtaboff); + SwapValue(C.nmodtab); + SwapValue(C.extrefsymoff); + SwapValue(C.nextrefsyms); + SwapValue(C.indirectsymoff); + SwapValue(C.nindirectsyms); + SwapValue(C.extreloff); + SwapValue(C.nextrel); + SwapValue(C.locreloff); + SwapValue(C.nlocrel); } template<> -void SwapStruct(macho::LinkeditDataLoadCommand &C) { - SwapValue(C.Type); - SwapValue(C.Size); - SwapValue(C.DataOffset); - SwapValue(C.DataSize); +void SwapStruct(MachO::linkedit_data_command &C) { + SwapValue(C.cmd); + SwapValue(C.cmdsize); + SwapValue(C.dataoff); + SwapValue(C.datasize); } template<> -void SwapStruct(macho::SegmentLoadCommand &C) { - SwapValue(C.Type); - SwapValue(C.Size); - SwapValue(C.VMAddress); - SwapValue(C.VMSize); - SwapValue(C.FileOffset); - SwapValue(C.FileSize); - SwapValue(C.MaxVMProtection); - SwapValue(C.InitialVMProtection); - SwapValue(C.NumSections); - SwapValue(C.Flags); +void SwapStruct(MachO::segment_command &C) { + SwapValue(C.cmd); + SwapValue(C.cmdsize); + SwapValue(C.vmaddr); + SwapValue(C.vmsize); + SwapValue(C.fileoff); + SwapValue(C.filesize); + SwapValue(C.maxprot); + SwapValue(C.initprot); + SwapValue(C.nsects); + SwapValue(C.flags); } template<> -void SwapStruct(macho::Segment64LoadCommand &C) { - SwapValue(C.Type); - SwapValue(C.Size); - SwapValue(C.VMAddress); - SwapValue(C.VMSize); - SwapValue(C.FileOffset); - SwapValue(C.FileSize); - SwapValue(C.MaxVMProtection); - SwapValue(C.InitialVMProtection); - SwapValue(C.NumSections); - SwapValue(C.Flags); +void SwapStruct(MachO::segment_command_64 &C) { + SwapValue(C.cmd); + SwapValue(C.cmdsize); + SwapValue(C.vmaddr); + SwapValue(C.vmsize); + SwapValue(C.fileoff); + SwapValue(C.filesize); + SwapValue(C.maxprot); + SwapValue(C.initprot); + SwapValue(C.nsects); + SwapValue(C.flags); +} + +template<> +void SwapStruct(uint32_t &C) { + SwapValue(C); +} + +template<> +void SwapStruct(MachO::linker_options_command &C) { + SwapValue(C.cmd); + SwapValue(C.cmdsize); + SwapValue(C.count); +} + +template<> +void SwapStruct(MachO::data_in_code_entry &C) { + SwapValue(C.offset); + SwapValue(C.length); + SwapValue(C.kind); } template @@ -174,52 +229,40 @@ T getStruct(const MachOObjectFile *O, const char *P) { return Cmd; } -static macho::SegmentLoadCommand -getSegmentLoadCommand(const MachOObjectFile *O, - const MachOObjectFile::LoadCommandInfo &L) { - return getStruct(O, L.Ptr); -} - -static macho::Segment64LoadCommand -getSegment64LoadCommand(const MachOObjectFile *O, - const MachOObjectFile::LoadCommandInfo &L) { - return getStruct(O, L.Ptr); -} - static uint32_t getSegmentLoadCommandNumSections(const MachOObjectFile *O, const MachOObjectFile::LoadCommandInfo &L) { if (O->is64Bit()) { - macho::Segment64LoadCommand S = getSegment64LoadCommand(O, L); - return S.NumSections; + MachO::segment_command_64 S = O->getSegment64LoadCommand(L); + return S.nsects; } - macho::SegmentLoadCommand S = getSegmentLoadCommand(O, L); - return S.NumSections; + MachO::segment_command S = O->getSegmentLoadCommand(L); + return S.nsects; } -static const SectionBase * -getSectionBase(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, - unsigned Sec) { +static const char * +getSectionPtr(const MachOObjectFile *O, MachOObjectFile::LoadCommandInfo L, + unsigned Sec) { uintptr_t CommandAddr = reinterpret_cast(L.Ptr); bool Is64 = O->is64Bit(); - unsigned SegmentLoadSize = Is64 ? sizeof(macho::Segment64LoadCommand) : - sizeof(macho::SegmentLoadCommand); - unsigned SectionSize = Is64 ? sizeof(macho::Section64) : - sizeof(macho::Section); + unsigned SegmentLoadSize = Is64 ? sizeof(MachO::segment_command_64) : + sizeof(MachO::segment_command); + unsigned SectionSize = Is64 ? sizeof(MachO::section_64) : + sizeof(MachO::section); uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + Sec * SectionSize; - return reinterpret_cast(SectionAddr); + return reinterpret_cast(SectionAddr); } static const char *getPtr(const MachOObjectFile *O, size_t Offset) { return O->getData().substr(Offset, 1).data(); } -static SymbolTableEntryBase +static nlist_base getSymbolTableEntryBase(const MachOObjectFile *O, DataRefImpl DRI) { const char *P = reinterpret_cast(DRI.p); - return getStruct(O, P); + return getStruct(O, P); } static StringRef parseSegmentOrSectionName(const char *P) { @@ -247,11 +290,11 @@ static void advanceTo(T &it, size_t Val) { } static unsigned getCPUType(const MachOObjectFile *O) { - return O->getHeader().CPUType; + return O->getHeader().cputype; } static void printRelocationTargetName(const MachOObjectFile *O, - const macho::RelocationEntry &RE, + const MachO::any_relocation_info &RE, raw_string_ostream &fmt) { bool IsScattered = O->isRelocationScattered(RE); @@ -303,7 +346,7 @@ static void printRelocationTargetName(const MachOObjectFile *O, StringRef S; bool isExtern = O->getPlainRelocationExternal(RE); - uint64_t Val = O->getAnyRelocationAddress(RE); + uint64_t Val = O->getPlainRelocationSymbolNum(RE); if (isExtern) { symbol_iterator SI = O->begin_symbols(); @@ -311,89 +354,96 @@ static void printRelocationTargetName(const MachOObjectFile *O, SI->getName(S); } else { section_iterator SI = O->begin_sections(); - advanceTo(SI, Val); + // Adjust for the fact that sections are 1-indexed. + advanceTo(SI, Val - 1); SI->getName(S); } fmt << S; } -static uint32_t getPlainRelocationAddress(const macho::RelocationEntry &RE) { - return RE.Word0; +static uint32_t +getPlainRelocationAddress(const MachO::any_relocation_info &RE) { + return RE.r_word0; } static unsigned -getScatteredRelocationAddress(const macho::RelocationEntry &RE) { - return RE.Word0 & 0xffffff; +getScatteredRelocationAddress(const MachO::any_relocation_info &RE) { + return RE.r_word0 & 0xffffff; } static bool getPlainRelocationPCRel(const MachOObjectFile *O, - const macho::RelocationEntry &RE) { + const MachO::any_relocation_info &RE) { if (O->isLittleEndian()) - return (RE.Word1 >> 24) & 1; - return (RE.Word1 >> 7) & 1; + return (RE.r_word1 >> 24) & 1; + return (RE.r_word1 >> 7) & 1; } static bool getScatteredRelocationPCRel(const MachOObjectFile *O, - const macho::RelocationEntry &RE) { - return (RE.Word0 >> 30) & 1; + const MachO::any_relocation_info &RE) { + return (RE.r_word0 >> 30) & 1; } static unsigned getPlainRelocationLength(const MachOObjectFile *O, - const macho::RelocationEntry &RE) { + const MachO::any_relocation_info &RE) { if (O->isLittleEndian()) - return (RE.Word1 >> 25) & 3; - return (RE.Word1 >> 5) & 3; + return (RE.r_word1 >> 25) & 3; + return (RE.r_word1 >> 5) & 3; } static unsigned -getScatteredRelocationLength(const macho::RelocationEntry &RE) { - return (RE.Word0 >> 28) & 3; +getScatteredRelocationLength(const MachO::any_relocation_info &RE) { + return (RE.r_word0 >> 28) & 3; } static unsigned getPlainRelocationType(const MachOObjectFile *O, - const macho::RelocationEntry &RE) { + const MachO::any_relocation_info &RE) { if (O->isLittleEndian()) - return RE.Word1 >> 28; - return RE.Word1 & 0xf; + return RE.r_word1 >> 28; + return RE.r_word1 & 0xf; } -static unsigned getScatteredRelocationType(const macho::RelocationEntry &RE) { - return (RE.Word0 >> 24) & 0xf; +static unsigned +getScatteredRelocationType(const MachO::any_relocation_info &RE) { + return (RE.r_word0 >> 24) & 0xf; } static uint32_t getSectionFlags(const MachOObjectFile *O, DataRefImpl Sec) { if (O->is64Bit()) { - macho::Section64 Sect = O->getSection64(Sec); - return Sect.Flags; + MachO::section_64 Sect = O->getSection64(Sec); + return Sect.flags; } - macho::Section Sect = O->getSection(Sec); - return Sect.Flags; + MachO::section Sect = O->getSection(Sec); + return Sect.flags; } MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64bits, error_code &ec) : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object), - SymtabLoadCmd(NULL) { - uint32_t LoadCommandCount = this->getHeader().NumLoadCommands; - macho::LoadCommandType SegmentLoadType = is64Bit() ? - macho::LCT_Segment64 : macho::LCT_Segment; + SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL), DataInCodeLoadCmd(NULL) { + uint32_t LoadCommandCount = this->getHeader().ncmds; + MachO::LoadCommandType SegmentLoadType = is64Bit() ? + MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT; MachOObjectFile::LoadCommandInfo Load = getFirstLoadCommandInfo(); for (unsigned I = 0; ; ++I) { - if (Load.C.Type == macho::LCT_Symtab) { + if (Load.C.cmd == MachO::LC_SYMTAB) { assert(!SymtabLoadCmd && "Multiple symbol tables"); SymtabLoadCmd = Load.Ptr; - } - - if (Load.C.Type == SegmentLoadType) { + } else if (Load.C.cmd == MachO::LC_DYSYMTAB) { + assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables"); + DysymtabLoadCmd = Load.Ptr; + } else if (Load.C.cmd == MachO::LC_DATA_IN_CODE) { + assert(!DataInCodeLoadCmd && "Multiple data in code tables"); + DataInCodeLoadCmd = Load.Ptr; + } else if (Load.C.cmd == SegmentLoadType) { uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load); for (unsigned J = 0; J < NumSections; ++J) { - const SectionBase *Sec = getSectionBase(this, Load, J); - Sections.push_back(reinterpret_cast(Sec)); + const char *Sec = getSectionPtr(this, Load, J); + Sections.push_back(Sec); } } @@ -407,8 +457,8 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, error_code MachOObjectFile::getSymbolNext(DataRefImpl Symb, SymbolRef &Res) const { unsigned SymbolTableEntrySize = is64Bit() ? - sizeof(macho::Symbol64TableEntry) : - sizeof(macho::SymbolTableEntry); + sizeof(MachO::nlist_64) : + sizeof(MachO::nlist); Symb.p += SymbolTableEntrySize; Res = SymbolRef(Symb, this); return object_error::success; @@ -416,10 +466,9 @@ error_code MachOObjectFile::getSymbolNext(DataRefImpl Symb, error_code MachOObjectFile::getSymbolName(DataRefImpl Symb, StringRef &Res) const { - macho::SymtabLoadCommand S = getSymtabLoadCommand(); - const char *StringTable = getPtr(this, S.StringTableOffset); - SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb); - const char *Start = &StringTable[Entry.StringIndex]; + StringRef StringTable = getStringTableData(); + nlist_base Entry = getSymbolTableEntryBase(this, Symb); + const char *Start = &StringTable.data()[Entry.n_strx]; Res = StringRef(Start); return object_error::success; } @@ -427,11 +476,11 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl Symb, error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const { if (is64Bit()) { - macho::Symbol64TableEntry Entry = getSymbol64TableEntry(Symb); - Res = Entry.Value; + MachO::nlist_64 Entry = getSymbol64TableEntry(Symb); + Res = Entry.n_value; } else { - macho::SymbolTableEntry Entry = getSymbolTableEntry(Symb); - Res = Entry.Value; + MachO::nlist Entry = getSymbolTableEntry(Symb); + Res = Entry.n_value; } return object_error::success; } @@ -439,18 +488,18 @@ error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb, error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb, uint64_t &Res) const { - SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb); + nlist_base Entry = getSymbolTableEntryBase(this, Symb); getSymbolAddress(Symb, Res); - if (Entry.SectionIndex) { + if (Entry.n_sect) { uint64_t Delta; DataRefImpl SecRel; - SecRel.d.a = Entry.SectionIndex-1; + SecRel.d.a = Entry.n_sect-1; if (is64Bit()) { - macho::Section64 Sec = getSection64(SecRel); - Delta = Sec.Offset - Sec.Address; + MachO::section_64 Sec = getSection64(SecRel); + Delta = Sec.offset - Sec.addr; } else { - macho::Section Sec = getSection(SecRel); - Delta = Sec.Offset - Sec.Address; + MachO::section Sec = getSection(SecRel); + Delta = Sec.offset - Sec.addr; } Res += Delta; @@ -459,19 +508,32 @@ MachOObjectFile::getSymbolFileOffset(DataRefImpl Symb, return object_error::success; } +error_code MachOObjectFile::getSymbolAlignment(DataRefImpl DRI, + uint32_t &Result) const { + uint32_t flags; + this->getSymbolFlags(DRI, flags); + if (flags & SymbolRef::SF_Common) { + nlist_base Entry = getSymbolTableEntryBase(this, DRI); + Result = 1 << MachO::GET_COMM_ALIGN(Entry.n_desc); + } else { + Result = 0; + } + return object_error::success; +} + error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, uint64_t &Result) const { uint64_t BeginOffset; uint64_t EndOffset = 0; uint8_t SectionIndex; - SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, DRI); + nlist_base Entry = getSymbolTableEntryBase(this, DRI); uint64_t Value; getSymbolAddress(DRI, Value); BeginOffset = Value; - SectionIndex = Entry.SectionIndex; + SectionIndex = Entry.n_sect; if (!SectionIndex) { uint32_t flags = SymbolRef::SF_None; this->getSymbolFlags(DRI, flags); @@ -489,7 +551,7 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, DataRefImpl DRI = I->getRawDataRefImpl(); Entry = getSymbolTableEntryBase(this, DRI); getSymbolAddress(DRI, Value); - if (Entry.SectionIndex == SectionIndex && Value > BeginOffset) + if (Entry.n_sect == SectionIndex && Value > BeginOffset) if (!EndOffset || Value < EndOffset) EndOffset = Value; } @@ -507,80 +569,58 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const { - SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb); - uint8_t n_type = Entry.Type; + nlist_base Entry = getSymbolTableEntryBase(this, Symb); + uint8_t n_type = Entry.n_type; Res = SymbolRef::ST_Other; // If this is a STAB debugging symbol, we can do nothing more. - if (n_type & MachO::NlistMaskStab) { + if (n_type & MachO::N_STAB) { Res = SymbolRef::ST_Debug; return object_error::success; } - switch (n_type & MachO::NlistMaskType) { - case MachO::NListTypeUndefined : + switch (n_type & MachO::N_TYPE) { + case MachO::N_UNDF : Res = SymbolRef::ST_Unknown; break; - case MachO::NListTypeSection : + case MachO::N_SECT : Res = SymbolRef::ST_Function; break; } return object_error::success; } -error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl Symb, - char &Res) const { - SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb); - uint8_t Type = Entry.Type; - uint16_t Flags = Entry.Flags; - - char Char; - switch (Type & macho::STF_TypeMask) { - case macho::STT_Undefined: - Char = 'u'; - break; - case macho::STT_Absolute: - case macho::STT_Section: - Char = 's'; - break; - default: - Char = '?'; - break; - } - - if (Flags & (macho::STF_External | macho::STF_PrivateExtern)) - Char = toupper(static_cast(Char)); - Res = Char; - return object_error::success; -} - error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, uint32_t &Result) const { - SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, DRI); + nlist_base Entry = getSymbolTableEntryBase(this, DRI); - uint8_t MachOType = Entry.Type; - uint16_t MachOFlags = Entry.Flags; + uint8_t MachOType = Entry.n_type; + uint16_t MachOFlags = Entry.n_desc; // TODO: Correctly set SF_ThreadLocal Result = SymbolRef::SF_None; - if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined) + if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) Result |= SymbolRef::SF_Undefined; - if (MachOFlags & macho::STF_StabsEntryMask) + if (MachOType & MachO::N_STAB) Result |= SymbolRef::SF_FormatSpecific; - if (MachOType & MachO::NlistMaskExternal) { + if (MachOType & MachO::N_EXT) { Result |= SymbolRef::SF_Global; - if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeUndefined) - Result |= SymbolRef::SF_Common; + if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) { + uint64_t Value; + getSymbolAddress(DRI, Value); + if (Value) + Result |= SymbolRef::SF_Common; + } } - if (MachOFlags & (MachO::NListDescWeakRef | MachO::NListDescWeakDef)) + if (MachOFlags & (MachO::N_WEAK_REF | MachO::N_WEAK_DEF)) Result |= SymbolRef::SF_Weak; - if ((MachOType & MachO::NlistMaskType) == MachO::NListTypeAbsolute) + if ((MachOType & MachO::N_TYPE) == MachO::N_ABS) Result |= SymbolRef::SF_Absolute; return object_error::success; @@ -589,8 +629,8 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, section_iterator &Res) const { - SymbolTableEntryBase Entry = getSymbolTableEntryBase(this, Symb); - uint8_t index = Entry.SectionIndex; + nlist_base Entry = getSymbolTableEntryBase(this, Symb); + uint8_t index = Entry.n_sect; if (index == 0) { Res = end_sections(); @@ -625,11 +665,11 @@ MachOObjectFile::getSectionName(DataRefImpl Sec, StringRef &Result) const { error_code MachOObjectFile::getSectionAddress(DataRefImpl Sec, uint64_t &Res) const { if (is64Bit()) { - macho::Section64 Sect = getSection64(Sec); - Res = Sect.Address; + MachO::section_64 Sect = getSection64(Sec); + Res = Sect.addr; } else { - macho::Section Sect = getSection(Sec); - Res = Sect.Address; + MachO::section Sect = getSection(Sec); + Res = Sect.addr; } return object_error::success; } @@ -637,11 +677,11 @@ MachOObjectFile::getSectionAddress(DataRefImpl Sec, uint64_t &Res) const { error_code MachOObjectFile::getSectionSize(DataRefImpl Sec, uint64_t &Res) const { if (is64Bit()) { - macho::Section64 Sect = getSection64(Sec); - Res = Sect.Size; + MachO::section_64 Sect = getSection64(Sec); + Res = Sect.size; } else { - macho::Section Sect = getSection(Sec); - Res = Sect.Size; + MachO::section Sect = getSection(Sec); + Res = Sect.size; } return object_error::success; @@ -653,13 +693,13 @@ MachOObjectFile::getSectionContents(DataRefImpl Sec, StringRef &Res) const { uint64_t Size; if (is64Bit()) { - macho::Section64 Sect = getSection64(Sec); - Offset = Sect.Offset; - Size = Sect.Size; + MachO::section_64 Sect = getSection64(Sec); + Offset = Sect.offset; + Size = Sect.size; } else { - macho::Section Sect =getSection(Sec); - Offset = Sect.Offset; - Size = Sect.Size; + MachO::section Sect = getSection(Sec); + Offset = Sect.offset; + Size = Sect.size; } Res = this->getData().substr(Offset, Size); @@ -670,11 +710,11 @@ error_code MachOObjectFile::getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const { uint32_t Align; if (is64Bit()) { - macho::Section64 Sect = getSection64(Sec); - Align = Sect.Align; + MachO::section_64 Sect = getSection64(Sec); + Align = Sect.align; } else { - macho::Section Sect = getSection(Sec); - Align = Sect.Align; + MachO::section Sect = getSection(Sec); + Align = Sect.align; } Res = uint64_t(1) << Align; @@ -684,7 +724,7 @@ MachOObjectFile::getSectionAlignment(DataRefImpl Sec, uint64_t &Res) const { error_code MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const { uint32_t Flags = getSectionFlags(this, Sec); - Res = Flags & macho::SF_PureInstructions; + Res = Flags & MachO::S_ATTR_PURE_INSTRUCTIONS; return object_error::success; } @@ -718,9 +758,9 @@ error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec, error_code MachOObjectFile::isSectionZeroInit(DataRefImpl Sec, bool &Res) const { uint32_t Flags = getSectionFlags(this, Sec); - unsigned SectionType = Flags & MachO::SectionFlagMaskSectionType; - Res = SectionType == MachO::SectionTypeZeroFill || - SectionType == MachO::SectionTypeZeroFillLarge; + unsigned SectionType = Flags & MachO::SECTION_TYPE; + Res = SectionType == MachO::S_ZEROFILL || + SectionType == MachO::S_GB_ZEROFILL; return object_error::success; } @@ -757,14 +797,14 @@ MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, return object_error::success; } -relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { +relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const { uint32_t Offset; if (is64Bit()) { - macho::Section64 Sect = getSection64(Sec); - Offset = Sect.RelocationTableOffset; + MachO::section_64 Sect = getSection64(Sec); + Offset = Sect.reloff; } else { - macho::Section Sect = getSection(Sec); - Offset = Sect.RelocationTableOffset; + MachO::section Sect = getSection(Sec); + Offset = Sect.reloff; } DataRefImpl Ret; @@ -773,21 +813,21 @@ relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { } relocation_iterator -MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { +MachOObjectFile::section_rel_end(DataRefImpl Sec) const { uint32_t Offset; uint32_t Num; if (is64Bit()) { - macho::Section64 Sect = getSection64(Sec); - Offset = Sect.RelocationTableOffset; - Num = Sect.NumRelocationTableEntries; + MachO::section_64 Sect = getSection64(Sec); + Offset = Sect.reloff; + Num = Sect.nreloc; } else { - macho::Section Sect = getSection(Sec); - Offset = Sect.RelocationTableOffset; - Num = Sect.NumRelocationTableEntries; + MachO::section Sect = getSection(Sec); + Offset = Sect.reloff; + Num = Sect.nreloc; } - const macho::RelocationEntry *P = - reinterpret_cast(getPtr(this, Offset)); + const MachO::any_relocation_info *P = + reinterpret_cast(getPtr(this, Offset)); DataRefImpl Ret; Ret.p = reinterpret_cast(P + Num); @@ -796,8 +836,8 @@ MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, RelocationRef &Res) const { - const macho::RelocationEntry *P = - reinterpret_cast(Rel.p); + const MachO::any_relocation_info *P = + reinterpret_cast(Rel.p); Rel.p = reinterpret_cast(P + 1); Res = RelocationRef(Rel, this); return object_error::success; @@ -810,35 +850,32 @@ MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const { error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, uint64_t &Res) const { - macho::RelocationEntry RE = getRelocation(Rel); + MachO::any_relocation_info RE = getRelocation(Rel); Res = getAnyRelocationAddress(RE); return object_error::success; } -error_code -MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const { - macho::RelocationEntry RE = getRelocation(Rel); +symbol_iterator +MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const { + MachO::any_relocation_info RE = getRelocation(Rel); uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE); bool isExtern = getPlainRelocationExternal(RE); - if (!isExtern) { - Res = *end_symbols(); - return object_error::success; - } + if (!isExtern) + return end_symbols(); - macho::SymtabLoadCommand S = getSymtabLoadCommand(); + MachO::symtab_command S = getSymtabLoadCommand(); unsigned SymbolTableEntrySize = is64Bit() ? - sizeof(macho::Symbol64TableEntry) : - sizeof(macho::SymbolTableEntry); - uint64_t Offset = S.SymbolTableOffset + SymbolIdx * SymbolTableEntrySize; + sizeof(MachO::nlist_64) : + sizeof(MachO::nlist); + uint64_t Offset = S.symoff + SymbolIdx * SymbolTableEntrySize; DataRefImpl Sym; Sym.p = reinterpret_cast(getPtr(this, Offset)); - Res = SymbolRef(Sym, this); - return object_error::success; + return symbol_iterator(SymbolRef(Sym, this)); } error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, uint64_t &Res) const { - macho::RelocationEntry RE = getRelocation(Rel); + MachO::any_relocation_info RE = getRelocation(Rel); Res = getAnyRelocationType(RE); return object_error::success; } @@ -862,7 +899,7 @@ MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, "GENERIC_RELOC_LOCAL_SECTDIFF", "GENERIC_RELOC_TLV" }; - if (RType > 6) + if (RType > 5) res = "Unknown"; else res = Table[RType]; @@ -925,7 +962,10 @@ MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, "PPC_RELOC_LO14_SECTDIFF", "PPC_RELOC_LOCAL_SECTDIFF" }; - res = Table[RType]; + if (RType > 15) + res = "Unknown"; + else + res = Table[RType]; break; } case Triple::UnknownArch: @@ -936,16 +976,10 @@ MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, return object_error::success; } -error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, - int64_t &Res) const { - Res = 0; - return object_error::success; -} - error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, SmallVectorImpl &Result) const { - macho::RelocationEntry RE = getRelocation(Rel); + MachO::any_relocation_info RE = getRelocation(Rel); unsigned Arch = this->getArch(); @@ -962,47 +996,47 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel, bool isPCRel = getAnyRelocationPCRel(RE); switch (Type) { - case macho::RIT_X86_64_GOTLoad: // X86_64_RELOC_GOT_LOAD - case macho::RIT_X86_64_GOT: { // X86_64_RELOC_GOT + case MachO::X86_64_RELOC_GOT_LOAD: + case MachO::X86_64_RELOC_GOT: { printRelocationTargetName(this, RE, fmt); fmt << "@GOT"; if (isPCRel) fmt << "PCREL"; break; } - case macho::RIT_X86_64_Subtractor: { // X86_64_RELOC_SUBTRACTOR + case MachO::X86_64_RELOC_SUBTRACTOR: { DataRefImpl RelNext = Rel; RelNext.d.a++; - macho::RelocationEntry RENext = getRelocation(RelNext); + MachO::any_relocation_info RENext = getRelocation(RelNext); - // X86_64_SUBTRACTOR must be followed by a relocation of type + // X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type // X86_64_RELOC_UNSIGNED. // NOTE: Scattered relocations don't exist on x86_64. unsigned RType = getAnyRelocationType(RENext); - if (RType != 0) + if (RType != MachO::X86_64_RELOC_UNSIGNED) report_fatal_error("Expected X86_64_RELOC_UNSIGNED after " "X86_64_RELOC_SUBTRACTOR."); - // The X86_64_RELOC_UNSIGNED contains the minuend symbol, - // X86_64_SUBTRACTOR contains to the subtrahend. + // The X86_64_RELOC_UNSIGNED contains the minuend symbol; + // X86_64_RELOC_SUBTRACTOR contains the subtrahend. printRelocationTargetName(this, RENext, fmt); fmt << "-"; printRelocationTargetName(this, RE, fmt); break; } - case macho::RIT_X86_64_TLV: + case MachO::X86_64_RELOC_TLV: printRelocationTargetName(this, RE, fmt); fmt << "@TLV"; if (isPCRel) fmt << "P"; break; - case macho::RIT_X86_64_Signed1: // X86_64_RELOC_SIGNED1 + case MachO::X86_64_RELOC_SIGNED_1: printRelocationTargetName(this, RE, fmt); fmt << "-1"; break; - case macho::RIT_X86_64_Signed2: // X86_64_RELOC_SIGNED2 + case MachO::X86_64_RELOC_SIGNED_2: printRelocationTargetName(this, RE, fmt); fmt << "-2"; break; - case macho::RIT_X86_64_Signed4: // X86_64_RELOC_SIGNED4 + case MachO::X86_64_RELOC_SIGNED_4: printRelocationTargetName(this, RE, fmt); fmt << "-4"; break; @@ -1011,21 +1045,22 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel, break; } // X86 and ARM share some relocation types in common. - } else if (Arch == Triple::x86 || Arch == Triple::arm) { + } else if (Arch == Triple::x86 || Arch == Triple::arm || + Arch == Triple::ppc) { // Generic relocation types... switch (Type) { - case macho::RIT_Pair: // GENERIC_RELOC_PAIR - prints no info + case MachO::GENERIC_RELOC_PAIR: // prints no info return object_error::success; - case macho::RIT_Difference: { // GENERIC_RELOC_SECTDIFF + case MachO::GENERIC_RELOC_SECTDIFF: { DataRefImpl RelNext = Rel; RelNext.d.a++; - macho::RelocationEntry RENext = getRelocation(RelNext); + MachO::any_relocation_info RENext = getRelocation(RelNext); // X86 sect diff's must be followed by a relocation of type // GENERIC_RELOC_PAIR. unsigned RType = getAnyRelocationType(RENext); - if (RType != 1) + if (RType != MachO::GENERIC_RELOC_PAIR) report_fatal_error("Expected GENERIC_RELOC_PAIR after " "GENERIC_RELOC_SECTDIFF."); @@ -1036,19 +1071,17 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel, } } - if (Arch == Triple::x86) { - // All X86 relocations that need special printing were already - // handled in the generic code. + if (Arch == Triple::x86 || Arch == Triple::ppc) { switch (Type) { - case macho::RIT_Generic_LocalDifference:{// GENERIC_RELOC_LOCAL_SECTDIFF + case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: { DataRefImpl RelNext = Rel; RelNext.d.a++; - macho::RelocationEntry RENext = getRelocation(RelNext); + MachO::any_relocation_info RENext = getRelocation(RelNext); // X86 sect diff's must be followed by a relocation of type // GENERIC_RELOC_PAIR. unsigned RType = getAnyRelocationType(RENext); - if (RType != 1) + if (RType != MachO::GENERIC_RELOC_PAIR) report_fatal_error("Expected GENERIC_RELOC_PAIR after " "GENERIC_RELOC_LOCAL_SECTDIFF."); @@ -1057,7 +1090,7 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel, printRelocationTargetName(this, RENext, fmt); break; } - case macho::RIT_Generic_TLV: { + case MachO::GENERIC_RELOC_TLV: { printRelocationTargetName(this, RE, fmt); fmt << "@TLV"; if (IsPCRel) fmt << "P"; @@ -1068,8 +1101,8 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel, } } else { // ARM-specific relocations switch (Type) { - case macho::RIT_ARM_Half: // ARM_RELOC_HALF - case macho::RIT_ARM_HalfDifference: { // ARM_RELOC_HALF_SECTDIFF + case MachO::ARM_RELOC_HALF: + case MachO::ARM_RELOC_HALF_SECTDIFF: { // Half relocations steal a bit from the length field to encode // whether this is an upper16 or a lower16 relocation. bool isUpper = getAnyRelocationLength(RE) >> 1; @@ -1082,14 +1115,14 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel, DataRefImpl RelNext = Rel; RelNext.d.a++; - macho::RelocationEntry RENext = getRelocation(RelNext); + MachO::any_relocation_info RENext = getRelocation(RelNext); // ARM half relocs must be followed by a relocation of type // ARM_RELOC_PAIR. unsigned RType = getAnyRelocationType(RENext); - if (RType != 1) + if (RType != MachO::ARM_RELOC_PAIR) report_fatal_error("Expected ARM_RELOC_PAIR after " - "GENERIC_RELOC_HALF"); + "ARM_RELOC_HALF"); // NOTE: The half of the target virtual address is stashed in the // address field of the secondary relocation, but we can't reverse @@ -1098,7 +1131,7 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel, // ARM_RELOC_HALF_SECTDIFF encodes the second section in the // symbol/section pointer of the follow-on relocation. - if (Type == macho::RIT_ARM_HalfDifference) { + if (Type == MachO::ARM_RELOC_HALF_SECTDIFF) { fmt << "-"; printRelocationTargetName(this, RENext, fmt); } @@ -1129,17 +1162,17 @@ MachOObjectFile::getRelocationHidden(DataRefImpl Rel, bool &Result) const { // On arches that use the generic relocations, GENERIC_RELOC_PAIR // is always hidden. - if (Arch == Triple::x86 || Arch == Triple::arm) { - if (Type == macho::RIT_Pair) Result = true; + if (Arch == Triple::x86 || Arch == Triple::arm || Arch == Triple::ppc) { + if (Type == MachO::GENERIC_RELOC_PAIR) Result = true; } else if (Arch == Triple::x86_64) { // On x86_64, X86_64_RELOC_UNSIGNED is hidden only when it follows - // an X864_64_RELOC_SUBTRACTOR. - if (Type == macho::RIT_X86_64_Unsigned && Rel.d.a > 0) { + // an X86_64_RELOC_SUBTRACTOR. + if (Type == MachO::X86_64_RELOC_UNSIGNED && Rel.d.a > 0) { DataRefImpl RelPrev = Rel; RelPrev.d.a--; uint64_t PrevType; getRelocationType(RelPrev, PrevType); - if (PrevType == macho::RIT_X86_64_Subtractor) + if (PrevType == MachO::X86_64_RELOC_SUBTRACTOR) Result = true; } } @@ -1162,8 +1195,8 @@ symbol_iterator MachOObjectFile::begin_symbols() const { if (!SymtabLoadCmd) return symbol_iterator(SymbolRef(DRI, this)); - macho::SymtabLoadCommand Symtab = getSymtabLoadCommand(); - DRI.p = reinterpret_cast(getPtr(this, Symtab.SymbolTableOffset)); + MachO::symtab_command Symtab = getSymtabLoadCommand(); + DRI.p = reinterpret_cast(getPtr(this, Symtab.symoff)); return symbol_iterator(SymbolRef(DRI, this)); } @@ -1172,12 +1205,12 @@ symbol_iterator MachOObjectFile::end_symbols() const { if (!SymtabLoadCmd) return symbol_iterator(SymbolRef(DRI, this)); - macho::SymtabLoadCommand Symtab = getSymtabLoadCommand(); + MachO::symtab_command Symtab = getSymtabLoadCommand(); unsigned SymbolTableEntrySize = is64Bit() ? - sizeof(macho::Symbol64TableEntry) : - sizeof(macho::SymbolTableEntry); - unsigned Offset = Symtab.SymbolTableOffset + - Symtab.NumSymbolTableEntries * SymbolTableEntrySize; + sizeof(MachO::nlist_64) : + sizeof(MachO::nlist); + unsigned Offset = Symtab.symoff + + Symtab.nsyms * SymbolTableEntrySize; DRI.p = reinterpret_cast(getPtr(this, Offset)); return symbol_iterator(SymbolRef(DRI, this)); } @@ -1221,56 +1254,93 @@ StringRef MachOObjectFile::getFileFormatName() const { unsigned CPUType = getCPUType(this); if (!is64Bit()) { switch (CPUType) { - case llvm::MachO::CPUTypeI386: + case llvm::MachO::CPU_TYPE_I386: return "Mach-O 32-bit i386"; - case llvm::MachO::CPUTypeARM: + case llvm::MachO::CPU_TYPE_ARM: return "Mach-O arm"; - case llvm::MachO::CPUTypePowerPC: + case llvm::MachO::CPU_TYPE_POWERPC: return "Mach-O 32-bit ppc"; default: - assert((CPUType & llvm::MachO::CPUArchABI64) == 0 && + assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) == 0 && "64-bit object file when we're not 64-bit?"); return "Mach-O 32-bit unknown"; } } // Make sure the cpu type has the correct mask. - assert((CPUType & llvm::MachO::CPUArchABI64) - == llvm::MachO::CPUArchABI64 && - "32-bit object file when we're 64-bit?"); + assert((CPUType & llvm::MachO::CPU_ARCH_ABI64) + == llvm::MachO::CPU_ARCH_ABI64 && + "32-bit object file when we're 64-bit?"); switch (CPUType) { - case llvm::MachO::CPUTypeX86_64: + case llvm::MachO::CPU_TYPE_X86_64: return "Mach-O 64-bit x86-64"; - case llvm::MachO::CPUTypePowerPC64: + case llvm::MachO::CPU_TYPE_POWERPC64: return "Mach-O 64-bit ppc64"; default: return "Mach-O 64-bit unknown"; } } -unsigned MachOObjectFile::getArch() const { - switch (getCPUType(this)) { - case llvm::MachO::CPUTypeI386: +Triple::ArchType MachOObjectFile::getArch(uint32_t CPUType) { + switch (CPUType) { + case llvm::MachO::CPU_TYPE_I386: return Triple::x86; - case llvm::MachO::CPUTypeX86_64: + case llvm::MachO::CPU_TYPE_X86_64: return Triple::x86_64; - case llvm::MachO::CPUTypeARM: + case llvm::MachO::CPU_TYPE_ARM: return Triple::arm; - case llvm::MachO::CPUTypePowerPC: + case llvm::MachO::CPU_TYPE_POWERPC: return Triple::ppc; - case llvm::MachO::CPUTypePowerPC64: + case llvm::MachO::CPU_TYPE_POWERPC64: return Triple::ppc64; default: return Triple::UnknownArch; } } +unsigned MachOObjectFile::getArch() const { + return getArch(getCPUType(this)); +} + StringRef MachOObjectFile::getLoadName() const { // TODO: Implement report_fatal_error("get_load_name() unimplemented in MachOObjectFile"); } +relocation_iterator MachOObjectFile::section_rel_begin(unsigned Index) const { + DataRefImpl DRI; + DRI.d.a = Index; + return section_rel_begin(DRI); +} + +relocation_iterator MachOObjectFile::section_rel_end(unsigned Index) const { + DataRefImpl DRI; + DRI.d.a = Index; + return section_rel_end(DRI); +} + +dice_iterator MachOObjectFile::begin_dices() const { + DataRefImpl DRI; + if (!DataInCodeLoadCmd) + return dice_iterator(DiceRef(DRI, this)); + + MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); + DRI.p = reinterpret_cast(getPtr(this, DicLC.dataoff)); + return dice_iterator(DiceRef(DRI, this)); +} + +dice_iterator MachOObjectFile::end_dices() const { + DataRefImpl DRI; + if (!DataInCodeLoadCmd) + return dice_iterator(DiceRef(DRI, this)); + + MachO::linkedit_data_command DicLC = getDataInCodeLoadCommand(); + unsigned Offset = DicLC.dataoff + DicLC.datasize; + DRI.p = reinterpret_cast(getPtr(this, Offset)); + return dice_iterator(DiceRef(DRI, this)); +} + StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const { ArrayRef Raw = getSectionRawFinalSegmentName(Sec); @@ -1279,132 +1349,220 @@ MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const { ArrayRef MachOObjectFile::getSectionRawName(DataRefImpl Sec) const { - const SectionBase *Base = - reinterpret_cast(Sections[Sec.d.a]); - return ArrayRef(Base->Name); + const section_base *Base = + reinterpret_cast(Sections[Sec.d.a]); + return ArrayRef(Base->sectname); } ArrayRef MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { - const SectionBase *Base = - reinterpret_cast(Sections[Sec.d.a]); - return ArrayRef(Base->SegmentName); + const section_base *Base = + reinterpret_cast(Sections[Sec.d.a]); + return ArrayRef(Base->segname); } bool -MachOObjectFile::isRelocationScattered(const macho::RelocationEntry &RE) +MachOObjectFile::isRelocationScattered(const MachO::any_relocation_info &RE) const { - if (getCPUType(this) == llvm::MachO::CPUTypeX86_64) + if (getCPUType(this) == MachO::CPU_TYPE_X86_64) return false; - return getPlainRelocationAddress(RE) & macho::RF_Scattered; + return getPlainRelocationAddress(RE) & MachO::R_SCATTERED; } -unsigned MachOObjectFile::getPlainRelocationSymbolNum(const macho::RelocationEntry &RE) const { +unsigned MachOObjectFile::getPlainRelocationSymbolNum( + const MachO::any_relocation_info &RE) const { if (isLittleEndian()) - return RE.Word1 & 0xffffff; - return RE.Word1 >> 8; + return RE.r_word1 & 0xffffff; + return RE.r_word1 >> 8; } -bool MachOObjectFile::getPlainRelocationExternal(const macho::RelocationEntry &RE) const { +bool MachOObjectFile::getPlainRelocationExternal( + const MachO::any_relocation_info &RE) const { if (isLittleEndian()) - return (RE.Word1 >> 27) & 1; - return (RE.Word1 >> 4) & 1; + return (RE.r_word1 >> 27) & 1; + return (RE.r_word1 >> 4) & 1; } -bool -MachOObjectFile::getScatteredRelocationScattered(const macho::RelocationEntry &RE) const { - return RE.Word0 >> 31; +bool MachOObjectFile::getScatteredRelocationScattered( + const MachO::any_relocation_info &RE) const { + return RE.r_word0 >> 31; } -uint32_t -MachOObjectFile::getScatteredRelocationValue(const macho::RelocationEntry &RE) const { - return RE.Word1; +uint32_t MachOObjectFile::getScatteredRelocationValue( + const MachO::any_relocation_info &RE) const { + return RE.r_word1; } -unsigned -MachOObjectFile::getAnyRelocationAddress(const macho::RelocationEntry &RE) const { +unsigned MachOObjectFile::getAnyRelocationAddress( + const MachO::any_relocation_info &RE) const { if (isRelocationScattered(RE)) return getScatteredRelocationAddress(RE); return getPlainRelocationAddress(RE); } -unsigned -MachOObjectFile::getAnyRelocationPCRel(const macho::RelocationEntry &RE) const { +unsigned MachOObjectFile::getAnyRelocationPCRel( + const MachO::any_relocation_info &RE) const { if (isRelocationScattered(RE)) return getScatteredRelocationPCRel(this, RE); return getPlainRelocationPCRel(this, RE); } -unsigned -MachOObjectFile::getAnyRelocationLength(const macho::RelocationEntry &RE) const { +unsigned MachOObjectFile::getAnyRelocationLength( + const MachO::any_relocation_info &RE) const { if (isRelocationScattered(RE)) return getScatteredRelocationLength(RE); return getPlainRelocationLength(this, RE); } unsigned -MachOObjectFile::getAnyRelocationType(const macho::RelocationEntry &RE) const { +MachOObjectFile::getAnyRelocationType( + const MachO::any_relocation_info &RE) const { if (isRelocationScattered(RE)) return getScatteredRelocationType(RE); return getPlainRelocationType(this, RE); } +SectionRef +MachOObjectFile::getRelocationSection( + const MachO::any_relocation_info &RE) const { + if (isRelocationScattered(RE) || getPlainRelocationExternal(RE)) + return *end_sections(); + unsigned SecNum = getPlainRelocationSymbolNum(RE) - 1; + DataRefImpl DRI; + DRI.d.a = SecNum; + return SectionRef(DRI, this); +} + MachOObjectFile::LoadCommandInfo MachOObjectFile::getFirstLoadCommandInfo() const { MachOObjectFile::LoadCommandInfo Load; - unsigned HeaderSize = is64Bit() ? macho::Header64Size : macho::Header32Size; + unsigned HeaderSize = is64Bit() ? sizeof(MachO::mach_header_64) : + sizeof(MachO::mach_header); Load.Ptr = getPtr(this, HeaderSize); - Load.C = getStruct(this, Load.Ptr); + Load.C = getStruct(this, Load.Ptr); return Load; } MachOObjectFile::LoadCommandInfo MachOObjectFile::getNextLoadCommandInfo(const LoadCommandInfo &L) const { MachOObjectFile::LoadCommandInfo Next; - Next.Ptr = L.Ptr + L.C.Size; - Next.C = getStruct(this, Next.Ptr); + Next.Ptr = L.Ptr + L.C.cmdsize; + Next.C = getStruct(this, Next.Ptr); return Next; } -macho::Section MachOObjectFile::getSection(DataRefImpl DRI) const { - return getStruct(this, Sections[DRI.d.a]); +MachO::section MachOObjectFile::getSection(DataRefImpl DRI) const { + return getStruct(this, Sections[DRI.d.a]); } -macho::Section64 MachOObjectFile::getSection64(DataRefImpl DRI) const { - return getStruct(this, Sections[DRI.d.a]); +MachO::section_64 MachOObjectFile::getSection64(DataRefImpl DRI) const { + return getStruct(this, Sections[DRI.d.a]); } -macho::SymbolTableEntry +MachO::section MachOObjectFile::getSection(const LoadCommandInfo &L, + unsigned Index) const { + const char *Sec = getSectionPtr(this, L, Index); + return getStruct(this, Sec); +} + +MachO::section_64 MachOObjectFile::getSection64(const LoadCommandInfo &L, + unsigned Index) const { + const char *Sec = getSectionPtr(this, L, Index); + return getStruct(this, Sec); +} + +MachO::nlist MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { const char *P = reinterpret_cast(DRI.p); - return getStruct(this, P); + return getStruct(this, P); } -macho::Symbol64TableEntry +MachO::nlist_64 MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { const char *P = reinterpret_cast(DRI.p); - return getStruct(this, P); + return getStruct(this, P); +} + +MachO::linkedit_data_command +MachOObjectFile::getLinkeditDataLoadCommand(const LoadCommandInfo &L) const { + return getStruct(this, L.Ptr); +} + +MachO::segment_command +MachOObjectFile::getSegmentLoadCommand(const LoadCommandInfo &L) const { + return getStruct(this, L.Ptr); +} + +MachO::segment_command_64 +MachOObjectFile::getSegment64LoadCommand(const LoadCommandInfo &L) const { + return getStruct(this, L.Ptr); } -macho::LinkeditDataLoadCommand -MachOObjectFile::getLinkeditDataLoadCommand(const MachOObjectFile::LoadCommandInfo &L) const { - return getStruct(this, L.Ptr); +MachO::linker_options_command +MachOObjectFile::getLinkerOptionsLoadCommand(const LoadCommandInfo &L) const { + return getStruct(this, L.Ptr); } -macho::RelocationEntry +MachO::any_relocation_info MachOObjectFile::getRelocation(DataRefImpl Rel) const { const char *P = reinterpret_cast(Rel.p); - return getStruct(this, P); + return getStruct(this, P); +} + +MachO::data_in_code_entry +MachOObjectFile::getDice(DataRefImpl Rel) const { + const char *P = reinterpret_cast(Rel.p); + return getStruct(this, P); +} + +MachO::mach_header MachOObjectFile::getHeader() const { + return getStruct(this, getPtr(this, 0)); +} + +MachO::mach_header_64 MachOObjectFile::getHeader64() const { + return getStruct(this, getPtr(this, 0)); +} + +uint32_t MachOObjectFile::getIndirectSymbolTableEntry( + const MachO::dysymtab_command &DLC, + unsigned Index) const { + uint64_t Offset = DLC.indirectsymoff + Index * sizeof(uint32_t); + return getStruct(this, getPtr(this, Offset)); } -macho::Header MachOObjectFile::getHeader() const { - return getStruct(this, getPtr(this, 0)); +MachO::data_in_code_entry +MachOObjectFile::getDataInCodeTableEntry(uint32_t DataOffset, + unsigned Index) const { + uint64_t Offset = DataOffset + Index * sizeof(MachO::data_in_code_entry); + return getStruct(this, getPtr(this, Offset)); } -macho::SymtabLoadCommand -MachOObjectFile::getSymtabLoadCommand() const { - return getStruct(this, SymtabLoadCmd); +MachO::symtab_command MachOObjectFile::getSymtabLoadCommand() const { + return getStruct(this, SymtabLoadCmd); +} + +MachO::dysymtab_command MachOObjectFile::getDysymtabLoadCommand() const { + return getStruct(this, DysymtabLoadCmd); +} + +MachO::linkedit_data_command +MachOObjectFile::getDataInCodeLoadCommand() const { + if (DataInCodeLoadCmd) + return getStruct(this, DataInCodeLoadCmd); + + // If there is no DataInCodeLoadCmd return a load command with zero'ed fields. + MachO::linkedit_data_command Cmd; + Cmd.cmd = MachO::LC_DATA_IN_CODE; + Cmd.cmdsize = sizeof(MachO::linkedit_data_command); + Cmd.dataoff = 0; + Cmd.datasize = 0; + return Cmd; +} + +StringRef MachOObjectFile::getStringTableData() const { + MachO::symtab_command S = getSymtabLoadCommand(); + return getData().substr(S.stroff, S.strsize); } bool MachOObjectFile::is64Bit() const { @@ -1424,24 +1582,26 @@ void MachOObjectFile::ReadULEB128s(uint64_t Index, } } -ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { +ErrorOr ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { StringRef Magic = Buffer->getBuffer().slice(0, 4); - error_code ec; - ObjectFile *Ret; + error_code EC; + OwningPtr Ret; if (Magic == "\xFE\xED\xFA\xCE") - Ret = new MachOObjectFile(Buffer, false, false, ec); + Ret.reset(new MachOObjectFile(Buffer, false, false, EC)); else if (Magic == "\xCE\xFA\xED\xFE") - Ret = new MachOObjectFile(Buffer, true, false, ec); + Ret.reset(new MachOObjectFile(Buffer, true, false, EC)); else if (Magic == "\xFE\xED\xFA\xCF") - Ret = new MachOObjectFile(Buffer, false, true, ec); + Ret.reset(new MachOObjectFile(Buffer, false, true, EC)); else if (Magic == "\xCF\xFA\xED\xFE") - Ret = new MachOObjectFile(Buffer, true, true, ec); - else - return NULL; + Ret.reset(new MachOObjectFile(Buffer, true, true, EC)); + else { + delete Buffer; + return object_error::parse_failed; + } - if (ec) - return NULL; - return Ret; + if (EC) + return EC; + return Ret.take(); } } // end namespace object