llvm.org GIT mirror llvm / 6ea11a4
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273790 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 3 years ago
3 changed file(s) with 47 addition(s) and 31 deletion(s). Raw diff Collapse all Expand all
633633 const char *StringTable;
634634 uint32_t StringTableSize;
635635 const import_directory_table_entry *ImportDirectory;
636 uint32_t NumberOfImportDirectory;
637636 const delay_import_directory_table_entry *DelayImportDirectory;
638637 uint32_t NumberOfDelayImportDirectory;
639638 const export_directory_table_entry *ExportDirectory;
910909 std::error_code
911910 getImportTableEntry(const import_directory_table_entry *&Result) const;
912911
913 std::error_code
914 getImportLookupEntry(const import_lookup_table_entry32 *&Result) const;
915
916912 private:
917913 const import_directory_table_entry *ImportTable;
918914 uint32_t Index;
984980 void moveNext();
985981
986982 std::error_code getSymbolName(StringRef &Result) const;
983 std::error_code isOrdinal(bool &Result) const;
987984 std::error_code getOrdinal(uint16_t &Result) const;
985 std::error_code getHintNameRVA(uint32_t &Result) const;
988986
989987 private:
990988 const import_lookup_table_entry32 *Entry32;
528528 return std::error_code();
529529
530530 uint32_t ImportTableRva = DataEntry->RelativeVirtualAddress;
531 // -1 because the last entry is the null entry.
532 NumberOfImportDirectory = DataEntry->Size /
533 sizeof(import_directory_table_entry) - 1;
534531
535532 // Find the section that contains the RVA. This is needed because the RVA is
536533 // the import table's memory address which is different from its file offset.
537534 uintptr_t IntPtr = 0;
538535 if (std::error_code EC = getRvaPtr(ImportTableRva, IntPtr))
536 return EC;
537 if (std::error_code EC = checkOffset(Data, IntPtr, DataEntry->Size))
539538 return EC;
540539 ImportDirectory = reinterpret_cast<
541540 const import_directory_table_entry *>(IntPtr);
630629 COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),
631630 DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),
632631 SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),
633 ImportDirectory(nullptr), NumberOfImportDirectory(0),
632 ImportDirectory(nullptr),
634633 DelayImportDirectory(nullptr), NumberOfDelayImportDirectory(0),
635634 ExportDirectory(nullptr), BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),
636635 DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr) {
770769 }
771770
772771 import_directory_iterator COFFObjectFile::import_directory_begin() const {
772 if (!ImportDirectory)
773 return import_directory_end();
774 if (ImportDirectory[0].ImportLookupTableRVA == 0)
775 return import_directory_end();
773776 return import_directory_iterator(
774777 ImportDirectoryEntryRef(ImportDirectory, 0, this));
775778 }
776779
777780 import_directory_iterator COFFObjectFile::import_directory_end() const {
778781 return import_directory_iterator(
779 ImportDirectoryEntryRef(ImportDirectory, NumberOfImportDirectory, this));
782 ImportDirectoryEntryRef(nullptr, -1, this));
780783 }
781784
782785 delay_import_directory_iterator
11971200
11981201 void ImportDirectoryEntryRef::moveNext() {
11991202 ++Index;
1203 if (ImportTable[Index].ImportLookupTableRVA == 0) {
1204 Index = -1;
1205 ImportTable = nullptr;
1206 }
12001207 }
12011208
12021209 std::error_code ImportDirectoryEntryRef::getImportTableEntry(
12031210 const import_directory_table_entry *&Result) const {
1204 Result = ImportTable + Index;
1205 return std::error_code();
1211 return getObject(Result, OwningObject->Data, ImportTable + Index);
12061212 }
12071213
12081214 static imported_symbol_iterator
12761282 std::error_code
12771283 ImportDirectoryEntryRef::getImportAddressTableRVA(uint32_t &Result) const {
12781284 Result = ImportTable[Index].ImportAddressTableRVA;
1279 return std::error_code();
1280 }
1281
1282 std::error_code ImportDirectoryEntryRef::getImportLookupEntry(
1283 const import_lookup_table_entry32 *&Result) const {
1284 uintptr_t IntPtr = 0;
1285 uint32_t RVA = ImportTable[Index].ImportLookupTableRVA;
1286 if (std::error_code EC = OwningObject->getRvaPtr(RVA, IntPtr))
1287 return EC;
1288 Result = reinterpret_cast(IntPtr);
12891285 return std::error_code();
12901286 }
12911287
14691465 return EC;
14701466 // +2 because the first two bytes is hint.
14711467 Result = StringRef(reinterpret_cast(IntPtr + 2));
1468 return std::error_code();
1469 }
1470
1471 std::error_code ImportedSymbolRef::isOrdinal(bool &Result) const {
1472 if (Entry32)
1473 Result = Entry32[Index].isOrdinal();
1474 else
1475 Result = Entry64[Index].isOrdinal();
1476 return std::error_code();
1477 }
1478
1479 std::error_code ImportedSymbolRef::getHintNameRVA(uint32_t &Result) const {
1480 if (Entry32)
1481 Result = Entry32[Index].getHintNameRVA();
1482 else
1483 Result = Entry64[Index].getHintNameRVA();
14721484 return std::error_code();
14731485 }
14741486
351351 if (I == E)
352352 return;
353353 outs() << "The Import Tables:\n";
354 for (; I != E; I = ++I) {
354 for (const ImportDirectoryEntryRef &DirRef : Obj->import_directories()) {
355355 const import_directory_table_entry *Dir;
356356 StringRef Name;
357 if (I->getImportTableEntry(Dir)) return;
358 if (I->getName(Name)) return;
357 if (DirRef.getImportTableEntry(Dir)) return;
358 if (DirRef.getName(Name)) return;
359359
360360 outs() << format(" lookup %08x time %08x fwd %08x name %08x addr %08x\n\n",
361361 static_cast(Dir->ImportLookupTableRVA),
365365 static_cast(Dir->ImportAddressTableRVA));
366366 outs() << " DLL Name: " << Name << "\n";
367367 outs() << " Hint/Ord Name\n";
368 const import_lookup_table_entry32 *entry;
369 if (I->getImportLookupEntry(entry))
370 return;
371 for (; entry->Data; ++entry) {
372 if (entry->isOrdinal()) {
373 outs() << format(" % 6d\n", entry->getOrdinal());
368 for (const ImportedSymbolRef &Entry : DirRef.imported_symbols()) {
369 bool IsOrdinal;
370 if (Entry.isOrdinal(IsOrdinal))
371 return;
372 if (IsOrdinal) {
373 uint16_t Ordinal;
374 if (Entry.getOrdinal(Ordinal))
375 return;
376 outs() << format(" % 6d\n", Ordinal);
374377 continue;
375378 }
379 uint32_t HintNameRVA;
380 if (Entry.getHintNameRVA(HintNameRVA))
381 return;
376382 uint16_t Hint;
377383 StringRef Name;
378 if (Obj->getHintName(entry->getHintNameRVA(), Hint, Name))
384 if (Obj->getHintName(HintNameRVA, Hint, Name))
379385 return;
380386 outs() << format(" % 6d ", Hint) << Name << "\n";
381387 }