LLVM: lib/Object/COFFObjectFile.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

28#include

29#include

30#include

31#include

32#include

33#include

34#include

35#include <system_error>

36

37using namespace llvm;

38using namespace object;

39

44

45

47 if (M.getBufferSize() < Size) {

48 EC = object_error::unexpected_eof;

49 return false;

50 }

51 return true;

52}

53

54

55

56template

59 uintptr_t Addr = reinterpret_cast<uintptr_t>(Ptr);

61 return E;

62 Obj = reinterpret_cast<const T *>(Addr);

64}

65

66

67

69 assert(Str.size() <= 6 && "String too long, possible overflow.");

70 if (Str.size() > 6)

71 return true;

72

74 while (!Str.empty()) {

75 unsigned CharVal;

76 if (Str[0] >= 'A' && Str[0] <= 'Z')

77 CharVal = Str[0] - 'A';

78 else if (Str[0] >= 'a' && Str[0] <= 'z')

79 CharVal = Str[0] - 'a' + 26;

80 else if (Str[0] >= '0' && Str[0] <= '9')

81 CharVal = Str[0] - '0' + 52;

82 else if (Str[0] == '+')

83 CharVal = 62;

84 else if (Str[0] == '/')

85 CharVal = 63;

86 else

87 return true;

88

90 Str = Str.substr(1);

91 }

92

93 if (Value > std::numeric_limits<uint32_t>::max())

94 return true;

95

97 return false;

98}

99

100template <typename coff_symbol_type>

101const coff_symbol_type *COFFObjectFile::toSymb(DataRefImpl Ref) const {

102 const coff_symbol_type *Addr =

103 reinterpret_cast<const coff_symbol_type *>(Ref.p);

104

106#ifndef NDEBUG

107

109 reinterpret_cast<uintptr_t>(Addr) - reinterpret_cast<uintptr_t>(base());

110

112 "Symbol did not point to the beginning of a symbol");

113#endif

114

115 return Addr;

116}

117

119 const coff_section *Addr = reinterpret_cast<const coff_section*>(Ref.p);

120

121#ifndef NDEBUG

122

123 if (Addr < SectionTable || Addr >= (SectionTable + getNumberOfSections()))

125

126 uintptr_t Offset = reinterpret_cast<uintptr_t>(Addr) -

127 reinterpret_cast<uintptr_t>(SectionTable);

129 "Section did not point to the beginning of a section");

130#endif

131

132 return Addr;

133}

134

136 auto End = reinterpret_cast<uintptr_t>(StringTable);

137 if (SymbolTable16) {

140 Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);

141 } else if (SymbolTable32) {

144 Ref.p = std::min(reinterpret_cast<uintptr_t>(Symb), End);

145 } else {

147 }

148}

149

153

157

164

169

172 return Result;

173

175 if (!Section)

176 return Section.takeError();

177 Result += (*Section)->VirtualAddress;

178

179

180

182

183 return Result;

184}

185

208

212

215

220 }

221

224

227

230

233

236

237 return Result;

238}

239

244

251 if (!Sec)

254 Ret.p = reinterpret_cast<uintptr_t>(*Sec);

256}

257

262

265 Sec += 1;

266 Ref.p = reinterpret_cast<uintptr_t>(Sec);

267}

268

273

277

278

279

281 return Result;

282}

283

285 return toSec(Sec) - SectionTable;

286}

287

291

297 return E;

298 return Res;

299}

300

305

309

314

319

327

328

329

332 if (!SectionNameOrErr) {

333

335 return false;

336 }

338 return SectionName.starts_with(".debug");

339}

340

347

354

357

358

359

360

367 return 0;

368 }

369

371 }

373}

374

378 if (!NumRelocs)

379 return nullptr;

383

384

385 begin++;

386 }

390 return nullptr;

391 }

392 return begin;

393}

394

399 report_fatal_error("Sections with relocations should have an address of 0");

401 Ret.p = reinterpret_cast<uintptr_t>(begin);

403}

404

408 if (I)

411 Ret.p = reinterpret_cast<uintptr_t>(I);

413}

414

415

416Error COFFObjectFile::initSymbolTablePtr() {

417 if (COFFHeader)

421 return E;

422

423 if (COFFBigObjHeader)

427 return E;

428

429

430

431

435 const ulittle32_t *StringTableSizePtr;

437 return E;

438 StringTableSize = *StringTableSizePtr;

440 return E;

441

442

443

444 if (StringTableSize < 4)

445 StringTableSize = 4;

446

447

448 if (StringTableSize > 4 && StringTable[StringTableSize - 1] != 0)

450 "string table missing null terminator");

452}

453

455 if (PE32Header)

456 return PE32Header->ImageBase;

457 else if (PE32PlusHeader)

458 return PE32PlusHeader->ImageBase;

459

460 return 0;

461}

462

463

466 uint64_t Rva = Addr - ImageBase;

467 assert(Rva <= UINT32_MAX);

469}

470

471

473 const char *ErrorContext) const {

476 uint32_t SectionStart = Section->VirtualAddress;

477 uint32_t SectionEnd = Section->VirtualAddress + Section->VirtualSize;

478 if (SectionStart <= Addr && Addr < SectionEnd) {

479

480

481

482

483

484

485

486

487

488 if (Section->SizeOfRawData < Section->VirtualSize &&

489 Addr >= SectionStart + Section->SizeOfRawData) {

491 }

493 Res = reinterpret_cast<uintptr_t>(base()) + Section->PointerToRawData +

496 }

497 }

498 if (ErrorContext)

500 "RVA 0x%" PRIx32 " for %s not found", Addr,

501 ErrorContext);

503 "RVA 0x%" PRIx32 " not found", Addr);

504}

505

508 const char *ErrorContext) const {

511 uint32_t SectionStart = Section->VirtualAddress;

512

513

514 uint32_t OffsetIntoSection = RVA - SectionStart;

515 if (SectionStart <= RVA && OffsetIntoSection < Section->VirtualSize &&

517 uintptr_t Begin = reinterpret_cast<uintptr_t>(base()) +

518 Section->PointerToRawData + OffsetIntoSection;

519 Contents =

522 }

523 }

524 if (ErrorContext)

526 "RVA 0x%" PRIx32 " for %s not found", RVA,

527 ErrorContext);

529 "RVA 0x%" PRIx32 " not found", RVA);

530}

531

532

533

536 uintptr_t IntPtr = 0;

538 return E;

539 const uint8_t *Ptr = reinterpret_cast<const uint8_t *>(IntPtr);

540 Hint = *reinterpret_cast<const ulittle16_t *>(Ptr);

541 Name = StringRef(reinterpret_cast<const char *>(Ptr + 2));

543}

544

551 InfoBytes, "PDB info"))

552 return E;

553 if (InfoBytes.size() < sizeof(*PDBInfo) + 1)

556 InfoBytes = InfoBytes.drop_front(sizeof(*PDBInfo));

557 PDBFileName = StringRef(reinterpret_cast<const char *>(InfoBytes.data()),

558 InfoBytes.size());

559

560 PDBFileName = PDBFileName.split('\0').first;

562}

563

569

570 PDBInfo = nullptr;

573}

574

575

576Error COFFObjectFile::initImportTablePtr() {

577

578

580 if (!DataEntry)

582

583

586

588

589

590

591 uintptr_t IntPtr = 0;

592 if (Error E = getRvaPtr(ImportTableRva, IntPtr, "import table"))

593 return E;

595 return E;

596 ImportDirectory = reinterpret_cast<

599}

600

601

602Error COFFObjectFile::initDelayImportTablePtr() {

605 if (!DataEntry)

609

611 NumberOfDelayImportDirectory = DataEntry->Size /

613

614 uintptr_t IntPtr = 0;

615 if (Error E = getRvaPtr(RVA, IntPtr, "delay import table"))

616 return E;

618 return E;

619

620 DelayImportDirectory = reinterpret_cast<

623}

624

625

626Error COFFObjectFile::initExportTablePtr() {

627

628

630 if (!DataEntry)

632

633

636

638 uintptr_t IntPtr = 0;

639 if (Error E = getRvaPtr(ExportTableRva, IntPtr, "export table"))

640 return E;

642 return E;

643

644 ExportDirectory =

647}

