mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 00:11:00 +00:00
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
This commit is contained in:
parent
07e1080b89
commit
4787059b2f
@ -36,7 +36,7 @@ typedef content_iterator<ImportedSymbolRef> imported_symbol_iterator;
|
||||
|
||||
/// The DOS compatible header at the front of all PE/COFF executables.
|
||||
struct dos_header {
|
||||
support::ulittle16_t Magic;
|
||||
char Magic[2];
|
||||
support::ulittle16_t UsedBytesInTheLastPage;
|
||||
support::ulittle16_t FileSizeInPages;
|
||||
support::ulittle16_t NumberOfRelocationItems;
|
||||
@ -621,6 +621,11 @@ public:
|
||||
delay_import_directories() const;
|
||||
iterator_range<export_directory_iterator> export_directories() const;
|
||||
|
||||
const dos_header *getDOSHeader() const {
|
||||
if (!PE32Header && !PE32PlusHeader)
|
||||
return nullptr;
|
||||
return reinterpret_cast<const dos_header *>(base());
|
||||
}
|
||||
std::error_code getPE32Header(const pe32_header *&Res) const;
|
||||
std::error_code getPE32PlusHeader(const pe32plus_header *&Res) const;
|
||||
std::error_code getDataDirectory(uint32_t index,
|
||||
|
@ -572,20 +572,20 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
|
||||
bool HasPEHeader = false;
|
||||
|
||||
// Check if this is a PE/COFF file.
|
||||
if (base()[0] == 0x4d && base()[1] == 0x5a) {
|
||||
if (checkSize(Data, EC, sizeof(dos_header) + sizeof(COFF::PEMagic))) {
|
||||
// PE/COFF, seek through MS-DOS compatibility stub and 4-byte
|
||||
// PE signature to find 'normal' COFF header.
|
||||
if (!checkSize(Data, EC, 0x3c + 8))
|
||||
return;
|
||||
CurPtr = *reinterpret_cast<const ulittle16_t *>(base() + 0x3c);
|
||||
// Check the PE magic bytes. ("PE\0\0")
|
||||
if (std::memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) !=
|
||||
0) {
|
||||
EC = object_error::parse_failed;
|
||||
return;
|
||||
const auto *DH = reinterpret_cast<const dos_header *>(base());
|
||||
if (DH->Magic[0] == 'M' && DH->Magic[1] == 'Z') {
|
||||
CurPtr = DH->AddressOfNewExeHeader;
|
||||
// Check the PE magic bytes. ("PE\0\0")
|
||||
if (memcmp(base() + CurPtr, COFF::PEMagic, sizeof(COFF::PEMagic)) != 0) {
|
||||
EC = object_error::parse_failed;
|
||||
return;
|
||||
}
|
||||
CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
|
||||
HasPEHeader = true;
|
||||
}
|
||||
CurPtr += sizeof(COFF::PEMagic); // Skip the PE magic bytes.
|
||||
HasPEHeader = true;
|
||||
}
|
||||
|
||||
if ((EC = getObject(COFFHeader, Data, base() + CurPtr)))
|
||||
@ -627,11 +627,11 @@ COFFObjectFile::COFFObjectFile(MemoryBufferRef Object, std::error_code &EC)
|
||||
|
||||
const uint8_t *DataDirAddr;
|
||||
uint64_t DataDirSize;
|
||||
if (Header->Magic == 0x10b) {
|
||||
if (Header->Magic == COFF::PE32Header::PE32) {
|
||||
PE32Header = Header;
|
||||
DataDirAddr = base() + CurPtr + sizeof(pe32_header);
|
||||
DataDirSize = sizeof(data_directory) * PE32Header->NumberOfRvaAndSize;
|
||||
} else if (Header->Magic == 0x20b) {
|
||||
} else if (Header->Magic == COFF::PE32Header::PE32_PLUS) {
|
||||
PE32PlusHeader = reinterpret_cast<const pe32plus_header *>(Header);
|
||||
DataDirAddr = base() + CurPtr + sizeof(pe32plus_header);
|
||||
DataDirSize = sizeof(data_directory) * PE32PlusHeader->NumberOfRvaAndSize;
|
||||
|
@ -1020,12 +1020,13 @@ file_magic identify_magic(StringRef Magic) {
|
||||
return file_magic::coff_object;
|
||||
break;
|
||||
|
||||
case 0x4d: // Possible MS-DOS stub on Windows PE file
|
||||
if (Magic[1] == 0x5a) {
|
||||
case 'M': // Possible MS-DOS stub on Windows PE file
|
||||
if (Magic[1] == 'Z') {
|
||||
uint32_t off =
|
||||
*reinterpret_cast<const support::ulittle32_t*>(Magic.data() + 0x3c);
|
||||
// PE/COFF file, either EXE or DLL.
|
||||
if (off < Magic.size() && memcmp(Magic.data() + off, "PE\0\0",4) == 0)
|
||||
if (off < Magic.size() &&
|
||||
memcmp(Magic.data()+off, COFF::PEMagic, sizeof(COFF::PEMagic)) == 0)
|
||||
return file_magic::pecoff_executable;
|
||||
}
|
||||
break;
|
||||
|
@ -204,6 +204,25 @@ PE32-NEXT: ReservedRVA: 0x0
|
||||
PE32-NEXT: ReservedSize: 0x0
|
||||
PE32-NEXT: }
|
||||
PE32-NEXT: }
|
||||
PE32-NEXT: DOSHeader {
|
||||
PE32-NEXT: Magic: MZ
|
||||
PE32-NEXT: UsedBytesInTheLastPage: 144
|
||||
PE32-NEXT: FileSizeInPages: 3
|
||||
PE32-NEXT: NumberOfRelocationItems: 0
|
||||
PE32-NEXT: HeaderSizeInParagraphs: 4
|
||||
PE32-NEXT: MinimumExtraParagraphs: 0
|
||||
PE32-NEXT: MaximumExtraParagraphs: 65535
|
||||
PE32-NEXT: InitialRelativeSS: 0
|
||||
PE32-NEXT: InitialSP: 184
|
||||
PE32-NEXT: Checksum: 0
|
||||
PE32-NEXT: InitialIP: 0
|
||||
PE32-NEXT: InitialRelativeCS: 0
|
||||
PE32-NEXT: AddressOfRelocationTable: 64
|
||||
PE32-NEXT: OverlayNumber: 0
|
||||
PE32-NEXT: OEMid: 0
|
||||
PE32-NEXT: OEMinfo: 0
|
||||
PE32-NEXT: AddressOfNewExeHeader: 176
|
||||
PE32-NEXT: }
|
||||
|
||||
COFF-UNKNOWN: Format: COFF-<unknown arch>
|
||||
COFF-UNKNOWN-NEXT: Arch: unknown
|
||||
|
@ -63,6 +63,7 @@ private:
|
||||
void printRelocation(const SectionRef &Section, const RelocationRef &Reloc);
|
||||
void printDataDirectory(uint32_t Index, const std::string &FieldName);
|
||||
|
||||
void printDOSHeader(const dos_header *DH);
|
||||
template <class PEHeader> void printPEHeader(const PEHeader *Hdr);
|
||||
void printBaseOfDataField(const pe32_header *Hdr);
|
||||
void printBaseOfDataField(const pe32plus_header *Hdr);
|
||||
@ -382,6 +383,30 @@ void COFFDumper::printFileHeaders() {
|
||||
return;
|
||||
if (PEPlusHeader)
|
||||
printPEHeader<pe32plus_header>(PEPlusHeader);
|
||||
|
||||
if (const dos_header *DH = Obj->getDOSHeader())
|
||||
printDOSHeader(DH);
|
||||
}
|
||||
|
||||
void COFFDumper::printDOSHeader(const dos_header *DH) {
|
||||
DictScope D(W, "DOSHeader");
|
||||
W.printString("Magic", StringRef(DH->Magic, sizeof(DH->Magic)));
|
||||
W.printNumber("UsedBytesInTheLastPage", DH->UsedBytesInTheLastPage);
|
||||
W.printNumber("FileSizeInPages", DH->FileSizeInPages);
|
||||
W.printNumber("NumberOfRelocationItems", DH->NumberOfRelocationItems);
|
||||
W.printNumber("HeaderSizeInParagraphs", DH->HeaderSizeInParagraphs);
|
||||
W.printNumber("MinimumExtraParagraphs", DH->MinimumExtraParagraphs);
|
||||
W.printNumber("MaximumExtraParagraphs", DH->MaximumExtraParagraphs);
|
||||
W.printNumber("InitialRelativeSS", DH->InitialRelativeSS);
|
||||
W.printNumber("InitialSP", DH->InitialSP);
|
||||
W.printNumber("Checksum", DH->Checksum);
|
||||
W.printNumber("InitialIP", DH->InitialIP);
|
||||
W.printNumber("InitialRelativeCS", DH->InitialRelativeCS);
|
||||
W.printNumber("AddressOfRelocationTable", DH->AddressOfRelocationTable);
|
||||
W.printNumber("OverlayNumber", DH->OverlayNumber);
|
||||
W.printNumber("OEMid", DH->OEMid);
|
||||
W.printNumber("OEMinfo", DH->OEMinfo);
|
||||
W.printNumber("AddressOfNewExeHeader", DH->AddressOfNewExeHeader);
|
||||
}
|
||||
|
||||
template <class PEHeader>
|
||||
|
Loading…
Reference in New Issue
Block a user