https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
		
			
				
	
	
		
			84 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  IA-32/x64 PatchInstructionX86()
 | 
						|
 | 
						|
  Copyright (C) 2018, Intel Corporation. All rights reserved.<BR>
 | 
						|
  Copyright (C) 2018, Red Hat, Inc.
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
**/
 | 
						|
 | 
						|
#include "BaseLibInternals.h"
 | 
						|
 | 
						|
/**
 | 
						|
  Patch the immediate operand of an IA32 or X64 instruction such that the byte,
 | 
						|
  word, dword or qword operand is encoded at the end of the instruction's
 | 
						|
  binary representation.
 | 
						|
 | 
						|
  This function should be used to update object code that was compiled with
 | 
						|
  NASM from assembly source code. Example:
 | 
						|
 | 
						|
  NASM source code:
 | 
						|
 | 
						|
        mov     eax, strict dword 0 ; the imm32 zero operand will be patched
 | 
						|
    ASM_PFX(gPatchCr3):
 | 
						|
        mov     cr3, eax
 | 
						|
 | 
						|
  C source code:
 | 
						|
 | 
						|
    X86_ASSEMBLY_PATCH_LABEL gPatchCr3;
 | 
						|
    PatchInstructionX86 (gPatchCr3, AsmReadCr3 (), 4);
 | 
						|
 | 
						|
  @param[out] InstructionEnd  Pointer right past the instruction to patch. The
 | 
						|
                              immediate operand to patch is expected to
 | 
						|
                              comprise the trailing bytes of the instruction.
 | 
						|
                              If InstructionEnd is closer to address 0 than
 | 
						|
                              ValueSize permits, then ASSERT().
 | 
						|
 | 
						|
  @param[in] PatchValue       The constant to write to the immediate operand.
 | 
						|
                              The caller is responsible for ensuring that
 | 
						|
                              PatchValue can be represented in the byte, word,
 | 
						|
                              dword or qword operand (as indicated through
 | 
						|
                              ValueSize); otherwise ASSERT().
 | 
						|
 | 
						|
  @param[in] ValueSize        The size of the operand in bytes; must be 1, 2,
 | 
						|
                              4, or 8. ASSERT() otherwise.
 | 
						|
**/
 | 
						|
VOID
 | 
						|
EFIAPI
 | 
						|
PatchInstructionX86 (
 | 
						|
  OUT X86_ASSEMBLY_PATCH_LABEL *InstructionEnd,
 | 
						|
  IN  UINT64                   PatchValue,
 | 
						|
  IN  UINTN                    ValueSize
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // The equality ((UINTN)InstructionEnd == ValueSize) would assume a zero-size
 | 
						|
  // instruction at address 0; forbid it.
 | 
						|
  //
 | 
						|
  ASSERT ((UINTN)InstructionEnd > ValueSize);
 | 
						|
 | 
						|
  switch (ValueSize) {
 | 
						|
  case 1:
 | 
						|
    ASSERT (PatchValue <= MAX_UINT8);
 | 
						|
    *((UINT8 *)(UINTN)InstructionEnd - 1) = (UINT8)PatchValue;
 | 
						|
    break;
 | 
						|
 | 
						|
  case 2:
 | 
						|
    ASSERT (PatchValue <= MAX_UINT16);
 | 
						|
    WriteUnaligned16 ((UINT16 *)(UINTN)InstructionEnd - 1, (UINT16)PatchValue);
 | 
						|
    break;
 | 
						|
 | 
						|
  case 4:
 | 
						|
    ASSERT (PatchValue <= MAX_UINT32);
 | 
						|
    WriteUnaligned32 ((UINT32 *)(UINTN)InstructionEnd - 1, (UINT32)PatchValue);
 | 
						|
    break;
 | 
						|
 | 
						|
  case 8:
 | 
						|
    WriteUnaligned64 ((UINT64 *)(UINTN)InstructionEnd - 1, PatchValue);
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    ASSERT (FALSE);
 | 
						|
  }
 | 
						|
}
 |