648

649Error COFFObjectFile::initBaseRelocPtr() {

650 const data_directory *DataEntry =

652 if (!DataEntry)

656

657 uintptr_t IntPtr = 0;

659 "base reloc table"))

660 return E;

662 return E;

663

664 BaseRelocHeader = reinterpret_cast<const coff_base_reloc_block_header *>(

665 IntPtr);

666 BaseRelocEnd = reinterpret_cast<coff_base_reloc_block_header *>(

667 IntPtr + DataEntry->Size);

668

669

671}

672

673Error COFFObjectFile::initDebugDirectoryPtr() {

674

676 if (!DataEntry)

678

679

682

683

684 if (DataEntry->Size % sizeof(debug_directory) != 0)

686 "debug directory has uneven size");

687

688 uintptr_t IntPtr = 0;

690 "debug directory"))

691 return E;

693 return E;

694

695 DebugDirectoryBegin = reinterpret_cast<const debug_directory *>(IntPtr);

696 DebugDirectoryEnd = reinterpret_cast<const debug_directory *>(

697 IntPtr + DataEntry->Size);

698

699

701}

702

703Error COFFObjectFile::initTLSDirectoryPtr() {

704

706 if (!DataEntry)

708

709

712

713 uint64_t DirSize =

715

716

717 if (DataEntry->Size != DirSize)

720 "TLS Directory size (%u) is not the expected size (%" PRIu64 ").",

721 static_cast<uint32_t>(DataEntry->Size), DirSize);

722

723 uintptr_t IntPtr = 0;

726 return E;

728 return E;

729

732 else

734

736}

737

738Error COFFObjectFile::initLoadConfigPtr() {

739

741 if (!DataEntry)

743

744

747 uintptr_t IntPtr = 0;

749 "load config table"))

750 return E;

752 return E;

753

754 LoadConfig = (const void *)IntPtr;

755

756 if (is64()) {

758 if (Config->Size >=

759 offsetof(coff_load_configuration64, CHPEMetadataPointer) +

760 sizeof(Config->CHPEMetadataPointer) &&

761 Config->CHPEMetadataPointer) {

762 uint64_t ChpeOff = Config->CHPEMetadataPointer;

765 return E;

767 return E;

768

769 CHPEMetadata = reinterpret_cast<const chpe_metadata *>(IntPtr);

770

771

772 if (CHPEMetadata->CodeMapCount) {

773 if (Error E = getRvaPtr(CHPEMetadata->CodeMap, IntPtr, "CHPE code map"))

774 return E;

776 CHPEMetadata->CodeMapCount *

777 sizeof(chpe_range_entry)))

778 return E;

779 }

780

781 if (CHPEMetadata->CodeRangesToEntryPointsCount) {

782 if (Error E = getRvaPtr(CHPEMetadata->CodeRangesToEntryPoints, IntPtr,

783 "CHPE entry point ranges"))

784 return E;

786 CHPEMetadata->CodeRangesToEntryPointsCount *

787 sizeof(chpe_code_range_entry)))

788 return E;

789 }

790

791 if (CHPEMetadata->RedirectionMetadataCount) {

792 if (Error E = getRvaPtr(CHPEMetadata->RedirectionMetadata, IntPtr,

793 "CHPE redirection metadata"))

794 return E;

796 CHPEMetadata->RedirectionMetadataCount *

797 sizeof(chpe_redirection_entry)))

798 return E;

799 }

800 }

801

802 if (Config->Size >=

803 offsetof(coff_load_configuration64, DynamicValueRelocTableSection) +

804 sizeof(Config->DynamicValueRelocTableSection))

805 if (Error E = initDynamicRelocPtr(Config->DynamicValueRelocTableSection,

806 Config->DynamicValueRelocTableOffset))

807 return E;

808 } else {

810 if (Config->Size >=

811 offsetof(coff_load_configuration32, DynamicValueRelocTableSection) +

812 sizeof(Config->DynamicValueRelocTableSection)) {

813 if (Error E = initDynamicRelocPtr(Config->DynamicValueRelocTableSection,

814 Config->DynamicValueRelocTableOffset))

815 return E;

816 }

817 }

819}

820

821Error COFFObjectFile::initDynamicRelocPtr(uint32_t SectionIndex,

822 uint32_t SectionOffset) {

823 Expected<const coff_section *> Section = getSection(SectionIndex);

824 if (!Section)

825 return Section.takeError();

826 if (!*Section)

828

829

830 ArrayRef<uint8_t> Contents;

832 return E;

833

834 Contents = Contents.drop_front(SectionOffset);

835 if (Contents.size() < sizeof(coff_dynamic_reloc_table))

837 "Too large DynamicValueRelocTableOffset (" +

838 Twine(SectionOffset) + ")");

839

840 DynamicRelocTable =

841 reinterpret_cast<const coff_dynamic_reloc_table *>(Contents.data());

842

843 if (DynamicRelocTable->Version != 1 && DynamicRelocTable->Version != 2)

845 "Unsupported dynamic relocations table version (" +

846 Twine(DynamicRelocTable->Version) + ")");

847 if (DynamicRelocTable->Size > Contents.size() - sizeof(*DynamicRelocTable))

849 "Indvalid dynamic relocations directory size (" +

850 Twine(DynamicRelocTable->Size) + ")");

851

853 if (Error e = DynReloc.validate())

854 return e;

855 }

856

858}

859

860Expected<std::unique_ptr>

862 std::unique_ptr Obj(new COFFObjectFile(std::move(Object)));

863 if (Error E = Obj->initialize())

864 return E;

865 return std::move(Obj);

866}

867

870 COFFBigObjHeader(nullptr), PE32Header(nullptr), PE32PlusHeader(nullptr),

871 DataDirectory(nullptr), SectionTable(nullptr), SymbolTable16(nullptr),

872 SymbolTable32(nullptr), StringTable(nullptr), StringTableSize(0),

873 ImportDirectory(nullptr), DelayImportDirectory(nullptr),

874 NumberOfDelayImportDirectory(0), ExportDirectory(nullptr),

875 BaseRelocHeader(nullptr), BaseRelocEnd(nullptr),

876 DebugDirectoryBegin(nullptr), DebugDirectoryEnd(nullptr),

877 TLSDirectory32(nullptr), TLSDirectory64(nullptr) {}

878

886

887Error COFFObjectFile::initialize() {

888

889 std::error_code EC;

890 if (checkSize(Data, EC, sizeof(coff_file_header)))

892

893

894 uint64_t CurPtr = 0;

895

896

897

898 bool HasPEHeader = false;

899

900

902

903

904 const auto *DH = reinterpret_cast<const dos_header *>(base());

905 if (DH->Magic[0] == 'M' && DH->Magic[1] == 'Z') {

906 CurPtr = DH->AddressOfNewExeHeader;

907

910 "incorrect PE magic");

911 }

912 CurPtr += sizeof(COFF::PEMagic);

913 HasPEHeader = true;

914 }

915 }

916

918 return E;

919

920

921

923 COFFHeader->NumberOfSections == uint16_t(0xffff) &&

924 checkSize(Data, EC, sizeof(coff_bigobj_file_header))) {

926 return E;

927

928

932 COFFHeader = nullptr;

933 CurPtr += sizeof(coff_bigobj_file_header);

934 } else {

935

936 COFFBigObjHeader = nullptr;

937 }

938 }

939 if (COFFHeader) {

940

941

942 EC = std::error_code();

943 CurPtr += sizeof(coff_file_header);

944

945 if (COFFHeader->isImportLibrary())

947 }

948

949 if (HasPEHeader) {

950 const pe32_header *Header;

952 return E;

953

954 const uint8_t *DataDirAddr;

955 uint64_t DataDirSize;

957 PE32Header = Header;

958 DataDirAddr = base() + CurPtr + sizeof(pe32_header);

959 DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize;

961 PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header);

962 DataDirAddr = base() + CurPtr + sizeof(pe32plus_header);

963 DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;

964 } else {

965

967 "incorrect PE magic");

968 }

970 return E;

971 }

972

973 if (COFFHeader)

974 CurPtr += COFFHeader->SizeOfOptionalHeader;

975

976 assert(COFFHeader || COFFBigObjHeader);

977

