llvm.org GIT mirror llvm / 4787059
llvm-readobj: Add support for dumping the DOS header in PE files git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221333 91177308-0d34-0410-b5e6-96231b3b80d8 David Majnemer 6 years ago
5 changed file(s) with 67 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
3535
3636 /// The DOS compatible header at the front of all PE/COFF executables.
3737 struct dos_header {
38 support::ulittle16_t Magic;
38 char Magic[2];
3939 support::ulittle16_t UsedBytesInTheLastPage;
4040 support::ulittle16_t FileSizeInPages;
4141 support::ulittle16_t NumberOfRelocationItems;
620620 delay_import_directories() const;
621621 iterator_range export_directories() const;
622622
623 const dos_header *getDOSHeader() const {
624 if (!PE32Header && !PE32PlusHeader)
625 return nullptr;
626 return reinterpret_cast(base());
627 }
623628 std::error_code getPE32Header(const pe32_header *&Res) const;
624629 std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const;
625630 std::error_code getDataDirectory(uint32_t index,
571571 bool HasPEHeader = false;
572572
573573 // Check if this is a PE/COFF file.
574 if (base()[0] == 0x4d && base()[1] == 0x5a) {
574 if (checkSize(Data, EC, sizeof(dos_header) + sizeof(COFF::PEMagic))) {
575575 // PE/COFF, seek through MS-DOS compatibility stub and 4-byte
576576 // PE signature to find 'normal' COFF header.
577 if (!checkSize(Data, EC, 0x3c + 8))
578 return;
579 CurPtr = *reinterpret_cast(base() + 0x3c);
580 // Check the PE magic bytes. ("PE\0\0")
581 if (std::memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) !=
582 0) {
583 EC = object_error::parse_failed;
584 return;
577 const auto *DH = reinterpret_cast(base());
578 if (DH->Magic[0] == 'M' && DH->Magic[1] == 'Z') {
579 CurPtr = DH->AddressOfNewExeHeader;
580 // Check the PE magic bytes. ("PE\0\0")
581 if (memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0) {
582 EC = object_error::parse_failed;
583 return;
584 }
585 CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
586 HasPEHeader = true;
585587 }
586 CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
587 HasPEHeader = true;
588588 }
589589
590590 if ((EC = getObject(COFFHeader, Data, base() + CurPtr)))
626626
627627 const uint8_t *DataDirAddr;
628628 uint64_t DataDirSize;
629 if (Header->Magic == 0x10b) {
629 if (Header->Magic == COFF::PE32Header::PE32) {
630630 PE32Header = Header;
631631 DataDirAddr = base() + CurPtr + sizeof(pe32_header);
632632 DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize;
633 } else if (Header->Magic == 0x20b) {
633 } else if (Header->Magic == COFF::PE32Header::PE32_PLUS) {
634634 PE32PlusHeader = reinterpret_cast(Header);
635635 DataDirAddr = base() + CurPtr + sizeof(pe32plus_header);
636636 DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;
10191019 return file_magic::coff_object;
10201020 break;
10211021
1022 case 0x4d: // Possible MS-DOS stub on Windows PE file
1023 if (Magic[1] == 0x5a) {
1022 case 'M': // Possible MS-DOS stub on Windows PE file
1023 if (Magic[1] == 'Z') {
10241024 uint32_t off =
10251025 *reinterpret_cast(Magic.data() + 0x3c);
10261026 // PE/COFF file, either EXE or DLL.
1027 if (off < Magic.size() && memcmp(Magic.data() + off, "PE\0\0",4) == 0)
1027 if (off < Magic.size() &&
1028 memcmp(Magic.data()+off, COFF::PEMagic, sizeof(COFF::PEMagic)) == 0)
10281029 return file_magic::pecoff_executable;
10291030 }
10301031 break;
203203 PE32-NEXT: ReservedSize: 0x0
204204 PE32-NEXT: }
205205 PE32-NEXT: }
206 PE32-NEXT: DOSHeader {
207 PE32-NEXT: Magic: MZ
208 PE32-NEXT: UsedBytesInTheLastPage: 144
209 PE32-NEXT: FileSizeInPages: 3
210 PE32-NEXT: NumberOfRelocationItems: 0
211 PE32-NEXT: HeaderSizeInParagraphs: 4
212 PE32-NEXT: MinimumExtraParagraphs: 0
213 PE32-NEXT: MaximumExtraParagraphs: 65535
214 PE32-NEXT: InitialRelativeSS: 0
215 PE32-NEXT: InitialSP: 184
216 PE32-NEXT: Checksum: 0
217 PE32-NEXT: InitialIP: 0
218 PE32-NEXT: InitialRelativeCS: 0
219 PE32-NEXT: AddressOfRelocationTable: 64
220 PE32-NEXT: OverlayNumber: 0
221 PE32-NEXT: OEMid: 0
222 PE32-NEXT: OEMinfo: 0
223 PE32-NEXT: AddressOfNewExeHeader: 176
224 PE32-NEXT: }
206225
207226 COFF-UNKNOWN: Format: COFF-
208227 COFF-UNKNOWN-NEXT: Arch: unknown
6262 void printRelocation(const SectionRef &Section, const RelocationRef &Reloc);
6363 void printDataDirectory(uint32_t Index, const std::string &FieldName);
6464
65 void printDOSHeader(const dos_header *DH);
6566 template void printPEHeader(const PEHeader *Hdr);
6667 void printBaseOfDataField(const pe32_header *Hdr);
6768 void printBaseOfDataField(const pe32plus_header *Hdr);
381382 return;
382383 if (PEPlusHeader)
383384 printPEHeader(PEPlusHeader);
385
386 if (const dos_header *DH = Obj->getDOSHeader())
387 printDOSHeader(DH);
388 }
389
390 void COFFDumper::printDOSHeader(const dos_header *DH) {
391 DictScope D(W, "DOSHeader");
392 W.printString("Magic", StringRef(DH->Magic, sizeof(DH->Magic)));
393 W.printNumber("UsedBytesInTheLastPage", DH->UsedBytesInTheLastPage);
394 W.printNumber("FileSizeInPages", DH->FileSizeInPages);
395 W.printNumber("NumberOfRelocationItems", DH->NumberOfRelocationItems);
396 W.printNumber("HeaderSizeInParagraphs", DH->HeaderSizeInParagraphs);
397 W.printNumber("MinimumExtraParagraphs", DH->MinimumExtraParagraphs);
398 W.printNumber("MaximumExtraParagraphs", DH->MaximumExtraParagraphs);
399 W.printNumber("InitialRelativeSS", DH->InitialRelativeSS);
400 W.printNumber("InitialSP", DH->InitialSP);
401 W.printNumber("Checksum", DH->Checksum);
402 W.printNumber("InitialIP", DH->InitialIP);
403 W.printNumber("InitialRelativeCS", DH->InitialRelativeCS);
404 W.printNumber("AddressOfRelocationTable", DH->AddressOfRelocationTable);
405 W.printNumber("OverlayNumber", DH->OverlayNumber);
406 W.printNumber("OEMid", DH->OEMid);
407 W.printNumber("OEMinfo", DH->OEMinfo);
408 W.printNumber("AddressOfNewExeHeader", DH->AddressOfNewExeHeader);
384409 }
385410
386411 template