Add support for Apple-specific section headers

- and some new PE machine types
This commit is contained in:
Nikolaj Schlej 2016-05-04 19:41:03 +02:00
parent cd1cc09b39
commit 2d932da1f3
5 changed files with 955 additions and 883 deletions

View file

@ -17,7 +17,7 @@
UEFITool::UEFITool(QWidget *parent) : UEFITool::UEFITool(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::UEFITool), ui(new Ui::UEFITool),
version(tr("0.30.0_alpha27")) version(tr("0.30.0_alpha28"))
{ {
clipboard = QApplication::clipboard(); clipboard = QApplication::clipboard();

View file

@ -368,14 +368,24 @@ typedef struct EFI_COMMON_SECTION_HEADER_ {
// Large file common section header // Large file common section header
typedef struct EFI_COMMON_SECTION_HEADER2_ { typedef struct EFI_COMMON_SECTION_HEADER2_ {
UINT8 Size[3]; //Must be 0xFFFFFF for this header to be used UINT8 Size[3]; // Must be 0xFFFFFF for this header to be used
UINT8 Type; UINT8 Type;
UINT32 ExtendedSize; UINT32 ExtendedSize;
} EFI_COMMON_SECTION_HEADER2; } EFI_COMMON_SECTION_HEADER2;
// Apple common section header
typedef struct EFI_COMMON_SECTION_HEADER_APPLE {
UINT8 Size[3];
UINT8 Type;
UINT32 Reserved; // Must be 0x7FFF for this header to be used
} EFI_COMMON_SECTION_HEADER_APPLE;
// Section2 usage indicator // Section2 usage indicator
#define EFI_SECTION2_IS_USED 0xFFFFFF #define EFI_SECTION2_IS_USED 0xFFFFFF
// Apple section usage indicator
#define EFI_SECTION_APPLE_USED 0x7FFF
// File section types // File section types
#define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS #define EFI_SECTION_ALL 0x00 // Impossible attribute for file in the FS
@ -398,23 +408,18 @@ typedef struct EFI_COMMON_SECTION_HEADER2_ {
#define EFI_SECTION_PEI_DEPEX 0x1B #define EFI_SECTION_PEI_DEPEX 0x1B
#define EFI_SECTION_SMM_DEPEX 0x1C #define EFI_SECTION_SMM_DEPEX 0x1C
#define PHOENIX_SECTION_POSTCODE 0xF0 // Specific to Phoenix SCT images #define PHOENIX_SECTION_POSTCODE 0xF0 // Specific to Phoenix SCT images
#define INSYDE_SECTION_POSTCODE 0x20 // Specific to Insyde images #define INSYDE_SECTION_POSTCODE 0x20 // Specific to Insyde H2O images
// Compression section // Compression section
typedef struct EFI_COMPRESSION_SECTION_ { typedef struct EFI_COMPRESSION_SECTION_ {
UINT8 Size[3];
UINT8 Type;
UINT32 UncompressedLength; UINT32 UncompressedLength;
UINT8 CompressionType; UINT8 CompressionType;
} EFI_COMPRESSION_SECTION; } EFI_COMPRESSION_SECTION;
typedef struct EFI_COMPRESSION_SECTION2_ { typedef struct EFI_COMPRESSION_SECTION_APPLE_ {
UINT8 Size[3];
UINT8 Type;
UINT32 ExtendedSize;
UINT32 UncompressedLength; UINT32 UncompressedLength;
UINT8 CompressionType; UINT32 CompressionType;
} EFI_COMPRESSION_SECTION2; } EFI_COMPRESSION_SECTION_APPLE;
// Compression types // Compression types
#define EFI_NOT_COMPRESSED 0x00 #define EFI_NOT_COMPRESSED 0x00
@ -423,21 +428,17 @@ typedef struct EFI_COMPRESSION_SECTION2_ {
//GUID defined section //GUID defined section
typedef struct EFI_GUID_DEFINED_SECTION_ { typedef struct EFI_GUID_DEFINED_SECTION_ {
UINT8 Size[3];
UINT8 Type;
EFI_GUID SectionDefinitionGuid; EFI_GUID SectionDefinitionGuid;
UINT16 DataOffset; UINT16 DataOffset;
UINT16 Attributes; UINT16 Attributes;
} EFI_GUID_DEFINED_SECTION; } EFI_GUID_DEFINED_SECTION;
typedef struct EFI_GUID_DEFINED_SECTION2_ { typedef struct EFI_GUID_DEFINED_SECTION_APPLE_ {
UINT8 Size[3];
UINT8 Type;
UINT32 ExtendedSize;
EFI_GUID SectionDefinitionGuid; EFI_GUID SectionDefinitionGuid;
UINT16 DataOffset; UINT16 DataOffset;
UINT16 Attributes; UINT16 Attributes;
} EFI_GUID_DEFINED_SECTION2; UINT32 Reserved;
} EFI_GUID_DEFINED_SECTION_APPLE;
// Attributes for GUID defined section // Attributes for GUID defined section
#define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01 #define EFI_GUIDED_SECTION_PROCESSING_REQUIRED 0x01
@ -453,7 +454,7 @@ const QByteArray EFI_GUIDED_SECTION_TIANO // A31280AD-481E-41B6-95E8-127F4C98477
const QByteArray EFI_GUIDED_SECTION_LZMA // EE4E5898-3914-4259-9D6E-DC7BD79403CF const QByteArray EFI_GUIDED_SECTION_LZMA // EE4E5898-3914-4259-9D6E-DC7BD79403CF
("\x98\x58\x4E\xEE\x14\x39\x59\x42\x9D\x6E\xDC\x7B\xD7\x94\x03\xCF", 16); ("\x98\x58\x4E\xEE\x14\x39\x59\x42\x9D\x6E\xDC\x7B\xD7\x94\x03\xCF", 16);
const QByteArray EFI_FIRMWARE_CONTENTS_SIGNED_GUID //0F9D89E8-9259-4F76-A5AF-0C89E34023DF const QByteArray EFI_FIRMWARE_CONTENTS_SIGNED_GUID // 0F9D89E8-9259-4F76-A5AF-0C89E34023DF
("\xE8\x89\x9D\x0F\x59\x92\x76\x4F\xA5\xAF\x0C\x89\xE3\x40\x23\xDF", 16); ("\xE8\x89\x9D\x0F\x59\x92\x76\x4F\xA5\xAF\x0C\x89\xE3\x40\x23\xDF", 16);
//#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002 //#define WIN_CERT_TYPE_PKCS_SIGNED_DATA 0x0002
@ -475,8 +476,6 @@ typedef struct WIN_CERTIFICATE_UEFI_GUID_ {
// WIN_CERTIFICATE_UEFI_GUID.CertType // WIN_CERTIFICATE_UEFI_GUID.CertType
const QByteArray EFI_CERT_TYPE_RSA2048_SHA256_GUID const QByteArray EFI_CERT_TYPE_RSA2048_SHA256_GUID
("\x14\x74\x71\xA7\x16\xC6\x77\x49\x94\x20\x84\x47\x12\xA7\x35\xBF"); ("\x14\x74\x71\xA7\x16\xC6\x77\x49\x94\x20\x84\x47\x12\xA7\x35\xBF");
//const QByteArray EFI_CERT_TYPE_PKCS7_GUID
//("\x9D\xD2\xAF\x4A\xDF\x68\xEE\x49\x8A\xA9\x34\x7D\x37\x56\x65\xA7");
// WIN_CERTIFICATE_UEFI_GUID.CertData // WIN_CERTIFICATE_UEFI_GUID.CertData
typedef struct EFI_CERT_BLOCK_RSA_2048_SHA256_ { typedef struct EFI_CERT_BLOCK_RSA_2048_SHA256_ {
@ -487,70 +486,19 @@ typedef struct EFI_CERT_BLOCK_RSA_2048_SHA256_ {
// Version section // Version section
typedef struct EFI_VERSION_SECTION_ { typedef struct EFI_VERSION_SECTION_ {
UINT8 Size[3];
UINT8 Type;
UINT16 BuildNumber; UINT16 BuildNumber;
} EFI_VERSION_SECTION; } EFI_VERSION_SECTION;
typedef struct EFI_VERSION_SECTION2_ {
UINT8 Size[3];
UINT8 Type;
UINT32 ExtendedSize;
UINT16 BuildNumber;
} EFI_VERSION_SECTION2;
// Freeform subtype GUID section // Freeform subtype GUID section
typedef struct EFI_FREEFORM_SUBTYPE_GUID_SECTION_ { typedef struct EFI_FREEFORM_SUBTYPE_GUID_SECTION_ {
UINT8 Size[3];
UINT8 Type;
EFI_GUID SubTypeGuid; EFI_GUID SubTypeGuid;
} EFI_FREEFORM_SUBTYPE_GUID_SECTION; } EFI_FREEFORM_SUBTYPE_GUID_SECTION;
typedef struct EFI_FREEFORM_SUBTYPE_GUID_SECTION2_ {
UINT8 Size[3];
UINT8 Type;
UINT32 ExtendedSize;
EFI_GUID SubTypeGuid;
} EFI_FREEFORM_SUBTYPE_GUID_SECTION2;
// Phoenix SCT and Insyde postcode section // Phoenix SCT and Insyde postcode section
typedef struct POSTCODE_SECTION_ { typedef struct POSTCODE_SECTION_ {
UINT8 Size[3];
UINT8 Type;
UINT32 Postcode; UINT32 Postcode;
} POSTCODE_SECTION; } POSTCODE_SECTION;
typedef struct POSTCODE_SECTION2_ {
UINT8 Size[3];
UINT8 Type;
UINT32 ExtendedSize;
UINT32 Postcode;
} POSTCODE_SECTION2;
// Other sections
typedef EFI_COMMON_SECTION_HEADER EFI_DISPOSABLE_SECTION;
typedef EFI_COMMON_SECTION_HEADER2 EFI_DISPOSABLE_SECTION2;
typedef EFI_COMMON_SECTION_HEADER EFI_RAW_SECTION;
typedef EFI_COMMON_SECTION_HEADER2 EFI_RAW_SECTION2;
typedef EFI_COMMON_SECTION_HEADER EFI_DXE_DEPEX_SECTION;
typedef EFI_COMMON_SECTION_HEADER2 EFI_DXE_DEPEX_SECTION2;
typedef EFI_COMMON_SECTION_HEADER EFI_PEI_DEPEX_SECTION;
typedef EFI_COMMON_SECTION_HEADER2 EFI_PEI_DEPEX_SECTION2;
typedef EFI_COMMON_SECTION_HEADER EFI_SMM_DEPEX_SECTION;
typedef EFI_COMMON_SECTION_HEADER2 EFI_SMM_DEPEX_SECTION2;
typedef EFI_COMMON_SECTION_HEADER EFI_PE32_SECTION;
typedef EFI_COMMON_SECTION_HEADER2 EFI_PE32_SECTION2;
typedef EFI_COMMON_SECTION_HEADER EFI_PIC_SECTION;
typedef EFI_COMMON_SECTION_HEADER2 EFI_PIC_SECTION2;
typedef EFI_COMMON_SECTION_HEADER EFI_TE_SECTION;
typedef EFI_COMMON_SECTION_HEADER2 EFI_TE_SECTION2;
typedef EFI_COMMON_SECTION_HEADER EFI_COMPATIBILITY16_SECTION;
typedef EFI_COMMON_SECTION_HEADER2 EFI_COMPATIBILITY16_SECTION2;
typedef EFI_COMMON_SECTION_HEADER EFI_FIRMWARE_VOLUME_IMAGE_SECTION;
typedef EFI_COMMON_SECTION_HEADER2 EFI_FIRMWARE_VOLUME_IMAGE_SECTION2;
typedef EFI_COMMON_SECTION_HEADER EFI_USER_INTERFACE_SECTION;
typedef EFI_COMMON_SECTION_HEADER2 EFI_USER_INTERFACE_SECTION2;
//***************************************************************************** //*****************************************************************************
// EFI Dependency Expression // EFI Dependency Expression
//***************************************************************************** //*****************************************************************************

View file

@ -1875,18 +1875,32 @@ STATUS FfsParser::parseCommonSectionHeader(const QByteArray & section, const UIN
PARSING_DATA pdata = parsingDataFromQModelIndex(parent); PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
// Obtain header fields // Obtain header fields
UINT32 headerSize;
UINT8 type;
const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) {
headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE);
type = appleHeader->Type;
}
else {
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
UINT32 headerSize = sizeof(EFI_COMMON_SECTION_HEADER); headerSize = sizeof(EFI_COMMON_SECTION_HEADER);
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED)
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2); headerSize = sizeof(EFI_COMMON_SECTION_HEADER2);
type = sectionHeader->Type;
}
// Check sanity again
if ((UINT32)section.size() < headerSize)
return ERR_INVALID_SECTION;
QByteArray header = section.left(headerSize); QByteArray header = section.left(headerSize);
QByteArray body = section.mid(headerSize); QByteArray body = section.mid(headerSize);
// Get info // Get info
QString name = sectionTypeToQString(sectionHeader->Type) + QObject::tr(" section"); QString name = sectionTypeToQString(type) + QObject::tr(" section");
QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)") QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)")
.hexarg2(sectionHeader->Type, 2) .hexarg2(type, 2)
.hexarg(section.size()).arg(section.size()) .hexarg(section.size()).arg(section.size())
.hexarg(headerSize).arg(headerSize) .hexarg(headerSize).arg(headerSize)
.hexarg(body.size()).arg(body.size()); .hexarg(body.size()).arg(body.size());
@ -1896,7 +1910,7 @@ STATUS FfsParser::parseCommonSectionHeader(const QByteArray & section, const UIN
// Add tree item // Add tree item
if (!preparse) { if (!preparse) {
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, QByteArray(), true, parsingDataToQByteArray(pdata), parent); index = model->addItem(Types::Section, type, name, QString(), info, header, body, QByteArray(), true, parsingDataToQByteArray(pdata), parent);
} }
return ERR_SUCCESS; return ERR_SUCCESS;
} }
@ -1904,26 +1918,44 @@ STATUS FfsParser::parseCommonSectionHeader(const QByteArray & section, const UIN
STATUS FfsParser::parseCompressedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse) STATUS FfsParser::parseCompressedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
{ {
// Check sanity // Check sanity
if ((UINT32)section.size() < sizeof(EFI_COMPRESSION_SECTION)) if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
return ERR_INVALID_SECTION; return ERR_INVALID_SECTION;
// Get data from parent's parsing data // Get data from parent's parsing data
PARSING_DATA pdata = parsingDataFromQModelIndex(parent); PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
// Obtain header fields // Obtain header fields
UINT32 headerSize;
UINT8 compressionType;
UINT32 uncompressedLength;
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
const EFI_COMPRESSION_SECTION* compressedSectionHeader = (const EFI_COMPRESSION_SECTION*)sectionHeader; const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
UINT32 headerSize = sizeof(EFI_COMPRESSION_SECTION); const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
UINT8 compressionType = compressedSectionHeader->CompressionType;
UINT32 uncompressedLength = compressedSectionHeader->UncompressedLength; if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { const EFI_COMPRESSION_SECTION_APPLE* appleSectionHeader = (const EFI_COMPRESSION_SECTION_APPLE*)(appleHeader + 1);
if ((UINT32)section.size() < sizeof(EFI_COMPRESSION_SECTION2)) headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_COMPRESSION_SECTION_APPLE);
compressionType = (UINT8)appleSectionHeader->CompressionType;
uncompressedLength = appleSectionHeader->UncompressedLength;
}
else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
const EFI_COMPRESSION_SECTION* compressedSectionHeader = (const EFI_COMPRESSION_SECTION*)(section2Header + 1);
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_COMPRESSION_SECTION))
return ERR_INVALID_SECTION; return ERR_INVALID_SECTION;
const EFI_COMPRESSION_SECTION2* compressedSectionHeader2 = (const EFI_COMPRESSION_SECTION2*)sectionHeader; headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_COMPRESSION_SECTION);
headerSize = sizeof(EFI_COMPRESSION_SECTION2); compressionType = compressedSectionHeader->CompressionType;
compressionType = compressedSectionHeader2->CompressionType;
uncompressedLength = compressedSectionHeader->UncompressedLength; uncompressedLength = compressedSectionHeader->UncompressedLength;
} }
else { // Normal section
const EFI_COMPRESSION_SECTION* compressedSectionHeader = (const EFI_COMPRESSION_SECTION*)(sectionHeader + 1);
headerSize = sizeof(EFI_COMMON_SECTION_HEADER) + sizeof(EFI_COMPRESSION_SECTION);
compressionType = compressedSectionHeader->CompressionType;
uncompressedLength = compressedSectionHeader->UncompressedLength;
}
// Check sanity again
if ((UINT32)section.size() < headerSize)
return ERR_INVALID_SECTION;
QByteArray header = section.left(headerSize); QByteArray header = section.left(headerSize);
QByteArray body = section.mid(headerSize); QByteArray body = section.mid(headerSize);
@ -1953,28 +1985,49 @@ STATUS FfsParser::parseCompressedSectionHeader(const QByteArray & section, const
STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse) STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
{ {
// Check sanity // Check sanity
if ((UINT32)section.size() < sizeof(EFI_GUID_DEFINED_SECTION)) if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
return ERR_INVALID_SECTION; return ERR_INVALID_SECTION;
// Get data from parent's parsing data // Get data from parent's parsing data
PARSING_DATA pdata = parsingDataFromQModelIndex(parent); PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
// Obtain header fields // Obtain header fields
UINT32 headerSize;
EFI_GUID guid;
UINT16 dataOffset;
UINT16 attributes;
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
const EFI_GUID_DEFINED_SECTION* guidDefinedSectionHeader = (const EFI_GUID_DEFINED_SECTION*)sectionHeader; const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
EFI_GUID guid = guidDefinedSectionHeader->SectionDefinitionGuid; const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
UINT16 dataOffset = guidDefinedSectionHeader->DataOffset;
UINT16 attributes = guidDefinedSectionHeader->Attributes; if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
UINT32 nextHeaderOffset = sizeof(EFI_GUID_DEFINED_SECTION); const EFI_GUID_DEFINED_SECTION_APPLE* appleSectionHeader = (const EFI_GUID_DEFINED_SECTION_APPLE*)(appleHeader + 1);
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_GUID_DEFINED_SECTION_APPLE);
if ((UINT32)section.size() < sizeof(EFI_GUID_DEFINED_SECTION2)) if ((UINT32)section.size() < headerSize)
return ERR_INVALID_SECTION; return ERR_INVALID_SECTION;
const EFI_GUID_DEFINED_SECTION2* guidDefinedSectionHeader2 = (const EFI_GUID_DEFINED_SECTION2*)sectionHeader; guid = appleSectionHeader->SectionDefinitionGuid;
guid = guidDefinedSectionHeader2->SectionDefinitionGuid; dataOffset = appleSectionHeader->DataOffset;
dataOffset = guidDefinedSectionHeader2->DataOffset; attributes = appleSectionHeader->Attributes;
attributes = guidDefinedSectionHeader2->Attributes;
nextHeaderOffset = sizeof(EFI_GUID_DEFINED_SECTION2);
} }
else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
const EFI_GUID_DEFINED_SECTION* guidDefinedSectionHeader = (const EFI_GUID_DEFINED_SECTION*)(section2Header + 1);
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_GUID_DEFINED_SECTION))
return ERR_INVALID_SECTION;
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_GUID_DEFINED_SECTION);
guid = guidDefinedSectionHeader->SectionDefinitionGuid;
dataOffset = guidDefinedSectionHeader->DataOffset;
attributes = guidDefinedSectionHeader->Attributes;
}
else { // Normal section
const EFI_GUID_DEFINED_SECTION* guidDefinedSectionHeader = (const EFI_GUID_DEFINED_SECTION*)(sectionHeader + 1);
headerSize = sizeof(EFI_COMMON_SECTION_HEADER) + sizeof(EFI_GUID_DEFINED_SECTION);
guid = guidDefinedSectionHeader->SectionDefinitionGuid;
dataOffset = guidDefinedSectionHeader->DataOffset;
attributes = guidDefinedSectionHeader->Attributes;
}
// Check sanity again
if ((UINT32)section.size() < headerSize)
return ERR_INVALID_SECTION;
// Check for special GUIDed sections // Check for special GUIDed sections
QByteArray additionalInfo; QByteArray additionalInfo;
@ -1991,10 +2044,10 @@ STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UIN
msgNoAuthStatusAttribute = true; msgNoAuthStatusAttribute = true;
} }
if ((UINT32)section.size() < nextHeaderOffset + sizeof(UINT32)) if ((UINT32)section.size() < headerSize + sizeof(UINT32))
return ERR_INVALID_SECTION; return ERR_INVALID_SECTION;
UINT32 crc = *(UINT32*)(section.constData() + nextHeaderOffset); UINT32 crc = *(UINT32*)(section.constData() + headerSize);
additionalInfo += QObject::tr("\nChecksum type: CRC32"); additionalInfo += QObject::tr("\nChecksum type: CRC32");
// Calculate CRC32 of section data // Calculate CRC32 of section data
UINT32 calculated = crc32(0, (const UINT8*)section.constData() + dataOffset, section.size() - dataOffset); UINT32 calculated = crc32(0, (const UINT8*)section.constData() + dataOffset, section.size() - dataOffset);
@ -2019,10 +2072,10 @@ STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UIN
} }
// Get certificate type and length // Get certificate type and length
if ((UINT32)section.size() < nextHeaderOffset + sizeof(WIN_CERTIFICATE)) if ((UINT32)section.size() < headerSize + sizeof(WIN_CERTIFICATE))
return ERR_INVALID_SECTION; return ERR_INVALID_SECTION;
const WIN_CERTIFICATE* winCertificate = (const WIN_CERTIFICATE*)(section.constData() + nextHeaderOffset); const WIN_CERTIFICATE* winCertificate = (const WIN_CERTIFICATE*)(section.constData() + headerSize);
UINT32 certLength = winCertificate->Length; UINT32 certLength = winCertificate->Length;
UINT16 certType = winCertificate->CertificateType; UINT16 certType = winCertificate->CertificateType;
@ -2038,7 +2091,7 @@ STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UIN
additionalInfo += QObject::tr("\nCertificate type: UEFI"); additionalInfo += QObject::tr("\nCertificate type: UEFI");
// Get certificate GUID // Get certificate GUID
const WIN_CERTIFICATE_UEFI_GUID* winCertificateUefiGuid = (const WIN_CERTIFICATE_UEFI_GUID*)(section.constData() + nextHeaderOffset); const WIN_CERTIFICATE_UEFI_GUID* winCertificateUefiGuid = (const WIN_CERTIFICATE_UEFI_GUID*)(section.constData() + headerSize);
QByteArray certTypeGuid((const char*)&winCertificateUefiGuid->CertType, sizeof(EFI_GUID)); QByteArray certTypeGuid((const char*)&winCertificateUefiGuid->CertType, sizeof(EFI_GUID));
if (certTypeGuid == EFI_CERT_TYPE_RSA2048_SHA256_GUID) { if (certTypeGuid == EFI_CERT_TYPE_RSA2048_SHA256_GUID) {
@ -2104,32 +2157,52 @@ STATUS FfsParser::parseGuidedSectionHeader(const QByteArray & section, const UIN
STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse) STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
{ {
// Check sanity // Check sanity
if ((UINT32)section.size() < sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION)) if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
return ERR_INVALID_SECTION; return ERR_INVALID_SECTION;
// Get data from parent's parsing data // Get data from parent's parsing data
PARSING_DATA pdata = parsingDataFromQModelIndex(parent); PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
// Obtain header fields // Obtain header fields
UINT32 headerSize;
EFI_GUID guid;
UINT8 type;
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
const EFI_FREEFORM_SUBTYPE_GUID_SECTION* fsgHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)sectionHeader; const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
UINT32 headerSize = sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION); const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
EFI_GUID guid = fsgHeader->SubTypeGuid;
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
if ((UINT32)section.size() < sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION2)) const EFI_FREEFORM_SUBTYPE_GUID_SECTION* appleSectionHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)(appleHeader + 1);
return ERR_INVALID_SECTION; headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
const EFI_FREEFORM_SUBTYPE_GUID_SECTION2* fsgHeader2 = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION2*)sectionHeader; guid = appleSectionHeader->SubTypeGuid;
headerSize = sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION2); type = appleHeader->Type;
guid = fsgHeader2->SubTypeGuid;
} }
else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
const EFI_FREEFORM_SUBTYPE_GUID_SECTION* fsgSectionHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)(section2Header + 1);
if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION))
return ERR_INVALID_SECTION;
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
guid = fsgSectionHeader->SubTypeGuid;
type = section2Header->Type;
}
else { // Normal section
const EFI_FREEFORM_SUBTYPE_GUID_SECTION* fsgSectionHeader = (const EFI_FREEFORM_SUBTYPE_GUID_SECTION*)(sectionHeader + 1);
headerSize = sizeof(EFI_COMMON_SECTION_HEADER) + sizeof(EFI_FREEFORM_SUBTYPE_GUID_SECTION);
guid = fsgSectionHeader->SubTypeGuid;
type = sectionHeader->Type;
}
// Check sanity again
if ((UINT32)section.size() < headerSize)
return ERR_INVALID_SECTION;
QByteArray header = section.left(headerSize); QByteArray header = section.left(headerSize);
QByteArray body = section.mid(headerSize); QByteArray body = section.mid(headerSize);
// Get info // Get info
QString name = sectionTypeToQString(sectionHeader->Type) + QObject::tr(" section"); QString name = sectionTypeToQString(type) + QObject::tr(" section");
QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nSubtype GUID: %8") QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nSubtype GUID: %8")
.hexarg2(fsgHeader->Type, 2) .hexarg2(type, 2)
.hexarg(section.size()).arg(section.size()) .hexarg(section.size()).arg(section.size())
.hexarg(header.size()).arg(header.size()) .hexarg(header.size()).arg(header.size())
.hexarg(body.size()).arg(body.size()) .hexarg(body.size()).arg(body.size())
@ -2141,7 +2214,7 @@ STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, c
// Add tree item // Add tree item
if (!preparse) { if (!preparse) {
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, QByteArray(), false, parsingDataToQByteArray(pdata), parent); index = model->addItem(Types::Section, type, name, QString(), info, header, body, QByteArray(), false, parsingDataToQByteArray(pdata), parent);
// Rename section // Rename section
model->setName(index, guidToQString(guid)); model->setName(index, guidToQString(guid));
@ -2152,32 +2225,50 @@ STATUS FfsParser::parseFreeformGuidedSectionHeader(const QByteArray & section, c
STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse) STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
{ {
// Check sanity // Check sanity
if ((UINT32)section.size() < sizeof(EFI_VERSION_SECTION)) if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
return ERR_INVALID_SECTION; return ERR_INVALID_SECTION;
// Get data from parent's parsing data // Get data from parent's parsing data
PARSING_DATA pdata = parsingDataFromQModelIndex(parent); PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
// Obtain header fields // Obtain header fields
UINT32 headerSize;
UINT16 buildNumber;
UINT8 type;
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)sectionHeader; const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
UINT32 headerSize = sizeof(EFI_VERSION_SECTION); const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
UINT16 buildNumber = versionHeader->BuildNumber;
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
if ((UINT32)section.size() < sizeof(EFI_VERSION_SECTION2)) const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)(appleHeader + 1);
return ERR_INVALID_SECTION; headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(EFI_VERSION_SECTION);
const EFI_VERSION_SECTION2* versionHeader2 = (const EFI_VERSION_SECTION2*)sectionHeader; buildNumber = versionHeader->BuildNumber;
headerSize = sizeof(EFI_VERSION_SECTION2); type = appleHeader->Type;
buildNumber = versionHeader2->BuildNumber;
} }
else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)(section2Header + 1);
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(EFI_VERSION_SECTION);
buildNumber = versionHeader->BuildNumber;
type = section2Header->Type;
}
else { // Normal section
const EFI_VERSION_SECTION* versionHeader = (const EFI_VERSION_SECTION*)(sectionHeader + 1);
headerSize = sizeof(EFI_COMMON_SECTION_HEADER) + sizeof(EFI_VERSION_SECTION);
buildNumber = versionHeader->BuildNumber;
type = sectionHeader->Type;
}
// Check sanity again
if ((UINT32)section.size() < headerSize)
return ERR_INVALID_SECTION;
QByteArray header = section.left(headerSize); QByteArray header = section.left(headerSize);
QByteArray body = section.mid(headerSize); QByteArray body = section.mid(headerSize);
// Get info // Get info
QString name = sectionTypeToQString(sectionHeader->Type) + QObject::tr(" section"); QString name = sectionTypeToQString(type) + QObject::tr(" section");
QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nBuild number: %8") QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nBuild number: %8")
.hexarg2(versionHeader->Type, 2) .hexarg2(type, 2)
.hexarg(section.size()).arg(section.size()) .hexarg(section.size()).arg(section.size())
.hexarg(header.size()).arg(header.size()) .hexarg(header.size()).arg(header.size())
.hexarg(body.size()).arg(body.size()) .hexarg(body.size()).arg(body.size())
@ -2188,7 +2279,7 @@ STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UI
// Add tree item // Add tree item
if (!preparse) { if (!preparse) {
index = model->addItem(Types::Section, sectionHeader->Type, name, QString(), info, header, body, QByteArray(), false, parsingDataToQByteArray(pdata), parent); index = model->addItem(Types::Section, type, name, QString(), info, header, body, QByteArray(), false, parsingDataToQByteArray(pdata), parent);
} }
return ERR_SUCCESS; return ERR_SUCCESS;
} }
@ -2196,32 +2287,50 @@ STATUS FfsParser::parseVersionSectionHeader(const QByteArray & section, const UI
STATUS FfsParser::parsePostcodeSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse) STATUS FfsParser::parsePostcodeSectionHeader(const QByteArray & section, const UINT32 parentOffset, const QModelIndex & parent, QModelIndex & index, const bool preparse)
{ {
// Check sanity // Check sanity
if ((UINT32)section.size() < sizeof(POSTCODE_SECTION)) if ((UINT32)section.size() < sizeof(EFI_COMMON_SECTION_HEADER))
return ERR_INVALID_SECTION; return ERR_INVALID_SECTION;
// Get data from parent's parsing data // Get data from parent's parsing data
PARSING_DATA pdata = parsingDataFromQModelIndex(parent); PARSING_DATA pdata = parsingDataFromQModelIndex(parent);
// Obtain header fields // Obtain header fields
UINT32 headerSize;
UINT32 postCode;
UINT8 type;
const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData()); const EFI_COMMON_SECTION_HEADER* sectionHeader = (const EFI_COMMON_SECTION_HEADER*)(section.constData());
const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)sectionHeader; const EFI_COMMON_SECTION_HEADER2* section2Header = (const EFI_COMMON_SECTION_HEADER2*)(section.constData());
UINT32 headerSize = sizeof(POSTCODE_SECTION); const EFI_COMMON_SECTION_HEADER_APPLE* appleHeader = (const EFI_COMMON_SECTION_HEADER_APPLE*)(section.constData());
UINT32 postCode = postcodeHeader->Postcode;
if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { if ((UINT32)section.size() >= sizeof(EFI_COMMON_SECTION_HEADER_APPLE) && appleHeader->Reserved == EFI_SECTION_APPLE_USED) { // Check for apple section
if ((UINT32)section.size() < sizeof(POSTCODE_SECTION2)) const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)(appleHeader + 1);
return ERR_INVALID_SECTION; headerSize = sizeof(EFI_COMMON_SECTION_HEADER_APPLE) + sizeof(POSTCODE_SECTION);
const POSTCODE_SECTION2* postcodeHeader2 = (const POSTCODE_SECTION2*)sectionHeader; postCode = postcodeHeader->Postcode;
headerSize = sizeof(POSTCODE_SECTION2); type = appleHeader->Type;
postCode = postcodeHeader2->Postcode;
} }
else if (pdata.ffsVersion == 3 && uint24ToUint32(sectionHeader->Size) == EFI_SECTION2_IS_USED) { // Check for extended header section
const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)(section2Header + 1);
headerSize = sizeof(EFI_COMMON_SECTION_HEADER2) + sizeof(POSTCODE_SECTION);
postCode = postcodeHeader->Postcode;
type = section2Header->Type;
}
else { // Normal section
const POSTCODE_SECTION* postcodeHeader = (const POSTCODE_SECTION*)(sectionHeader + 1);
headerSize = sizeof(EFI_COMMON_SECTION_HEADER) + sizeof(POSTCODE_SECTION);
postCode = postcodeHeader->Postcode;
type = sectionHeader->Type;
}
// Check sanity again
if ((UINT32)section.size() < headerSize)
return ERR_INVALID_SECTION;
QByteArray header = section.left(headerSize); QByteArray header = section.left(headerSize);
QByteArray body = section.mid(headerSize); QByteArray body = section.mid(headerSize);
// Get info // Get info
QString name = sectionTypeToQString(sectionHeader->Type) + QObject::tr(" section"); QString name = sectionTypeToQString(type) + QObject::tr(" section");
QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nPostcode: %8h") QString info = QObject::tr("Type: %1h\nFull size: %2h (%3)\nHeader size: %4h (%5)\nBody size: %6h (%7)\nPostcode: %8h")
.hexarg2(postcodeHeader->Type, 2) .hexarg2(type, 2)
.hexarg(section.size()).arg(section.size()) .hexarg(section.size()).arg(section.size())
.hexarg(header.size()).arg(header.size()) .hexarg(header.size()).arg(header.size())
.hexarg(body.size()).arg(body.size()) .hexarg(body.size()).arg(body.size())

