mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-03 08:51:43 +00:00
[Object, COFF] An import data directory might not consist soley of imports
The last import is the penultimate entry, the last entry is nulled out. Data beyond the null entry should not be considered to hold import entries. This fixes PR28302. N.B. I am working on a reduced testcase, the one in PR28302 is too large. llvm-svn: 273790
This commit is contained in:
parent
0bf7c0b1b7
commit
4bf2509bdc
@ -634,7 +634,6 @@ private:
|
||||
const char *StringTable;
|
||||
uint32_t StringTableSize;
|
||||
const import_directory_table_entry *ImportDirectory;
|
||||
uint32_t NumberOfImportDirectory;
|
||||
const delay_import_directory_table_entry *DelayImportDirectory;
|
||||
uint32_t NumberOfDelayImportDirectory;
|
||||
const export_directory_table_entry *ExportDirectory;
|
||||
@ -911,9 +910,6 @@ public:
|
||||
std::error_code
|
||||
getImportTableEntry(const import_directory_table_entry *&Result) const;
|
||||
|
||||
std::error_code
|
||||
getImportLookupEntry(const import_lookup_table_entry32 *&Result) const;
|
||||
|
||||
private:
|
||||
const import_directory_table_entry *ImportTable;
|
||||
uint32_t Index;
|
||||
@ -985,7 +981,9 @@ public:
|
||||
void moveNext();
|
||||
|
||||
std::error_code getSymbolName(StringRef &Result) const;
|
||||
std::error_code isOrdinal(bool &Result) const;
|
||||
std::error_code getOrdinal(uint16_t &Result) const;
|
||||
std::error_code getHintNameRVA(uint32_t &Result) const;
|
||||
|
||||
private:
|
||||
const import_lookup_table_entry32 *Entry32;
|
||||
|
@ -529,15 +529,14 @@ std::error_code COFFObjectFile::initImportTablePtr() {
|
||||
return std::error_code();
|
||||
|
||||
uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
|
||||
// -1 because the last entry is the null entry.
|
||||
NumberOfImportDirectory = DataEntry->Size /
|
||||
sizeof(import_directory_table_entry) - 1;
|
||||
|
||||
// Find the section that contains the RVA. This is needed because the RVA is
|
||||
// the import table's memory address which is different from its file offset.
|
||||
uintptr_t IntPtr = 0;
|
||||
if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr))
|
||||
return EC;
|
||||
if (std::error_code EC = checkOffset(Data, IntPtr, DataEntry->Size))
|
||||
return EC;
|
||||
ImportDirectory = reinterpret_cast<
|
||||
const import_directory_table_entry *>(IntPtr);
|
||||
return std::error_code();
|
||||
@ -631,7 +630,7 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
|
||||
COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
|
||||
DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),
|
||||
SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),
|
||||
ImportDirectory(nullptr), NumberOfImportDirectory(0),
|
||||
ImportDirectory(nullptr),
|
||||
DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0),
|
||||
ExportDirectory(nullptr), BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
|
||||
DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr) {
|
||||
@ -771,13 +770,17 @@ basic_symbol_iterator COFFObjectFile::symbol_end_impl() const {
|
||||
}
|
||||
|
||||
import_directory_iterator COFFObjectFile::import_directory_begin() const {
|
||||
if (!ImportDirectory)
|
||||
return import_directory_end();
|
||||
if (ImportDirectory[0].ImportLookupTableRVA == 0)
|
||||
return import_directory_end();
|
||||
return import_directory_iterator(
|
||||
ImportDirectoryEntryRef(ImportDirectory, 0, this));
|
||||
}
|
||||
|
||||
import_directory_iterator COFFObjectFile::import_directory_end() const {
|
||||
return import_directory_iterator(
|
||||
ImportDirectoryEntryRef(ImportDirectory, NumberOfImportDirectory, this));
|
||||
ImportDirectoryEntryRef(nullptr, -1, this));
|
||||
}
|
||||
|
||||
delay_import_directory_iterator
|
||||
@ -1198,12 +1201,15 @@ operator==(const ImportDirectoryEntryRef &Other) const {
|
||||
|
||||
void ImportDirectoryEntryRef::moveNext() {
|
||||
++Index;
|
||||
if (ImportTable[Index].ImportLookupTableRVA == 0) {
|
||||
Index = -1;
|
||||
ImportTable = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::error_code ImportDirectoryEntryRef::getImportTableEntry(
|
||||
const import_directory_table_entry *&Result) const {
|
||||
Result = ImportTable + Index;
|
||||
return std::error_code();
|
||||
return getObject(Result, OwningObject->Data, ImportTable + Index);
|
||||
}
|
||||
|
||||
static imported_symbol_iterator
|
||||
@ -1280,16 +1286,6 @@ ImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const {
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code ImportDirectoryEntryRef::getImportLookupEntry(
|
||||
const import_lookup_table_entry32 *&Result) const {
|
||||
uintptr_t IntPtr = 0;
|
||||
uint32_t RVA = ImportTable[Index].ImportLookupTableRVA;
|
||||
if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
|
||||
return EC;
|
||||
Result = reinterpret_cast<const import_lookup_table_entry32 *>(IntPtr);
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
bool DelayImportDirectoryEntryRef::
|
||||
operator==(const DelayImportDirectoryEntryRef &Other) const {
|
||||
return Table == Other.Table && Index == Other.Index;
|
||||
@ -1473,6 +1469,22 @@ ImportedSymbolRef::getSymbolName(StringRef &Result) const {
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code ImportedSymbolRef::isOrdinal(bool &Result) const {
|
||||
if (Entry32)
|
||||
Result = Entry32[Index].isOrdinal();
|
||||
else
|
||||
Result = Entry64[Index].isOrdinal();
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code ImportedSymbolRef::getHintNameRVA(uint32_t &Result) const {
|
||||
if (Entry32)
|
||||
Result = Entry32[Index].getHintNameRVA();
|
||||
else
|
||||
Result = Entry64[Index].getHintNameRVA();
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
|
||||
uint32_t RVA;
|
||||
if (Entry32) {
|
||||
|
@ -352,11 +352,11 @@ static void printImportTables(const COFFObjectFile *Obj) {
|
||||
if (I == E)
|
||||
return;
|
||||
outs() << "The Import Tables:\n";
|
||||
for (; I != E; I = ++I) {
|
||||
for (const ImportDirectoryEntryRef &DirRef : Obj->import_directories()) {
|
||||
const import_directory_table_entry *Dir;
|
||||
StringRef Name;
|
||||
if (I->getImportTableEntry(Dir)) return;
|
||||
if (I->getName(Name)) return;
|
||||
if (DirRef.getImportTableEntry(Dir)) return;
|
||||
if (DirRef.getName(Name)) return;
|
||||
|
||||
outs() << format(" lookup %08x time %08x fwd %08x name %08x addr %08x\n\n",
|
||||
static_cast<uint32_t>(Dir->ImportLookupTableRVA),
|
||||
@ -366,17 +366,23 @@ static void printImportTables(const COFFObjectFile *Obj) {
|
||||
static_cast<uint32_t>(Dir->ImportAddressTableRVA));
|
||||
outs() << " DLL Name: " << Name << "\n";
|
||||
outs() << " Hint/Ord Name\n";
|
||||
const import_lookup_table_entry32 *entry;
|
||||
if (I->getImportLookupEntry(entry))
|
||||
return;
|
||||
for (; entry->Data; ++entry) {
|
||||
if (entry->isOrdinal()) {
|
||||
outs() << format(" % 6d\n", entry->getOrdinal());
|
||||
for (const ImportedSymbolRef &Entry : DirRef.imported_symbols()) {
|
||||
bool IsOrdinal;
|
||||
if (Entry.isOrdinal(IsOrdinal))
|
||||
return;
|
||||
if (IsOrdinal) {
|
||||
uint16_t Ordinal;
|
||||
if (Entry.getOrdinal(Ordinal))
|
||||
return;
|
||||
outs() << format(" % 6d\n", Ordinal);
|
||||
continue;
|
||||
}
|
||||
uint32_t HintNameRVA;
|
||||
if (Entry.getHintNameRVA(HintNameRVA))
|
||||
return;
|
||||
uint16_t Hint;
|
||||
StringRef Name;
|
||||
if (Obj->getHintName(entry->getHintNameRVA(), Hint, Name))
|
||||
if (Obj->getHintName(HintNameRVA, Hint, Name))
|
||||
return;
|
||||
outs() << format(" % 6d ", Hint) << Name << "\n";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user