BaseTools/GenFw: Add DllCharacteristicsEx field to debug data

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4405

The PE/COFF spec describes an additional DllCharacteristics field
implemented as a debug directory entry, which carries flags related to
which control flow integrity (CFI) features are supported by the binary.

So let's add this entry when doing ELF to PE/COFF conversion - we will
add support for setting the flags in a subsequent patch.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
Reviewed-by: Oliver Smith-Denny <osde@linux.microsoft.com>
Reviewed-by: Michael Kubacki <michael.kubacki@microsoft.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
This commit is contained in:
Ard Biesheuvel 2023-03-25 15:50:54 +01:00 committed by mergify[bot]
parent 6c299acf48
commit b62d7ac97b
3 changed files with 59 additions and 19 deletions

View File

@ -992,6 +992,16 @@ ScanSections64 (
sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) +
strlen(mInImageName) + 1;
//
// Add more space in the .debug data region for the DllCharacteristicsEx
// field.
//
if (mDllCharacteristicsEx != 0) {
mCoffOffset = DebugRvaAlign(mCoffOffset) +
sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY) +
sizeof (EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY);
}
mCoffOffset = CoffAlign(mCoffOffset);
if (SectionCount == 0) {
mDataOffset = mCoffOffset;
@ -2244,29 +2254,47 @@ WriteDebug64 (
VOID
)
{
UINT32 Len;
EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
EFI_IMAGE_DATA_DIRECTORY *DataDir;
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir;
EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;
UINT32 Len;
EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;
EFI_IMAGE_DATA_DIRECTORY *DataDir;
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *Dir;
EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY *Nb10;
EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY *DllEntry;
Len = strlen(mInImageName) + 1;
Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + mDebugOffset);
Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;
Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len;
Dir->RVA = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
Dir->FileOffset = mDebugOffset + sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);
Nb10->Signature = CODEVIEW_SIGNATURE_NB10;
strcpy ((char *)(Nb10 + 1), mInImageName);
NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);
DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG];
DataDir->VirtualAddress = mDebugOffset;
DataDir->Size = sizeof(EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
DataDir->Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
Dir = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY*)(mCoffFile + mDebugOffset);
if (mDllCharacteristicsEx != 0) {
DataDir->Size += sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
Dir->Type = EFI_IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS;
Dir->SizeOfData = sizeof (EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY);
Dir->FileOffset = mDebugOffset + DataDir->Size +
sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) +
DebugRvaAlign(Len);
Dir->RVA = Dir->FileOffset;
DllEntry = (VOID *)(mCoffFile + Dir->FileOffset);
DllEntry->DllCharacteristicsEx = mDllCharacteristicsEx;
Dir++;
}
Dir->Type = EFI_IMAGE_DEBUG_TYPE_CODEVIEW;
Dir->SizeOfData = sizeof(EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY) + Len;
Dir->RVA = mDebugOffset + DataDir->Size;
Dir->FileOffset = mDebugOffset + DataDir->Size;
Nb10 = (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY*)(Dir + 1);
Nb10->Signature = CODEVIEW_SIGNATURE_NB10;
strcpy ((char *)(Nb10 + 1), mInImageName);
}
STATIC

View File

@ -2932,7 +2932,8 @@ Returns:
if (mIsConvertXip) {
DebugEntry->FileOffset = DebugEntry->RVA;
}
if (ZeroDebugFlag || DebugEntry->Type != EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
if ((ZeroDebugFlag || DebugEntry->Type != EFI_IMAGE_DEBUG_TYPE_CODEVIEW) &&
(DebugEntry->Type != EFI_IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS)) {
memset (FileBuffer + DebugEntry->FileOffset, 0, DebugEntry->SizeOfData);
memset (DebugEntry, 0, sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
}

View File

@ -615,7 +615,8 @@ typedef struct {
///
/// Debug Format
///
#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2
#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2
#define EFI_IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS 20
typedef struct {
UINT32 Characteristics;
@ -664,6 +665,16 @@ typedef struct {
//
} EFI_IMAGE_DEBUG_CODEVIEW_MTOC_ENTRY;
///
/// Extended DLL Characteristics
///
#define EFI_IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT 0x0001
#define EFI_IMAGE_DLLCHARACTERISTICS_EX_FORWARD_CFI_COMPAT 0x0040
typedef struct {
UINT32 DllCharacteristicsEx;
} EFI_IMAGE_DEBUG_EX_DLLCHARACTERISTICS_ENTRY;
//
// .pdata entries for X64
//