diff options
author | Eric Christopher <echristo@apple.com> | 2011-04-03 22:53:19 +0000 |
---|---|---|
committer | Eric Christopher <echristo@apple.com> | 2011-04-03 22:53:19 +0000 |
commit | 539d8d8a72995d08afe7b986fe98a1dc7fec4b0a (patch) | |
tree | e2a279ac67ecb0a4297e67753e0a608a73ae1af0 /lib/Object | |
parent | e243fd9e2be8897c9350650b724d7eda2f607f8f (diff) |
Assorted bugfixes in object file handling:
- Adds support for sniffing PE/COFF files on win32 (.exe and .dll)
which are COFF files that have an MS-DOS compatibility stub on
the front of them.
- Fixes a bug in the COFFObjectFile's support for the Microsoft COFF
extension for long symbol names, wherein it was attempting to parse
the leading '/' in an extended symbol name reference as part of the
integer offset.
- Fixes bugs in COFFObjectFile and ELFObjectFile wherein section
and symbol iterators were being returned with uninitialized bytes;
the type DataRefImpl is a union between 2 32-bit words (d.a and d.b)
and a single intptr_t word (p). Only p was being initialized, so in
32-bit builds the result would be iterators with random upper 32-bit
words in their DataRefImpls. This caused random failures when
seeking around in object files.
Patch by Graydon Hoare!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128799 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Object')
-rw-r--r-- | lib/Object/COFFObjectFile.cpp | 20 | ||||
-rw-r--r-- | lib/Object/ELFObjectFile.cpp | 2 |
2 files changed, 20 insertions, 2 deletions
diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index cfee82a0b2..30709f176b 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -91,6 +91,7 @@ extern char coff_coff_section_layout_static_assert namespace { class COFFObjectFile : public ObjectFile { private: + uint64_t HeaderOff; const coff_file_header *Header; const coff_section *SectionTable; const coff_symbol *SymbolTable; @@ -256,7 +257,7 @@ StringRef COFFObjectFile::getSectionName(DataRefImpl Sec) const { // Check for string table entry. First byte is '/'. if (name[0] == '/') { uint32_t Offset; - name.getAsInteger(10, Offset); + name.substr(1).getAsInteger(10, Offset); return StringRef(getString(Offset)); } @@ -287,9 +288,20 @@ bool COFFObjectFile::isSectionText(DataRefImpl Sec) const { COFFObjectFile::COFFObjectFile(MemoryBuffer *Object) : ObjectFile(Object) { - Header = reinterpret_cast<const coff_file_header *>(base); + + HeaderOff = 0; + + if (base[0] == 0x4d && base[1] == 0x5a) { + // PE/COFF, seek through MS-DOS compatibility stub and 4-byte + // PE signature to find 'normal' COFF header. + HeaderOff += *reinterpret_cast<const ulittle32_t *>(base + 0x3c); + HeaderOff += 4; + } + + Header = reinterpret_cast<const coff_file_header *>(base + HeaderOff); SectionTable = reinterpret_cast<const coff_section *>( base + + HeaderOff + sizeof(coff_file_header) + Header->SizeOfOptionalHeader); SymbolTable = @@ -303,6 +315,7 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object) ObjectFile::symbol_iterator COFFObjectFile::begin_symbols() const { DataRefImpl ret; + memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast<intptr_t>(SymbolTable); return symbol_iterator(SymbolRef(ret, this)); } @@ -310,18 +323,21 @@ ObjectFile::symbol_iterator COFFObjectFile::begin_symbols() const { ObjectFile::symbol_iterator COFFObjectFile::end_symbols() const { // The symbol table ends where the string table begins. DataRefImpl ret; + memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast<intptr_t>(StringTable); return symbol_iterator(SymbolRef(ret, this)); } ObjectFile::section_iterator COFFObjectFile::begin_sections() const { DataRefImpl ret; + memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast<intptr_t>(SectionTable); return section_iterator(SectionRef(ret, this)); } ObjectFile::section_iterator COFFObjectFile::end_sections() const { DataRefImpl ret; + memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast<intptr_t>(SectionTable + Header->NumberOfSections); return section_iterator(SectionRef(ret, this)); } diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index 682be770f4..d2a2726ce7 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -547,6 +547,7 @@ template<support::endianness target_endianness, bool is64Bits> ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits> ::begin_sections() const { DataRefImpl ret; + memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast<intptr_t>(base + Header->e_shoff); return section_iterator(SectionRef(ret, this)); } @@ -555,6 +556,7 @@ template<support::endianness target_endianness, bool is64Bits> ObjectFile::section_iterator ELFObjectFile<target_endianness, is64Bits> ::end_sections() const { DataRefImpl ret; + memset(&ret, 0, sizeof(DataRefImpl)); ret.p = reinterpret_cast<intptr_t>(base + Header->e_shoff + (Header->e_shentsize * Header->e_shnum)); |