981 return E;

982

983

985 if (Error E = initSymbolTablePtr()) {

986

988 SymbolTable16 = nullptr;

989 SymbolTable32 = nullptr;

990 StringTable = nullptr;

991 StringTableSize = 0;

992 }

993 } else {

994

997 "symbol table missing");

998 }

999 }

1000

1001

1003 return E;

1005 return E;

1006

1007

1009 return E;

1010

1011

1013 return E;

1014

1015

1017 return E;

1018

1019

1021 return E;

1022

1024 return E;

1025

1027}

1028

1034

1036

1038 Ret.p = reinterpret_cast<uintptr_t>(StringTable);

1040}

1041

1043 if (!ImportDirectory)

1045 if (ImportDirectory->isNull())

1049}

1050

1055

1061

1066 DelayImportDirectory, NumberOfDelayImportDirectory, this));

1067}

1068

1073

1075 if (!ExportDirectory)

1078 ExportDirectory->AddressTableEntries, this);

1080}

1081

1084 Ret.p = reinterpret_cast<uintptr_t>(SectionTable);

1086}

1087

1090 int NumSections =

1091 COFFHeader && COFFHeader->isImportLibrary() ? 0 : getNumberOfSections();

1092 Ret.p = reinterpret_cast<uintptr_t>(SectionTable + NumSections);

1094}

1095

1099

1103

1105 const void *Header = DynamicRelocTable ? DynamicRelocTable + 1 : nullptr;

1107}

1108

1110 const void *Header = nullptr;

1111 if (DynamicRelocTable)

1112 Header = reinterpret_cast<const uint8_t *>(DynamicRelocTable + 1) +

1113 DynamicRelocTable->Size;

1115}

1116

1120

1124 return "COFF-i386";

1126 return "COFF-x86-64";

1128 return "COFF-ARM";

1130 return "COFF-ARM64";

1132 return "COFF-ARM64EC";

1134 return "COFF-ARM64X";

1136 return "COFF-MIPS";

1137 default:

1138 return "COFF-";

1139 }

1140}

1141

1145

1147 if (PE32Header)

1148 return PE32Header->AddressOfEntryPoint;

1149 return 0;

1150}

1151

1156

1162

1167

1171

1175

1177 if (!DataDirectory)

1178 return nullptr;

1179 assert(PE32Header || PE32PlusHeader);

1180 uint32_t NumEnt = PE32Header ? PE32Header->NumberOfRvaAndSize

1181 : PE32PlusHeader->NumberOfRvaAndSize;

1182 if (Index >= NumEnt)

1183 return nullptr;

1184 return &DataDirectory[Index];

1185}

1186

1188

1189

1193

1194 return SectionTable + (Index - 1);

1195 }

1197 "section index out of bounds");

1198}

1199

1201 if (StringTableSize <= 4)

1202

1204 if (Offset >= StringTableSize)

1207}

1208

1212

1215

1216 if (Symbol->Name.Offset.Zeroes == 0)

1217 return getString(Symbol->Name.Offset.Offset);

1218

1219

1220 if (Symbol->Name.ShortName[COFF::NameSize - 1] == 0)

1221 return StringRef(Symbol->Name.ShortName);

1222

1223

1225}

1226

1229 const uint8_t *Aux = nullptr;

1230

1232 if (Symbol.getNumberOfAuxSymbols() > 0) {

1233

1234 Aux = reinterpret_cast<const uint8_t *>(Symbol.getRawPtr()) + SymbolSize;

1235#ifndef NDEBUG

1236

1237 uintptr_t Offset = uintptr_t(Aux) - uintptr_t(base());

1242

1244 "Aux Symbol data did not point to the beginning of a symbol");

1245#endif

1246 }

1247 return ArrayRef(Aux, Symbol.getNumberOfAuxSymbols() * SymbolSize);

1248}

1249

1252 reinterpret_cast<uintptr_t>(Symbol.getRawPtr()) - getSymbolTable();

1254 "Symbol did not point to the beginning of a symbol");

1257 return Index;

1258}

1259

1263

1264

1265 if (Name.starts_with("/")) {

1267 if (Name.starts_with("//")) {

1270 "invalid section name");

1271 } else {

1272 if (Name.substr(1).getAsInteger(10, Offset))

1274 "invalid section name");

1275 }

1276 return getString(Offset);

1277 }

1278

1279 return Name;

1280}

1281

1283

1284

1285

1286

1287

1288

1289

1290

1291

1292

1296}

1297

1300

1301

1304

1305

1306

1307 uintptr_t ConStart =

1311 return E;

1312 Res = ArrayRef(reinterpret_cast<const uint8_t *>(ConStart), SectionSize);

1314}

1315

1318}

1319

1321 Rel.p = reinterpret_cast<uintptr_t>(

1323}

1324

1327 return R->VirtualAddress;

1328}

1329

1335 if (SymbolTable16)

1336 Ref.p = reinterpret_cast<uintptr_t>(SymbolTable16 + R->SymbolTableIndex);

1337 else if (SymbolTable32)

1338 Ref.p = reinterpret_cast<uintptr_t>(SymbolTable32 + R->SymbolTableIndex);

1339 else

1342}

1343

1346 return R->Type;

1347}

1348

1351 return toSec(Section.getRawDataRefImpl());

1352}

1353

1355 if (SymbolTable16)

1356 return toSymb<coff_symbol16>(Ref);

1357 if (SymbolTable32)

1358 return toSymb<coff_symbol32>(Ref);

1360}

1361

1365

1368 return toRel(Reloc.getRawDataRefImpl());

1369}

1370

1376

1377#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type) \

1378 case COFF::reloc_type: \

1379 return #reloc_type;

1380

1384 switch (Type) {

1402 default:

1403 return "Unknown";

1404 }

1405 break;

1407 switch (Type) {

1425 default:

1426 return "Unknown";

1427 }

1428 break;

1430 switch (Type) {

1449 default:

1450 return "Unknown";

1451 }

1452 break;

1454 switch (Type) {

1466 default:

1467 return "Unknown";

1468 }

1469 break;

1471 switch (Type) {

1487 default:

1488 return "Unknown";

1489 }

1490 break;

1491 default:

1492 return "Unknown";

1493 }

1494}

1495

1496#undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME

1497

1502 Result.append(Res.begin(), Res.end());

1503}

1504

1506 return !DataDirectory;

1507}

1508

1511 .Case("eh_fram", "eh_frame")

1513}

1514

1517 return nullptr;

1518

1519 std::unique_ptr HybridView;

1520

1523 continue;

1524

1525 for (auto reloc : DynReloc.arm64x_relocs()) {

1526 if (!HybridView) {

1527 HybridView =

1529 memcpy(HybridView->getBufferStart(), Data.getBufferStart(),

1530 Data.getBufferSize());

1531 }

1532

1533 uint32_t RVA = reloc.getRVA();

1534 void *Ptr;

1535 uintptr_t IntPtr;

1536 if (RVA & ~0xfff) {

1538 Ptr = HybridView->getBufferStart() + IntPtr -

1539 reinterpret_cast<uintptr_t>(base());

1540 } else {

1541

1542 Ptr = HybridView->getBufferStart() + RVA;

1543 }

1544

1545 switch (reloc.getType()) {

1547 memset(Ptr, 0, reloc.getSize());

1548 break;

1550 auto Value = static_cast<ulittle64_t>(reloc.getValue());

1551 memcpy(Ptr, &Value, reloc.getSize());

1552 break;

1553 }

1555 *reinterpret_cast<ulittle32_t *>(Ptr) += reloc.getValue();

1556 break;

1557 }

1558 }

1559 }

1560 return HybridView;

1561}

1562

1565 return ImportTable == Other.ImportTable && Index == Other.Index;

1566}

1567

1569 ++Index;

1570 if (ImportTable[Index].isNull()) {

1571 Index = -1;

1572 ImportTable = nullptr;

1573 }

1574}

1575

1578 return getObject(Result, OwningObject->Data, ImportTable + Index);

1579}

1580

1583 uintptr_t Ptr, int Index) {

1584 if (Object->getBytesInAddress() == 4) {

1587 }

1590}

1591

1594 uintptr_t IntPtr = 0;

1595

