From nobody Fri Sep 20 22:14:50 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+103668+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+103668+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1682543237; cv=none; d=zohomail.com; s=zohoarc; b=RbiWYNkuMIFXinF5yBsdfHbf2GhOo87kt+/8MzHRWoNw7iYF/S0bm6uv4e+grH5eqOS3hHI5gJM+kBfteyfYlPeQx5BKvEMSxiv1nqa8RbQzSynS+BShx6VW1CH9mbG7rhsX2D387ZiOzIDdyrO4zGO4YQ8hxoiuuSw6uAVWyik= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1682543237; h=Content-Transfer-Encoding:Cc:Date:From:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Sender:Subject:To; bh=r8GhcN8NEPeiie/TdlVPL/BeVO4ZtwatZPtuCC1EThY=; b=VX9QZm0lPPEHtqAZUUCH6zUXQS1HtcAHng3BeECqm7a3cxv4XGr5J10F2Yi5HMRrbw+STth9vak3fOV+eNnuHDBiUMA5jAZmAw4yQhrcipsfuM8DSwGgP2phdNzhwlJXjBE7DllDGwQxWsgS/XHVqM+8G5TI09sIsBaBf82NsKU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+103668+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1682543237126484.45926495245385; Wed, 26 Apr 2023 14:07:17 -0700 (PDT) Return-Path: X-Received: by 127.0.0.2 with SMTP id E9fSYY1788612xli67X61M7I; Wed, 26 Apr 2023 14:07:16 -0700 X-Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web10.2297.1682493122178670563 for ; Wed, 26 Apr 2023 00:12:02 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10691"; a="374976797" X-IronPort-AV: E=Sophos;i="5.99,227,1677571200"; d="scan'208";a="374976797" X-Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Apr 2023 00:11:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10691"; a="940087816" X-IronPort-AV: E=Sophos;i="5.99,227,1677571200"; d="scan'208";a="940087816" X-Received: from coreboot.itwn.intel.com (HELO juichenx-mobl3.gar.corp.intel.com) ([10.5.215.15]) by fmsmga006.fm.intel.com with ESMTP; 26 Apr 2023 00:11:50 -0700 From: brucex.wang@intel.com To: devel@edk2.groups.io Cc: BruceX Wang , Guo Dong , Ray Ni , Sean Rhodes , James Lu , Gua Guo Subject: [edk2-devel] [PATCH] * UefiPayloadPkg: Clang dependency removal Date: Wed, 26 Apr 2023 15:11:39 +0800 Message-Id: <0b1c996e78cddfa3a272187bd783f0c8b8e33492.1682492500.git.brucex.wang@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Unsubscribe: List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,brucex.wang@intel.com X-Gm-Message-State: KXSxnDITVLTi0voQEWri0CfVx1787277AA= Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=groups.io; q=dns/txt; s=20140610; t=1682543236; bh=SBrIiK5KvQ/76TEonKXtH9rRGxZHl6FCJey0gbATgCI=; h=Cc:Date:From:Reply-To:Subject:To; b=WqtbA8aRPH1peIVCUauAB9PHuy/RZ6pxn6Hdvx7F0F1daDsc4nJukFBrGaqXtn5M0dP XPd4O4Tf2rg3B3bej1CeIUOII/1P8ecQdI1yHZMGc+K40t8htpsZ3rOJWTYfFl/y4jrLH pfGIqNsGyCc8aaTs8utg4GVknuKeMGqDRoE= X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1682543238140100005 Content-Type: text/plain; charset="utf-8" From: BruceX Wang REF: TBD Use Python to replace llvm-objcopy in UniversalPayloadBuild.py. 1. AddSection32() and AddSection64(): Make a section named
with the contents of . 2. RemoveSection32() and RemoveSection64(): Remove
. 3. ReplaceFv (): remove the section before add the section if the file exists. Cc: Guo Dong Cc: Ray Ni Cc: Sean Rhodes Cc: James Lu Cc: Gua Guo Signed-off-by: BruceX Wang Reviewed-by: Gua Guo --- UefiPayloadPkg/Tools/ElfFv.py | 809 ++++++++++++++++++++++++ UefiPayloadPkg/Tools/__init__.py | 19 + UefiPayloadPkg/UniversalPayloadBuild.py | 232 ++++--- 3 files changed, 935 insertions(+), 125 deletions(-) create mode 100644 UefiPayloadPkg/Tools/ElfFv.py create mode 100644 UefiPayloadPkg/Tools/__init__.py diff --git a/UefiPayloadPkg/Tools/ElfFv.py b/UefiPayloadPkg/Tools/ElfFv.py new file mode 100644 index 0000000000..a3d5bf08b9 --- /dev/null +++ b/UefiPayloadPkg/Tools/ElfFv.py @@ -0,0 +1,809 @@ +## @file +# OBJCOPY parser, it's used to replace FV +# +# Copyright (c) 2023, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +import argparse +from ctypes import * +import struct + +class ElfSectionHeader64: + def __init__(self, sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_= size, sh_link, sh_info, sh_addralign, sh_entsize): + self.sh_name =3D sh_name + self.sh_type =3D sh_type + self.sh_flags =3D sh_flags + self.sh_addr =3D sh_addr + self.sh_offset =3D sh_offset + self.sh_size =3D sh_size + self.sh_link =3D sh_link + self.sh_info =3D sh_info + self.sh_addralign =3D sh_addralign + self.sh_entsize =3D sh_entsize + + def pack(self): + return struct.pack(' RemoveNameOffset): + unpacked_header.sh_name -=3D RemoveNameOffset + # Modify size of name string section entry in section entry. + if (Index =3D=3D StringIndexNumber): + unpacked_header.sh_size -=3D len (SectionName) + # added section + else : + if (Index =3D=3D StringIndexNumber): + unpacked_header.sh_size +=3D len (SectionName) + NewSHentry =3D ElfSectionHeader64 ( + unpacked_header.sh_name, + unpacked_header.sh_type, + unpacked_header.sh_flags, + unpacked_header.sh_addr, + unpacked_header.sh_offset, + unpacked_header.sh_size, + unpacked_header.sh_link, + unpacked_header.sh_info, + unpacked_header.sh_addralign, + unpacked_header.sh_entsize).pack() + return NewSHentry + +def AddSectionHeader32(SHentry, NewUPLEntrylen, SectionHeaderEntrySize, In= dex, RemoveNameOffset, SectionName, StringIndexNumber): + SHentry =3D bytearray(SHentry) + unpacked_header =3D ElfSectionHeader32.unpack(SHentry[(Index * Section= HeaderEntrySize):((Index * SectionHeaderEntrySize) + SectionHeaderEntrySize= )]) + if (Index !=3D 0): + NewSHentry =3D SHentry[(Index * SectionHeaderEntrySize):((Index * = SectionHeaderEntrySize) + SectionHeaderEntrySize)] + unpacked_header.sh_offset =3D NewUPLEntrylen + # Modify offset of name in section entry + # if RemoveNameOffset !=3D 0 that is remove function. + if (RemoveNameOffset !=3D 0): + if (unpacked_header.sh_name > RemoveNameOffset): + unpacked_header.sh_name -=3D RemoveNameOffset + # Modify size of name string section entry in section entry. + if (Index =3D=3D StringIndexNumber): + unpacked_header.sh_size -=3D len (SectionName) + # added section + else : + if (Index =3D=3D StringIndexNumber): + unpacked_header.sh_size +=3D len (SectionName) + NewSHentry =3D ElfSectionHeader32 ( + unpacked_header.sh_name, + unpacked_header.sh_type, + unpacked_header.sh_flags, + unpacked_header.sh_addr, + unpacked_header.sh_offset, + unpacked_header.sh_size, + unpacked_header.sh_link, + unpacked_header.sh_info, + unpacked_header.sh_addralign, + unpacked_header.sh_entsize).pack() + return NewSHentry + +def ModifyPHSegmentOffset64(NewUPLEntry, ElfHeaderOffset, PHSegmentName): + # Modify offset and address of program header tables. + elf_header =3D ElfHeader64(NewUPLEntry[:64]) + SHentry =3D NewUPLEntry[ElfHeaderOffset:] + # Elf program header tables start from 0x40 in 64-bits objects + PHentry =3D NewUPLEntry[64: 64 + (elf_header.e_phnum * elf_header.e_ph= entsize)] + PHdrs =3D [] + SHdrs =3D [] + for i in range(elf_header.e_shnum): + SHData =3D SHentry[(i * elf_header.e_shentsize): (i * elf_header.e= _shentsize) + elf_header.e_shentsize] + unpacked_SectionHeader =3D ElfSectionHeader64.unpack(SHData) + SHdrs.append(unpacked_SectionHeader) + for i in range(elf_header.e_phnum): + PHData =3D PHentry[(i * elf_header.e_phentsize): (i * elf_header.e= _phentsize) + elf_header.e_phentsize] + unpacked_ProgramHeader =3D Elf64_Phdr(PHData) + PHdrs.append(unpacked_ProgramHeader) + if (PHSegmentName =3D=3D '.text'): + PHdrs[0].p_offset =3D SHdrs[1].sh_offset + PHdrs[0].p_paddr =3D SHdrs[1].sh_addr + PHdrs[4].p_offset =3D SHdrs[1].sh_offset + PHdrs[4].p_paddr =3D SHdrs[1].sh_addr + elif (PHSegmentName =3D=3D '.dynamic'): + PHdrs[1].p_offset =3D SHdrs[2].sh_offset + PHdrs[1].p_paddr =3D SHdrs[2].sh_addr + PHdrs[3].p_offset =3D SHdrs[2].sh_offset + PHdrs[3].p_paddr =3D SHdrs[2].sh_addr + elif (PHSegmentName =3D=3D '.data'): + PHdrs[2].p_offset =3D SHdrs[3].sh_offset + PHdrs[2].p_paddr =3D SHdrs[3].sh_addr + packed_PHData =3D b'' + for phdr in PHdrs: + packed_PHData +=3D phdr.pack() + NewUPLEntry =3D bytearray(NewUPLEntry) + NewUPLEntry[64: 64 + (elf_header.e_phnum * elf_header.e_phentsize)] = =3D packed_PHData + return NewUPLEntry + +def ModifyPHSegmentOffset32(NewUPLEntry, ElfHeaderOffset, PHSegmentName): + # Modify offset and address of program header tables. + # Elf header is stored at 0x0-0x34 in 32-bits objects + elf_header =3D ElfHeader32(NewUPLEntry[:52]) + SHentry =3D NewUPLEntry[ElfHeaderOffset:] + # Elf program header tables start from 0x34 in 32-bits objects + PHentry =3D NewUPLEntry[52: 52 + (elf_header.e_phnum * elf_header.e_ph= entsize)] + PHdrs =3D [] + SHdrs =3D [] + for i in range(elf_header.e_shnum): + SHData =3D SHentry[(i * elf_header.e_shentsize): (i * elf_header.e= _shentsize) + elf_header.e_shentsize] + unpacked_SectionHeader =3D ElfSectionHeader32.unpack(SHData) + SHdrs.append(unpacked_SectionHeader) + for i in range(elf_header.e_phnum): + PHData =3D PHentry[(i * elf_header.e_phentsize): (i * elf_header.e= _phentsize) + elf_header.e_phentsize] + unpacked_ProgramHeader =3D Elf32_Phdr(PHData) + PHdrs.append(unpacked_ProgramHeader) + if (PHSegmentName =3D=3D '.text'): + PHdrs[0].p_offset =3D SHdrs[1].sh_offset + PHdrs[0].p_paddr =3D SHdrs[1].sh_addr + PHdrs[0].p_vaddr =3D SHdrs[1].sh_addr + PHdrs[2].p_offset =3D SHdrs[1].sh_offset + PHdrs[2].p_paddr =3D SHdrs[1].sh_addr + PHdrs[0].p_vaddr =3D SHdrs[1].sh_addr + elif (PHSegmentName =3D=3D '.data'): + PHdrs[1].p_offset =3D SHdrs[2].sh_offset + PHdrs[1].p_paddr =3D SHdrs[2].sh_addr + PHdrs[1].p_vaddr =3D SHdrs[2].sh_addr + packed_PHData =3D b'' + for phdr in PHdrs: + packed_PHData +=3D phdr.pack() + NewUPLEntry =3D bytearray(NewUPLEntry) + NewUPLEntry[52: 52 + (elf_header.e_phnum * elf_header.e_phentsize)] = =3D packed_PHData + return NewUPLEntry + +def RemoveSection64(UniversalPayloadEntry, RemoveSectionName): + # If elf is 64-bit objects. + # Get offsets as follows: + # 1. Section name which will remove in section na= me string. + # 2. Section which will remove. + # 3. Section header which will remove. + with open(UniversalPayloadEntry,'rb') as f: + UPLEntry =3D f.read() + RemoveSectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, = SectionHeaderEntryNumber, _, StringIndexNumber, _ =3D FindSection(UPLEntry,= RemoveSectionName) + if (RemoveSectionNameOffset =3D=3D -1): + raise argparse.ArgumentTypeError ('Section: {} not found.'.for= mat (RemoveSectionNameOffset)) + # Read section header entry + SHentry =3D UPLEntry[ElfHeaderOffset:] + # find deleted fv section offset. + # Elf header is stored at 0x0-0x40 in 64-bits objects + elf_header =3D ElfHeader64(UPLEntry[:64]) + Counter =3D 0 + RemoveIndex =3D 0 + RemoveNameOffset =3D 0 + for Index in range(0, elf_header.e_shnum): + # Read Index of section header. + unpacked_SectionHeader =3D ElfSectionHeader64.unpack(SHentry[(= Index * elf_header.e_shentsize):((Index * elf_header.e_shentsize) + elf_hea= der.e_shentsize)]) + # Find offset of section name which is removed. + if (unpacked_SectionHeader.sh_name =3D=3D RemoveSectionNameOff= set): + RemoveIndex =3D Counter + Counter +=3D 1 + else: + Counter +=3D 1 + # Elf header is recombined. + # Elf header and program header table in front of first section ar= e reserved. + # Elf header size is 0x40 with 64-bit object. + ElfHeaderSize =3D 64 + ElfHandPH =3D ElfHeaderSize + (elf_header.e_phnum * elf_header.e_p= hentsize) + NewUPLEntry =3D UPLEntry[:ElfHandPH] + # Keep Section header and program header table, RemoveSection64() = only recombined section and section header. + NewUPLEntry =3D bytearray(NewUPLEntry) + # Sections is recombined. + # 1. name of deleted section is removed in name string section. + # 2. deleted section is removed in dll file. + # 3. re-align sections before and after deleted section. + NewUPLEntrylen =3D [] + for Index in range(0, (SectionHeaderEntryNumber)): + unpacked_SectionHeader =3D ElfSectionHeader64.unpack(SHentry[(= Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + Section= HeaderEntrySize)]) + NewUPLEntrylen.append(len(NewUPLEntry)) + if (Index =3D=3D 0): + # Address alignment, section will align with alignment of = next section. + AlignmentIndex =3D 8 + if (SectionHeaderEntryNumber > 2): + unpacked_NextSectionHeader =3D ElfSectionHeader64.unpac= k(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHea= derEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign) + # Section in front of removed section + elif (Index + 1 =3D=3D RemoveIndex): + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Read section address alignment + # If section that will be removed in .dll is not first and= last one . + # Address alignment, section will align with alignment of = section after deleted section. + # Check next and the section after next are not end of sec= tion. + if ((Index + 2) < (SectionHeaderEntryNumber - 1)): + unpacked_Next2SectionHeader =3D ElfSectionHeader64.unp= ack(SHentry[((Index + 2) * SectionHeaderEntrySize):(((Index + 2) * SectionH= eaderEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _Next2SectionHeader.sh_addralign) + else: + # It is align 8 bytes if next section or the section a= fter next is last one. + AlignmentIndex =3D 8 + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignmen= tIndex) + # section is Deleted section + elif (Index =3D=3D RemoveIndex): + # Don't add removed section to elf. + # Find offset of section name. + RemoveNameOffset =3D unpacked_SectionHeader.sh_name + # section is name string section. + elif (Index =3D=3D StringIndexNumber): + # StringIndex is String Index section + StringIndex =3D UPLEntry[unpacked_SectionHeader.sh_offset:= (unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Remove name of removed section in name string section. + # Section header isn't exist if RemoveSectionNameOffset eq= ual to -1. + StringIndex =3D bytearray(StringIndex) + RemoveSectionName =3D bytearray(RemoveSectionName, encodin= g=3D'utf-8') + RemoveSectionName =3D RemoveSectionName + bytes('\0', enco= ding=3D'utf-8') + StringIndex =3D StringIndex.replace(RemoveSectionName,b'') + NewUPLEntry +=3D StringIndex + # other sections. + else: + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Address alignment, section will align with alignment of = next section. + if (Index < (SectionHeaderEntryNumber - 1)): + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _NextSectionHeader.sh_addralign) + else: + # If section is last one. + AlignmentIndex =3D 8 + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignmen= tIndex) + SectionHeaderOffset =3D len(NewUPLEntry) + # Add section header + for Number in range(0, (SectionHeaderEntryNumber)): + if (Number !=3D RemoveIndex): + NewSHentry =3D AddSectionHeader64(SHentry, NewUPLEntrylen[= Number], SectionHeaderEntrySize, Number, RemoveNameOffset, RemoveSectionNam= e, StringIndexNumber) + NewUPLEntry +=3D NewSHentry + # Modify number of sections and offset of section header in Elf he= ader. + elf_header.e_shoff =3D SectionHeaderOffset + elf_header.e_shnum -=3D 1 + NewUPLEntry =3D elf_header.pack() + NewUPLEntry[64:] + # write to Elf. + with open(UniversalPayloadEntry,'wb') as f: + f.write(NewUPLEntry) + +def RemoveSection32(UniversalPayloadEntry, RemoveSectionName): + # If elf is 32-bit objects. + # Get offsets as follows: + # 1. Section name which will remove in section na= me string. + # 2. Section which will remove. + # 3. Section header which will remove. + with open(UniversalPayloadEntry,'rb') as f: + UPLEntry =3D f.read() + RemoveSectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, = SectionHeaderEntryNumber, _, StringIndexNumber, EI_CLASS =3D FindSection(UP= LEntry, RemoveSectionName) + if (RemoveSectionNameOffset =3D=3D -1): + raise argparse.ArgumentTypeError ('Section: {} not found.'.for= mat (RemoveSectionNameOffset)) + # Read section header entry + SHentry =3D UPLEntry[ElfHeaderOffset:] + # find deleted fv section offset. + # Elf header is stored at 0x0-0x34 in 32-bits objects + elf_header =3D ElfHeader32(UPLEntry[:52]) + Counter =3D 0 + RemoveIndex =3D 0 + RemoveNameOffset =3D 0 + for Index in range(0, elf_header.e_shnum): + # Read Index of section header. + unpacked_SectionHeader =3D ElfSectionHeader32.unpack(SHentry[(= Index * elf_header.e_shentsize):((Index * elf_header.e_shentsize) + elf_hea= der.e_shentsize)]) + # Find offset of section name which is removed. + if (unpacked_SectionHeader.sh_name =3D=3D RemoveSectionNameOff= set): + RemoveIndex =3D Counter + Counter +=3D 1 + else: + Counter +=3D 1 + # Elf header is recombined. + # Elf header and program header table in front of first section ar= e reserved. + # Elf header size is 0x34 with 32-bit object. + ElfHeaderSize =3D 52 + ElfHandPH =3D ElfHeaderSize + (elf_header.e_phnum * elf_header.e_p= hentsize) + NewUPLEntry =3D UPLEntry[:ElfHandPH] + # Keep Section header and program header table, RemoveSection32() = only recombined section and section header. + NewUPLEntry =3D bytearray(NewUPLEntry) + # Sections is recombined. + # 1. name of deleted section is removed in name string section. + # 2. deleted section is removed in dll file. + # 3. re-align sections before and after deleted section. + NewUPLEntrylen =3D [] + for Index in range(0, (SectionHeaderEntryNumber)): + unpacked_SectionHeader =3D ElfSectionHeader32.unpack(SHentry[(= Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + Section= HeaderEntrySize)]) + NewUPLEntrylen.append(len(NewUPLEntry)) + if (Index =3D=3D 0): + # Address alignment, section will align with alignment of = next section. + AlignmentIndex =3D 8 + if (SectionHeaderEntryNumber > 2): + unpacked_NextSectionHeader =3D ElfSectionHeader32.unpac= k(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHea= derEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign) + # Section in front of removed section + elif (Index + 1 =3D=3D RemoveIndex): + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Read section address alignment + # If section that will be removed in .dll is not first and= last one . + # Address alignment, section will align with alignment of = section after deleted section. + # Check next and the section after next are not end of sec= tion. + if ((Index + 2) < (SectionHeaderEntryNumber - 1)): + unpacked_Next2SectionHeader =3D ElfSectionHeader32.unp= ack(SHentry[((Index + 2) * SectionHeaderEntrySize):(((Index + 2) * SectionH= eaderEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _Next2SectionHeader.sh_addralign) + else: + # It is align 8 bytes if next section or the section a= fter next is last one. + AlignmentIndex =3D 8 + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignmen= tIndex) + # section is Deleted section + elif (Index =3D=3D RemoveIndex): + # Don't add removed section to elf. + # Find offset of section name. + RemoveNameOffset =3D unpacked_SectionHeader.sh_name + # section is name string section. + elif (Index =3D=3D StringIndexNumber): + # StringIndex is String Index section + StringIndex =3D UPLEntry[unpacked_SectionHeader.sh_offset:= (unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Remove name of removed section in name string section. + # Section header isn't exist if RemoveSectionNameOffset eq= ual to -1. + StringIndex =3D bytearray(StringIndex) + RemoveSectionName =3D bytearray(RemoveSectionName, encodin= g=3D'utf-8') + RemoveSectionName =3D RemoveSectionName + bytes('\0', enco= ding=3D'utf-8') + StringIndex =3D StringIndex.replace(RemoveSectionName,b'') + NewUPLEntry +=3D StringIndex + # other sections. + else: + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Address alignment, section will align with alignment of = next section. + if (Index < (SectionHeaderEntryNumber - 1)): + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _NextSectionHeader.sh_addralign) + else: + # If section is last one. + AlignmentIndex =3D 8 + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignmen= tIndex) + SectionHeaderOffset =3D len(NewUPLEntry) + # Add section header + for Number in range(0, (SectionHeaderEntryNumber)): + if (Number !=3D RemoveIndex): + NewSHentry =3D AddSectionHeader32(SHentry, NewUPLEntrylen[= Number], SectionHeaderEntrySize, Number, RemoveNameOffset, RemoveSectionNam= e, StringIndexNumber) + NewUPLEntry +=3D NewSHentry + # Modify number of sections and offset of section header in Elf he= ader. + elf_header.e_shoff =3D SectionHeaderOffset + elf_header.e_shnum -=3D 1 + NewUPLEntry =3D elf_header.pack() + NewUPLEntry[52:] + # write to Elf. + with open(UniversalPayloadEntry,'wb') as f: + f.write(NewUPLEntry) + +def AddSection64(UniversalPayloadEntry, AddSectionName, ElfHeaderOffset, S= ectionHeaderEntrySize, SectionHeaderEntryNumber, StringIndexNumber, FileBin= ary, Alignment): + with open(UniversalPayloadEntry,'rb+') as f: + UPLEntry =3D f.read() + fFileBinary =3D open(FileBinary, 'rb') + Binary_File =3D fFileBinary.read() + ElfHeaderOffset, SectionHeaderEntryNumber, StringIndexNumber, _, _= , SectionHeaderEntrySize, _, _ =3D ElfHeaderParser(UPLEntry) + # Read section header entry + SHentry =3D UPLEntry[ElfHeaderOffset:] + # Elf header is recombined. + # Elf header and program header table in front of first section ar= e reserved. + # Elf header is stored at 0x0-0x40 in 64-bits objects + elf_header =3D ElfHeader64(UPLEntry[:64]) + # Elf header size is 0x40 with 64-bit object. + ElfHeaderSize =3D 64 + ElfHandPH =3D ElfHeaderSize + (elf_header.e_phnum * elf_header.e_p= hentsize) + NewUPLEntry =3D UPLEntry[:ElfHandPH] + # Keep Section header and program header table, AddSection64() onl= y recombined section and section header. + NewUPLEntry =3D bytearray(NewUPLEntry) + # Sections is recombined. + # 1. name of added section is added in name string section. + # 2. added section is added in dll file. + # 3. re-align sections before and after added section. + NewUPLEntrylen =3D [] + StringIndexValue =3D 0 + for Index in range(0, SectionHeaderEntryNumber): + NewUPLEntrylen.append(len(NewUPLEntry)) + unpacked_SectionHeader =3D ElfSectionHeader64.unpack(SHentry[(= Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + Section= HeaderEntrySize)]) + # Sections is recombined. + if (Index =3D=3D 0): + # Address alignment, section will align with alignment of = next section. + AlignmentIndex =3D 8 + if (SectionHeaderEntryNumber > 2): + unpacked_NextSectionHeader =3D ElfSectionHeader64.unpa= ck(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHe= aderEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign) + # Section is last one. + elif (Index =3D=3D (SectionHeaderEntryNumber - 1)): + # Add new section at the end. + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignment) + LastUPLEntrylen =3D len(NewUPLEntry) + NewUPLEntry +=3D Binary_File + # Address alignment, section will align with alignment of = next section. + AlignmentIndex =3D 8 + NewUPLEntry =3D SectionAlignment(NewUPLEntry, AlignmentInd= ex) + # section is name string section. + elif (Index =3D=3D StringIndexNumber): + # StringIndex is String Index section + StringIndex =3D UPLEntry[unpacked_SectionHeader.sh_offset:= (unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Read name of added Section after StringIndex is transfor= m into string. + StringIndex =3D bytearray(StringIndex) + StringIndexValue =3D len(StringIndex) + AddSectionName =3D bytearray(AddSectionName, encoding=3D'u= tf-8') + bytes('\0', encoding=3D'utf-8') + StringIndex +=3D AddSectionName + NewUPLEntry +=3D StringIndex + # section after name string section but not last one. + elif ((Index > StringIndexNumber) and (Index < (SectionHeaderE= ntryNumber - 1))): + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Address alignment, section will align with alignment of = next section. + unpacked_NextSectionHeader =3D ElfSectionHeader64.unpack(S= Hentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeader= EntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign) + # Section before name string section. + else: + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Address alignment, section will align with alignment= of next section. + if (Index < (SectionHeaderEntryNumber - 1)): + unpacked_NextSectionHeader =3D ElfSectionHeader64.unpa= ck(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHe= aderEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _NextSectionHeader.sh_addralign) + SectionHeaderOffset =3D len(NewUPLEntry) + RemoveNameOffset =3D 0 + # Add section header + for Number in range(0, (SectionHeaderEntryNumber)): + NewSHentry =3D AddSectionHeader64(SHentry, NewUPLEntrylen[Numb= er], SectionHeaderEntrySize, Number, RemoveNameOffset, AddSectionName, Stri= ngIndexNumber) + NewUPLEntry +=3D NewSHentry + NewUPLEntry +=3D bytearray(AddNewSectionEntry64(LastUPLEntrylen, S= tringIndexValue, len(Binary_File), Alignment)) + # Modify number of sections and offset of section header in Elf he= ader. + # Modify offset in in Elf header. + elf_header.e_shoff =3D SectionHeaderOffset + elf_header.e_shnum +=3D 1 + elf_header =3D elf_header.pack() + UPLEntryBin =3D elf_header + NewUPLEntry[64:] + # Modify offsets and address of program header table in elf. + PHSegmentName =3D '.text' + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName) + UPLEntryBin =3D ModifyPHSegmentOffset64(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName) + # Modify offsets and address of program header table in elf. + PHSegmentName =3D '.dynamic' + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName) + UPLEntryBin =3D ModifyPHSegmentOffset64(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName) + # Modify offsets and address of program header table in elf. + PHSegmentName =3D '.data' + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName) + UPLEntryBin =3D ModifyPHSegmentOffset64(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName) + fFileBinary.close() + return UPLEntryBin + +def AddSection32(UniversalPayloadEntry, AddSectionName, ElfHeaderOffset, S= ectionHeaderEntrySize, SectionHeaderEntryNumber, StringIndexNumber, FileBin= ary, Alignment): + with open(UniversalPayloadEntry,'rb+') as f: + # Read Elf and binary which will be write to elf. + UPLEntry =3D f.read() + fFileBinary =3D open(FileBinary, 'rb') + Binary_File =3D fFileBinary.read() + ElfHeaderOffset, SectionHeaderEntryNumber, StringIndexNumber, _, _= , SectionHeaderEntrySize, _, _ =3D ElfHeaderParser(UPLEntry) + # Read section header entry + SHentry =3D UPLEntry[ElfHeaderOffset:] + # Elf header is recombined. + # Elf header and program header table in front of first section ar= e reserved. + # Elf header is stored at 0x0-0x34 in 32-bits objects + elf_header =3D ElfHeader32(UPLEntry[:52]) + # Elf header size is 0x34 with 32-bit object. + ElfHeaderSize =3D 52 + ElfHandPH =3D ElfHeaderSize + (elf_header.e_phnum * elf_header.e_p= hentsize) + NewUPLEntry =3D UPLEntry[:ElfHandPH] + # Keep Section header and program header table, AddSection64() onl= y recombined section and section header. + NewUPLEntry =3D bytearray(NewUPLEntry) + # Sections is recombined. + # 1. name of added section is added in name string section. + # 2. added section is added in dll file. + # 3. re-align sections before and after added section. + NewUPLEntrylen =3D [] + StringIndexValue =3D 0 + for Index in range(0, SectionHeaderEntryNumber): + NewUPLEntrylen.append(len(NewUPLEntry)) + unpacked_SectionHeader =3D ElfSectionHeader32.unpack(SHentry[(= Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + Section= HeaderEntrySize)]) + # Sections is recombined. + if (Index =3D=3D 0): + # Address alignment, section will align with alignment of = next section. + AlignmentIndex =3D 8 + if (SectionHeaderEntryNumber > 2): + unpacked_NextSectionHeader =3D ElfSectionHeader32.unpa= ck(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHe= aderEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign) + # Section is last one. + elif (Index =3D=3D (SectionHeaderEntryNumber - 1)): + # Add new section at the end. + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignment) + LastUPLEntrylen =3D len(NewUPLEntry) + NewUPLEntry +=3D Binary_File + # Address alignment, section will align with alignment of = next section. + AlignmentIndex =3D 8 + NewUPLEntry =3D SectionAlignment(NewUPLEntry, AlignmentInd= ex) + # section is name string section. + elif (Index =3D=3D StringIndexNumber): + # StringIndex is String Index section + StringIndex =3D UPLEntry[unpacked_SectionHeader.sh_offset:= (unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Read name of added Section after StringIndex is transfor= m into string. + StringIndex =3D bytearray(StringIndex) + StringIndexValue =3D len(StringIndex) + AddSectionName =3D bytearray(AddSectionName, encoding=3D'u= tf-8') + bytes('\0', encoding=3D'utf-8') + StringIndex +=3D AddSectionName + NewUPLEntry +=3D StringIndex + # section after name string section but not last one. + elif ((Index > StringIndexNumber) and (Index < (SectionHeaderE= ntryNumber - 1))): + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Address alignment, section will align with alignment of = next section. + unpacked_NextSectionHeader =3D ElfSectionHeader32.unpack(S= Hentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeader= EntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign) + # Section before name string section. + else: + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)] + # Address alignment, section will align with alignment= of next section. + if (Index < (SectionHeaderEntryNumber - 1)): + unpacked_NextSectionHeader =3D ElfSectionHeader32.unpa= ck(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHe= aderEntrySize) + SectionHeaderEntrySize)]) + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _NextSectionHeader.sh_addralign) + SectionHeaderOffset =3D len(NewUPLEntry) + RemoveNameOffset =3D 0 + # Add section header + for Number in range(0, (SectionHeaderEntryNumber)): + NewSHentry =3D AddSectionHeader32(SHentry, NewUPLEntrylen[Numb= er], SectionHeaderEntrySize, Number, RemoveNameOffset, AddSectionName, Stri= ngIndexNumber) + NewUPLEntry +=3D NewSHentry + NewUPLEntry +=3D bytearray(AddNewSectionEntry32(LastUPLEntrylen, S= tringIndexValue, len(Binary_File), Alignment)) + # Modify number of sections and offset of section header in Elf he= ader. + # Modify offset in in Elf header. + elf_header.e_shoff =3D SectionHeaderOffset + elf_header.e_shnum +=3D 1 + PHTableSize =3D elf_header.e_phentsize + elf_header =3D elf_header.pack() + UPLEntryBin =3D elf_header + NewUPLEntry[52:] + # Modify offsets and address of program header table in elf. + PHSegmentName =3D '.text' + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName) + UPLEntryBin =3D ModifyPHSegmentOffset32(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName) + # Modify offsets and address of program header table in elf. Its a= re stored at 0x08-0x0F and 0x10-0x17 + PHSegmentName =3D '.data' + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName) + UPLEntryBin =3D ModifyPHSegmentOffset32(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName) + fFileBinary.close() + return UPLEntryBin + +def ReplaceFv (UniversalPayloadEntry, FileBinary, AddSectionName, Alignmen= t =3D 16): + with open(UniversalPayloadEntry,'rb+') as f: + UPLEntry =3D f.read() + SectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, Sectio= nHeaderEntryNumber, _, StringIndexNumber, EI_CLASS =3D FindSection(UPLEntry= , AddSectionName) + # If elf is 64-bit objects. + if (EI_CLASS =3D=3D 2): + # Remove section if it exists. + if (SectionNameOffset !=3D -1): + RemoveSection64(UniversalPayloadEntry, AddSectionName) + # Add section. + NewUPLEntry =3D AddSection64(UniversalPayloadEntry, AddSectionName= , ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, String= IndexNumber, FileBinary, Alignment) + # If elf is 32-bit objects. + else: + # Remove section if it exists. + if (SectionNameOffset !=3D -1): + RemoveSection32(UniversalPayloadEntry, AddSectionName) + # Add section. + NewUPLEntry =3D AddSection32(UniversalPayloadEntry, AddSectionName= , ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, String= IndexNumber, FileBinary, Alignment) + with open(UniversalPayloadEntry,'wb') as f: + f.write(NewUPLEntry) + return 0 diff --git a/UefiPayloadPkg/Tools/__init__.py b/UefiPayloadPkg/Tools/__init= __.py new file mode 100644 index 0000000000..de57d1b907 --- /dev/null +++ b/UefiPayloadPkg/Tools/__init__.py @@ -0,0 +1,19 @@ +## @file +# Python 'Tools' package initialization file. +# +# @copyright +# INTEL CONFIDENTIAL +# +# Copyright (C) 2023 Intel Corporation +# +# This software and the related documents are Intel copyrighted materials= , and your +# use of them is governed by the express license under which they were pr= ovided to +# you ("License"). Unless the License provides otherwise, you may not use= , modify, +# copy, publish, distribute, disclose or transmit this software or the re= lated +# documents without Intel's prior written permission. +# +# This software and the related documents are provided as is, with no exp= ress or +# implied warranties, other than those that are expressly stated in the L= icense. +# +# @par Specification +## diff --git a/UefiPayloadPkg/UniversalPayloadBuild.py b/UefiPayloadPkg/Unive= rsalPayloadBuild.py index 83e0de95d8..416946a431 100644 --- a/UefiPayloadPkg/UniversalPayloadBuild.py +++ b/UefiPayloadPkg/UniversalPayloadBuild.py @@ -11,7 +11,7 @@ import os import shutil import sys from ctypes import * - +from Tools.ElfFv import ReplaceFv sys.dont_write_bytecode =3D True =20 class UPLD_INFO_HEADER(LittleEndianStructure): @@ -36,106 +36,56 @@ class UPLD_INFO_HEADER(LittleEndianStructure): self.ImageId =3D b'UEFI' self.ProducerId =3D b'INTEL' =20 -def GenSpecRevision (Argument): - try: - (MajorStr, MinorStr) =3D Argument.split('.') - except: - raise argparse.ArgumentTypeError ('{} is not a valid SpecRevision = format (Major[8-bits].Minor[8-bits]).'.format (Argument)) - # - # Spec Revision Bits 15 : 8 - Major Version. Bits 7 : 0 - Minor Versio= n. - # - if len(MinorStr) > 0 and len(MinorStr) < 3: - try: - Minor =3D int(MinorStr, 16) if len(MinorStr) =3D=3D 2 else (in= t(MinorStr, 16) << 4) - except: - raise argparse.ArgumentTypeError ('{} Minor version of SpecRev= ision is not a valid integer value.'.format (Argument)) - else: - raise argparse.ArgumentTypeError ('{} is not a valid SpecRevision = format (Major[8-bits].Minor[8-bits]).'.format (Argument)) +def BuildUniversalPayload(Args): + def RunCommand(cmd): + print(cmd) + p =3D subprocess.Popen(cmd, shell=3DTrue, stdout=3Dsubprocess.PIPE= , stderr=3Dsubprocess.STDOUT,cwd=3Dos.environ['WORKSPACE']) + while True: + line =3D p.stdout.readline() + if not line: + break + print(line.strip().decode(errors=3D'ignore')) + + p.communicate() + if p.returncode !=3D 0: + print("- Failed - error happened when run command: %s"%cmd) + raise Exception("ERROR: when run command: %s"%cmd) =20 - if len(MajorStr) > 0 and len(MajorStr) < 3: - try: - Major =3D int(MajorStr, 16) - except: - raise argparse.ArgumentTypeError ('{} Major version of SpecRev= ision is not a valid integer value.'.format (Argument)) - else: - raise argparse.ArgumentTypeError ('{} is not a valid SpecRevision = format (Major[8-bits].Minor[8-bits]).'.format (Argument)) - - return int('0x{0:02x}{1:02x}'.format(Major, Minor), 0) - -def Validate32BitInteger (Argument): - try: - Value =3D int (Argument, 0) - except: - raise argparse.ArgumentTypeError ('{} is not a valid integer value= .'.format (Argument)) - if Value < 0: - raise argparse.ArgumentTypeError ('{} is a negative value.'.format= (Argument)) - if Value > 0xffffffff: - raise argparse.ArgumentTypeError ('{} is larger than 32-bits.'.for= mat (Argument)) - return Value - -def RunCommand(cmd): - print(cmd) - p =3D subprocess.Popen(cmd, shell=3DTrue, stdout=3Dsubprocess.PIPE, st= derr=3Dsubprocess.STDOUT,cwd=3Dos.environ['WORKSPACE']) - while True: - line =3D p.stdout.readline() - if not line: - break - print(line.strip().decode(errors=3D'ignore')) - - p.communicate() - if p.returncode !=3D 0: - print("- Failed - error happened when run command: %s"%cmd) - raise Exception("ERROR: when run command: %s"%cmd) - -def BuildUniversalPayload(Args, MacroList): BuildTarget =3D Args.Target ToolChain =3D Args.ToolChain Quiet =3D "--quiet" if Args.Quiet else "" ElfToolChain =3D 'CLANGDWARF' BuildDir =3D os.path.join(os.environ['WORKSPACE'], os.path.normpat= h("Build/UefiPayloadPkgX64")) + BuildModule =3D "" + BuildArch =3D "" if Args.Arch =3D=3D 'X64': BuildArch =3D "X64" - ObjCopyFlag =3D "elf64-x86-64" EntryOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ElfToolChain), os.path.normpath("X64/UefiPayloadPkg/UefiPayloadEntry/U= niversalPayloadEntry/DEBUG/UniversalPayloadEntry.dll")) else: BuildArch =3D "IA32 -a X64" - ObjCopyFlag =3D "elf32-i386" EntryOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ElfToolChain), os.path.normpath("IA32/UefiPayloadPkg/UefiPayloadEntry/= UniversalPayloadEntry/DEBUG/UniversalPayloadEntry.dll")) =20 if Args.PreBuildUplBinary is not None: EntryOutputDir =3D os.path.abspath(Args.PreBuildUplBinary) - EntryModuleInf =3D os.path.normpath("UefiPayloadPkg/UefiPayloadEntry/U= niversalPayloadEntry.inf") DscPath =3D os.path.normpath("UefiPayloadPkg/UefiPayloadPkg.dsc") - DxeFvOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTarget,= ToolChain), os.path.normpath("FV/DXEFV.Fv")) - BdsFvOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTarget,= ToolChain), os.path.normpath("FV/BDSFV.Fv")) - NetworkFvOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/NETWORKFV.Fv")) - PayloadReportPath =3D os.path.join(BuildDir, "UefiUniversalPayload.txt= ") ModuleReportPath =3D os.path.join(BuildDir, "UefiUniversalPayloadEntry= .txt") UpldInfoFile =3D os.path.join(BuildDir, "UniversalPayloadInfo.bin") =20 - if "CLANG_BIN" in os.environ: - LlvmObjcopyPath =3D os.path.join(os.environ["CLANG_BIN"], "llvm-ob= jcopy") - else: - LlvmObjcopyPath =3D "llvm-objcopy" - try: - RunCommand('"%s" --version'%LlvmObjcopyPath) - except: - print("- Failed - Please check if LLVM is installed or if CLANG_BI= N is set correctly") - sys.exit(1) - Pcds =3D "" if (Args.pcd !=3D None): for PcdItem in Args.pcd: Pcds +=3D " --pcd {}".format (PcdItem) =20 Defines =3D "" - for key in MacroList: - Defines +=3D" -D {0}=3D{1}".format(key, MacroList[key]) + if (Args.Macro !=3D None): + for MacroItem in Args.Macro: + Defines +=3D " -D {}".format (MacroItem) =20 # # Building DXE core and DXE drivers as DXEFV. # if Args.BuildEntryOnly =3D=3D False: + PayloadReportPath =3D os.path.join(BuildDir, "UefiUniversalPayload= .txt") BuildPayload =3D "build -p {} -b {} -a X64 -t {} -y {} {}".format = (DscPath, BuildTarget, ToolChain, PayloadReportPath, Quiet) BuildPayload +=3D Pcds BuildPayload +=3D Defines @@ -144,6 +94,7 @@ def BuildUniversalPayload(Args, MacroList): # Building Universal Payload entry. # if Args.PreBuildUplBinary is None: + EntryModuleInf =3D os.path.normpath("UefiPayloadPkg/UefiPayloadEnt= ry/UniversalPayloadEntry.inf") BuildModule =3D "build -p {} -b {} -a {} -m {} -t {} -y {} {}".for= mat (DscPath, BuildTarget, BuildArch, EntryModuleInf, ElfToolChain, ModuleR= eportPath, Quiet) BuildModule +=3D Pcds BuildModule +=3D Defines @@ -151,59 +102,80 @@ def BuildUniversalPayload(Args, MacroList): # # Buid Universal Payload Information Section ".upld_info" # - upld_info_hdr =3D UPLD_INFO_HEADER() + upld_info_hdr =3D UPLD_INFO_HEADER() upld_info_hdr.SpecRevision =3D Args.SpecRevision - upld_info_hdr.Revision =3D Args.Revision - upld_info_hdr.ProducerId =3D Args.ProducerId.encode()[:16] - upld_info_hdr.ImageId =3D Args.ImageId.encode()[:16] - upld_info_hdr.Attribute |=3D 1 if BuildTarget =3D=3D "DEBUG" else 0 + upld_info_hdr.Revision =3D Args.Revision + upld_info_hdr.ProducerId =3D Args.ProducerId.encode()[:16] + upld_info_hdr.ImageId =3D Args.ImageId.encode()[:16] + upld_info_hdr.Attribute |=3D 1 if BuildTarget =3D=3D "DEBUG" else 0 fp =3D open(UpldInfoFile, 'wb') fp.write(bytearray(upld_info_hdr)) fp.close() =20 + MultiFvList =3D [] if Args.BuildEntryOnly =3D=3D False: - # - # Copy the DXEFV as a section in elf format Universal Payload entr= y. - # - remove_section =3D '"{}" -I {} -O {} --remove-section .upld_info -= -remove-section .upld.uefi_fv --remove-section .upld.bds_fv {}'.format ( - LlvmObjcopyPath, - ObjCopyFlag, - ObjCopyFlag, - EntryOutputDir - ) - add_section =3D '"{}" -I {} -O {} --add-section .upld_info=3D{}= --add-section .upld.uefi_fv=3D{} --add-section .upld.bds_fv=3D{} {}'.forma= t ( - LlvmObjcopyPath, - ObjCopyFlag, - ObjCopyFlag, - UpldInfoFile, - DxeFvOutputDir, - BdsFvOutputDir, - EntryOutputDir - ) - set_section =3D '"{}" -I {} -O {} --set-section-alignment .upld= _info=3D4 --set-section-alignment .upld.uefi_fv=3D16 --set-section-alignmen= t .upld.bds_fv=3D16 {}'.format ( - LlvmObjcopyPath, - ObjCopyFlag, - ObjCopyFlag, - EntryOutputDir - ) - # - # Append network fv to sections if exists - # - if os.path.isfile(NetworkFvOutputDir): - index =3D remove_section.find(EntryOutputDir) - remove_section =3D remove_section[:index] + '--remove-section = .upld.network_fv ' + remove_section[index:] - index =3D add_section.find(EntryOutputDir) - add_section =3D add_section[:index] + '--add-section .upld.net= work_fv=3D' + NetworkFvOutputDir + ' ' + add_section[index:] - index =3D set_section.find(EntryOutputDir) - set_section =3D set_section[:index] + '--set-section-alignment= .upld.network_fv=3D16 ' + set_section[index:] - - RunCommand(remove_section) - RunCommand(add_section) - RunCommand(set_section) + MultiFvList =3D [ + ['uefi_fv', os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/DXEFV.Fv")) ], + ['bds_fv', os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/BDSFV.Fv")) ], + ['network_fv', os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/NETWORKFV.Fv")) ], + ] + AddSectionName =3D '.upld_info' + ReplaceFv (EntryOutputDir, UpldInfoFile, AddSectionName, Alignment= =3D 4) =20 shutil.copy (EntryOutputDir, os.path.join(BuildDir, 'UniversalPayload.= elf')) =20 + return MultiFvList, os.path.join(BuildDir, 'UniversalPayload.elf') + def main(): + def ValidateSpecRevision (Argument): + try: + (MajorStr, MinorStr) =3D Argument.split('.') + except: + raise argparse.ArgumentTypeError ('{} is not a valid SpecRevis= ion format (Major[8-bits].Minor[8-bits]).'.format (Argument)) + # + # Spec Revision Bits 15 : 8 - Major Version. Bits 7 : 0 - Minor Ve= rsion. + # + if len(MinorStr) > 0 and len(MinorStr) < 3: + try: + Minor =3D int(MinorStr, 16) if len(MinorStr) =3D=3D 2 else= (int(MinorStr, 16) << 4) + except: + raise argparse.ArgumentTypeError ('{} Minor version of Spe= cRevision is not a valid integer value.'.format (Argument)) + else: + raise argparse.ArgumentTypeError ('{} is not a valid SpecRevis= ion format (Major[8-bits].Minor[8-bits]).'.format (Argument)) + + if len(MajorStr) > 0 and len(MajorStr) < 3: + try: + Major =3D int(MajorStr, 16) + except: + raise argparse.ArgumentTypeError ('{} Major version of Spe= cRevision is not a valid integer value.'.format (Argument)) + else: + raise argparse.ArgumentTypeError ('{} is not a valid SpecRevis= ion format (Major[8-bits].Minor[8-bits]).'.format (Argument)) + + return int('0x{0:02x}{1:02x}'.format(Major, Minor), 0) + + def Validate32BitInteger (Argument): + try: + Value =3D int (Argument, 0) + except: + raise argparse.ArgumentTypeError ('{} is not a valid integer v= alue.'.format (Argument)) + if Value < 0: + raise argparse.ArgumentTypeError ('{} is a negative value.'.fo= rmat (Argument)) + if Value > 0xffffffff: + raise argparse.ArgumentTypeError ('{} is larger than 32-bits.'= .format (Argument)) + return Value + + def ValidateAddFv (Argument): + Value =3D Argument.split ("=3D") + if len (Value) !=3D 2: + raise argparse.ArgumentTypeError ('{} is incorrect format with= "xxx_fv=3Dxxx.fv"'.format (Argument)) + if Value[0][-3:] !=3D "_fv": + raise argparse.ArgumentTypeError ('{} is incorrect format with= "xxx_fv=3Dxxx.fv"'.format (Argument)) + if Value[1][-3:].lower () !=3D ".fv": + raise argparse.ArgumentTypeError ('{} is incorrect format with= "xxx_fv=3Dxxx.fv"'.format (Argument)) + if os.path.exists (Value[1]) =3D=3D False: + raise argparse.ArgumentTypeError ('File {} is not found.'.form= at (Value[1])) + return Value + parser =3D argparse.ArgumentParser(description=3D'For building Univers= al Payload') parser.add_argument('-t', '--ToolChain') parser.add_argument('-b', '--Target', default=3D'DEBUG') @@ -212,22 +184,32 @@ def main(): parser.add_argument('-i', '--ImageId', type=3Dstr, help=3D'Specify pay= load ID (16 bytes maximal).', default =3D'UEFI') parser.add_argument('-q', '--Quiet', action=3D'store_true', help=3D'Di= sable all build messages except FATAL ERRORS.') parser.add_argument("-p", "--pcd", action=3D"append") - parser.add_argument("-s", "--SpecRevision", type=3DGenSpecRevision, de= fault =3D'0.7', help=3D'Indicates compliance with a revision of this specif= ication in the BCD format.') + parser.add_argument("-s", "--SpecRevision", type=3DValidateSpecRevisio= n, default =3D'0.7', help=3D'Indicates compliance with a revision of this s= pecification in the BCD format.') parser.add_argument("-r", "--Revision", type=3DValidate32BitInteger, d= efault =3D'0x0000010105', help=3D'Revision of the Payload binary. Major.Min= or.Revision.Build') parser.add_argument("-o", "--ProducerId", default =3D'INTEL', help=3D'= A null-terminated OEM-supplied string that identifies the payload producer = (16 bytes maximal).') parser.add_argument("-e", "--BuildEntryOnly", action=3D'store_true', h= elp=3D'Build UniversalPayload Entry file') parser.add_argument("-pb", "--PreBuildUplBinary", default=3DNone, help= =3D'Specify the UniversalPayload file') - MacroList =3D {} + parser.add_argument("-sk", "--SkipBuild", action=3D'store_true', help= =3D'Skip UniversalPayload build') + parser.add_argument("-af", "--AddFv", type=3DValidateAddFv, action=3D'= append', help=3D'Add or replace specific FV into payload, Ex: uefi_fv=3DXXX= .fv') args =3D parser.parse_args() - if args.Macro is not None: - for Argument in args.Macro: - if Argument.count('=3D') !=3D 1: - print("Unknown variable passed in: %s"%Argument) - raise Exception("ERROR: Unknown variable passed in: %s"%Ar= gument) - tokens =3D Argument.strip().split('=3D') - MacroList[tokens[0].upper()] =3D tokens[1] - BuildUniversalPayload(args, MacroList) - print ("Successfully build Universal Payload") + + MultiFvList =3D [] + UniversalPayloadBinary =3D args.PreBuildUplBinary + if (args.SkipBuild =3D=3D False): + MultiFvList, UniversalPayloadBinary =3D BuildUniversalPayload(args) + + if (args.AddFv !=3D None): + for (SectionName, SectionFvFile) in args.AddFv: + MultiFvList.append ([SectionName, SectionFvFile]) + + if (UniversalPayloadBinary !=3D None): + for (SectionName, SectionFvFile) in MultiFvList: + if os.path.exists (SectionFvFile) =3D=3D False: + continue + print ("Patch {}=3D{} into {}".format (SectionName, SectionFvF= ile, UniversalPayloadBinary)) + ReplaceFv (UniversalPayloadBinary, SectionFvFile, '.upld.{}'.f= ormat (SectionName)) + + print ("\nSuccessfully build Universal Payload") =20 if __name__ =3D=3D '__main__': main() --=20 2.39.1.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#103668): https://edk2.groups.io/g/devel/message/103668 Mute This Topic: https://groups.io/mt/98510058/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-