@@ -447,7 +447,8 @@ Error COFFObjectFile::initSymbolTablePtr() {
447
447
448
448
// Check that the string table is null terminated if has any in it.
449
449
if (StringTableSize > 4 && StringTable[StringTableSize - 1 ] != 0 )
450
- return errorCodeToError (object_error::parse_failed);
450
+ return createStringError (object_error::parse_failed,
451
+ " string table missing null terminator" );
451
452
return Error::success ();
452
453
}
453
454
@@ -469,7 +470,8 @@ Error COFFObjectFile::getVaPtr(uint64_t Addr, uintptr_t &Res) const {
469
470
}
470
471
471
472
// Returns the file offset for the given RVA.
472
- Error COFFObjectFile::getRvaPtr (uint32_t Addr, uintptr_t &Res) const {
473
+ Error COFFObjectFile::getRvaPtr (uint32_t Addr, uintptr_t &Res,
474
+ const char *ErrorContext) const {
473
475
for (const SectionRef &S : sections ()) {
474
476
const coff_section *Section = getCOFFSection (S);
475
477
uint32_t SectionStart = Section->VirtualAddress ;
@@ -481,11 +483,17 @@ Error COFFObjectFile::getRvaPtr(uint32_t Addr, uintptr_t &Res) const {
481
483
return Error::success ();
482
484
}
483
485
}
484
- return errorCodeToError (object_error::parse_failed);
486
+ if (ErrorContext)
487
+ return createStringError (object_error::parse_failed,
488
+ " RVA 0x%" PRIx32 " for %s not found" , Addr,
489
+ ErrorContext);
490
+ return createStringError (object_error::parse_failed,
491
+ " RVA 0x%" PRIx32 " not found" , Addr);
485
492
}
486
493
487
494
Error COFFObjectFile::getRvaAndSizeAsBytes (uint32_t RVA, uint32_t Size,
488
- ArrayRef<uint8_t > &Contents) const {
495
+ ArrayRef<uint8_t > &Contents,
496
+ const char *ErrorContext) const {
489
497
for (const SectionRef &S : sections ()) {
490
498
const coff_section *Section = getCOFFSection (S);
491
499
uint32_t SectionStart = Section->VirtualAddress ;
@@ -501,7 +509,12 @@ Error COFFObjectFile::getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size,
501
509
return Error::success ();
502
510
}
503
511
}
504
- return errorCodeToError (object_error::parse_failed);
512
+ if (ErrorContext)
513
+ return createStringError (object_error::parse_failed,
514
+ " RVA 0x%" PRIx32 " for %s not found" , RVA,
515
+ ErrorContext);
516
+ return createStringError (object_error::parse_failed,
517
+ " RVA 0x%" PRIx32 " not found" , RVA);
505
518
}
506
519
507
520
// Returns hint and name fields, assuming \p Rva is pointing to a Hint/Name
@@ -521,11 +534,12 @@ Error COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir,
521
534
const codeview::DebugInfo *&PDBInfo,
522
535
StringRef &PDBFileName) const {
523
536
ArrayRef<uint8_t > InfoBytes;
524
- if (Error E = getRvaAndSizeAsBytes (
525
- DebugDir->AddressOfRawData , DebugDir->SizeOfData , InfoBytes))
537
+ if (Error E =
538
+ getRvaAndSizeAsBytes (DebugDir->AddressOfRawData , DebugDir->SizeOfData ,
539
+ InfoBytes, " PDB info" ))
526
540
return E;
527
541
if (InfoBytes.size () < sizeof (*PDBInfo) + 1 )
528
- return errorCodeToError (object_error::parse_failed);
542
+ return createStringError (object_error::parse_failed, " PDB info too small " );
529
543
PDBInfo = reinterpret_cast <const codeview::DebugInfo *>(InfoBytes.data ());
530
544
InfoBytes = InfoBytes.drop_front (sizeof (*PDBInfo));
531
545
PDBFileName = StringRef (reinterpret_cast <const char *>(InfoBytes.data ()),
@@ -563,7 +577,7 @@ Error COFFObjectFile::initImportTablePtr() {
563
577
// Find the section that contains the RVA. This is needed because the RVA is
564
578
// the import table's memory address which is different from its file offset.
565
579
uintptr_t IntPtr = 0 ;
566
- if (Error E = getRvaPtr (ImportTableRva, IntPtr))
580
+ if (Error E = getRvaPtr (ImportTableRva, IntPtr, " import table " ))
567
581
return E;
568
582
if (Error E = checkOffset (Data, IntPtr, DataEntry->Size ))
569
583
return E;
@@ -586,7 +600,7 @@ Error COFFObjectFile::initDelayImportTablePtr() {
586
600
sizeof (delay_import_directory_table_entry) - 1 ;
587
601
588
602
uintptr_t IntPtr = 0 ;
589
- if (Error E = getRvaPtr (RVA, IntPtr))
603
+ if (Error E = getRvaPtr (RVA, IntPtr, " delay import table " ))
590
604
return E;
591
605
DelayImportDirectory = reinterpret_cast <
592
606
const delay_import_directory_table_entry *>(IntPtr);
@@ -607,7 +621,7 @@ Error COFFObjectFile::initExportTablePtr() {
607
621
608
622
uint32_t ExportTableRva = DataEntry->RelativeVirtualAddress ;
609
623
uintptr_t IntPtr = 0 ;
610
- if (Error E = getRvaPtr (ExportTableRva, IntPtr))
624
+ if (Error E = getRvaPtr (ExportTableRva, IntPtr, " export table " ))
611
625
return E;
612
626
ExportDirectory =
613
627
reinterpret_cast <const export_directory_table_entry *>(IntPtr);
@@ -623,7 +637,8 @@ Error COFFObjectFile::initBaseRelocPtr() {
623
637
return Error::success ();
624
638
625
639
uintptr_t IntPtr = 0 ;
626
- if (Error E = getRvaPtr (DataEntry->RelativeVirtualAddress , IntPtr))
640
+ if (Error E = getRvaPtr (DataEntry->RelativeVirtualAddress , IntPtr,
641
+ " base reloc table" ))
627
642
return E;
628
643
BaseRelocHeader = reinterpret_cast <const coff_base_reloc_block_header *>(
629
644
IntPtr);
@@ -646,10 +661,12 @@ Error COFFObjectFile::initDebugDirectoryPtr() {
646
661
647
662
// Check that the size is a multiple of the entry size.
648
663
if (DataEntry->Size % sizeof (debug_directory) != 0 )
649
- return errorCodeToError (object_error::parse_failed);
664
+ return createStringError (object_error::parse_failed,
665
+ " debug directory has uneven size" );
650
666
651
667
uintptr_t IntPtr = 0 ;
652
- if (Error E = getRvaPtr (DataEntry->RelativeVirtualAddress , IntPtr))
668
+ if (Error E = getRvaPtr (DataEntry->RelativeVirtualAddress , IntPtr,
669
+ " debug directory" ))
653
670
return E;
654
671
DebugDirectoryBegin = reinterpret_cast <const debug_directory *>(IntPtr);
655
672
DebugDirectoryEnd = reinterpret_cast <const debug_directory *>(
@@ -680,7 +697,8 @@ Error COFFObjectFile::initTLSDirectoryPtr() {
680
697
static_cast <uint32_t >(DataEntry->Size ), DirSize);
681
698
682
699
uintptr_t IntPtr = 0 ;
683
- if (Error E = getRvaPtr (DataEntry->RelativeVirtualAddress , IntPtr))
700
+ if (Error E =
701
+ getRvaPtr (DataEntry->RelativeVirtualAddress , IntPtr, " TLS directory" ))
684
702
return E;
685
703
686
704
if (is64 ())
@@ -701,7 +719,8 @@ Error COFFObjectFile::initLoadConfigPtr() {
701
719
if (DataEntry->RelativeVirtualAddress == 0 )
702
720
return Error::success ();
703
721
uintptr_t IntPtr = 0 ;
704
- if (Error E = getRvaPtr (DataEntry->RelativeVirtualAddress , IntPtr))
722
+ if (Error E = getRvaPtr (DataEntry->RelativeVirtualAddress , IntPtr,
723
+ " load config table" ))
705
724
return E;
706
725
707
726
LoadConfig = (const void *)IntPtr;
@@ -749,7 +768,8 @@ Error COFFObjectFile::initialize() {
749
768
CurPtr = DH->AddressOfNewExeHeader ;
750
769
// Check the PE magic bytes. ("PE\0\0")
751
770
if (memcmp (base () + CurPtr, COFF::PEMagic, sizeof (COFF::PEMagic)) != 0 ) {
752
- return errorCodeToError (object_error::parse_failed);
771
+ return createStringError (object_error::parse_failed,
772
+ " incorrect PE magic" );
753
773
}
754
774
CurPtr += sizeof (COFF::PEMagic); // Skip the PE magic bytes.
755
775
HasPEHeader = true ;
@@ -805,7 +825,8 @@ Error COFFObjectFile::initialize() {
805
825
DataDirSize = sizeof (data_directory) * PE32PlusHeader->NumberOfRvaAndSize ;
806
826
} else {
807
827
// It's neither PE32 nor PE32+.
808
- return errorCodeToError (object_error::parse_failed);
828
+ return createStringError (object_error::parse_failed,
829
+ " incorrect PE magic" );
809
830
}
810
831
if (Error E = getObject (DataDirectory, Data, DataDirAddr, DataDirSize))
811
832
return E;
@@ -834,7 +855,8 @@ Error COFFObjectFile::initialize() {
834
855
} else {
835
856
// We had better not have any symbols if we don't have a symbol table.
836
857
if (getNumberOfSymbols () != 0 ) {
837
- return errorCodeToError (object_error::parse_failed);
858
+ return createStringError (object_error::parse_failed,
859
+ " symbol table missing" );
838
860
}
839
861
}
840
862
@@ -1021,13 +1043,14 @@ Expected<const coff_section *> COFFObjectFile::getSection(int32_t Index) const {
1021
1043
// We already verified the section table data, so no need to check again.
1022
1044
return SectionTable + (Index - 1 );
1023
1045
}
1024
- return errorCodeToError (object_error::parse_failed);
1046
+ return createStringError (object_error::parse_failed,
1047
+ " section index out of bounds" );
1025
1048
}
1026
1049
1027
1050
Expected<StringRef> COFFObjectFile::getString (uint32_t Offset) const {
1028
1051
if (StringTableSize <= 4 )
1029
1052
// Tried to get a string from an empty string table.
1030
- return errorCodeToError (object_error::parse_failed);
1053
+ return createStringError (object_error::parse_failed, " string table empty " );
1031
1054
if (Offset >= StringTableSize)
1032
1055
return errorCodeToError (object_error::unexpected_eof);
1033
1056
return StringRef (StringTable + Offset);
@@ -1414,7 +1437,8 @@ ImportDirectoryEntryRef::lookup_table_symbols() const {
1414
1437
1415
1438
Error ImportDirectoryEntryRef::getName (StringRef &Result) const {
1416
1439
uintptr_t IntPtr = 0 ;
1417
- if (Error E = OwningObject->getRvaPtr (ImportTable[Index].NameRVA , IntPtr))
1440
+ if (Error E = OwningObject->getRvaPtr (ImportTable[Index].NameRVA , IntPtr,
1441
+ " import directory name" ))
1418
1442
return E;
1419
1443
Result = StringRef (reinterpret_cast <const char *>(IntPtr));
1420
1444
return Error::success ();
@@ -1460,7 +1484,8 @@ DelayImportDirectoryEntryRef::imported_symbols() const {
1460
1484
1461
1485
Error DelayImportDirectoryEntryRef::getName (StringRef &Result) const {
1462
1486
uintptr_t IntPtr = 0 ;
1463
- if (Error E = OwningObject->getRvaPtr (Table[Index].Name , IntPtr))
1487
+ if (Error E = OwningObject->getRvaPtr (Table[Index].Name , IntPtr,
1488
+ " delay import directory name" ))
1464
1489
return E;
1465
1490
Result = StringRef (reinterpret_cast <const char *>(IntPtr));
1466
1491
return Error::success ();
@@ -1477,7 +1502,7 @@ Error DelayImportDirectoryEntryRef::getImportAddress(int AddrIndex,
1477
1502
uint32_t RVA = Table[Index].DelayImportAddressTable +
1478
1503
AddrIndex * (OwningObject->is64 () ? 8 : 4 );
1479
1504
uintptr_t IntPtr = 0 ;
1480
- if (Error E = OwningObject->getRvaPtr (RVA, IntPtr))
1505
+ if (Error E = OwningObject->getRvaPtr (RVA, IntPtr, " import address " ))
1481
1506
return E;
1482
1507
if (OwningObject->is64 ())
1483
1508
Result = *reinterpret_cast <const ulittle64_t *>(IntPtr);
@@ -1499,7 +1524,8 @@ void ExportDirectoryEntryRef::moveNext() {
1499
1524
// by ordinal, the empty string is set as a result.
1500
1525
Error ExportDirectoryEntryRef::getDllName (StringRef &Result) const {
1501
1526
uintptr_t IntPtr = 0 ;
1502
- if (Error E = OwningObject->getRvaPtr (ExportTable->NameRVA , IntPtr))
1527
+ if (Error E =
1528
+ OwningObject->getRvaPtr (ExportTable->NameRVA , IntPtr, " dll name" ))
1503
1529
return E;
1504
1530
Result = StringRef (reinterpret_cast <const char *>(IntPtr));
1505
1531
return Error::success ();
@@ -1520,8 +1546,8 @@ Error ExportDirectoryEntryRef::getOrdinal(uint32_t &Result) const {
1520
1546
// Returns the address of the current export symbol.
1521
1547
Error ExportDirectoryEntryRef::getExportRVA (uint32_t &Result) const {
1522
1548
uintptr_t IntPtr = 0 ;
1523
- if (Error EC =
1524
- OwningObject-> getRvaPtr (ExportTable-> ExportAddressTableRVA , IntPtr))
1549
+ if (Error EC = OwningObject-> getRvaPtr (ExportTable-> ExportAddressTableRVA ,
1550
+ IntPtr, " export address " ))
1525
1551
return EC;
1526
1552
const export_address_table_entry *entry =
1527
1553
reinterpret_cast <const export_address_table_entry *>(IntPtr);
@@ -1534,8 +1560,8 @@ Error ExportDirectoryEntryRef::getExportRVA(uint32_t &Result) const {
1534
1560
Error
1535
1561
ExportDirectoryEntryRef::getSymbolName (StringRef &Result) const {
1536
1562
uintptr_t IntPtr = 0 ;
1537
- if (Error EC =
1538
- OwningObject-> getRvaPtr (ExportTable-> OrdinalTableRVA , IntPtr ))
1563
+ if (Error EC = OwningObject-> getRvaPtr (ExportTable-> OrdinalTableRVA , IntPtr,
1564
+ " export ordinal table " ))
1539
1565
return EC;
1540
1566
const ulittle16_t *Start = reinterpret_cast <const ulittle16_t *>(IntPtr);
1541
1567
@@ -1545,11 +1571,12 @@ ExportDirectoryEntryRef::getSymbolName(StringRef &Result) const {
1545
1571
I < E; ++I, ++Offset) {
1546
1572
if (*I != Index)
1547
1573
continue ;
1548
- if (Error EC =
1549
- OwningObject-> getRvaPtr (ExportTable-> NamePointerRVA , IntPtr ))
1574
+ if (Error EC = OwningObject-> getRvaPtr (ExportTable-> NamePointerRVA , IntPtr,
1575
+ " export table entry " ))
1550
1576
return EC;
1551
1577
const ulittle32_t *NamePtr = reinterpret_cast <const ulittle32_t *>(IntPtr);
1552
- if (Error EC = OwningObject->getRvaPtr (NamePtr[Offset], IntPtr))
1578
+ if (Error EC = OwningObject->getRvaPtr (NamePtr[Offset], IntPtr,
1579
+ " export symbol name" ))
1553
1580
return EC;
1554
1581
Result = StringRef (reinterpret_cast <const char *>(IntPtr));
1555
1582
return Error::success ();
@@ -1562,7 +1589,8 @@ Error ExportDirectoryEntryRef::isForwarder(bool &Result) const {
1562
1589
const data_directory *DataEntry =
1563
1590
OwningObject->getDataDirectory (COFF::EXPORT_TABLE);
1564
1591
if (!DataEntry)
1565
- return errorCodeToError (object_error::parse_failed);
1592
+ return createStringError (object_error::parse_failed,
1593
+ " export table missing" );
1566
1594
uint32_t RVA;
1567
1595
if (auto EC = getExportRVA (RVA))
1568
1596
return EC;
@@ -1577,7 +1605,7 @@ Error ExportDirectoryEntryRef::getForwardTo(StringRef &Result) const {
1577
1605
if (auto EC = getExportRVA (RVA))
1578
1606
return EC;
1579
1607
uintptr_t IntPtr = 0 ;
1580
- if (auto EC = OwningObject->getRvaPtr (RVA, IntPtr))
1608
+ if (auto EC = OwningObject->getRvaPtr (RVA, IntPtr, " export forward target " ))
1581
1609
return EC;
1582
1610
Result = StringRef (reinterpret_cast <const char *>(IntPtr));
1583
1611
return Error::success ();
@@ -1606,7 +1634,7 @@ Error ImportedSymbolRef::getSymbolName(StringRef &Result) const {
1606
1634
RVA = Entry64[Index].getHintNameRVA ();
1607
1635
}
1608
1636
uintptr_t IntPtr = 0 ;
1609
- if (Error EC = OwningObject->getRvaPtr (RVA, IntPtr))
1637
+ if (Error EC = OwningObject->getRvaPtr (RVA, IntPtr, " import symbol name " ))
1610
1638
return EC;
1611
1639
// +2 because the first two bytes is hint.
1612
1640
Result = StringRef (reinterpret_cast <const char *>(IntPtr + 2 ));
@@ -1645,7 +1673,7 @@ Error ImportedSymbolRef::getOrdinal(uint16_t &Result) const {
1645
1673
RVA = Entry64[Index].getHintNameRVA ();
1646
1674
}
1647
1675
uintptr_t IntPtr = 0 ;
1648
- if (Error EC = OwningObject->getRvaPtr (RVA, IntPtr))
1676
+ if (Error EC = OwningObject->getRvaPtr (RVA, IntPtr, " import symbol ordinal " ))
1649
1677
return EC;
1650
1678
Result = *reinterpret_cast <const ulittle16_t *>(IntPtr);
1651
1679
return Error::success ();
0 commit comments