diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index a87f7651a2e..dcc58b06e22 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -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; diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 878b93fcda0..0f790086cfc 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -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(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) { diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index 4f1b9b11913..3ec6a1f7375 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -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(Dir->ImportLookupTableRVA), @@ -366,17 +366,23 @@ static void printImportTables(const COFFObjectFile *Obj) { static_cast(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"; }