1596 cantFail(Object->getRvaPtr(RVA, IntPtr));

1598}

1599

1602 uintptr_t IntPtr = 0;

1603

1604 cantFail(Object->getRvaPtr(RVA, IntPtr));

1605

1606 int Index = 0;

1607 if (Object->getBytesInAddress() == 4) {

1608 auto *Entry = reinterpret_cast<ulittle32_t *>(IntPtr);

1609 while (*Entry++)

1610 ++Index;

1611 } else {

1612 auto *Entry = reinterpret_cast<ulittle64_t *>(IntPtr);

1613 while (*Entry++)

1614 ++Index;

1615 }

1617}

1618

1622 OwningObject);

1623}

1624

1627 return importedSymbolEnd(ImportTable[Index].ImportAddressTableRVA,

1628 OwningObject);

1629}

1630

1635

1638 OwningObject);

1639}

1640

1642 return importedSymbolEnd(ImportTable[Index].ImportLookupTableRVA,

1643 OwningObject);

1644}

1645

1650

1652 uintptr_t IntPtr = 0;

1653 if (Error E = OwningObject->getRvaPtr(ImportTable[Index].NameRVA, IntPtr,

1654 "import directory name"))

1655 return E;

1656 Result = StringRef(reinterpret_cast<const char *>(IntPtr));

1658}

1659

1662 Result = ImportTable[Index].ImportLookupTableRVA;

1664}

1665

1668 Result = ImportTable[Index].ImportAddressTableRVA;

1670}

1671

1674 return Table == Other.Table && Index == Other.Index;

1675}

1676

1680

1684 OwningObject);

1685}

1686

1690 OwningObject);

1691}

1692

1697

1699 uintptr_t IntPtr = 0;

1700 if (Error E = OwningObject->getRvaPtr(Table[Index].Name, IntPtr,

1701 "delay import directory name"))

1702 return E;

1703 Result = StringRef(reinterpret_cast<const char *>(IntPtr));

1705}

1706

1709 Result = &Table[Index];

1711}

1712

1715 uint32_t RVA = Table[Index].DelayImportAddressTable +

1716 AddrIndex * (OwningObject->is64() ? 8 : 4);

1717 uintptr_t IntPtr = 0;

1718 if (Error E = OwningObject->getRvaPtr(RVA, IntPtr, "import address"))

1719 return E;

1720 if (OwningObject->is64())

1721 Result = *reinterpret_cast<const ulittle64_t *>(IntPtr);

1722 else

1723 Result = *reinterpret_cast<const ulittle32_t *>(IntPtr);

1725}

1726

1729 return ExportTable == Other.ExportTable && Index == Other.Index;

1730}

1731

1735

1736

1737

1739 uintptr_t IntPtr = 0;

1741 OwningObject->getRvaPtr(ExportTable->NameRVA, IntPtr, "dll name"))

1742 return E;

1743 Result = StringRef(reinterpret_cast<const char *>(IntPtr));

1745}

1746

1747

1749 Result = ExportTable->OrdinalBase;

1751}

1752

1753

1755 Result = ExportTable->OrdinalBase + Index;

1757}

1758

1759

1761 uintptr_t IntPtr = 0;

1762 if (Error EC = OwningObject->getRvaPtr(ExportTable->ExportAddressTableRVA,

1763 IntPtr, "export address"))

1764 return EC;

1767 Result = entry[Index].ExportRVA;

1769}

1770

1771

1772

1775 uintptr_t IntPtr = 0;

1776 if (Error EC = OwningObject->getRvaPtr(ExportTable->OrdinalTableRVA, IntPtr,

1777 "export ordinal table"))

1778 return EC;

1779 const ulittle16_t *Start = reinterpret_cast<const ulittle16_t *>(IntPtr);

1780

1781 uint32_t NumEntries = ExportTable->NumberOfNamePointers;

1783 for (const ulittle16_t *I = Start, *E = Start + NumEntries;

1785 if (*I != Index)

1786 continue;

1787 if (Error EC = OwningObject->getRvaPtr(ExportTable->NamePointerRVA, IntPtr,

1788 "export table entry"))

1789 return EC;

1790 const ulittle32_t *NamePtr = reinterpret_cast<const ulittle32_t *>(IntPtr);

1791 if (Error EC = OwningObject->getRvaPtr(NamePtr[Offset], IntPtr,

1792 "export symbol name"))

1793 return EC;

1794 Result = StringRef(reinterpret_cast<const char *>(IntPtr));

1796 }

1797 Result = "";

1799}

1800

1804 if (!DataEntry)

1806 "export table missing");

1809 return EC;

1812 Result = (Begin <= RVA && RVA < End);

1814}

1815

1819 return EC;

1820 uintptr_t IntPtr = 0;

1821 if (auto EC = OwningObject->getRvaPtr(RVA, IntPtr, "export forward target"))

1822 return EC;

1823 Result = StringRef(reinterpret_cast<const char *>(IntPtr));

1825}

1826

1829 return Entry32 == Other.Entry32 && Entry64 == Other.Entry64

1830 && Index == Other.Index;

1831}

1832

1836

1839 if (Entry32) {

1840

1843 RVA = Entry32[Index].getHintNameRVA();

1844 } else {

1847 RVA = Entry64[Index].getHintNameRVA();

1848 }

1849 uintptr_t IntPtr = 0;

1850 if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr, "import symbol name"))

1851 return EC;

1852

1853 Result = StringRef(reinterpret_cast<const char *>(IntPtr + 2));

1855}

1856

1858 if (Entry32)

1859 Result = Entry32[Index].isOrdinal();

1860 else

1861 Result = Entry64[Index].isOrdinal();

1863}

1864

1866 if (Entry32)

1867 Result = Entry32[Index].getHintNameRVA();

1868 else

1869 Result = Entry64[Index].getHintNameRVA();

1871}

1872

1875 if (Entry32) {

1876 if (Entry32[Index].isOrdinal()) {

1877 Result = Entry32[Index].getOrdinal();

1879 }

1880 RVA = Entry32[Index].getHintNameRVA();

1881 } else {

1882 if (Entry64[Index].isOrdinal()) {

1883 Result = Entry64[Index].getOrdinal();

1885 }

1886 RVA = Entry64[Index].getHintNameRVA();

1887 }

1888 uintptr_t IntPtr = 0;

1889 if (Error EC = OwningObject->getRvaPtr(RVA, IntPtr, "import symbol ordinal"))

1890 return EC;

1891 Result = *reinterpret_cast<const ulittle16_t *>(IntPtr);

1893}

1894

1899

1901 return Header == Other.Header && Index == Other.Index;

1902}

1903

1905

1906

1909 if (Size == Header->BlockSize) {

1910

1911

1912

1913

1915 reinterpret_cast<const uint8_t *>(Header) + Size);

1916 Index = 0;

1917 } else {

1918 ++Index;

1919 }

1920}

1921

1924 Type = Entry[Index].getType();

1926}

1927

1930 Result = Header->PageRVA + Entry[Index].getOffset();

1932}

1933

1935 return Header == Other.Header;

1936}

1937

1939 switch (Obj->getDynamicRelocTable()->Version) {

1940 case 1:

1941 if (Obj->is64()) {

1943 Header += sizeof(*H) + H->BaseRelocSize;

1944 } else {

1946 Header += sizeof(*H) + H->BaseRelocSize;

1947 }

1948 break;

1949 case 2:

1950 if (Obj->is64()) {

1952 Header += H->HeaderSize + H->FixupInfoSize;

1953 } else {

1955 Header += H->HeaderSize + H->FixupInfoSize;

1956 }

1957 break;

1958 }

1959}

1960

1962 switch (Obj->getDynamicRelocTable()->Version) {

1963 case 1:

1964 if (Obj->is64()) {

1966 return H->Symbol;

1967 } else {

1969 return H->Symbol;

1970 }

1971 break;

1972 case 2:

1973 if (Obj->is64()) {

1975 return H->Symbol;

1976 } else {

1978 return H->Symbol;

1979 }

1980 break;

1981 default:

1983 }

1984}

1985

