/** @file Copyright (c) 2020 - 2025, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include //#undef DEBUG_VERBOSE //#define DEBUG_VERBOSE DEBUG_INFO /** Load universal payload image into memory. @param[in] ImageBase The universal payload image base @param[out] PayloadInfo Pointer to receive payload related info @retval EFI_SUCCESS The image was loaded successfully EFI_ABORTED The image loading failed EFI_UNSUPPORTED The relocation format is not supported **/ EFI_STATUS EFIAPI LoadElfPayload ( IN VOID *ImageBase, OUT LOADED_PAYLOAD_INFO *PayloadInfo ) { EFI_STATUS Status; ELF_IMAGE_CONTEXT Context; UNIVERSAL_PAYLOAD_INFO_HEADER *PldInfo; UINT16 ExtraDataCount; UINT32 Index; CHAR8 *SectionName; UINTN Offset; UINTN Size; if ((ImageBase == NULL) || (PayloadInfo == NULL)) { return EFI_INVALID_PARAMETER; } Status = ParseElfImage (ImageBase, &Context); if (EFI_ERROR(Status)) { return EFI_UNSUPPORTED; } // Get UNIVERSAL_PAYLOAD_INFO and number of additional PLD sections. PldInfo = NULL; ExtraDataCount = 0; ASSERT(Context.ShNum < MAX_ELF_SHNUM); for (Index = 0; Index < Context.ShNum; Index++) { Status = GetElfSectionName (&Context, Index, &SectionName); if (EFI_ERROR(Status)) { continue; } if (AsciiStrCmp(SectionName, UNIVERSAL_PAYLOAD_INFO_SEC_NAME) == 0) { Status = GetElfSectionPos (&Context, Index, &Offset, &Size); if (!EFI_ERROR(Status)) { PldInfo = (UNIVERSAL_PAYLOAD_INFO_HEADER *)(Context.FileBase + Offset); } } else if (AsciiStrnCmp(SectionName, UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX, UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX_LENGTH) == 0) { Status = GetElfSectionPos (&Context, Index, &Offset, &Size); if (!EFI_ERROR (Status) && (ExtraDataCount < ARRAY_SIZE(PayloadInfo->LoadedImage))) { AsciiStrCpyS (PayloadInfo->LoadedImage[ExtraDataCount].Identifier, sizeof(PayloadInfo->LoadedImage[ExtraDataCount].Identifier), SectionName + UNIVERSAL_PAYLOAD_EXTRA_SEC_NAME_PREFIX_LENGTH); PayloadInfo->LoadedImage[ExtraDataCount].Base = (UINTN)(Context.FileBase + Offset); PayloadInfo->LoadedImage[ExtraDataCount].Size = Size; ExtraDataCount++; } } } if (Context.ReloadRequired) { Context.ImageAddress = AllocatePages (EFI_SIZE_TO_PAGES (Context.ImageSize)); } // Load ELF into the required base Status = LoadElfImage (&Context); if (!EFI_ERROR(Status)) { if ((PldInfo != NULL) && (PldInfo->Identifier == UNIVERSAL_PAYLOAD_IDENTIFIER)) { CopyMem (&PayloadInfo->Info, PldInfo, sizeof(UNIVERSAL_PAYLOAD_INFO_HEADER)); PayloadInfo->ImageCount = ExtraDataCount; } PayloadInfo->Machine = (Context.EiClass == ELF_CLASS32) ? IMAGE_FILE_MACHINE_I386 : IMAGE_FILE_MACHINE_X64; PayloadInfo->EntryPoint = Context.EntryPoint; PayloadInfo->PayloadSize = Context.FileSize; PayloadInfo->PayloadBase = (UINTN)Context.FileBase; } return Status; }