View file

@ -21,13 +21,17 @@ QString machineTypeToQString(UINT16 machineType)
case EFI_IMAGE_FILE_MACHINE_AMD64: return QObject::tr("x86-64"); case EFI_IMAGE_FILE_MACHINE_AMD64: return QObject::tr("x86-64");
case EFI_IMAGE_FILE_MACHINE_ARM: return QObject::tr("ARM"); case EFI_IMAGE_FILE_MACHINE_ARM: return QObject::tr("ARM");
case EFI_IMAGE_FILE_MACHINE_ARMNT: return QObject::tr("ARMv7"); case EFI_IMAGE_FILE_MACHINE_ARMNT: return QObject::tr("ARMv7");
case EFI_IMAGE_FILE_MACHINE_ARM64: return QObject::tr("ARM64"); case EFI_IMAGE_FILE_MACHINE_APPLE_ARM: return QObject::tr("Apple ARM");
case EFI_IMAGE_FILE_MACHINE_AARCH64: return QObject::tr("AARCH64");
case EFI_IMAGE_FILE_MACHINE_EBC: return QObject::tr("EBC"); case EFI_IMAGE_FILE_MACHINE_EBC: return QObject::tr("EBC");
case EFI_IMAGE_FILE_MACHINE_I386: return QObject::tr("x86"); case EFI_IMAGE_FILE_MACHINE_I386: return QObject::tr("x86");
case EFI_IMAGE_FILE_MACHINE_IA64: return QObject::tr("IA64"); case EFI_IMAGE_FILE_MACHINE_IA64: return QObject::tr("IA64");
case EFI_IMAGE_FILE_MACHINE_POWERPC: return QObject::tr("PowerPC"); case EFI_IMAGE_FILE_MACHINE_POWERPC: return QObject::tr("PowerPC");
case EFI_IMAGE_FILE_MACHINE_POWERPCFP: return QObject::tr("PowerPC FP"); case EFI_IMAGE_FILE_MACHINE_POWERPCFP: return QObject::tr("PowerPC FP");
case EFI_IMAGE_FILE_MACHINE_THUMB: return QObject::tr("Thumb"); case EFI_IMAGE_FILE_MACHINE_THUMB: return QObject::tr("ARM Thumb");
case EFI_IMAGE_FILE_MACHINE_RISCV32: return QObject::tr("RISC-V 32-bit");
case EFI_IMAGE_FILE_MACHINE_RISCV64: return QObject::tr("RISC-V 64-bit");
case EFI_IMAGE_FILE_MACHINE_RISCV128: return QObject::tr("RISC-V 128-bit");
default: return QObject::tr("Unknown %1h").hexarg2(machineType, 4); default: return QObject::tr("Unknown %1h").hexarg2(machineType, 4);
} }
} }