1987 switch (Obj->getDynamicRelocTable()->Version) {

1988 case 1:

1989 if (Obj->is64()) {

1991 Ref = ArrayRef(Header + sizeof(*H), H->BaseRelocSize);

1992 } else {

1994 Ref = ArrayRef(Header + sizeof(*H), H->BaseRelocSize);

1995 }

1996 break;

1997 case 2:

1998 if (Obj->is64()) {

2000 Ref = ArrayRef(Header + H->HeaderSize, H->FixupInfoSize);

2001 } else {

2003 Ref = ArrayRef(Header + H->HeaderSize, H->FixupInfoSize);

2004 }

2005 break;

2006 }

2007}

2008

2009Error DynamicRelocRef::validate() const {

2011 size_t ContentsSize =

2012 reinterpret_cast<const uint8_t *>(Table + 1) + Table->Size - Header;

2013 size_t HeaderSize;

2014 if (Table->Version == 1)

2017 else

2020 if (HeaderSize > ContentsSize)

2022 "Unexpected end of dynamic relocations data");

2023

2024 if (Table->Version == 2) {

2025 size_t Size =

2026 Obj->is64()

2027 ? reinterpret_cast<const coff_dynamic_relocation64_v2 *>(Header)

2028 ->HeaderSize

2029 : reinterpret_cast<const coff_dynamic_relocation32_v2 *>(Header)

2030 ->HeaderSize;

2031 if (Size < HeaderSize || Size > ContentsSize)

2032 return createStringError(object_error::parse_failed,

2033 "Invalid dynamic relocation header size (" +

2034 Twine(Size) + ")");

2035 HeaderSize = Size;

2036 }

2037

2040 if (Contents.size() > ContentsSize - HeaderSize)

2042 "Too large dynamic relocation size (" +

2044

2049 return E;

2050 }

2051 break;

2052 }

2053

2055}

2056

2065

2074

2078

2080 return Header == Other.Header && Index == Other.Index;

2081}

2082

2083uint8_t Arm64XRelocRef::getEntrySize() const {

2086 return (1ull << getArg()) / sizeof(uint16_t) + 1;

2088 return 2;

2089 default:

2090 return 1;

2091 }

2092}

2093

2095 Index += getEntrySize();

2096 if (sizeof(*Header) + Index * sizeof(uint16_t) < Header->BlockSize &&

2097 !getReloc())

2098 ++Index;

2099 if (sizeof(*Header) + Index * sizeof(uint16_t) == Header->BlockSize) {

2100

2101 Header =

2103 Index = 0;

2104 }

2105}

2106

2111 return 1 << getArg();

2114 }

2116}

2117

2119 auto Ptr = reinterpret_cast<const ulittle16_t *>(Header + 1) + Index + 1;

2120

2123 ulittle64_t Value(0);

2126 }

2129 int delta = *Ptr;

2130

2131 if (arg & 1)

2132 delta = -delta;

2133 delta *= (arg & 2) ? 8 : 4;

2134 return delta;

2135 }

2136 default:

2137 return 0;

2138 }

2139}

2140

2142 if (!Index) {

2144 size_t ContentsSize = reinterpret_cast<const uint8_t *>(Table + 1) +

2145 Table->Size -

2146 reinterpret_cast<const uint8_t *>(Header);

2149 "Unexpected end of ARM64X relocations data");

2150 if (Header->BlockSize <= sizeof(*Header))

2152 "ARM64X relocations block size (" +

2153 Twine(Header->BlockSize) + ") is too small");

2154 if (Header->BlockSize % sizeof(uint32_t))

2156 "Unaligned ARM64X relocations block size (" +

2157 Twine(Header->BlockSize) + ")");

2158 if (Header->BlockSize > ContentsSize)

2160 "ARM64X relocations block size (" +

2161 Twine(Header->BlockSize) + ") is too large");

2162 if (Header->PageRVA & 0xfff)

2164 "Unaligned ARM64X relocations page RVA (" +

2165 Twine(Header->PageRVA) + ")");

2166 }

2167

2168 switch ((getReloc() >> 12) & 3) {

2171 break;

2173 if (!getArg())

2175 "Invalid ARM64X relocation value size (0)");

2176 break;

2177 default:

2179 "Invalid relocation type");

2180 }

2181

2183 (Header->BlockSize - sizeof(*Header)) / sizeof(uint16_t);

2184 uint16_t EntrySize = getEntrySize();

2185 if (!getReloc() ||

2186 (Index + EntrySize + 1 < RelocsSize && !getReloc(EntrySize)))

2188 "Unexpected ARM64X relocations terminator");

2189 if (Index + EntrySize > RelocsSize)

2191 "Unexpected end of ARM64X relocations");

2194 "Unaligned ARM64X relocation RVA (" +

2196 if (Header->PageRVA) {

2197 uintptr_t IntPtr;

2198 return Obj->getRvaPtr(getRVA() + getSize(), IntPtr, "ARM64X reloc");

2199 }

2201}

2202

2203#define RETURN_IF_ERROR(Expr) \

2204 do { \

2205 Error E = (Expr); \

2206 if (E) \

2207 return std::move(E); \

2208 } while (0)

2209

2211ResourceSectionRef::getDirStringAtOffset(uint32_t Offset) {

2218 return RawDirString;

2219}

2220

2221Expected<ArrayRef>

2223 return getDirStringAtOffset(Entry.Identifier.getNameOffset());

2224}

2225

2227ResourceSectionRef::getTableAtOffset(uint32_t Offset) {

2229

2231 Reader.setOffset(Offset);

2233 assert(Table != nullptr);

2234 return *Table;

2235}

2236

2238ResourceSectionRef::getTableEntryAtOffset(uint32_t Offset) {

2240

2242 Reader.setOffset(Offset);

2244 assert(Entry != nullptr);

2245 return *Entry;

2246}

2247

2249ResourceSectionRef::getDataEntryAtOffset(uint32_t Offset) {

2251

2253 Reader.setOffset(Offset);

2255 assert(Entry != nullptr);

2256 return *Entry;

2257}

2258

2259Expected<const coff_resource_dir_table &>

2261 assert(Entry.Offset.isSubDir());

2262 return getTableAtOffset(Entry.Offset.value());

2263}

2264

2267 assert(!Entry.Offset.isSubDir());

2268 return getDataEntryAtOffset(Entry.Offset.value());

2269}

2270

2272 return getTableAtOffset(0);

2273}

2274

2280 const uint8_t *TablePtr = reinterpret_cast<const uint8_t *>(&Table);

2281 ptrdiff_t TableOffset = TablePtr - BBS.data().data();

2282 return getTableEntryAtOffset(TableOffset + sizeof(Table) +

2284}

2285

2287 for (const SectionRef &S : O->sections()) {

2289 if (!Name)

2290 return Name.takeError();

2291

2292 if (*Name == ".rsrc" || *Name == ".rsrc$01")

2293 return load(O, S);

2294 }

2296 "no resource section found");

2297}

2298

2300 Obj = O;

2301 Section = S;

2303 if (!Contents)

2306 const coff_section *COFFSect = Obj->getCOFFSection(Section);

2308 Relocs.reserve(OrigRelocs.size());

2310 Relocs.push_back(&R);

2312 return A->VirtualAddress < B->VirtualAddress;

2313 });

2315}

2316

2319 if (!Obj)

2321

2322

2323

2324 const uint8_t *EntryPtr = reinterpret_cast<const uint8_t *>(&Entry);

2325 ptrdiff_t EntryOffset = EntryPtr - BBS.data().data();

2326 coff_relocation RelocTarget{ulittle32_t(EntryOffset), ulittle32_t(0),

2327 ulittle16_t(0)};

2328 auto RelocsForOffset =

2329 std::equal_range(Relocs.begin(), Relocs.end(), &RelocTarget,

2331 return A->VirtualAddress < B->VirtualAddress;

2332 });

2333

2334 if (RelocsForOffset.first != RelocsForOffset.second) {

2335

2336

2339 switch (Obj->getArch()) {

2342 break;

2345 break;

2348 break;

2351 break;

2352 default:

2354 "unsupported architecture");

2355 }

2356 if (R.Type != RVAReloc)

2358 "unexpected relocation type");

2359

2361 if (!Sym)

2363

2365 Obj->getSection(Sym->getSectionNumber());

2366 if (!Section)

2368

2369

2372 if (Error E = Obj->getSectionContents(*Section, Contents))

