diff options
Diffstat (limited to 'lib/Object')
-rw-r--r-- | lib/Object/COFFObjectFile.cpp | 17 | ||||
-rw-r--r-- | lib/Object/ELFObjectFile.cpp | 12 | ||||
-rw-r--r-- | lib/Object/MachOObjectFile.cpp | 187 |
3 files changed, 176 insertions, 40 deletions
diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 18aad9a..07de6bc 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -117,7 +117,7 @@ error_code COFFObjectFile::getSymbolNext(DataRefImpl Symb, error_code COFFObjectFile::getSymbolAddress(DataRefImpl Symb, uint64_t &Result) const { const coff_symbol *symb = toSymb(Symb); - const coff_section *Section; + const coff_section *Section = NULL; if (error_code ec = getSection(symb->SectionNumber, Section)) return ec; char Type; @@ -138,7 +138,7 @@ error_code COFFObjectFile::getSymbolSize(DataRefImpl Symb, // in the same section as this symbol, and looking for either the next // symbol, or the end of the section. const coff_symbol *symb = toSymb(Symb); - const coff_section *Section; + const coff_section *Section = NULL; if (error_code ec = getSection(symb->SectionNumber, Section)) return ec; char Type; @@ -171,7 +171,7 @@ error_code COFFObjectFile::getSymbolNMTypeChar(DataRefImpl Symb, uint32_t Characteristics = 0; if (symb->SectionNumber > 0) { - const coff_section *Section; + const coff_section *Section = NULL; if (error_code ec = getSection(symb->SectionNumber, Section)) return ec; Characteristics = Section->Characteristics; @@ -293,6 +293,14 @@ error_code COFFObjectFile::isSectionText(DataRefImpl Sec, return object_error::success; } +error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl Sec, + DataRefImpl Symb, + bool &Result) const { + // FIXME: Unimplemented. + Result = false; + return object_error::success; +} + COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) : ObjectFile(Binary::isCOFF, Object, ec) { // Check that we at least have enough room for a header. @@ -309,8 +317,7 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &ec) if (!checkSize(Data, ec, 0x3c + 8)) return; HeaderStart += *reinterpret_cast<const ulittle32_t *>(base() + 0x3c); // Check the PE header. ("PE\0\0") - if (StringRef(reinterpret_cast<const char *>(base() + HeaderStart), 4) - != "PE\0\0") { + if (std::memcmp(base() + HeaderStart, "PE\0\0", 4) != 0) { ec = object_error::parse_failed; return; } diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index edf9824..e2ff4df 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -235,6 +235,8 @@ protected: virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; + virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, + bool &Result) const; public: ELFObjectFile(MemoryBuffer *Object, error_code &ec); @@ -496,6 +498,16 @@ error_code ELFObjectFile<target_endianness, is64Bits> } template<support::endianness target_endianness, bool is64Bits> +error_code ELFObjectFile<target_endianness, is64Bits> + ::sectionContainsSymbol(DataRefImpl Sec, + DataRefImpl Symb, + bool &Result) const { + // FIXME: Unimplemented. + Result = false; + return object_error::success; +} + +template<support::endianness target_endianness, bool is64Bits> ELFObjectFile<target_endianness, is64Bits>::ELFObjectFile(MemoryBuffer *Object , error_code &ec) : ObjectFile(Binary::isELF, Object, ec) diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index 71f1f8c..26a6e13 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -60,6 +60,8 @@ protected: virtual error_code getSectionSize(DataRefImpl Sec, uint64_t &Res) const; virtual error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const; virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; + virtual error_code sectionContainsSymbol(DataRefImpl DRI, DataRefImpl S, + bool &Result) const; private: MachOObject *MachOObj; @@ -68,8 +70,12 @@ private: void moveToNextSection(DataRefImpl &DRI) const; void getSymbolTableEntry(DataRefImpl DRI, InMemoryStruct<macho::SymbolTableEntry> &Res) const; + void getSymbol64TableEntry(DataRefImpl DRI, + InMemoryStruct<macho::Symbol64TableEntry> &Res) const; void moveToNextSymbol(DataRefImpl &DRI) const; void getSection(DataRefImpl DRI, InMemoryStruct<macho::Section> &Res) const; + void getSection64(DataRefImpl DRI, + InMemoryStruct<macho::Section64> &Res) const; }; ObjectFile *ObjectFile::createMachOObjectFile(MemoryBuffer *Buffer) { @@ -114,6 +120,21 @@ void MachOObjectFile::getSymbolTableEntry(DataRefImpl DRI, Res); } +void MachOObjectFile::getSymbol64TableEntry(DataRefImpl DRI, + InMemoryStruct<macho::Symbol64TableEntry> &Res) const { + InMemoryStruct<macho::SymtabLoadCommand> SymtabLoadCmd; + LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + MachOObj->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); + + if (RegisteredStringTable != DRI.d.a) { + MachOObj->RegisterStringTable(*SymtabLoadCmd); + RegisteredStringTable = DRI.d.a; + } + + MachOObj->ReadSymbol64TableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, + Res); +} + error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI, SymbolRef &Result) const { @@ -125,17 +146,29 @@ error_code MachOObjectFile::getSymbolNext(DataRefImpl DRI, error_code MachOObjectFile::getSymbolName(DataRefImpl DRI, StringRef &Result) const { - InMemoryStruct<macho::SymbolTableEntry> Entry; - getSymbolTableEntry(DRI, Entry); - Result = MachOObj->getStringAtIndex(Entry->StringIndex); + if (MachOObj->is64Bit()) { + InMemoryStruct<macho::Symbol64TableEntry> Entry; + getSymbol64TableEntry(DRI, Entry); + Result = MachOObj->getStringAtIndex(Entry->StringIndex); + } else { + InMemoryStruct<macho::SymbolTableEntry> Entry; + getSymbolTableEntry(DRI, Entry); + Result = MachOObj->getStringAtIndex(Entry->StringIndex); + } return object_error::success; } error_code MachOObjectFile::getSymbolAddress(DataRefImpl DRI, uint64_t &Result) const { - InMemoryStruct<macho::SymbolTableEntry> Entry; - getSymbolTableEntry(DRI, Entry); - Result = Entry->Value; + if (MachOObj->is64Bit()) { + InMemoryStruct<macho::Symbol64TableEntry> Entry; + getSymbol64TableEntry(DRI, Entry); + Result = Entry->Value; + } else { + InMemoryStruct<macho::SymbolTableEntry> Entry; + getSymbolTableEntry(DRI, Entry); + Result = Entry->Value; + } return object_error::success; } @@ -147,11 +180,21 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI, error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, char &Result) const { - InMemoryStruct<macho::SymbolTableEntry> Entry; - getSymbolTableEntry(DRI, Entry); + uint8_t Type, Flags; + if (MachOObj->is64Bit()) { + InMemoryStruct<macho::Symbol64TableEntry> Entry; + getSymbol64TableEntry(DRI, Entry); + Type = Entry->Type; + Flags = Entry->Flags; + } else { + InMemoryStruct<macho::SymbolTableEntry> Entry; + getSymbolTableEntry(DRI, Entry); + Type = Entry->Type; + Flags = Entry->Flags; + } char Char; - switch (Entry->Type & macho::STF_TypeMask) { + switch (Type & macho::STF_TypeMask) { case macho::STT_Undefined: Char = 'u'; break; @@ -164,7 +207,7 @@ error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, break; } - if (Entry->Flags & (macho::STF_External | macho::STF_PrivateExtern)) + if (Flags & (macho::STF_External | macho::STF_PrivateExtern)) Char = toupper(Char); Result = Char; return object_error::success; @@ -172,9 +215,15 @@ error_code MachOObjectFile::getSymbolNMTypeChar(DataRefImpl DRI, error_code MachOObjectFile::isSymbolInternal(DataRefImpl DRI, bool &Result) const { - InMemoryStruct<macho::SymbolTableEntry> Entry; - getSymbolTableEntry(DRI, Entry); - Result = Entry->Flags & macho::STF_StabsEntryMask; + if (MachOObj->is64Bit()) { + InMemoryStruct<macho::Symbol64TableEntry> Entry; + getSymbol64TableEntry(DRI, Entry); + Result = Entry->Flags & macho::STF_StabsEntryMask; + } else { + InMemoryStruct<macho::SymbolTableEntry> Entry; + getSymbolTableEntry(DRI, Entry); + Result = Entry->Flags & macho::STF_StabsEntryMask; + } return object_error::success; } @@ -234,52 +283,120 @@ MachOObjectFile::getSection(DataRefImpl DRI, MachOObj->ReadSection(LCI, DRI.d.b, Res); } -error_code MachOObjectFile::getSectionName(DataRefImpl DRI, - StringRef &Result) const { - InMemoryStruct<macho::SegmentLoadCommand> SLC; +void +MachOObjectFile::getSection64(DataRefImpl DRI, + InMemoryStruct<macho::Section64> &Res) const { + InMemoryStruct<macho::Segment64LoadCommand> SLC; LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); - MachOObj->ReadSegmentLoadCommand(LCI, SLC); - InMemoryStruct<macho::Section> Sect; - MachOObj->ReadSection(LCI, DRI.d.b, Sect); + MachOObj->ReadSegment64LoadCommand(LCI, SLC); + MachOObj->ReadSection64(LCI, DRI.d.b, Res); +} +static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { + LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + if (LCI.Command.Type == macho::LCT_Segment64) + return true; + assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type."); + return false; +} + +error_code MachOObjectFile::getSectionName(DataRefImpl DRI, + StringRef &Result) const { + // FIXME: thread safety. static char result[34]; - strcpy(result, SLC->Name); - strcat(result, ","); - strcat(result, Sect->Name); + if (is64BitLoadCommand(MachOObj, DRI)) { + InMemoryStruct<macho::Segment64LoadCommand> SLC; + LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + MachOObj->ReadSegment64LoadCommand(LCI, SLC); + InMemoryStruct<macho::Section64> Sect; + MachOObj->ReadSection64(LCI, DRI.d.b, Sect); + + strcpy(result, Sect->SegmentName); + strcat(result, ","); + strcat(result, Sect->Name); + } else { + InMemoryStruct<macho::SegmentLoadCommand> SLC; + LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + MachOObj->ReadSegmentLoadCommand(LCI, SLC); + InMemoryStruct<macho::Section> Sect; + MachOObj->ReadSection(LCI, DRI.d.b, Sect); + + strcpy(result, Sect->SegmentName); + strcat(result, ","); + strcat(result, Sect->Name); + } Result = StringRef(result); return object_error::success; } error_code MachOObjectFile::getSectionAddress(DataRefImpl DRI, uint64_t &Result) const { - InMemoryStruct<macho::Section> Sect; - getSection(DRI, Sect); - Result = Sect->Address; + if (is64BitLoadCommand(MachOObj, DRI)) { + InMemoryStruct<macho::Section64> Sect; + getSection64(DRI, Sect); + Result = Sect->Address; + } else { + InMemoryStruct<macho::Section> Sect; + getSection(DRI, Sect); + Result = Sect->Address; + } return object_error::success; } error_code MachOObjectFile::getSectionSize(DataRefImpl DRI, uint64_t &Result) const { - InMemoryStruct<macho::Section> Sect; - getSection(DRI, Sect); - Result = Sect->Size; + if (is64BitLoadCommand(MachOObj, DRI)) { + InMemoryStruct<macho::Section64> Sect; + getSection64(DRI, Sect); + Result = Sect->Size; + } else { + InMemoryStruct<macho::Section> Sect; + getSection(DRI, Sect); + Result = Sect->Size; + } return object_error::success; } error_code MachOObjectFile::getSectionContents(DataRefImpl DRI, StringRef &Result) const { - InMemoryStruct<macho::Section> Sect; - getSection(DRI, Sect); - Result = MachOObj->getData(Sect->Offset, Sect->Size); + if (is64BitLoadCommand(MachOObj, DRI)) { + InMemoryStruct<macho::Section64> Sect; + getSection64(DRI, Sect); + Result = MachOObj->getData(Sect->Offset, Sect->Size); + } else { + InMemoryStruct<macho::Section> Sect; + getSection(DRI, Sect); + Result = MachOObj->getData(Sect->Offset, Sect->Size); + } return object_error::success; } error_code MachOObjectFile::isSectionText(DataRefImpl DRI, bool &Result) const { - InMemoryStruct<macho::SegmentLoadCommand> SLC; - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); - MachOObj->ReadSegmentLoadCommand(LCI, SLC); - Result = !strcmp(SLC->Name, "__TEXT"); + if (is64BitLoadCommand(MachOObj, DRI)) { + InMemoryStruct<macho::Section64> Sect; + getSection64(DRI, Sect); + Result = !strcmp(Sect->Name, "__text"); + } else { + InMemoryStruct<macho::Section> Sect; + getSection(DRI, Sect); + Result = !strcmp(Sect->Name, "__text"); + } + return object_error::success; +} + +error_code MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, + DataRefImpl Symb, + bool &Result) const { + if (MachOObj->is64Bit()) { + InMemoryStruct<macho::Symbol64TableEntry> Entry; + getSymbol64TableEntry(Symb, Entry); + Result = Entry->SectionIndex == 1 + Sec.d.a + Sec.d.b; + } else { + InMemoryStruct<macho::SymbolTableEntry> Entry; + getSymbolTableEntry(Symb, Entry); + Result = Entry->SectionIndex == 1 + Sec.d.a + Sec.d.b; + } return object_error::success; } |