Beispiel #1
0
/**
  ImageRead function that operates on a memory buffer whos base is passed into
  FileHandle.

  @param  Reloc             Ponter to baes of the input stream
  @param  Fixup             Offset to the start of the buffer
  @param  FixupData         Number of bytes to copy into the buffer
  @param  Adjust            Location to place results of read

  @retval RETURN_SUCCESS    Data is read from FileOffset from the Handle into
                            the buffer.
**/
RETURN_STATUS
GluePeHotRelocateImageEx (
  IN UINT16      *Reloc,
  IN OUT CHAR8   *Fixup,
  IN OUT CHAR8   **FixupData,
  IN UINT64      Adjust
  )
{
  UINT64  *F64;
  UINT64  FixupVal;

  switch ((*Reloc) >> 12) {
  case EFI_IMAGE_REL_BASED_DIR64:
    F64         = (UINT64 *) Fixup;
    *FixupData  = ALIGN_POINTER (*FixupData, sizeof (UINT64));
    if (*(UINT64 *) (*FixupData) == *F64) {
      *F64 = *F64 + (UINT64) Adjust;
    }

    *FixupData = *FixupData + sizeof (UINT64);
    break;

  case EFI_IMAGE_REL_BASED_IA64_IMM64:
    F64         = (UINT64 *) Fixup;
    *FixupData  = ALIGN_POINTER (*FixupData, sizeof (UINT64));
    if (*(UINT64 *) (*FixupData) == *F64) {
      //
      // Align it to bundle address before fixing up the
      // 64-bit immediate value of the movl instruction.
      //
      //
      Fixup     = (CHAR8 *) ((UINT64) Fixup & (UINT64)~(15));
      FixupVal  = (UINT64) 0;

      //
      // Extract the lower 32 bits of IMM64 from bundle
      //
      EXT_IMM64 (
        FixupVal,
        (UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X,
        IMM64_IMM7B_SIZE_X,
        IMM64_IMM7B_INST_WORD_POS_X,
        IMM64_IMM7B_VAL_POS_X
        );

      EXT_IMM64 (
        FixupVal,
        (UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X,
        IMM64_IMM9D_SIZE_X,
        IMM64_IMM9D_INST_WORD_POS_X,
        IMM64_IMM9D_VAL_POS_X
        );

      EXT_IMM64 (
        FixupVal,
        (UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X,
        IMM64_IMM5C_SIZE_X,
        IMM64_IMM5C_INST_WORD_POS_X,
        IMM64_IMM5C_VAL_POS_X
        );

      EXT_IMM64 (
        FixupVal,
        (UINT32 *) Fixup + IMM64_IC_INST_WORD_X,
        IMM64_IC_SIZE_X,
        IMM64_IC_INST_WORD_POS_X,
        IMM64_IC_VAL_POS_X
        );

      EXT_IMM64 (
        FixupVal,
        (UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X,
        IMM64_IMM41a_SIZE_X,
        IMM64_IMM41a_INST_WORD_POS_X,
        IMM64_IMM41a_VAL_POS_X
        );

      //
      // Update 64-bit address
      //
      FixupVal += Adjust;

      //
      // Insert IMM64 into bundle
      //
      INS_IMM64 (
        FixupVal,
        ((UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X),
        IMM64_IMM7B_SIZE_X,
        IMM64_IMM7B_INST_WORD_POS_X,
        IMM64_IMM7B_VAL_POS_X
        );

      INS_IMM64 (
        FixupVal,
        ((UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X),
        IMM64_IMM9D_SIZE_X,
        IMM64_IMM9D_INST_WORD_POS_X,
        IMM64_IMM9D_VAL_POS_X
        );

      INS_IMM64 (
        FixupVal,
        ((UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X),
        IMM64_IMM5C_SIZE_X,
        IMM64_IMM5C_INST_WORD_POS_X,
        IMM64_IMM5C_VAL_POS_X
        );

      INS_IMM64 (
        FixupVal,
        ((UINT32 *) Fixup + IMM64_IC_INST_WORD_X),
        IMM64_IC_SIZE_X,
        IMM64_IC_INST_WORD_POS_X,
        IMM64_IC_VAL_POS_X
        );

      INS_IMM64 (
        FixupVal,
        ((UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X),
        IMM64_IMM41a_SIZE_X,
        IMM64_IMM41a_INST_WORD_POS_X,
        IMM64_IMM41a_VAL_POS_X
        );

      INS_IMM64 (
        FixupVal,
        ((UINT32 *) Fixup + IMM64_IMM41b_INST_WORD_X),
        IMM64_IMM41b_SIZE_X,
        IMM64_IMM41b_INST_WORD_POS_X,
        IMM64_IMM41b_VAL_POS_X
        );

      INS_IMM64 (
        FixupVal,
        ((UINT32 *) Fixup + IMM64_IMM41c_INST_WORD_X),
        IMM64_IMM41c_SIZE_X,
        IMM64_IMM41c_INST_WORD_POS_X,
        IMM64_IMM41c_VAL_POS_X
        );

      INS_IMM64 (
        FixupVal,
        ((UINT32 *) Fixup + IMM64_SIGN_INST_WORD_X),
        IMM64_SIGN_SIZE_X,
        IMM64_SIGN_INST_WORD_POS_X,
        IMM64_SIGN_VAL_POS_X
        );

      *(UINT64 *) (*FixupData) = *F64;
    }

    *FixupData = *FixupData + sizeof (UINT64);
    break;

  default:
    DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));
    return RETURN_UNSUPPORTED;
  }

  return RETURN_SUCCESS;
}
Beispiel #2
0
/**
  Performs an Itanium-based specific relocation fixup.

  @param  Reloc       The pointer to the relocation record.
  @param  Fixup       The pointer to the address to fix up.
  @param  FixupData   The pointer to a buffer to log the fixups.
  @param  Adjust      The offset to adjust the fixup.

  @retval RETURN_SUCCESS Succeed to fix the relocation entry.
  @retval RETURN_UNSUPPOTED Unrecoganized relocation entry.

**/
RETURN_STATUS
PeCoffLoaderRelocateImageEx (
  IN UINT16      *Reloc,
  IN OUT CHAR8   *Fixup,
  IN OUT CHAR8   **FixupData,
  IN UINT64      Adjust
  )
{
  UINT64      *Fixup64;
  UINT64      FixupVal;

  switch ((*Reloc) >> 12) {
    case EFI_IMAGE_REL_BASED_IA64_IMM64:

      //
      // Align it to bundle address before fixing up the
      // 64-bit immediate value of the movl instruction.
      //

      Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));
      FixupVal = (UINT64)0;

      //
      // Extract the lower 32 bits of IMM64 from bundle
      //
      EXT_IMM64(FixupVal,
                (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,
                IMM64_IMM7B_SIZE_X,
                IMM64_IMM7B_INST_WORD_POS_X,
                IMM64_IMM7B_VAL_POS_X
                );

      EXT_IMM64(FixupVal,
                (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,
                IMM64_IMM9D_SIZE_X,
                IMM64_IMM9D_INST_WORD_POS_X,
                IMM64_IMM9D_VAL_POS_X
                );

      EXT_IMM64(FixupVal,
                (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,
                IMM64_IMM5C_SIZE_X,
                IMM64_IMM5C_INST_WORD_POS_X,
                IMM64_IMM5C_VAL_POS_X
                );

      EXT_IMM64(FixupVal,
                (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,
                IMM64_IC_SIZE_X,
                IMM64_IC_INST_WORD_POS_X,
                IMM64_IC_VAL_POS_X
                );

      EXT_IMM64(FixupVal,
                (UINT32 *)Fixup + IMM64_IMM41A_INST_WORD_X,
                IMM64_IMM41A_SIZE_X,
                IMM64_IMM41A_INST_WORD_POS_X,
                IMM64_IMM41A_VAL_POS_X
                );

      //
      // Update 64-bit address
      //
      FixupVal += Adjust;

      //
      // Insert IMM64 into bundle
      //
      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),
                IMM64_IMM7B_SIZE_X,
                IMM64_IMM7B_INST_WORD_POS_X,
                IMM64_IMM7B_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),
                IMM64_IMM9D_SIZE_X,
                IMM64_IMM9D_INST_WORD_POS_X,
                IMM64_IMM9D_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),
                IMM64_IMM5C_SIZE_X,
                IMM64_IMM5C_INST_WORD_POS_X,
                IMM64_IMM5C_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),
                IMM64_IC_SIZE_X,
                IMM64_IC_INST_WORD_POS_X,
                IMM64_IC_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IMM41A_INST_WORD_X),
                IMM64_IMM41A_SIZE_X,
                IMM64_IMM41A_INST_WORD_POS_X,
                IMM64_IMM41A_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IMM41B_INST_WORD_X),
                IMM64_IMM41B_SIZE_X,
                IMM64_IMM41B_INST_WORD_POS_X,
                IMM64_IMM41B_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IMM41C_INST_WORD_X),
                IMM64_IMM41C_SIZE_X,
                IMM64_IMM41C_INST_WORD_POS_X,
                IMM64_IMM41C_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),
                IMM64_SIGN_SIZE_X,
                IMM64_SIGN_INST_WORD_POS_X,
                IMM64_SIGN_VAL_POS_X
                );

      Fixup64 = (UINT64 *) Fixup;
      if (*FixupData != NULL) {
        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
        *(UINT64 *)(*FixupData) = *Fixup64;
        *FixupData = *FixupData + sizeof(UINT64);
      }
      break;

    default:
      return RETURN_UNSUPPORTED;
  }

  return RETURN_SUCCESS;
}
Beispiel #3
0
EFI_STATUS
PeCoffLoaderRelocateImageEx (
  IN UINT16      *Reloc,
  IN OUT CHAR8   *Fixup, 
  IN OUT CHAR8   **FixupData,
  IN UINT64      Adjust
  )
