diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-09 14:49:08 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2013-04-09 14:49:08 +0000 |
commit | f6cfc15705140cc958b784a1bc98f7f0f09be6be (patch) | |
tree | 9481eebb2dc98f8adf2c67e452fd1ac8815e0513 /lib/Object/MachOObjectFile.cpp | |
parent | 32a3e78304a94ea214aee5fe82b10dd110e8863a (diff) |
Convert MachOObjectFile to a template.
For now it is templated only on being 64 or 32 bits. I will add little/big
endian next.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179097 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Object/MachOObjectFile.cpp')
-rw-r--r-- | lib/Object/MachOObjectFile.cpp | 962 |
1 files changed, 110 insertions, 852 deletions
diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index e1eec36598..20b66d94e8 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -15,6 +15,7 @@ #include "llvm/Object/MachO.h" #include "llvm/ADT/Triple.h" #include "llvm/Object/MachOFormat.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Format.h" #include "llvm/Support/MemoryBuffer.h" @@ -28,34 +29,25 @@ using namespace object; namespace llvm { namespace object { -MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool Is64bits, - error_code &ec) +MachOObjectFileBase::MachOObjectFileBase(MemoryBuffer *Object, bool Is64bits, + error_code &ec) : ObjectFile(getMachOType(true, Is64bits), Object) { - DataRefImpl DRI; - moveToNextSection(DRI); - uint32_t LoadCommandCount = getHeader()->NumLoadCommands; - while (DRI.d.a < LoadCommandCount) { - Sections.push_back(DRI); - DRI.d.b++; - moveToNextSection(DRI); - } } -bool MachOObjectFile::is64Bit() const { - unsigned int Type = getType(); - return Type == ID_MachO64L || Type == ID_MachO64B; +bool MachOObjectFileBase::is64Bit() const { + return isa<MachOObjectFile<true> >(this); } -const MachOFormat::LoadCommand * -MachOObjectFile::getLoadCommandInfo(unsigned Index) const { +const MachOObjectFileBase::LoadCommand * +MachOObjectFileBase::getLoadCommandInfo(unsigned Index) const { uint64_t Offset; uint64_t NewOffset = getHeaderSize(); - const MachOFormat::LoadCommand *Load; + const LoadCommand *Load; unsigned I = 0; do { Offset = NewOffset; - StringRef Data = getData(Offset, sizeof(MachOFormat::LoadCommand)); - Load = reinterpret_cast<const MachOFormat::LoadCommand*>(Data.data()); + StringRef Data = getData(Offset, sizeof(LoadCommand)); + Load = reinterpret_cast<const LoadCommand*>(Data.data()); NewOffset = Offset + Load->Size; ++I; } while (I != Index + 1); @@ -63,8 +55,8 @@ MachOObjectFile::getLoadCommandInfo(unsigned Index) const { return Load; } -void MachOObjectFile::ReadULEB128s(uint64_t Index, - SmallVectorImpl<uint64_t> &Out) const { +void MachOObjectFileBase::ReadULEB128s(uint64_t Index, + SmallVectorImpl<uint64_t> &Out) const { DataExtractor extractor(ObjectFile::getData(), true, 0); uint32_t offset = Index; @@ -75,16 +67,16 @@ void MachOObjectFile::ReadULEB128s(uint64_t Index, } } -const MachOFormat::Header *MachOObjectFile::getHeader() const { - StringRef Data = getData(0, sizeof(MachOFormat::Header)); - return reinterpret_cast<const MachOFormat::Header*>(Data.data()); +const MachOObjectFileBase::Header *MachOObjectFileBase::getHeader() const { + StringRef Data = getData(0, sizeof(Header)); + return reinterpret_cast<const Header*>(Data.data()); } -unsigned MachOObjectFile::getHeaderSize() const { +unsigned MachOObjectFileBase::getHeaderSize() const { return is64Bit() ? macho::Header64Size : macho::Header32Size; } -StringRef MachOObjectFile::getData(size_t Offset, size_t Size) const { +StringRef MachOObjectFileBase::getData(size_t Offset, size_t Size) const { return ObjectFile::getData().substr(Offset, Size); } @@ -92,7 +84,11 @@ ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { StringRef Magic = Buffer->getBuffer().slice(0, 4); error_code ec; bool Is64Bits = Magic == "\xFE\xED\xFA\xCF" || Magic == "\xCF\xFA\xED\xFE"; - ObjectFile *Ret = new MachOObjectFile(Buffer, Is64Bits, ec); + ObjectFile *Ret; + if (Is64Bits) + Ret = new MachOObjectFile<true>(Buffer, ec); + else + Ret = new MachOObjectFile<false>(Buffer, ec); if (ec) return NULL; return Ret; @@ -100,13 +96,13 @@ ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { /*===-- Symbols -----------------------------------------------------------===*/ -void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { +void MachOObjectFileBase::moveToNextSymbol(DataRefImpl &DRI) const { uint32_t LoadCommandCount = getHeader()->NumLoadCommands; while (DRI.d.a < LoadCommandCount) { - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); + const LoadCommand *Command = getLoadCommandInfo(DRI.d.a); if (Command->Type == macho::LCT_Symtab) { - const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = - reinterpret_cast<const MachOFormat::SymtabLoadCommand*>(Command); + const SymtabLoadCommand *SymtabLoadCmd = + reinterpret_cast<const SymtabLoadCommand*>(Command); if (DRI.d.b < SymtabLoadCmd->NumSymbolTableEntries) return; } @@ -116,23 +112,17 @@ void MachOObjectFile::moveToNextSymbol(DataRefImpl &DRI) const { } } -const MachOFormat::SymbolTableEntryBase * -MachOObjectFile::getSymbolTableEntryBase(DataRefImpl DRI) const { - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = - reinterpret_cast<const MachOFormat::SymtabLoadCommand*>(Command); +const MachOObjectFileBase::SymbolTableEntryBase * +MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI) const { + const LoadCommand *Command = getLoadCommandInfo(DRI.d.a); + const SymtabLoadCommand *SymtabLoadCmd = + reinterpret_cast<const SymtabLoadCommand*>(Command); return getSymbolTableEntryBase(DRI, SymtabLoadCmd); } -const MachOFormat::SymbolTableEntry<false> * -MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI) const { - const MachOFormat::SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI); - return reinterpret_cast<const MachOFormat::SymbolTableEntry<false>*>(Base); -} - -const MachOFormat::SymbolTableEntryBase * -MachOObjectFile::getSymbolTableEntryBase(DataRefImpl DRI, - const MachOFormat::SymtabLoadCommand *SymtabLoadCmd) const { +const MachOObjectFileBase::SymbolTableEntryBase * +MachOObjectFileBase::getSymbolTableEntryBase(DataRefImpl DRI, + const SymtabLoadCommand *SymtabLoadCmd) const { uint64_t SymbolTableOffset = SymtabLoadCmd->SymbolTableOffset; unsigned Index = DRI.d.b; @@ -142,34 +132,27 @@ MachOObjectFile::getSymbolTableEntryBase(DataRefImpl DRI, uint64_t Offset = SymbolTableOffset + Index * SymbolTableEntrySize; StringRef Data = getData(Offset, SymbolTableEntrySize); - return - reinterpret_cast<const MachOFormat::SymbolTableEntryBase*>(Data.data()); + return reinterpret_cast<const SymbolTableEntryBase*>(Data.data()); } -const MachOFormat::SymbolTableEntry<true>* -MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI) const { - const MachOFormat::SymbolTableEntryBase *Base = getSymbolTableEntryBase(DRI); - return reinterpret_cast<const MachOFormat::SymbolTableEntry<true>*>(Base); -} - -error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI, - SymbolRef &Result) const { +error_code MachOObjectFileBase::getSymbolNext(DataRefImpl DRI, + SymbolRef &Result) const { DRI.d.b++; moveToNextSymbol(DRI); Result = SymbolRef(DRI, this); return object_error::success; } -error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, - StringRef &Result) const { - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - const MachOFormat::SymtabLoadCommand *SymtabLoadCmd = - reinterpret_cast<const MachOFormat::SymtabLoadCommand*>(Command); +error_code MachOObjectFileBase::getSymbolName(DataRefImpl DRI, + StringRef &Result) const { + const LoadCommand *Command = getLoadCommandInfo(DRI.d.a); + const SymtabLoadCommand *SymtabLoadCmd = + reinterpret_cast<const SymtabLoadCommand*>(Command); StringRef StringTable = getData(SymtabLoadCmd->StringTableOffset, SymtabLoadCmd->StringTableSize); - const MachOFormat::SymbolTableEntryBase *Entry = + const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI, SymtabLoadCmd); uint32_t StringIndex = Entry->StringIndex; @@ -179,121 +162,9 @@ error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, return object_error::success; } -error_code MachOObjectFile::getSymbolFileOffset(DataRefImpl DRI, - uint64_t &Result) const { - if (is64Bit()) { - const MachOFormat::SymbolTableEntry<true> *Entry = - getSymbol64TableEntry(DRI); - Result = Entry->Value; - if (Entry->SectionIndex) { - const MachOFormat::Section<true> *Section = - getSection64(Sections[Entry->SectionIndex-1]); - Result += Section->Offset - Section->Address; - } - } else { - const MachOFormat::SymbolTableEntry<false> *Entry = - getSymbolTableEntry(DRI); - Result = Entry->Value; - if (Entry->SectionIndex) { - const MachOFormat::Section<false> *Section = - getSection(Sections[Entry->SectionIndex-1]); - Result += Section->Offset - Section->Address; - } - } - - return object_error::success; -} - -error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, - uint64_t &Result) const { - if (is64Bit()) { - const MachOFormat::SymbolTableEntry<true> *Entry = - getSymbol64TableEntry(DRI); - Result = Entry->Value; - } else { - const MachOFormat::SymbolTableEntry<false> *Entry = - getSymbolTableEntry(DRI); - Result = Entry->Value; - } - return object_error::success; -} - -error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, - uint64_t &Result) const { - uint32_t LoadCommandCount = getHeader()->NumLoadCommands; - uint64_t BeginOffset; - uint64_t EndOffset = 0; - uint8_t SectionIndex; - if (is64Bit()) { - const MachOFormat::SymbolTableEntry<true> *Entry = - getSymbol64TableEntry(DRI); - BeginOffset = Entry->Value; - SectionIndex = Entry->SectionIndex; - if (!SectionIndex) { - uint32_t flags = SymbolRef::SF_None; - getSymbolFlags(DRI, flags); - if (flags & SymbolRef::SF_Common) - Result = Entry->Value; - else - Result = UnknownAddressOrSize; - return object_error::success; - } - // Unfortunately symbols are unsorted so we need to touch all - // symbols from load command - DRI.d.b = 0; - uint32_t Command = DRI.d.a; - while (Command == DRI.d.a) { - moveToNextSymbol(DRI); - if (DRI.d.a < LoadCommandCount) { - Entry = getSymbol64TableEntry(DRI); - if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset) - if (!EndOffset || Entry->Value < EndOffset) - EndOffset = Entry->Value; - } - DRI.d.b++; - } - } else { - const MachOFormat::SymbolTableEntry<false> *Entry = - getSymbolTableEntry(DRI); - BeginOffset = Entry->Value; - SectionIndex = Entry->SectionIndex; - if (!SectionIndex) { - uint32_t flags = SymbolRef::SF_None; - getSymbolFlags(DRI, flags); - if (flags & SymbolRef::SF_Common) - Result = Entry->Value; - else - Result = UnknownAddressOrSize; - return object_error::success; - } - // Unfortunately symbols are unsorted so we need to touch all - // symbols from load command - DRI.d.b = 0; - uint32_t Command = DRI.d.a; - while (Command == DRI.d.a) { - moveToNextSymbol(DRI); - if (DRI.d.a < LoadCommandCount) { - Entry = getSymbolTableEntry(DRI); - if (Entry->SectionIndex == SectionIndex && Entry->Value > BeginOffset) - if (!EndOffset || Entry->Value < EndOffset) - EndOffset = Entry->Value; - } - DRI.d.b++; - } - } - if (!EndOffset) { - uint64_t Size; - getSectionSize(Sections[SectionIndex-1], Size); - getSectionAddress(Sections[SectionIndex-1], EndOffset); - EndOffset += Size; - } - Result = EndOffset - BeginOffset; - return object_error::success; -} - -error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, - char &Result) const { - const MachOFormat::SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI); +error_code MachOObjectFileBase::getSymbolNMTypeChar(DataRefImpl DRI, + char &Result) const { + const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI); uint8_t Type = Entry->Type; uint16_t Flags = Entry->Flags; @@ -317,9 +188,9 @@ error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, return object_error::success; } -error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, - uint32_t &Result) const { - const MachOFormat::SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI); +error_code MachOObjectFileBase::getSymbolFlags(DataRefImpl DRI, + uint32_t &Result) const { + const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(DRI); uint8_t MachOType = Entry->Type; uint16_t MachOFlags = Entry->Flags; @@ -347,10 +218,9 @@ error_code MachOObjectFile::getSymbolFlags(DataRefImpl DRI, return object_error::success; } -error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, - section_iterator &Res) const { - const MachOFormat::SymbolTableEntryBase *Entry = - getSymbolTableEntryBase(Symb); +error_code MachOObjectFileBase::getSymbolSection(DataRefImpl Symb, + section_iterator &Res) const { + const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb); uint8_t index = Entry->SectionIndex; if (index == 0) @@ -361,10 +231,9 @@ error_code MachOObjectFile::getSymbolSection(DataRefImpl Symb, return object_error::success; } -error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, - SymbolRef::Type &Res) const { - const MachOFormat::SymbolTableEntryBase *Entry = - getSymbolTableEntryBase(Symb); +error_code MachOObjectFileBase::getSymbolType(DataRefImpl Symb, + SymbolRef::Type &Res) const { + const SymbolTableEntryBase *Entry = getSymbolTableEntryBase(Symb); uint8_t n_type = Entry->Type; Res = SymbolRef::ST_Other; @@ -386,97 +255,61 @@ error_code MachOObjectFile::getSymbolType(DataRefImpl Symb, return object_error::success; } -error_code MachOObjectFile::getSymbolValue(DataRefImpl Symb, - uint64_t &Val) const { - report_fatal_error("getSymbolValue unimplemented in MachOObjectFile"); +error_code MachOObjectFileBase::getSymbolValue(DataRefImpl Symb, + uint64_t &Val) const { + report_fatal_error("getSymbolValue unimplemented in MachOObjectFileBase"); } -symbol_iterator MachOObjectFile::begin_symbols() const { +symbol_iterator MachOObjectFileBase::begin_symbols() const { // DRI.d.a = segment number; DRI.d.b = symbol index. DataRefImpl DRI; moveToNextSymbol(DRI); return symbol_iterator(SymbolRef(DRI, this)); } -symbol_iterator MachOObjectFile::end_symbols() const { +symbol_iterator MachOObjectFileBase::end_symbols() const { DataRefImpl DRI; DRI.d.a = getHeader()->NumLoadCommands; return symbol_iterator(SymbolRef(DRI, this)); } -symbol_iterator MachOObjectFile::begin_dynamic_symbols() const { +symbol_iterator MachOObjectFileBase::begin_dynamic_symbols() const { // TODO: implement - report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile"); + report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase"); } -symbol_iterator MachOObjectFile::end_dynamic_symbols() const { +symbol_iterator MachOObjectFileBase::end_dynamic_symbols() const { // TODO: implement - report_fatal_error("Dynamic symbols unimplemented in MachOObjectFile"); + report_fatal_error("Dynamic symbols unimplemented in MachOObjectFileBase"); } -library_iterator MachOObjectFile::begin_libraries_needed() const { +library_iterator MachOObjectFileBase::begin_libraries_needed() const { // TODO: implement - report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); + report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase"); } -library_iterator MachOObjectFile::end_libraries_needed() const { +library_iterator MachOObjectFileBase::end_libraries_needed() const { // TODO: implement - report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); + report_fatal_error("Needed libraries unimplemented in MachOObjectFileBase"); } -StringRef MachOObjectFile::getLoadName() const { +StringRef MachOObjectFileBase::getLoadName() const { // TODO: Implement - report_fatal_error("get_load_name() unimplemented in MachOObjectFile"); + report_fatal_error("get_load_name() unimplemented in MachOObjectFileBase"); } /*===-- Sections ----------------------------------------------------------===*/ -void MachOObjectFile::moveToNextSection(DataRefImpl &DRI) const { - uint32_t LoadCommandCount = getHeader()->NumLoadCommands; - while (DRI.d.a < LoadCommandCount) { - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); - if (Command->Type == macho::LCT_Segment) { - const MachOFormat::SegmentLoadCommand<false> *SegmentLoadCmd = - reinterpret_cast<const MachOFormat::SegmentLoadCommand<false>*>(Command); - if (DRI.d.b < SegmentLoadCmd->NumSections) - return; - } else if (Command->Type == macho::LCT_Segment64) { - const MachOFormat::SegmentLoadCommand<true> *SegmentLoadCmd = - reinterpret_cast<const MachOFormat::SegmentLoadCommand<true>*>(Command); - if (DRI.d.b < SegmentLoadCmd->NumSections) - return; - } - - DRI.d.a++; - DRI.d.b = 0; - } -} - -error_code MachOObjectFile::getSectionNext(DataRefImpl DRI, - SectionRef &Result) const { - DRI.d.b++; - moveToNextSection(DRI); - Result = SectionRef(DRI, this); - return object_error::success; -} - -const MachOFormat::Section<false> * -MachOObjectFile::getSection(DataRefImpl DRI) const { - assert(!is64Bit()); - const MachOFormat::SectionBase *Addr = getSectionBase(DRI); - return reinterpret_cast<const MachOFormat::Section<false>*>(Addr); -} - -std::size_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { +std::size_t MachOObjectFileBase::getSectionIndex(DataRefImpl Sec) const { SectionList::const_iterator loc = std::find(Sections.begin(), Sections.end(), Sec); assert(loc != Sections.end() && "Sec is not a valid section!"); return std::distance(Sections.begin(), loc); } -const MachOFormat::SectionBase* -MachOObjectFile::getSectionBase(DataRefImpl DRI) const { - const MachOFormat::LoadCommand *Command = getLoadCommandInfo(DRI.d.a); +const MachOObjectFileBase::SectionBase* +MachOObjectFileBase::getSectionBase(DataRefImpl DRI) const { + const LoadCommand *Command = getLoadCommandInfo(DRI.d.a); uintptr_t CommandAddr = reinterpret_cast<uintptr_t>(Command); bool Is64 = is64Bit(); @@ -487,14 +320,7 @@ MachOObjectFile::getSectionBase(DataRefImpl DRI) const { sizeof(MachOFormat::Section<false>); uintptr_t SectionAddr = CommandAddr + SegmentLoadSize + DRI.d.b * SectionSize; - return reinterpret_cast<const MachOFormat::SectionBase*>(SectionAddr); -} - -const MachOFormat::Section<true> * -MachOObjectFile::getSection64(DataRefImpl DRI) const { - assert(is64Bit()); - const MachOFormat::SectionBase *Addr = getSectionBase(DRI); - return reinterpret_cast<const MachOFormat::Section<true>*>(Addr); + return reinterpret_cast<const SectionBase*>(SectionAddr); } static StringRef parseSegmentOrSectionName(const char *P) { @@ -505,136 +331,61 @@ static StringRef parseSegmentOrSectionName(const char *P) { return StringRef(P, 16); } -ArrayRef<char> MachOObjectFile::getSectionRawName(DataRefImpl DRI) const { - const MachOFormat::SectionBase *Base = getSectionBase(DRI); +ArrayRef<char> MachOObjectFileBase::getSectionRawName(DataRefImpl DRI) const { + const SectionBase *Base = getSectionBase(DRI); return ArrayRef<char>(Base->Name); } -error_code MachOObjectFile::getSectionName(DataRefImpl DRI, - StringRef &Result) const { +error_code MachOObjectFileBase::getSectionName(DataRefImpl DRI, + StringRef &Result) const { ArrayRef<char> Raw = getSectionRawName(DRI); Result = parseSegmentOrSectionName(Raw.data()); return object_error::success; } ArrayRef<char> -MachOObjectFile::getSectionRawFinalSegmentName(DataRefImpl Sec) const { - const MachOFormat::SectionBase *Base = getSectionBase(Sec); +MachOObjectFileBase::getSectionRawFinalSegmentName(DataRefImpl Sec) const { + const SectionBase *Base = getSectionBase(Sec); return ArrayRef<char>(Base->SegmentName); } -StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl DRI) const { +StringRef +MachOObjectFileBase::getSectionFinalSegmentName(DataRefImpl DRI) const { ArrayRef<char> Raw = getSectionRawFinalSegmentName(DRI); return parseSegmentOrSectionName(Raw.data()); } -error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, - uint64_t &Result) const { - if (is64Bit()) { - const MachOFormat::Section<true> *Sect = getSection64(DRI); - Result = Sect->Address; - } else { - const MachOFormat::Section<false> *Sect = getSection(DRI); - Result = Sect->Address; - } - return object_error::success; -} - -error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, - uint64_t &Result) const { - if (is64Bit()) { - const MachOFormat::Section<true> *Sect = getSection64(DRI); - Result = Sect->Size; - } else { - const MachOFormat::Section<false> *Sect = getSection(DRI); - Result = Sect->Size; - } - return object_error::success; -} - -error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, - StringRef &Result) const { - if (is64Bit()) { - const MachOFormat::Section<true> *Sect = getSection64(DRI); - Result = getData(Sect->Offset, Sect->Size); - } else { - const MachOFormat::Section<false> *Sect = getSection(DRI); - Result = getData(Sect->Offset, Sect->Size); - } - return object_error::success; -} - -error_code MachOObjectFile::getSectionAlignment(DataRefImpl DRI, - uint64_t &Result) const { - if (is64Bit()) { - const MachOFormat::Section<true> *Sect = getSection64(DRI); - Result = uint64_t(1) << Sect->Align; - } else { - const MachOFormat::Section<false> *Sect = getSection(DRI); - Result = uint64_t(1) << Sect->Align; - } - return object_error::success; -} - -error_code MachOObjectFile::isSectionText(DataRefImpl DRI, - bool &Result) const { - if (is64Bit()) { - const MachOFormat::Section<true> *Sect = getSection64(DRI); - Result = Sect->Flags & macho::SF_PureInstructions; - } else { - const MachOFormat::Section<false> *Sect = getSection(DRI); - Result = Sect->Flags & macho::SF_PureInstructions; - } - return object_error::success; -} - -error_code MachOObjectFile::isSectionData(DataRefImpl DRI, - bool &Result) const { +error_code MachOObjectFileBase::isSectionData(DataRefImpl DRI, + bool &Result) const { // FIXME: Unimplemented. Result = false; return object_error::success; } -error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, - bool &Result) const { +error_code MachOObjectFileBase::isSectionBSS(DataRefImpl DRI, + bool &Result) const { // FIXME: Unimplemented. Result = false; return object_error::success; } -error_code MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sec, - bool &Result) const { +error_code +MachOObjectFileBase::isSectionRequiredForExecution(DataRefImpl Sec, + bool &Result) const { // FIXME: Unimplemented. Result = true; return object_error::success; } -error_code MachOObjectFile::isSectionVirtual(DataRefImpl Sec, - bool &Result) const { +error_code MachOObjectFileBase::isSectionVirtual(DataRefImpl Sec, + bool &Result) const { // FIXME: Unimplemented. Result = false; return object_error::success; } -error_code MachOObjectFile::isSectionZeroInit(DataRefImpl DRI, - bool &Result) const { - if (is64Bit()) { - const MachOFormat::Section<true> *Sect = getSection64(DRI); - unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType; - Result = (SectionType == MachO::SectionTypeZeroFill || - SectionType == MachO::SectionTypeZeroFillLarge); - } else { - const MachOFormat::Section<false> *Sect = getSection(DRI); - unsigned SectionType = Sect->Flags & MachO::SectionFlagMaskSectionType; - Result = (SectionType == MachO::SectionTypeZeroFill || - SectionType == MachO::SectionTypeZeroFillLarge); - } - - return object_error::success; -} - -error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec, - bool &Result) const { +error_code MachOObjectFileBase::isSectionReadOnlyData(DataRefImpl Sec, + bool &Result) const { // Consider using the code from isSectionText to look for __const sections. // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS // to use section attributes to distinguish code from data. @@ -644,64 +395,13 @@ error_code MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec, return object_error::success; } -error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, - DataRefImpl Symb, - bool &Result) const { - SymbolRef::Type ST; - getSymbolType(Symb, ST); - if (ST == SymbolRef::ST_Unknown) { - Result = false; - return object_error::success; - } - - uint64_t SectBegin, SectEnd; - getSectionAddress(Sec, SectBegin); - getSectionSize(Sec, SectEnd); - SectEnd += SectBegin; - - if (is64Bit()) { - const MachOFormat::SymbolTableEntry<true> *Entry = - getSymbol64TableEntry(Symb); - uint64_t SymAddr= Entry->Value; - Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); - } else { - const MachOFormat::SymbolTableEntry<false> *Entry = - getSymbolTableEntry(Symb); - uint64_t SymAddr= Entry->Value; - Result = (SymAddr >= SectBegin) && (SymAddr < SectEnd); - } - - return object_error::success; -} - -relocation_iterator MachOObjectFile::getSectionRelBegin(DataRefImpl Sec) const { +relocation_iterator MachOObjectFileBase::getSectionRelBegin(DataRefImpl Sec) const { DataRefImpl ret; ret.d.b = getSectionIndex(Sec); return relocation_iterator(RelocationRef(ret, this)); } -relocation_iterator MachOObjectFile::getSectionRelEnd(DataRefImpl Sec) const { - uint32_t last_reloc; - if (is64Bit()) { - const MachOFormat::Section<true> *Sect = getSection64(Sec); - last_reloc = Sect->NumRelocationTableEntries; - } else { - const MachOFormat::Section<false> *Sect = getSection(Sec); - last_reloc = Sect->NumRelocationTableEntries; - } - DataRefImpl ret; - ret.d.a = last_reloc; - ret.d.b = getSectionIndex(Sec); - return relocation_iterator(RelocationRef(ret, this)); -} - -section_iterator MachOObjectFile::begin_sections() const { - DataRefImpl DRI; - moveToNextSection(DRI); - return section_iterator(SectionRef(DRI, this)); -} - -section_iterator MachOObjectFile::end_sections() const { +section_iterator MachOObjectFileBase::end_sections() const { DataRefImpl DRI; DRI.d.a = getHeader()->NumLoadCommands; return section_iterator(SectionRef(DRI, this)); @@ -709,208 +409,12 @@ section_iterator MachOObjectFile::end_sections() const { /*===-- Relocations -------------------------------------------------------===*/ -const MachOFormat::RelocationEntry * -MachOObjectFile::getRelocation(DataRefImpl Rel) const { - uint32_t relOffset; - if (is64Bit()) { - const MachOFormat::Section<true> *Sect = getSection64(Sections[Rel.d.b]); - relOffset = Sect->RelocationTableOffset; - } else { - const MachOFormat::Section<false> *Sect = getSection(Sections[Rel.d.b]); - relOffset = Sect->RelocationTableOffset; - } - uint64_t Offset = relOffset + Rel.d.a * sizeof(MachOFormat::RelocationEntry); - StringRef Data = getData(Offset, sizeof(MachOFormat::RelocationEntry)); - return reinterpret_cast<const MachOFormat::RelocationEntry*>(Data.data()); -} - -error_code MachOObjectFile::getRelocationNext(DataRefImpl Rel, - RelocationRef &Res) const { +error_code MachOObjectFileBase::getRelocationNext(DataRefImpl Rel, + RelocationRef &Res) const { ++Rel.d.a; Res = RelocationRef(Rel, this); return object_error::success; } -error_code MachOObjectFile::getRelocationAddress(DataRefImpl Rel, - uint64_t &Res) const { - const uint8_t* sectAddress = 0; - if (is64Bit()) { - const MachOFormat::Section<true> *Sect = getSection64(Sections[Rel.d.b]); - sectAddress += Sect->Address; - } else { - const MachOFormat::Section<false> *Sect = getSection(Sections[Rel.d.b]); - sectAddress += Sect->Address; - } - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - - unsigned Arch = getArch(); - bool isScattered = (Arch != Triple::x86_64) && - (RE->Word0 & macho::RF_Scattered); - uint64_t RelAddr = 0; - if (isScattered) - RelAddr = RE->Word0 & 0xFFFFFF; - else - RelAddr = RE->Word0; - - Res = reinterpret_cast<uintptr_t>(sectAddress + RelAddr); - return object_error::success; -} -error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, - uint64_t &Res) const { - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - - unsigned Arch = getArch(); - bool isScattered = (Arch != Triple::x86_64) && - (RE->Word0 & macho::RF_Scattered); - if (isScattered) - Res = RE->Word0 & 0xFFFFFF; - else - Res = RE->Word0; - return object_error::success; -} -error_code MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, - SymbolRef &Res) const { - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - uint32_t SymbolIdx = RE->Word1 & 0xffffff; - bool isExtern = (RE->Word1 >> 27) & 1; - - DataRefImpl Sym; - moveToNextSymbol(Sym); - if (isExtern) { - for (unsigned i = 0; i < SymbolIdx; i++) { - Sym.d.b++; - moveToNextSymbol(Sym); - assert(Sym.d.a < getHeader()->NumLoadCommands && - "Relocation symbol index out of range!"); - } - } - Res = SymbolRef(Sym, this); - return object_error::success; -} -error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, - uint64_t &Res) const { - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - Res = RE->Word0; - Res <<= 32; - Res |= RE->Word1; - return object_error::success; -} -error_code MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const { - // TODO: Support scattered relocations. - StringRef res; - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - - unsigned Arch = getArch(); - bool isScattered = (Arch != Triple::x86_64) && - (RE->Word0 & macho::RF_Scattered); - - unsigned r_type; - if (isScattered) - r_type = (RE->Word0 >> 24) & 0xF; - else - r_type = (RE->Word1 >> 28) & 0xF; - - switch (Arch) { - case Triple::x86: { - static const char *const Table[] = { - "GENERIC_RELOC_VANILLA", - "GENERIC_RELOC_PAIR", - "GENERIC_RELOC_SECTDIFF", - "GENERIC_RELOC_PB_LA_PTR", - "GENERIC_RELOC_LOCAL_SECTDIFF", - "GENERIC_RELOC_TLV" }; - - if (r_type > 6) - res = "Unknown"; - else - res = Table[r_type]; - break; - } - case Triple::x86_64: { - static const char *const Table[] = { - "X86_64_RELOC_UNSIGNED", - "X86_64_RELOC_SIGNED", - "X86_64_RELOC_BRANCH", - "X86_64_RELOC_GOT_LOAD", - "X86_64_RELOC_GOT", - "X86_64_RELOC_SUBTRACTOR", - "X86_64_RELOC_SIGNED_1", - "X86_64_RELOC_SIGNED_2", - "X86_64_RELOC_SIGNED_4", - "X86_64_RELOC_TLV" }; - - if (r_type > 9) - res = "Unknown"; - else - res = Table[r_type]; - break; - } - case Triple::arm: { - static const char *const Table[] = { - "ARM_RELOC_VANILLA", - "ARM_RELOC_PAIR", - "ARM_RELOC_SECTDIFF", - "ARM_RELOC_LOCAL_SECTDIFF", - "ARM_RELOC_PB_LA_PTR", - "ARM_RELOC_BR24", - "ARM_THUMB_RELOC_BR22", - "ARM_THUMB_32BIT_BRANCH", - "ARM_RELOC_HALF", - "ARM_RELOC_HALF_SECTDIFF" }; - - if (r_type > 9) - res = "Unknown"; - else - res = Table[r_type]; - break; - } - case Triple::ppc: { - static const char *const Table[] = { - "PPC_RELOC_VANILLA", - "PPC_RELOC_PAIR", - "PPC_RELOC_BR14", - "PPC_RELOC_BR24", - "PPC_RELOC_HI16", - "PPC_RELOC_LO16", - "PPC_RELOC_HA16", - "PPC_RELOC_LO14", - "PPC_RELOC_SECTDIFF", - "PPC_RELOC_PB_LA_PTR", - "PPC_RELOC_HI16_SECTDIFF", - "PPC_RELOC_LO16_SECTDIFF", - "PPC_RELOC_HA16_SECTDIFF", - "PPC_RELOC_JBSR", - "PPC_RELOC_LO14_SECTDIFF", - "PPC_RELOC_LOCAL_SECTDIFF" }; - - res = Table[r_type]; - break; - } - case Triple::UnknownArch: - res = "Unknown"; - break; - } - Result.append(res.begin(), res.end()); - return object_error::success; -} -error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, - int64_t &Res) const { - const MachOFormat::RelocationEntry *RE = getRelocation(Rel); - bool isExtern = (RE->Word1 >> 27) & 1; - Res = 0; - if (!isExtern) { - const uint8_t* sectAddress = base(); - if (is64Bit()) { - const MachOFormat::Section<true> *Sect = getSection64(Sections[Rel.d.b]); - sectAddress += Sect->Offset; - } else { - const MachOFormat::Section<false> *Sect = getSection(Sections[Rel.d.b]); - sectAddress += Sect->Offset; - } - Res = reinterpret_cast<uintptr_t>(sectAddress); - } - return object_error::success; -} // Helper to advance a section or symbol iterator multiple increments at a time. template<class T> @@ -928,9 +432,9 @@ void advanceTo(T &it, size_t Val) { report_fatal_error(ec.message()); } -void MachOObjectFile::printRelocationTargetName( - const MachOFormat::RelocationEntry *RE, - raw_string_ostream &fmt) const { +void +MachOObjectFileBase::printRelocationTargetName(const RelocationEntry *RE, + raw_string_ostream &fmt) const { unsigned Arch = getArch(); bool isScattered = (Arch != Triple::x86_64) && (RE->Word0 & macho::RF_Scattered); @@ -998,270 +502,24 @@ void MachOObjectFile::printRe |