2373 return E;

2374 if (Offset + Entry.DataSize > Contents.size())

2376 "data outside of section");

2377

2378 return StringRef(reinterpret_cast<const char *>(Contents.data()) + Offset,

2379 Entry.DataSize);

2380 } else {

2381

2382 if (Obj->isRelocatableObject())

2384 "no relocation found for DataRVA");

2385

2386

2387 uint64_t VA = Entry.DataRVA + Obj->getImageBase();

2388 for (const SectionRef &S : Obj->sections()) {

2389 if (VA >= S.getAddress() &&

2390 VA + Entry.DataSize <= S.getAddress() + S.getSize()) {

2393 if (!Contents)

2395 return Contents->substr(Offset, Entry.DataSize);

2396 }

2397 }

2399 "address not found in image");

2400 }

2401}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

AMDGPU Mark last scratch load

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

static imported_symbol_iterator importedSymbolEnd(uint32_t RVA, const COFFObjectFile *Object)

Definition COFFObjectFile.cpp:1601

static uint32_t getNumberOfRelocations(const coff_section *Sec, MemoryBufferRef M, const uint8_t *base)

Definition COFFObjectFile.cpp:355

static Error getObject(const T *&Obj, MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))

Definition COFFObjectFile.cpp:57

static imported_symbol_iterator makeImportedSymbolIterator(const COFFObjectFile *Object, uintptr_t Ptr, int Index)

Definition COFFObjectFile.cpp:1582

#define LLVM_COFF_SWITCH_RELOC_TYPE_NAME(reloc_type)

Definition COFFObjectFile.cpp:1377

static const coff_relocation * getFirstReloc(const coff_section *Sec, MemoryBufferRef M, const uint8_t *Base)

Definition COFFObjectFile.cpp:376

static imported_symbol_iterator importedSymbolBegin(uint32_t RVA, const COFFObjectFile *Object)

Definition COFFObjectFile.cpp:1593

static bool checkSize(MemoryBufferRef M, std::error_code &EC, uint64_t Size)

Definition COFFObjectFile.cpp:46

#define RETURN_IF_ERROR(Expr)

Definition COFFObjectFile.cpp:2203

static bool decodeBase64StringEntry(StringRef Str, uint32_t &Result)

Definition COFFObjectFile.cpp:68

static Error ignoreStrippedErrors(Error E)

Definition COFFObjectFile.cpp:879

#define offsetof(TYPE, MEMBER)

Merge contiguous icmps into a memcmp

This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

ArrayRef< T > drop_front(size_t N=1) const

Drop the first N elements of the array.

size_t size() const

size - Get the array size.

An implementation of BinaryStream which holds its entire data set in a single contiguous buffer.

Provides read only access to a subclass of BinaryStream.

Error readInteger(T &Dest)

Read an integer of the specified endianness into Dest and update the stream's offset.

void setOffset(uint64_t Off)

Error readArray(ArrayRef< T > &Array, uint32_t NumElements)

Get a reference to a NumElements element array of objects of type T from the underlying stream as if ...

Lightweight error class with error context and mandatory checking.

static ErrorSuccess success()

Create a success value.

Tagged union holding either a T or a Error.

Error takeError()

Take ownership of the stored error.

reference get()

Returns a reference to the stored T value.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

StringRef - Represent a constant reference to a string, i.e.

std::pair< StringRef, StringRef > split(char Separator) const

Split into two substrings around the first occurrence of a separator character.

A switch()-like statement whose cases are string literals.

StringSwitch & Case(StringLiteral S, T Value)

A table of densely packed, null-terminated strings indexed by offset.

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

The instances of the Type class are immutable: once they are created, they are never changed.

LLVM Value Representation.

static LLVM_ABI std::unique_ptr< WritableMemoryBuffer > getNewUninitMemBuffer(size_t Size, const Twine &BufferName="", std::optional< Align > Alignment=std::nullopt)

Allocate a new MemoryBuffer of the specified size that is not initialized.

A range adaptor for a pair of iterators.

LLVM_ABI bool operator==(const Arm64XRelocRef &Other) const

Definition COFFObjectFile.cpp:2079

COFF::Arm64XFixupType getType() const

LLVM_ABI uint8_t getSize() const

Definition COFFObjectFile.cpp:2107

LLVM_ABI uint64_t getValue() const

Definition COFFObjectFile.cpp:2118

LLVM_ABI void moveNext()

Definition COFFObjectFile.cpp:2094

LLVM_ABI void moveNext()

Definition COFFObjectFile.cpp:1904

LLVM_ABI Error getType(uint8_t &Type) const

Definition COFFObjectFile.cpp:1922

LLVM_ABI bool operator==(const BaseRelocRef &Other) const

Definition COFFObjectFile.cpp:1900

LLVM_ABI Error getRVA(uint32_t &Result) const

Definition COFFObjectFile.cpp:1928

DataRefImpl getRawDataRefImpl() const

static Error checkOffset(MemoryBufferRef M, uintptr_t Addr, const uint64_t Size)

const dos_header * getDOSHeader() const