View file

@ -39,13 +39,16 @@ extern QString machineTypeToQString(UINT16 machineType);
#define EFI_IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM little endian #define EFI_IMAGE_FILE_MACHINE_ARM 0x01c0 // ARM little endian
#define EFI_IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM or Thumb (interworking) #define EFI_IMAGE_FILE_MACHINE_THUMB 0x01c2 // ARM or Thumb (interworking)
#define EFI_IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARMv7 (or higher) Thumb mode only #define EFI_IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARMv7 (or higher) Thumb mode only
#define EFI_IMAGE_FILE_MACHINE_APPLE_ARM 0x01c6 // Apple ARM
#define EFI_IMAGE_FILE_MACHINE_POWERPC 0x01f0 // Power PC little endian #define EFI_IMAGE_FILE_MACHINE_POWERPC 0x01f0 // Power PC little endian
#define EFI_IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 // Power PC with floating point support #define EFI_IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 // Power PC with floating point support
#define EFI_IMAGE_FILE_MACHINE_IA64 0x0200 // Itanium #define EFI_IMAGE_FILE_MACHINE_IA64 0x0200 // Itanium
#define EFI_IMAGE_FILE_MACHINE_EBC 0x0ebc // EFI Byte Code #define EFI_IMAGE_FILE_MACHINE_EBC 0x0ebc // EFI Byte Code
#define EFI_IMAGE_FILE_MACHINE_AMD64 0x8664 // x86-64 #define EFI_IMAGE_FILE_MACHINE_AMD64 0x8664 // x86-64
#define EFI_IMAGE_FILE_MACHINE_ARM64 0xaa64 // ARMv8 in 64-bit mode #define EFI_IMAGE_FILE_MACHINE_AARCH64 0xaa64 // ARMv8 in 64-bit mode
#define EFI_IMAGE_FILE_MACHINE_RISCV32 0x5032 // RISC-V 32-bit
#define EFI_IMAGE_FILE_MACHINE_RISCV64 0x5064 // RISC-V 64-bit
#define EFI_IMAGE_FILE_MACHINE_RISCV128 0x5128 // RISC-V 128-bit
// //
// EXE file formats // EXE file formats
// //
@ -439,8 +442,9 @@ typedef struct {
#define EFI_IMAGE_REL_I386_SECREL 0x000B #define EFI_IMAGE_REL_I386_SECREL 0x000B
#define EFI_IMAGE_REL_I386_REL32 0x0014 // PC-relative 32-bit reference to the symbols virtual address #define EFI_IMAGE_REL_I386_REL32 0x0014 // PC-relative 32-bit reference to the symbols virtual address
// //
// x64 processor relocation types // x64 relocation types
// //
#define EFI_IMAGE_REL_AMD64_ABSOLUTE 0x0000 #define EFI_IMAGE_REL_AMD64_ABSOLUTE 0x0000
#define EFI_IMAGE_REL_AMD64_ADDR64 0x0001 #define EFI_IMAGE_REL_AMD64_ADDR64 0x0001
@ -460,6 +464,13 @@ typedef struct {
#define EFI_IMAGE_REL_AMD64_PAIR 0x000F #define EFI_IMAGE_REL_AMD64_PAIR 0x000F
#define EFI_IMAGE_REL_AMD64_SSPAN32 0x0010 #define EFI_IMAGE_REL_AMD64_SSPAN32 0x0010
//
// RISC-V relocation types
//
#define EFI_IMAGE_REL_BASED_RISCV_HI20 0x0005
#define EFI_IMAGE_REL_BASED_RISCV_LO12I 0x0007
#define EFI_IMAGE_REL_BASED_RISCV_LO12S 0x0008
// //
// Based relocation format // Based relocation format
// //