/*++

Routine Description:

  Performs an Itanium-based specific relocation fixup

Arguments:

  Reloc      - Pointer to the relocation record

  Fixup      - Pointer to the address to fix up

  FixupData  - Pointer to a buffer to log the fixups

  Adjust     - The offset to adjust the fixup

Returns:

  Status code

--*/
{
  UINT64      *F64;
  UINT64      FixupVal;

  switch ((*Reloc) >> 12) {

    case EFI_IMAGE_REL_BASED_IA64_IMM64:

      //
      // Align it to bundle address before fixing up the
      // 64-bit immediate value of the movl instruction.
      //

      Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));
      FixupVal = (UINT64)0;
                       
      // 
      // Extract the lower 32 bits of IMM64 from bundle
      //
      EXT_IMM64(FixupVal,
                (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,
                IMM64_IMM7B_SIZE_X,
                IMM64_IMM7B_INST_WORD_POS_X,
                IMM64_IMM7B_VAL_POS_X
                );

      EXT_IMM64(FixupVal,
                (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,
                IMM64_IMM9D_SIZE_X,
                IMM64_IMM9D_INST_WORD_POS_X,
                IMM64_IMM9D_VAL_POS_X
                );

      EXT_IMM64(FixupVal,
                (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,
                IMM64_IMM5C_SIZE_X,
                IMM64_IMM5C_INST_WORD_POS_X,
                IMM64_IMM5C_VAL_POS_X
                );

      EXT_IMM64(FixupVal,
                (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,
                IMM64_IC_SIZE_X,
                IMM64_IC_INST_WORD_POS_X,
                IMM64_IC_VAL_POS_X
                );

      EXT_IMM64(FixupVal,
                (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X,
                IMM64_IMM41a_SIZE_X,
                IMM64_IMM41a_INST_WORD_POS_X,
                IMM64_IMM41a_VAL_POS_X
                );
                       
      // 
      // Update 64-bit address
      //
      FixupVal += Adjust;

      // 
      // Insert IMM64 into bundle
      //
      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),
                IMM64_IMM7B_SIZE_X,
                IMM64_IMM7B_INST_WORD_POS_X,
                IMM64_IMM7B_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),
                IMM64_IMM9D_SIZE_X,
                IMM64_IMM9D_INST_WORD_POS_X,
                IMM64_IMM9D_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),
                IMM64_IMM5C_SIZE_X,
                IMM64_IMM5C_INST_WORD_POS_X,
                IMM64_IMM5C_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),
                IMM64_IC_SIZE_X,
                IMM64_IC_INST_WORD_POS_X,
                IMM64_IC_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X),
                IMM64_IMM41a_SIZE_X,
                IMM64_IMM41a_INST_WORD_POS_X,
                IMM64_IMM41a_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X),
                IMM64_IMM41b_SIZE_X,
                IMM64_IMM41b_INST_WORD_POS_X,
                IMM64_IMM41b_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X),
                IMM64_IMM41c_SIZE_X,
                IMM64_IMM41c_INST_WORD_POS_X,
                IMM64_IMM41c_VAL_POS_X
                );

      INS_IMM64(FixupVal,
                ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),
                IMM64_SIGN_SIZE_X,
                IMM64_SIGN_INST_WORD_POS_X,
                IMM64_SIGN_VAL_POS_X
                );

      F64 = (UINT64 *) Fixup;
      if (*FixupData != NULL) {
        *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
        *(UINT64 *)(*FixupData) = *F64;
        *FixupData = *FixupData + sizeof(UINT64);
      }
      break;

    default:
      return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}