uint64_t getSectionSize(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:288

Expected< StringRef > getSectionName(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:269

uint64_t getSectionIndex(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:284

dynamic_reloc_iterator dynamic_reloc_begin() const

Definition COFFObjectFile.cpp:1104

std::unique_ptr< MemoryBuffer > getHybridObjectView() const

Definition COFFObjectFile.cpp:1515

uint32_t getSymbolAlignment(DataRefImpl Symb) const override

Definition COFFObjectFile.cpp:158

bool isSectionCompressed(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:306

void moveRelocationNext(DataRefImpl &Rel) const override

Definition COFFObjectFile.cpp:1320

Expected< section_iterator > getSymbolSection(DataRefImpl Symb) const override

Definition COFFObjectFile.cpp:246

uint8_t getBytesInAddress() const override

The number of bytes used to represent an address in this object file format.

Definition COFFObjectFile.cpp:1117

export_directory_iterator export_directory_begin() const

Definition COFFObjectFile.cpp:1069

delay_import_directory_iterator delay_import_directory_end() const

Definition COFFObjectFile.cpp:1063

base_reloc_iterator base_reloc_begin() const

Definition COFFObjectFile.cpp:1096

section_iterator section_end() const override

Definition COFFObjectFile.cpp:1088

Error getVaPtr(uint64_t VA, uintptr_t &Res) const

Definition COFFObjectFile.cpp:464

uint64_t getRelocationType(DataRefImpl Rel) const override

Definition COFFObjectFile.cpp:1344

void moveSymbolNext(DataRefImpl &Symb) const override

Definition COFFObjectFile.cpp:135

uint64_t getCommonSymbolSizeImpl(DataRefImpl Symb) const override

Definition COFFObjectFile.cpp:240

iterator_range< delay_import_directory_iterator > delay_import_directories() const

Definition COFFObjectFile.cpp:1158

import_directory_iterator import_directory_end() const

Definition COFFObjectFile.cpp:1051

uint32_t getPointerToSymbolTable() const

const coff_relocation * getCOFFRelocation(const RelocationRef &Reloc) const

Definition COFFObjectFile.cpp:1367

Expected< StringRef > getSymbolName(DataRefImpl Symb) const override

Definition COFFObjectFile.cpp:150

bool isDebugSection(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:330

iterator_range< const debug_directory * > debug_directories() const

StringRef getRelocationTypeName(uint16_t Type) const

Definition COFFObjectFile.cpp:1381

bool isSectionBSS(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:320

base_reloc_iterator base_reloc_end() const

Definition COFFObjectFile.cpp:1100

uint64_t getSectionAddress(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:274

Expected< uint64_t > getSymbolAddress(DataRefImpl Symb) const override

Definition COFFObjectFile.cpp:165

uint32_t getNumberOfSymbols() const

section_iterator section_begin() const override

Definition COFFObjectFile.cpp:1082

Expected< SymbolRef::Type > getSymbolType(DataRefImpl Symb) const override

Definition COFFObjectFile.cpp:186

size_t getSymbolTableEntrySize() const

friend class ImportDirectoryEntryRef

export_directory_iterator export_directory_end() const

Definition COFFObjectFile.cpp:1074

Error getHintName(uint32_t Rva, uint16_t &Hint, StringRef &Name) const

Definition COFFObjectFile.cpp:534

uintptr_t getSymbolTable() const

static Expected< std::unique_ptr< COFFObjectFile > > create(MemoryBufferRef Object)

Definition COFFObjectFile.cpp:861

bool isSectionVirtual(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:348

unsigned getSectionID(SectionRef Sec) const

Definition COFFObjectFile.cpp:341

relocation_iterator section_rel_begin(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:395

iterator_range< import_directory_iterator > import_directories() const

Definition COFFObjectFile.cpp:1153

delay_import_directory_iterator delay_import_directory_begin() const

Definition COFFObjectFile.cpp:1057

basic_symbol_iterator symbol_end() const override

Definition COFFObjectFile.cpp:1035

Error getRvaAndSizeAsBytes(uint32_t RVA, uint32_t Size, ArrayRef< uint8_t > &Contents, const char *ErrorContext=nullptr) const

Given an RVA base and size, returns a valid array of bytes or an error code if the RVA and size is no...

Definition COFFObjectFile.cpp:506

const coff_load_configuration64 * getLoadConfig64() const

iterator_range< export_directory_iterator > export_directories() const

Definition COFFObjectFile.cpp:1164

uint32_t getNumberOfSections() const

uint64_t getRelocationOffset(DataRefImpl Rel) const override

Definition COFFObjectFile.cpp:1325

basic_symbol_iterator symbol_begin() const override

Definition COFFObjectFile.cpp:1029

Triple::ArchType getArch() const override

Definition COFFObjectFile.cpp:1142

bool isRelocatableObject() const override

True if this is a relocatable object (.o/.obj).

Definition COFFObjectFile.cpp:1505

Expected< uint32_t > getSymbolFlags(DataRefImpl Symb) const override

Definition COFFObjectFile.cpp:209

Expected< const coff_section * > getSection(int32_t index) const

Definition COFFObjectFile.cpp:1187

bool isSectionText(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:310

Expected< ArrayRef< uint8_t > > getSectionContents(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:293

const data_directory * getDataDirectory(uint32_t index) const

Definition COFFObjectFile.cpp:1176

StringRef mapDebugSectionName(StringRef Name) const override

Maps a debug section name to a standard DWARF section name.

Definition COFFObjectFile.cpp:1509

ArrayRef< uint8_t > getSymbolAuxData(COFFSymbolRef Symbol) const

Definition COFFObjectFile.cpp:1228

uint64_t getImageBase() const

Definition COFFObjectFile.cpp:454

const coff_load_configuration32 * getLoadConfig32() const

const coff_section * getCOFFSection(const SectionRef &Section) const

Definition COFFObjectFile.cpp:1350

import_directory_iterator import_directory_begin() const

Definition COFFObjectFile.cpp:1042

void moveSectionNext(DataRefImpl &Sec) const override

Definition COFFObjectFile.cpp:263

relocation_iterator section_rel_end(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:405

dynamic_reloc_iterator dynamic_reloc_end() const

Definition COFFObjectFile.cpp:1109

ArrayRef< coff_relocation > getRelocations(const coff_section *Sec) const

Definition COFFObjectFile.cpp:1372

uint64_t getSymbolValueImpl(DataRefImpl Symb) const override

Definition COFFObjectFile.cpp:154

Error getRvaPtr(uint32_t Rva, uintptr_t &Res, const char *ErrorContext=nullptr) const

Definition COFFObjectFile.cpp:472

iterator_range< dynamic_reloc_iterator > dynamic_relocs() const

Definition COFFObjectFile.cpp:1172

unsigned getSymbolSectionID(SymbolRef Sym) const

Definition COFFObjectFile.cpp:258

Error getDebugPDBInfo(const debug_directory *DebugDir, const codeview::DebugInfo *&Info, StringRef &PDBFileName) const

Get PDB information out of a codeview debug directory entry.

Definition COFFObjectFile.cpp:545

friend class ExportDirectoryEntryRef

symbol_iterator getRelocationSymbol(DataRefImpl Rel) const override

Definition COFFObjectFile.cpp:1330

uint64_t getSectionAlignment(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:301

uint32_t getSymbolIndex(COFFSymbolRef Symbol) const

Definition COFFObjectFile.cpp:1250

uint16_t getMachine() const

COFFSymbolRef getCOFFSymbol(const DataRefImpl &Ref) const

Definition COFFObjectFile.cpp:1354

Expected< uint64_t > getStartAddress() const override

Definition COFFObjectFile.cpp:1146

iterator_range< base_reloc_iterator > base_relocs() const

Definition COFFObjectFile.cpp:1168

bool isSectionData(DataRefImpl Sec) const override

Definition COFFObjectFile.cpp:315

StringRef getFileFormatName() const override

Definition COFFObjectFile.cpp:1121

bool isAnyUndefined() const

bool isFileRecord() const

const coff_aux_weak_external * getWeakExternal() const

bool isSectionDefinition() const

uint8_t getComplexType() const

uint32_t getValue() const

bool isWeakExternal() const

int32_t getSectionNumber() const

LLVM_ABI void moveNext()

Definition COFFObjectFile.cpp:1677

LLVM_ABI bool operator==(const DelayImportDirectoryEntryRef &Other) const

Definition COFFObjectFile.cpp:1673

LLVM_ABI imported_symbol_iterator imported_symbol_begin() const

Definition COFFObjectFile.cpp:1682

LLVM_ABI Error getImportAddress(int AddrIndex, uint64_t &Result) const

Definition COFFObjectFile.cpp:1713

LLVM_ABI iterator_range< imported_symbol_iterator > imported_symbols() const

Definition COFFObjectFile.cpp:1694

DelayImportDirectoryEntryRef()=default

LLVM_ABI imported_symbol_iterator imported_symbol_end() const

Definition COFFObjectFile.cpp:1688

LLVM_ABI Error getDelayImportTable(const delay_import_directory_table_entry *&Result) const

Definition COFFObjectFile.cpp:1707

LLVM_ABI Error getName(StringRef &Result) const

Definition COFFObjectFile.cpp:1698

LLVM_ABI bool operator==(const DynamicRelocRef &Other) const

Definition COFFObjectFile.cpp:1934

LLVM_ABI arm64x_reloc_iterator arm64x_reloc_begin() const

Definition COFFObjectFile.cpp:2057

LLVM_ABI void getContents(ArrayRef< uint8_t > &Ref) const

Definition COFFObjectFile.cpp:1986

DynamicRelocRef()=default

LLVM_ABI uint32_t getType() const

Definition COFFObjectFile.cpp:1961

LLVM_ABI arm64x_reloc_iterator arm64x_reloc_end() const

Definition COFFObjectFile.cpp:2066

LLVM_ABI iterator_range< arm64x_reloc_iterator > arm64x_relocs() const

Definition COFFObjectFile.cpp:2075

LLVM_ABI void moveNext()

Definition COFFObjectFile.cpp:1938

LLVM_ABI bool operator==(const ExportDirectoryEntryRef &Other) const

Definition COFFObjectFile.cpp:1728

LLVM_ABI Error getDllName(StringRef &Result) const

Definition COFFObjectFile.cpp:1738

LLVM_ABI void moveNext()

Definition COFFObjectFile.cpp:1732

LLVM_ABI Error getExportRVA(uint32_t &Result) const

Definition COFFObjectFile.cpp:1760

LLVM_ABI Error getOrdinalBase(uint32_t &Result) const

Definition COFFObjectFile.cpp:1748

LLVM_ABI Error getOrdinal(uint32_t &Result) const

Definition COFFObjectFile.cpp:1754

LLVM_ABI Error isForwarder(bool &Result) const

Definition COFFObjectFile.cpp:1801

LLVM_ABI Error getForwardTo(StringRef &Result) const

Definition COFFObjectFile.cpp:1816

LLVM_ABI Error getSymbolName(StringRef &Result) const

Definition COFFObjectFile.cpp:1774

ExportDirectoryEntryRef()=default

LLVM_ABI bool operator==(const ImportDirectoryEntryRef &Other) const

Definition COFFObjectFile.cpp:1564

LLVM_ABI imported_symbol_iterator imported_symbol_end() const

Definition COFFObjectFile.cpp:1626

LLVM_ABI imported_symbol_iterator imported_symbol_begin() const

Definition COFFObjectFile.cpp:1620

LLVM_ABI Error getImportLookupTableRVA(uint32_t &Result) const

Definition COFFObjectFile.cpp:1661

LLVM_ABI Error getImportTableEntry(const coff_import_directory_table_entry *&Result) const

Definition COFFObjectFile.cpp:1576

LLVM_ABI imported_symbol_iterator lookup_table_end() const

Definition COFFObjectFile.cpp:1641

ImportDirectoryEntryRef()=default

LLVM_ABI iterator_range< imported_symbol_iterator > lookup_table_symbols() const

Definition COFFObjectFile.cpp:1647

LLVM_ABI iterator_range< imported_symbol_iterator > imported_symbols() const

Definition COFFObjectFile.cpp:1632

LLVM_ABI imported_symbol_iterator lookup_table_begin() const

Definition COFFObjectFile.cpp:1636

LLVM_ABI void moveNext()

Definition COFFObjectFile.cpp:1568

LLVM_ABI Error getImportAddressTableRVA(uint32_t &Result) const

Definition COFFObjectFile.cpp:1666

LLVM_ABI Error getName(StringRef &Result) const

Definition COFFObjectFile.cpp:1651

LLVM_ABI bool operator==(const ImportedSymbolRef &Other) const

Definition COFFObjectFile.cpp:1828

LLVM_ABI Error getHintNameRVA(uint32_t &Result) const

Definition COFFObjectFile.cpp:1865

LLVM_ABI Error getOrdinal(uint16_t &Result) const

Definition COFFObjectFile.cpp:1873

ImportedSymbolRef()=default

LLVM_ABI void moveNext()

Definition COFFObjectFile.cpp:1833

LLVM_ABI Error getSymbolName(StringRef &Result) const

Definition COFFObjectFile.cpp:1837

LLVM_ABI Error isOrdinal(bool &Result) const

Definition COFFObjectFile.cpp:1857

This class is the base class for all object file types.

friend class RelocationRef

static Expected< std::unique_ptr< COFFObjectFile > > createCOFFObjectFile(MemoryBufferRef Object)

Definition COFFObjectFile.cpp:1896

section_iterator_range sections() const

Expected< uint64_t > getSymbolValue(DataRefImpl Symb) const

const uint8_t * base() const

LLVM_ABI Expected< const coff_resource_dir_table & > getBaseTable()

Definition COFFObjectFile.cpp:2271

LLVM_ABI Expected< const coff_resource_dir_table & > getEntrySubDir(const coff_resource_dir_entry &Entry)

Definition COFFObjectFile.cpp:2260

LLVM_ABI Expected< const coff_resource_data_entry & > getEntryData(const coff_resource_dir_entry &Entry)

Definition COFFObjectFile.cpp:2266

LLVM_ABI Error load(const COFFObjectFile *O)

Definition COFFObjectFile.cpp:2286

LLVM_ABI Expected< ArrayRef< UTF16 > > getEntryNameString(const coff_resource_dir_entry &Entry)

Definition COFFObjectFile.cpp:2222

LLVM_ABI Expected< StringRef > getContents(const coff_resource_data_entry &Entry)

Definition COFFObjectFile.cpp:2318

LLVM_ABI Expected< const coff_resource_dir_entry & > getTableEntry(const coff_resource_dir_table &Table, uint32_t Index)

Definition COFFObjectFile.cpp:2276

This is a value type class that represents a single section in the list of sections in the object fil...

DataRefImpl getRawDataRefImpl() const

This provides a very simple, boring adaptor for a begin and end iterator into a range type.

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

@ IMAGE_DYNAMIC_RELOCATION_ARM64X

@ IMAGE_FILE_MACHINE_ARM64

@ IMAGE_FILE_MACHINE_UNKNOWN

@ IMAGE_FILE_MACHINE_AMD64

@ IMAGE_FILE_MACHINE_ARM64EC

@ IMAGE_FILE_MACHINE_R4000

@ IMAGE_FILE_MACHINE_I386

@ IMAGE_FILE_MACHINE_ARM64X

@ IMAGE_FILE_MACHINE_ARMNT

@ IMAGE_SCN_CNT_UNINITIALIZED_DATA

@ IMAGE_SCN_CNT_INITIALIZED_DATA

@ IMAGE_DEBUG_TYPE_CODEVIEW

@ IMAGE_REL_ARM64_ADDR32NB

@ IMAGE_REL_AMD64_ADDR32NB

@ DELAY_IMPORT_DESCRIPTOR

@ IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE

@ IMAGE_DVRT_ARM64X_FIXUP_TYPE_DELTA

@ IMAGE_DVRT_ARM64X_FIXUP_TYPE_ZEROFILL

@ IMAGE_WEAK_EXTERN_SEARCH_ALIAS

bool isReservedSectionNumber(int32_t SectionNumber)

static const char BigObjMagic[]

static const char PEMagic[]

@ IMAGE_SYM_DTYPE_FUNCTION

A function that returns a base type.

static Expected< const T * > getObject(MemoryBufferRef M, const void *Ptr, const uint64_t Size=sizeof(T))

content_iterator< SectionRef > section_iterator

coff_tls_directory< support::little64_t > coff_tls_directory64

content_iterator< BaseRelocRef > base_reloc_iterator

content_iterator< ExportDirectoryEntryRef > export_directory_iterator

content_iterator< BasicSymbolRef > basic_symbol_iterator

content_iterator< ImportedSymbolRef > imported_symbol_iterator

content_iterator< ImportDirectoryEntryRef > import_directory_iterator

coff_tls_directory< support::little32_t > coff_tls_directory32

import_lookup_table_entry< support::little32_t > import_lookup_table_entry32

coff_symbol< support::ulittle16_t > coff_symbol16

import_lookup_table_entry< support::little64_t > import_lookup_table_entry64

coff_symbol< support::ulittle32_t > coff_symbol32

content_iterator< RelocationRef > relocation_iterator

content_iterator< DynamicRelocRef > dynamic_reloc_iterator

content_iterator< Arm64XRelocRef > arm64x_reloc_iterator

content_iterator< DelayImportDirectoryEntryRef > delay_import_directory_iterator

detail::packed_endian_specific_integral< uint64_t, llvm::endianness::little, unaligned > ulittle64_t

detail::packed_endian_specific_integral< int16_t, llvm::endianness::little, unaligned > little16_t

detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t

detail::packed_endian_specific_integral< uint16_t, llvm::endianness::little, unaligned > ulittle16_t

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

Triple::ArchType getMachineArchType(T machine)

Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)

Create formatted StringError object.

uint64_t PowerOf2Ceil(uint64_t A)

Returns the power of two which is greater than or equal to the given value.

void sort(IteratorTy Start, IteratorTy End)

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

Error make_error(ArgTs &&... Args)

Make a Error instance representing failure using the given error info type.

@ Ref

The access may reference the value stored in memory.

void cantFail(Error Err, const char *Msg=nullptr)

Report a fatal error if Err is a failure value.

FunctionAddr VTableAddr uintptr_t uintptr_t Data

ArrayRef(const T &OneElt) -> ArrayRef< T >

LLVM_ABI Error errorCodeToError(std::error_code EC)

Helper for converting an std::error_code to a Error.

void consumeError(Error Err)

Consume a Error without doing anything.

support::ulittle32_t Version

support::ulittle32_t Size

support::ulittle32_t VirtualAddress

support::ulittle16_t NumberOfNameEntries

support::ulittle16_t NumberOfIDEntries

support::ulittle32_t PointerToRawData

char Name[COFF::NameSize]

support::ulittle32_t VirtualSize

bool hasExtendedRelocations() const

uint32_t getAlignment() const

support::ulittle32_t Characteristics

support::ulittle32_t SizeOfRawData

support::ulittle32_t VirtualAddress

support::ulittle32_t PointerToRelocations

support::ulittle16_t NumberOfRelocations

uint8_t NumberOfAuxSymbols

support::ulittle32_t RelativeVirtualAddress

support::ulittle32_t Size

support::ulittle32_t SizeOfData

support::ulittle32_t AddressOfRawData

support::ulittle32_t ExportRVA