提交 146e2405 编写于 作者: V vit9696

Implement binary patching in OcAcpiLib

上级 cce17e84
......@@ -36,6 +36,9 @@ typedef struct {
#pragma pack(pop)
//
// Main ACPI context describing current tableset worked on.
//
typedef struct {
//
// Pointer to original RSDP table.
......@@ -50,6 +53,14 @@ typedef struct {
//
OC_ACPI_6_2_EXTENDED_SYSTEM_DESCRIPTION_TABLE *Xsdt;
//
// Pointer to active FADT table.
//
EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
//
// Pointer to active DSDT table.
//
EFI_ACPI_DESCRIPTION_HEADER *Dsdt;
//
// Current list of tables allocated from heap.
//
EFI_ACPI_COMMON_HEADER **Tables;
......@@ -63,6 +74,48 @@ typedef struct {
UINT32 AllocatedTables;
} OC_ACPI_CONTEXT;
//
// ACPI patch structure.
//
typedef struct {
//
// Find bytes.
//
CONST UINT8 *Find;
//
// Replace bytes.
//
CONST UINT8 *Replace;
//
// Find mask or NULL.
//
CONST UINT8 *Mask;
//
// Patch size.
//
UINT32 Size;
//
// Replace count or 0 for all.
//
UINT32 Count;
//
// Skip count or 0 to start from 1 match.
//
UINT32 Skip;
//
// ACPI Table signature or 0.
//
UINT32 TableSignature;
//
// ACPI Table length or 0.
//
UINT32 TableLength;
//
// ACPI Table Id or 0.
//
UINT64 OemTableId;
} OC_ACPI_PATCH;
/** Find ACPI System Tables for later table configuration.
@param Context ACPI library context.
......@@ -94,7 +147,7 @@ AcpiApplyContext (
/** Drop one ACPI table.
@param Context ACPI library context
@param Context ACPI library context.
@param Signature Table signature or 0.
@param Length Table length or 0.
@param OemTableId Table Id or 0.
......@@ -109,7 +162,7 @@ AcpiDropTable (
/** Install one ACPI table. For DSDT this performs table replacement.
@param Context ACPI library context
@param Context ACPI library context.
@param Data Table data.
@param Length Table length.
**/
......@@ -122,11 +175,22 @@ AcpiInsertTable (
/** Normalise ACPI headers to contain 7-bit ASCII.
@param Context ACPI library context
@param Context ACPI library context.
**/
VOID
AcpiNormalizeHeaders (
IN OUT OC_ACPI_CONTEXT *Context
);
/** Patch ACPI tables.
@param Context ACPI library context.
@param Patch ACPI patch.
**/
EFI_STATUS
AcpiApplyPatch (
IN OUT OC_ACPI_CONTEXT *Context,
IN OC_ACPI_PATCH *Patch
);
#endif // OC_ACPI_LIB_H
......@@ -12,8 +12,10 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_MISC_LIB_H_
#define OC_MISC_LIB_H_
#ifndef OC_MISC_LIB_H
#define OC_MISC_LIB_H
#include <Uefi.h>
// PLATFORM_DATA_HEADER
typedef struct {
......@@ -166,4 +168,26 @@ WaitForKeyPress (
CONST CHAR16 *Message
);
#endif // OC_MISC_LIB_H_
INT32
FindPattern (
IN CONST UINT8 *Pattern,
IN CONST UINT8 *PatternMask OPTIONAL,
IN CONST UINT32 PatternSize,
IN CONST UINT8 *Data,
IN UINT32 DataSize,
IN INT32 DataOff
);
UINT32
ApplyPatch (
IN CONST UINT8 *Pattern,
IN CONST UINT8 *PatternMask OPTIONAL,
IN CONST UINT32 PatternSize,
IN CONST UINT8 *Replace,
IN UINT8 *Data,
IN UINT32 DataSize,
IN UINT32 Count,
IN UINT32 Skip
);
#endif // OC_MISC_LIB_H
......@@ -19,6 +19,7 @@
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/OcMiscLib.h>
#include <IndustryStandard/AcpiAml.h>
#include <IndustryStandard/Acpi62.h>
......@@ -202,9 +203,11 @@ AcpiInitContext (
? Context->Xsdt->Tables[Index] : (UINT64) Context->Rsdt->Tables[Index]);
//
// Skip NULL table entries if any.
// Skip NULL table entries, DSDT, and RSDP if any.
//
if (Context->Tables[DstIndex] == NULL) {
if (Context->Tables[DstIndex] == NULL
|| Context->Tables[DstIndex]->Signature == EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE
|| *(UINT64 *) Context->Tables[DstIndex] == EFI_ACPI_6_2_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE) {
continue;
}
......@@ -216,6 +219,16 @@ AcpiInitContext (
Index
));
if (Context->Tables[DstIndex]->Signature == EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
Context->Fadt = (EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE *) Context->Tables[DstIndex];
if (Context->Fadt->Header.Length >= OFFSET_OF (EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE, XDsdt) + sizeof (Context->Fadt->XDsdt)) {
Context->Dsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Context->Fadt->XDsdt;
} else {
Context->Dsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Context->Fadt->Dsdt;
}
}
++DstIndex;
}
......@@ -224,6 +237,14 @@ AcpiInitContext (
Context->NumberOfTables = DstIndex;
}
if (Context->Fadt == NULL) {
DEBUG ((DEBUG_WARN, "Failed to find ACPI FADT table\n"));
}
if (Context->Dsdt == NULL) {
DEBUG ((DEBUG_WARN, "Failed to find ACPI DSDT table\n"));
}
return EFI_SUCCESS;
}
......@@ -444,3 +465,111 @@ AcpiNormalizeHeaders (
}
}
}
EFI_STATUS
AcpiApplyPatch (
IN OUT OC_ACPI_CONTEXT *Context,
IN OC_ACPI_PATCH *Patch
)
{
UINT32 Index;
UINT64 CurrOemTableId;
UINT32 ReplaceCount;
DEBUG ((DEBUG_INFO, "Applying %u byte ACPI patch skip %u, count %u\n", Patch->Size, Patch->Skip, Patch->Count));
if (Context->Dsdt != NULL
&& (Patch->TableSignature == 0 || Patch->TableSignature == EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE)
&& (Patch->TableLength == 0 || Context->Dsdt->Length == Patch->TableLength)
&& (Patch->OemTableId == 0 || Context->Dsdt->OemTableId == Patch->OemTableId)) {
DEBUG ((
DEBUG_INFO,
"Patching DSDT of %u bytes with %016Lx ID\n",
Patch->TableLength,
Patch->OemTableId
));
ReplaceCount = ApplyPatch (
Patch->Find,
Patch->Mask,
Patch->Size,
Patch->Replace,
(UINT8 *) Context->Dsdt,
Context->Dsdt->Length,
Patch->Count,
Patch->Skip
);
(VOID) ReplaceCount;
DEBUG ((DEBUG_INFO, "Replaced %u matches out of requested %u in DSDT\n", ReplaceCount, Patch->Count));
if (ReplaceCount > 0) {
Context->Dsdt->Checksum = 0;
Context->Dsdt->Checksum = CalculateCheckSum8 (
(UINT8 *) Context->Dsdt,
Context->Dsdt->Length
);
DEBUG ((
DEBUG_INFO,
"Refreshed DSDT checksum to %02x\n",
Context->Dsdt->Checksum
));
}
}
for (Index = 0; Index < Context->NumberOfTables; ++Index) {
if ((Patch->TableSignature == 0 || Context->Tables[Index]->Signature == Patch->TableSignature)
&& (Patch->TableLength == 0 || Context->Tables[Index]->Length == Patch->TableLength)) {
if (Context->Tables[Index]->Length >= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
CurrOemTableId = ((EFI_ACPI_DESCRIPTION_HEADER *) Context->Tables[Index])->OemTableId;
} else {
CurrOemTableId = 0;
}
if (Patch->OemTableId != 0 && CurrOemTableId != Patch->OemTableId) {
continue;
}
DEBUG ((
DEBUG_INFO,
"Patching table %08x of %u bytes with %016Lx ID at index %u\n",
Context->Tables[Index]->Signature,
Context->Tables[Index]->Length,
CurrOemTableId,
Index
));
ReplaceCount = ApplyPatch (
Patch->Find,
Patch->Mask,
Patch->Size,
Patch->Replace,
(UINT8 *) Context->Tables[Index],
Context->Tables[Index]->Length,
Patch->Count,
Patch->Skip
);
(VOID) ReplaceCount;
DEBUG ((DEBUG_INFO, "Replaced %u matches out of requested %u\n", ReplaceCount, Patch->Count));
if (ReplaceCount > 0 && Context->Tables[Index]->Length >= sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
((EFI_ACPI_DESCRIPTION_HEADER *)Context->Tables[Index])->Checksum = 0;
((EFI_ACPI_DESCRIPTION_HEADER *)Context->Tables[Index])->Checksum = CalculateCheckSum8 (
(UINT8 *) Context->Tables[Index],
Context->Tables[Index]->Length
);
DEBUG ((
DEBUG_INFO,
"Refreshed checksum to %02x\n",
((EFI_ACPI_DESCRIPTION_HEADER *)Context->Tables[Index])->Checksum
));
}
}
}
return EFI_UNSUPPORTED;
}
......@@ -35,6 +35,7 @@
[LibraryClasses]
BaseLib
OcMiscLib
[Guids]
gEfiAcpi10TableGuid
......
/** @file
Copyright (C) 2019, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/OcMiscLib.h>
INT32
FindPattern (
IN CONST UINT8 *Pattern,
IN CONST UINT8 *PatternMask OPTIONAL,
IN CONST UINT32 PatternSize,
IN CONST UINT8 *Data,
IN UINT32 DataSize,
IN INT32 DataOff
)
{
BOOLEAN Matches;
UINT32 Index;
if (PatternSize == 0 || DataSize == 0 || DataOff >= DataSize || DataSize - DataOff < PatternSize) {
return -1;
}
while (DataOff + PatternSize < DataSize) {
Matches = TRUE;
for (Index = 0; Index < PatternSize; ++Index) {
if ((PatternMask == NULL && Data[DataOff + Index] != Pattern[Index])
|| (PatternMask != NULL && (Data[DataOff + Index] & PatternMask[Index]) != Pattern[Index])) {
Matches = FALSE;
break;
}
}
if (Matches) {
return DataOff;
}
++DataOff;
}
return -1;
}
UINT32
ApplyPatch (
IN CONST UINT8 *Pattern,
IN CONST UINT8 *PatternMask OPTIONAL,
IN CONST UINT32 PatternSize,
IN CONST UINT8 *Replace,
IN UINT8 *Data,
IN UINT32 DataSize,
IN UINT32 Count,
IN UINT32 Skip
)
{
UINT32 ReplaceCount;
INT32 DataOff;
ReplaceCount = 0;
DataOff = 0;
do {
DataOff = FindPattern (Pattern, PatternMask, PatternSize, Data, DataSize, DataOff);
if (DataOff >= 0) {
//
// Skip this finding if requested.
//
if (Skip > 0) {
--Skip;
DataOff += PatternSize;
continue;
}
//
// Perform replacement.
//
CopyMem (&Data[DataOff], Replace, PatternSize);
++ReplaceCount;
DataOff += PatternSize;
//
// Check replace count if requested.
//
if (Count > 0) {
--Count;
if (Count == 0) {
break;
}
}
}
} while (DataOff >= 0);
return ReplaceCount;
}
......@@ -48,6 +48,7 @@
[Sources]
Base64Decode.c
ConvertDataToString.c
DataPatcher.c
DebugHelp.c
LegacyRegionLock.c
LegacyRegionUnLock.c
......
......@@ -65,6 +65,28 @@ UINT8 PatchedSsdt8[] = {
0x47, 0x50, 0x45, 0x0A, 0x17
};
STATIC UINT8 HpetPatchFind[] = {'H', 'P', 'E', 'T'};
STATIC UINT8 HpetPatchReplace[] = {'X', 'P', 'E', 'T'};
STATIC UINT8 HpetPatchMask[] = {0xFF, 0xFF, 0xFF, 0xFF};
STATIC
OC_ACPI_PATCH
HpetPatch = {
.Find = HpetPatchFind,
.Replace = HpetPatchReplace,
.Mask = HpetPatchMask,
.Size = sizeof (HpetPatchFind),
//
// Replace only once.
//
.Count = 1,
.Skip = 0,
//
// Only patch DSDT.
//
.TableSignature = EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
.TableLength = 0,
.OemTableId = 0
};
EFI_STATUS
EFIAPI
......@@ -85,6 +107,8 @@ TestAcpi (
AcpiInsertTable (&Context, PatchedSsdt8, sizeof (PatchedSsdt8));
AcpiApplyPatch (&Context, &HpetPatch);
AcpiApplyContext (&Context);
AcpiFreeContext (&Context);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册