From mboxrd@z Thu Jan 1 00:00:00 1970 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 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=cV+d20Js; spf=pass (domain: intel.com, ip: 192.55.52.88, mailfrom: brucex.wang@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1682493122; x=1714029122; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=eeXMsc8xkQ87a/sHaVFeJDJ79La2vsM6XWYh9gUWhgk=; b=cV+d20JspLCwKBPzpKcp3/+e+ogGEj3189TInNe/uhRNT0ljM3K8Lwx6 6CY8yMJhZhOT8F5Tg00+XJY9Xey7QPeeihz4k0gWsDf75ZEH1XuOmxpBN L61TQ9+xHRRZcZz42V6Txm1Ox/MX+diWr4SN16ORnS9Xar3mUopQiG07V 5A4IhF9SYgoCpyr2ZybZahwWSlgFal+JFIkCUBCZ8pB3rQ+JGSqhNgIDJ yDQHFyCHL1NB4aJEVyXRJS8AFoSKJ/X6eLPjLJyl+GDMfE6Z2EBGD5ydO 29djhmgsFjh7b2GhUTjGfPsiVcAhFDsZaR8Oc77cI50vA0a/5jhcl7d14 Q==; 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" 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" 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: [PATCH] * UefiPayloadPkg: Clang dependency removal Date: Wed, 26 Apr 2023 15:11:39 +0800 Message-Id: <0b1c996e78cddfa3a272187bd783f0c8b8e33492.1682492500.git.brucex.wang@intel.com> X-Mailer: git-send-email 2.39.1.windows.1 MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable 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 --- 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=0D +# OBJCOPY parser, it's used to replace FV=0D +#=0D +# Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +##=0D +=0D +import argparse=0D +from ctypes import *=0D +import struct=0D +=0D +class ElfSectionHeader64:=0D + def __init__(self, sh_name, sh_type, sh_flags, sh_addr, sh_offset, sh_= size, sh_link, sh_info, sh_addralign, sh_entsize):=0D + self.sh_name =3D sh_name=0D + self.sh_type =3D sh_type=0D + self.sh_flags =3D sh_flags=0D + self.sh_addr =3D sh_addr=0D + self.sh_offset =3D sh_offset=0D + self.sh_size =3D sh_size=0D + self.sh_link =3D sh_link=0D + self.sh_info =3D sh_info=0D + self.sh_addralign =3D sh_addralign=0D + self.sh_entsize =3D sh_entsize=0D +=0D + def pack(self):=0D + return struct.pack(' RemoveNameOffset):=0D + unpacked_header.sh_name -=3D RemoveNameOffset=0D + # Modify size of name string section entry in section entry.=0D + if (Index =3D=3D StringIndexNumber):=0D + unpacked_header.sh_size -=3D len (SectionName)=0D + # added section=0D + else :=0D + if (Index =3D=3D StringIndexNumber):=0D + unpacked_header.sh_size +=3D len (SectionName)=0D + NewSHentry =3D ElfSectionHeader64 (=0D + unpacked_header.sh_name,=0D + unpacked_header.sh_type,=0D + unpacked_header.sh_flags,=0D + unpacked_header.sh_addr,=0D + unpacked_header.sh_offset,=0D + unpacked_header.sh_size,=0D + unpacked_header.sh_link,=0D + unpacked_header.sh_info,=0D + unpacked_header.sh_addralign,=0D + unpacked_header.sh_entsize).pack()=0D + return NewSHentry=0D +=0D +def AddSectionHeader32(SHentry, NewUPLEntrylen, SectionHeaderEntrySize, In= dex, RemoveNameOffset, SectionName, StringIndexNumber):=0D + SHentry =3D bytearray(SHentry)=0D + unpacked_header =3D ElfSectionHeader32.unpack(SHentry[(Index * Section= HeaderEntrySize):((Index * SectionHeaderEntrySize) + SectionHeaderEntrySize= )])=0D + if (Index !=3D 0):=0D + NewSHentry =3D SHentry[(Index * SectionHeaderEntrySize):((Index * = SectionHeaderEntrySize) + SectionHeaderEntrySize)]=0D + unpacked_header.sh_offset =3D NewUPLEntrylen=0D + # Modify offset of name in section entry=0D + # if RemoveNameOffset !=3D 0 that is remove function.=0D + if (RemoveNameOffset !=3D 0):=0D + if (unpacked_header.sh_name > RemoveNameOffset):=0D + unpacked_header.sh_name -=3D RemoveNameOffset=0D + # Modify size of name string section entry in section entry.=0D + if (Index =3D=3D StringIndexNumber):=0D + unpacked_header.sh_size -=3D len (SectionName)=0D + # added section=0D + else :=0D + if (Index =3D=3D StringIndexNumber):=0D + unpacked_header.sh_size +=3D len (SectionName)=0D + NewSHentry =3D ElfSectionHeader32 (=0D + unpacked_header.sh_name,=0D + unpacked_header.sh_type,=0D + unpacked_header.sh_flags,=0D + unpacked_header.sh_addr,=0D + unpacked_header.sh_offset,=0D + unpacked_header.sh_size,=0D + unpacked_header.sh_link,=0D + unpacked_header.sh_info,=0D + unpacked_header.sh_addralign,=0D + unpacked_header.sh_entsize).pack()=0D + return NewSHentry=0D +=0D +def ModifyPHSegmentOffset64(NewUPLEntry, ElfHeaderOffset, PHSegmentName):= =0D + # Modify offset and address of program header tables.=0D + elf_header =3D ElfHeader64(NewUPLEntry[:64])=0D + SHentry =3D NewUPLEntry[ElfHeaderOffset:]=0D + # Elf program header tables start from 0x40 in 64-bits objects=0D + PHentry =3D NewUPLEntry[64: 64 + (elf_header.e_phnum * elf_header.e_ph= entsize)]=0D + PHdrs =3D []=0D + SHdrs =3D []=0D + for i in range(elf_header.e_shnum):=0D + SHData =3D SHentry[(i * elf_header.e_shentsize): (i * elf_header.e= _shentsize) + elf_header.e_shentsize]=0D + unpacked_SectionHeader =3D ElfSectionHeader64.unpack(SHData)=0D + SHdrs.append(unpacked_SectionHeader)=0D + for i in range(elf_header.e_phnum):=0D + PHData =3D PHentry[(i * elf_header.e_phentsize): (i * elf_header.e= _phentsize) + elf_header.e_phentsize]=0D + unpacked_ProgramHeader =3D Elf64_Phdr(PHData)=0D + PHdrs.append(unpacked_ProgramHeader)=0D + if (PHSegmentName =3D=3D '.text'):=0D + PHdrs[0].p_offset =3D SHdrs[1].sh_offset=0D + PHdrs[0].p_paddr =3D SHdrs[1].sh_addr=0D + PHdrs[4].p_offset =3D SHdrs[1].sh_offset=0D + PHdrs[4].p_paddr =3D SHdrs[1].sh_addr=0D + elif (PHSegmentName =3D=3D '.dynamic'):=0D + PHdrs[1].p_offset =3D SHdrs[2].sh_offset=0D + PHdrs[1].p_paddr =3D SHdrs[2].sh_addr=0D + PHdrs[3].p_offset =3D SHdrs[2].sh_offset=0D + PHdrs[3].p_paddr =3D SHdrs[2].sh_addr=0D + elif (PHSegmentName =3D=3D '.data'):=0D + PHdrs[2].p_offset =3D SHdrs[3].sh_offset=0D + PHdrs[2].p_paddr =3D SHdrs[3].sh_addr=0D + packed_PHData =3D b''=0D + for phdr in PHdrs:=0D + packed_PHData +=3D phdr.pack()=0D + NewUPLEntry =3D bytearray(NewUPLEntry)=0D + NewUPLEntry[64: 64 + (elf_header.e_phnum * elf_header.e_phentsize)] = =3D packed_PHData=0D + return NewUPLEntry=0D +=0D +def ModifyPHSegmentOffset32(NewUPLEntry, ElfHeaderOffset, PHSegmentName):= =0D + # Modify offset and address of program header tables.=0D + # Elf header is stored at 0x0-0x34 in 32-bits objects=0D + elf_header =3D ElfHeader32(NewUPLEntry[:52])=0D + SHentry =3D NewUPLEntry[ElfHeaderOffset:]=0D + # Elf program header tables start from 0x34 in 32-bits objects=0D + PHentry =3D NewUPLEntry[52: 52 + (elf_header.e_phnum * elf_header.e_ph= entsize)]=0D + PHdrs =3D []=0D + SHdrs =3D []=0D + for i in range(elf_header.e_shnum):=0D + SHData =3D SHentry[(i * elf_header.e_shentsize): (i * elf_header.e= _shentsize) + elf_header.e_shentsize]=0D + unpacked_SectionHeader =3D ElfSectionHeader32.unpack(SHData)=0D + SHdrs.append(unpacked_SectionHeader)=0D + for i in range(elf_header.e_phnum):=0D + PHData =3D PHentry[(i * elf_header.e_phentsize): (i * elf_header.e= _phentsize) + elf_header.e_phentsize]=0D + unpacked_ProgramHeader =3D Elf32_Phdr(PHData)=0D + PHdrs.append(unpacked_ProgramHeader)=0D + if (PHSegmentName =3D=3D '.text'):=0D + PHdrs[0].p_offset =3D SHdrs[1].sh_offset=0D + PHdrs[0].p_paddr =3D SHdrs[1].sh_addr=0D + PHdrs[0].p_vaddr =3D SHdrs[1].sh_addr=0D + PHdrs[2].p_offset =3D SHdrs[1].sh_offset=0D + PHdrs[2].p_paddr =3D SHdrs[1].sh_addr=0D + PHdrs[0].p_vaddr =3D SHdrs[1].sh_addr=0D + elif (PHSegmentName =3D=3D '.data'):=0D + PHdrs[1].p_offset =3D SHdrs[2].sh_offset=0D + PHdrs[1].p_paddr =3D SHdrs[2].sh_addr=0D + PHdrs[1].p_vaddr =3D SHdrs[2].sh_addr=0D + packed_PHData =3D b''=0D + for phdr in PHdrs:=0D + packed_PHData +=3D phdr.pack()=0D + NewUPLEntry =3D bytearray(NewUPLEntry)=0D + NewUPLEntry[52: 52 + (elf_header.e_phnum * elf_header.e_phentsize)] = =3D packed_PHData=0D + return NewUPLEntry=0D +=0D +def RemoveSection64(UniversalPayloadEntry, RemoveSectionName):=0D + # If elf is 64-bit objects.=0D + # Get offsets as follows:=0D + # 1. Section name which will remove in section na= me string.=0D + # 2. Section which will remove.=0D + # 3. Section header which will remove.=0D + with open(UniversalPayloadEntry,'rb') as f:=0D + UPLEntry =3D f.read()=0D + RemoveSectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, = SectionHeaderEntryNumber, _, StringIndexNumber, _ =3D FindSection(UPLEntry,= RemoveSectionName)=0D + if (RemoveSectionNameOffset =3D=3D -1):=0D + raise argparse.ArgumentTypeError ('Section: {} not found.'.for= mat (RemoveSectionNameOffset))=0D + # Read section header entry=0D + SHentry =3D UPLEntry[ElfHeaderOffset:]=0D + # find deleted fv section offset.=0D + # Elf header is stored at 0x0-0x40 in 64-bits objects=0D + elf_header =3D ElfHeader64(UPLEntry[:64])=0D + Counter =3D 0=0D + RemoveIndex =3D 0=0D + RemoveNameOffset =3D 0=0D + for Index in range(0, elf_header.e_shnum):=0D + # Read Index of section header.=0D + unpacked_SectionHeader =3D ElfSectionHeader64.unpack(SHentry[(= Index * elf_header.e_shentsize):((Index * elf_header.e_shentsize) + elf_hea= der.e_shentsize)])=0D + # Find offset of section name which is removed.=0D + if (unpacked_SectionHeader.sh_name =3D=3D RemoveSectionNameOff= set):=0D + RemoveIndex =3D Counter=0D + Counter +=3D 1=0D + else:=0D + Counter +=3D 1=0D + # Elf header is recombined.=0D + # Elf header and program header table in front of first section ar= e reserved.=0D + # Elf header size is 0x40 with 64-bit object.=0D + ElfHeaderSize =3D 64=0D + ElfHandPH =3D ElfHeaderSize + (elf_header.e_phnum * elf_header.e_p= hentsize)=0D + NewUPLEntry =3D UPLEntry[:ElfHandPH]=0D + # Keep Section header and program header table, RemoveSection64() = only recombined section and section header.=0D + NewUPLEntry =3D bytearray(NewUPLEntry)=0D + # Sections is recombined.=0D + # 1. name of deleted section is removed in name string section.=0D + # 2. deleted section is removed in dll file.=0D + # 3. re-align sections before and after deleted section.=0D + NewUPLEntrylen =3D []=0D + for Index in range(0, (SectionHeaderEntryNumber)):=0D + unpacked_SectionHeader =3D ElfSectionHeader64.unpack(SHentry[(= Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + Section= HeaderEntrySize)])=0D + NewUPLEntrylen.append(len(NewUPLEntry))=0D + if (Index =3D=3D 0):=0D + # Address alignment, section will align with alignment of = next section.=0D + AlignmentIndex =3D 8=0D + if (SectionHeaderEntryNumber > 2):=0D + unpacked_NextSectionHeader =3D ElfSectionHeader64.unpac= k(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHea= derEntrySize) + SectionHeaderEntrySize)])=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign)=0D + # Section in front of removed section=0D + elif (Index + 1 =3D=3D RemoveIndex):=0D + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + # Read section address alignment=0D + # If section that will be removed in .dll is not first and= last one .=0D + # Address alignment, section will align with alignment of = section after deleted section.=0D + # Check next and the section after next are not end of sec= tion.=0D + if ((Index + 2) < (SectionHeaderEntryNumber - 1)):=0D + unpacked_Next2SectionHeader =3D ElfSectionHeader64.unp= ack(SHentry[((Index + 2) * SectionHeaderEntrySize):(((Index + 2) * SectionH= eaderEntrySize) + SectionHeaderEntrySize)])=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _Next2SectionHeader.sh_addralign)=0D + else:=0D + # It is align 8 bytes if next section or the section a= fter next is last one.=0D + AlignmentIndex =3D 8=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignmen= tIndex)=0D + # section is Deleted section=0D + elif (Index =3D=3D RemoveIndex):=0D + # Don't add removed section to elf.=0D + # Find offset of section name.=0D + RemoveNameOffset =3D unpacked_SectionHeader.sh_name=0D + # section is name string section.=0D + elif (Index =3D=3D StringIndexNumber):=0D + # StringIndex is String Index section=0D + StringIndex =3D UPLEntry[unpacked_SectionHeader.sh_offset:= (unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + # Remove name of removed section in name string section.=0D + # Section header isn't exist if RemoveSectionNameOffset eq= ual to -1.=0D + StringIndex =3D bytearray(StringIndex)=0D + RemoveSectionName =3D bytearray(RemoveSectionName, encodin= g=3D'utf-8')=0D + RemoveSectionName =3D RemoveSectionName + bytes('\0', enco= ding=3D'utf-8')=0D + StringIndex =3D StringIndex.replace(RemoveSectionName,b'')= =0D + NewUPLEntry +=3D StringIndex=0D + # other sections.=0D + else:=0D + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + # Address alignment, section will align with alignment of = next section.=0D + if (Index < (SectionHeaderEntryNumber - 1)):=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _NextSectionHeader.sh_addralign)=0D + else:=0D + # If section is last one.=0D + AlignmentIndex =3D 8=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignmen= tIndex)=0D + SectionHeaderOffset =3D len(NewUPLEntry)=0D + # Add section header=0D + for Number in range(0, (SectionHeaderEntryNumber)):=0D + if (Number !=3D RemoveIndex):=0D + NewSHentry =3D AddSectionHeader64(SHentry, NewUPLEntrylen[= Number], SectionHeaderEntrySize, Number, RemoveNameOffset, RemoveSectionNam= e, StringIndexNumber)=0D + NewUPLEntry +=3D NewSHentry=0D + # Modify number of sections and offset of section header in Elf he= ader.=0D + elf_header.e_shoff =3D SectionHeaderOffset=0D + elf_header.e_shnum -=3D 1=0D + NewUPLEntry =3D elf_header.pack() + NewUPLEntry[64:]=0D + # write to Elf.=0D + with open(UniversalPayloadEntry,'wb') as f:=0D + f.write(NewUPLEntry)=0D +=0D +def RemoveSection32(UniversalPayloadEntry, RemoveSectionName):=0D + # If elf is 32-bit objects.=0D + # Get offsets as follows:=0D + # 1. Section name which will remove in section na= me string.=0D + # 2. Section which will remove.=0D + # 3. Section header which will remove.=0D + with open(UniversalPayloadEntry,'rb') as f:=0D + UPLEntry =3D f.read()=0D + RemoveSectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, = SectionHeaderEntryNumber, _, StringIndexNumber, EI_CLASS =3D FindSection(UP= LEntry, RemoveSectionName)=0D + if (RemoveSectionNameOffset =3D=3D -1):=0D + raise argparse.ArgumentTypeError ('Section: {} not found.'.for= mat (RemoveSectionNameOffset))=0D + # Read section header entry=0D + SHentry =3D UPLEntry[ElfHeaderOffset:]=0D + # find deleted fv section offset.=0D + # Elf header is stored at 0x0-0x34 in 32-bits objects=0D + elf_header =3D ElfHeader32(UPLEntry[:52])=0D + Counter =3D 0=0D + RemoveIndex =3D 0=0D + RemoveNameOffset =3D 0=0D + for Index in range(0, elf_header.e_shnum):=0D + # Read Index of section header.=0D + unpacked_SectionHeader =3D ElfSectionHeader32.unpack(SHentry[(= Index * elf_header.e_shentsize):((Index * elf_header.e_shentsize) + elf_hea= der.e_shentsize)])=0D + # Find offset of section name which is removed.=0D + if (unpacked_SectionHeader.sh_name =3D=3D RemoveSectionNameOff= set):=0D + RemoveIndex =3D Counter=0D + Counter +=3D 1=0D + else:=0D + Counter +=3D 1=0D + # Elf header is recombined.=0D + # Elf header and program header table in front of first section ar= e reserved.=0D + # Elf header size is 0x34 with 32-bit object.=0D + ElfHeaderSize =3D 52=0D + ElfHandPH =3D ElfHeaderSize + (elf_header.e_phnum * elf_header.e_p= hentsize)=0D + NewUPLEntry =3D UPLEntry[:ElfHandPH]=0D + # Keep Section header and program header table, RemoveSection32() = only recombined section and section header.=0D + NewUPLEntry =3D bytearray(NewUPLEntry)=0D + # Sections is recombined.=0D + # 1. name of deleted section is removed in name string section.=0D + # 2. deleted section is removed in dll file.=0D + # 3. re-align sections before and after deleted section.=0D + NewUPLEntrylen =3D []=0D + for Index in range(0, (SectionHeaderEntryNumber)):=0D + unpacked_SectionHeader =3D ElfSectionHeader32.unpack(SHentry[(= Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + Section= HeaderEntrySize)])=0D + NewUPLEntrylen.append(len(NewUPLEntry))=0D + if (Index =3D=3D 0):=0D + # Address alignment, section will align with alignment of = next section.=0D + AlignmentIndex =3D 8=0D + if (SectionHeaderEntryNumber > 2):=0D + unpacked_NextSectionHeader =3D ElfSectionHeader32.unpac= k(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHea= derEntrySize) + SectionHeaderEntrySize)])=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign)=0D + # Section in front of removed section=0D + elif (Index + 1 =3D=3D RemoveIndex):=0D + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + # Read section address alignment=0D + # If section that will be removed in .dll is not first and= last one .=0D + # Address alignment, section will align with alignment of = section after deleted section.=0D + # Check next and the section after next are not end of sec= tion.=0D + if ((Index + 2) < (SectionHeaderEntryNumber - 1)):=0D + unpacked_Next2SectionHeader =3D ElfSectionHeader32.unp= ack(SHentry[((Index + 2) * SectionHeaderEntrySize):(((Index + 2) * SectionH= eaderEntrySize) + SectionHeaderEntrySize)])=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _Next2SectionHeader.sh_addralign)=0D + else:=0D + # It is align 8 bytes if next section or the section a= fter next is last one.=0D + AlignmentIndex =3D 8=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignmen= tIndex)=0D + # section is Deleted section=0D + elif (Index =3D=3D RemoveIndex):=0D + # Don't add removed section to elf.=0D + # Find offset of section name.=0D + RemoveNameOffset =3D unpacked_SectionHeader.sh_name=0D + # section is name string section.=0D + elif (Index =3D=3D StringIndexNumber):=0D + # StringIndex is String Index section=0D + StringIndex =3D UPLEntry[unpacked_SectionHeader.sh_offset:= (unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + # Remove name of removed section in name string section.=0D + # Section header isn't exist if RemoveSectionNameOffset eq= ual to -1.=0D + StringIndex =3D bytearray(StringIndex)=0D + RemoveSectionName =3D bytearray(RemoveSectionName, encodin= g=3D'utf-8')=0D + RemoveSectionName =3D RemoveSectionName + bytes('\0', enco= ding=3D'utf-8')=0D + StringIndex =3D StringIndex.replace(RemoveSectionName,b'')= =0D + NewUPLEntry +=3D StringIndex=0D + # other sections.=0D + else:=0D + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + # Address alignment, section will align with alignment of = next section.=0D + if (Index < (SectionHeaderEntryNumber - 1)):=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _NextSectionHeader.sh_addralign)=0D + else:=0D + # If section is last one.=0D + AlignmentIndex =3D 8=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignmen= tIndex)=0D + SectionHeaderOffset =3D len(NewUPLEntry)=0D + # Add section header=0D + for Number in range(0, (SectionHeaderEntryNumber)):=0D + if (Number !=3D RemoveIndex):=0D + NewSHentry =3D AddSectionHeader32(SHentry, NewUPLEntrylen[= Number], SectionHeaderEntrySize, Number, RemoveNameOffset, RemoveSectionNam= e, StringIndexNumber)=0D + NewUPLEntry +=3D NewSHentry=0D + # Modify number of sections and offset of section header in Elf he= ader.=0D + elf_header.e_shoff =3D SectionHeaderOffset=0D + elf_header.e_shnum -=3D 1=0D + NewUPLEntry =3D elf_header.pack() + NewUPLEntry[52:]=0D + # write to Elf.=0D + with open(UniversalPayloadEntry,'wb') as f:=0D + f.write(NewUPLEntry)=0D +=0D +def AddSection64(UniversalPayloadEntry, AddSectionName, ElfHeaderOffset, S= ectionHeaderEntrySize, SectionHeaderEntryNumber, StringIndexNumber, FileBin= ary, Alignment):=0D + with open(UniversalPayloadEntry,'rb+') as f:=0D + UPLEntry =3D f.read()=0D + fFileBinary =3D open(FileBinary, 'rb')=0D + Binary_File =3D fFileBinary.read()=0D + ElfHeaderOffset, SectionHeaderEntryNumber, StringIndexNumber, _, _= , SectionHeaderEntrySize, _, _ =3D ElfHeaderParser(UPLEntry)=0D + # Read section header entry=0D + SHentry =3D UPLEntry[ElfHeaderOffset:]=0D + # Elf header is recombined.=0D + # Elf header and program header table in front of first section ar= e reserved.=0D + # Elf header is stored at 0x0-0x40 in 64-bits objects=0D + elf_header =3D ElfHeader64(UPLEntry[:64])=0D + # Elf header size is 0x40 with 64-bit object.=0D + ElfHeaderSize =3D 64=0D + ElfHandPH =3D ElfHeaderSize + (elf_header.e_phnum * elf_header.e_p= hentsize)=0D + NewUPLEntry =3D UPLEntry[:ElfHandPH]=0D + # Keep Section header and program header table, AddSection64() onl= y recombined section and section header.=0D + NewUPLEntry =3D bytearray(NewUPLEntry)=0D + # Sections is recombined.=0D + # 1. name of added section is added in name string section.=0D + # 2. added section is added in dll file.=0D + # 3. re-align sections before and after added section.=0D + NewUPLEntrylen =3D []=0D + StringIndexValue =3D 0=0D + for Index in range(0, SectionHeaderEntryNumber):=0D + NewUPLEntrylen.append(len(NewUPLEntry))=0D + unpacked_SectionHeader =3D ElfSectionHeader64.unpack(SHentry[(= Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + Section= HeaderEntrySize)])=0D + # Sections is recombined.=0D + if (Index =3D=3D 0):=0D + # Address alignment, section will align with alignment of = next section.=0D + AlignmentIndex =3D 8=0D + if (SectionHeaderEntryNumber > 2):=0D + unpacked_NextSectionHeader =3D ElfSectionHeader64.unpa= ck(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHe= aderEntrySize) + SectionHeaderEntrySize)])=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign)=0D + # Section is last one.=0D + elif (Index =3D=3D (SectionHeaderEntryNumber - 1)):=0D + # Add new section at the end.=0D + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignment)=0D + LastUPLEntrylen =3D len(NewUPLEntry)=0D + NewUPLEntry +=3D Binary_File=0D + # Address alignment, section will align with alignment of = next section.=0D + AlignmentIndex =3D 8=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, AlignmentInd= ex)=0D + # section is name string section.=0D + elif (Index =3D=3D StringIndexNumber):=0D + # StringIndex is String Index section=0D + StringIndex =3D UPLEntry[unpacked_SectionHeader.sh_offset:= (unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + # Read name of added Section after StringIndex is transfor= m into string.=0D + StringIndex =3D bytearray(StringIndex)=0D + StringIndexValue =3D len(StringIndex)=0D + AddSectionName =3D bytearray(AddSectionName, encoding=3D'u= tf-8') + bytes('\0', encoding=3D'utf-8')=0D + StringIndex +=3D AddSectionName=0D + NewUPLEntry +=3D StringIndex=0D + # section after name string section but not last one.=0D + elif ((Index > StringIndexNumber) and (Index < (SectionHeaderE= ntryNumber - 1))):=0D + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + # Address alignment, section will align with alignment of = next section.=0D + unpacked_NextSectionHeader =3D ElfSectionHeader64.unpack(S= Hentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeader= EntrySize) + SectionHeaderEntrySize)])=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign)=0D + # Section before name string section.=0D + else:=0D + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + # Address alignment, section will align with alignment= of next section.=0D + if (Index < (SectionHeaderEntryNumber - 1)):=0D + unpacked_NextSectionHeader =3D ElfSectionHeader64.unpa= ck(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHe= aderEntrySize) + SectionHeaderEntrySize)])=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _NextSectionHeader.sh_addralign)=0D + SectionHeaderOffset =3D len(NewUPLEntry)=0D + RemoveNameOffset =3D 0=0D + # Add section header=0D + for Number in range(0, (SectionHeaderEntryNumber)):=0D + NewSHentry =3D AddSectionHeader64(SHentry, NewUPLEntrylen[Numb= er], SectionHeaderEntrySize, Number, RemoveNameOffset, AddSectionName, Stri= ngIndexNumber)=0D + NewUPLEntry +=3D NewSHentry=0D + NewUPLEntry +=3D bytearray(AddNewSectionEntry64(LastUPLEntrylen, S= tringIndexValue, len(Binary_File), Alignment))=0D + # Modify number of sections and offset of section header in Elf he= ader.=0D + # Modify offset in in Elf header.=0D + elf_header.e_shoff =3D SectionHeaderOffset=0D + elf_header.e_shnum +=3D 1=0D + elf_header =3D elf_header.pack()=0D + UPLEntryBin =3D elf_header + NewUPLEntry[64:]=0D + # Modify offsets and address of program header table in elf.=0D + PHSegmentName =3D '.text'=0D + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName)=0D + UPLEntryBin =3D ModifyPHSegmentOffset64(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName)=0D + # Modify offsets and address of program header table in elf.=0D + PHSegmentName =3D '.dynamic'=0D + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName)=0D + UPLEntryBin =3D ModifyPHSegmentOffset64(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName)=0D + # Modify offsets and address of program header table in elf.=0D + PHSegmentName =3D '.data'=0D + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName)=0D + UPLEntryBin =3D ModifyPHSegmentOffset64(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName)=0D + fFileBinary.close()=0D + return UPLEntryBin=0D +=0D +def AddSection32(UniversalPayloadEntry, AddSectionName, ElfHeaderOffset, S= ectionHeaderEntrySize, SectionHeaderEntryNumber, StringIndexNumber, FileBin= ary, Alignment):=0D + with open(UniversalPayloadEntry,'rb+') as f:=0D + # Read Elf and binary which will be write to elf.=0D + UPLEntry =3D f.read()=0D + fFileBinary =3D open(FileBinary, 'rb')=0D + Binary_File =3D fFileBinary.read()=0D + ElfHeaderOffset, SectionHeaderEntryNumber, StringIndexNumber, _, _= , SectionHeaderEntrySize, _, _ =3D ElfHeaderParser(UPLEntry)=0D + # Read section header entry=0D + SHentry =3D UPLEntry[ElfHeaderOffset:]=0D + # Elf header is recombined.=0D + # Elf header and program header table in front of first section ar= e reserved.=0D + # Elf header is stored at 0x0-0x34 in 32-bits objects=0D + elf_header =3D ElfHeader32(UPLEntry[:52])=0D + # Elf header size is 0x34 with 32-bit object.=0D + ElfHeaderSize =3D 52=0D + ElfHandPH =3D ElfHeaderSize + (elf_header.e_phnum * elf_header.e_p= hentsize)=0D + NewUPLEntry =3D UPLEntry[:ElfHandPH]=0D + # Keep Section header and program header table, AddSection64() onl= y recombined section and section header.=0D + NewUPLEntry =3D bytearray(NewUPLEntry)=0D + # Sections is recombined.=0D + # 1. name of added section is added in name string section.=0D + # 2. added section is added in dll file.=0D + # 3. re-align sections before and after added section.=0D + NewUPLEntrylen =3D []=0D + StringIndexValue =3D 0=0D + for Index in range(0, SectionHeaderEntryNumber):=0D + NewUPLEntrylen.append(len(NewUPLEntry))=0D + unpacked_SectionHeader =3D ElfSectionHeader32.unpack(SHentry[(= Index * SectionHeaderEntrySize):((Index * SectionHeaderEntrySize) + Section= HeaderEntrySize)])=0D + # Sections is recombined.=0D + if (Index =3D=3D 0):=0D + # Address alignment, section will align with alignment of = next section.=0D + AlignmentIndex =3D 8=0D + if (SectionHeaderEntryNumber > 2):=0D + unpacked_NextSectionHeader =3D ElfSectionHeader32.unpa= ck(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHe= aderEntrySize) + SectionHeaderEntrySize)])=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign)=0D + # Section is last one.=0D + elif (Index =3D=3D (SectionHeaderEntryNumber - 1)):=0D + # Add new section at the end.=0D + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, Alignment)=0D + LastUPLEntrylen =3D len(NewUPLEntry)=0D + NewUPLEntry +=3D Binary_File=0D + # Address alignment, section will align with alignment of = next section.=0D + AlignmentIndex =3D 8=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, AlignmentInd= ex)=0D + # section is name string section.=0D + elif (Index =3D=3D StringIndexNumber):=0D + # StringIndex is String Index section=0D + StringIndex =3D UPLEntry[unpacked_SectionHeader.sh_offset:= (unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + # Read name of added Section after StringIndex is transfor= m into string.=0D + StringIndex =3D bytearray(StringIndex)=0D + StringIndexValue =3D len(StringIndex)=0D + AddSectionName =3D bytearray(AddSectionName, encoding=3D'u= tf-8') + bytes('\0', encoding=3D'utf-8')=0D + StringIndex +=3D AddSectionName=0D + NewUPLEntry +=3D StringIndex=0D + # section after name string section but not last one.=0D + elif ((Index > StringIndexNumber) and (Index < (SectionHeaderE= ntryNumber - 1))):=0D + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + # Address alignment, section will align with alignment of = next section.=0D + unpacked_NextSectionHeader =3D ElfSectionHeader32.unpack(S= Hentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHeader= EntrySize) + SectionHeaderEntrySize)])=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked_Nex= tSectionHeader.sh_addralign)=0D + # Section before name string section.=0D + else:=0D + NewUPLEntry +=3D UPLEntry[unpacked_SectionHeader.sh_offset= :(unpacked_SectionHeader.sh_offset + unpacked_SectionHeader.sh_size)]=0D + # Address alignment, section will align with alignment= of next section.=0D + if (Index < (SectionHeaderEntryNumber - 1)):=0D + unpacked_NextSectionHeader =3D ElfSectionHeader32.unpa= ck(SHentry[((Index + 1) * SectionHeaderEntrySize):(((Index + 1) * SectionHe= aderEntrySize) + SectionHeaderEntrySize)])=0D + NewUPLEntry =3D SectionAlignment(NewUPLEntry, unpacked= _NextSectionHeader.sh_addralign)=0D + SectionHeaderOffset =3D len(NewUPLEntry)=0D + RemoveNameOffset =3D 0=0D + # Add section header=0D + for Number in range(0, (SectionHeaderEntryNumber)):=0D + NewSHentry =3D AddSectionHeader32(SHentry, NewUPLEntrylen[Numb= er], SectionHeaderEntrySize, Number, RemoveNameOffset, AddSectionName, Stri= ngIndexNumber)=0D + NewUPLEntry +=3D NewSHentry=0D + NewUPLEntry +=3D bytearray(AddNewSectionEntry32(LastUPLEntrylen, S= tringIndexValue, len(Binary_File), Alignment))=0D + # Modify number of sections and offset of section header in Elf he= ader.=0D + # Modify offset in in Elf header.=0D + elf_header.e_shoff =3D SectionHeaderOffset=0D + elf_header.e_shnum +=3D 1=0D + PHTableSize =3D elf_header.e_phentsize=0D + elf_header =3D elf_header.pack()=0D + UPLEntryBin =3D elf_header + NewUPLEntry[52:]=0D + # Modify offsets and address of program header table in elf.=0D + PHSegmentName =3D '.text'=0D + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName)=0D + UPLEntryBin =3D ModifyPHSegmentOffset32(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName)=0D + # Modify offsets and address of program header table in elf. Its a= re stored at 0x08-0x0F and 0x10-0x17=0D + PHSegmentName =3D '.data'=0D + _, ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumb= er, _, StringIndexNumber, _ =3D FindSection(UPLEntryBin, PHSegmentName)=0D + UPLEntryBin =3D ModifyPHSegmentOffset32(UPLEntryBin, ElfHeaderOffs= et, PHSegmentName)=0D + fFileBinary.close()=0D + return UPLEntryBin=0D +=0D +def ReplaceFv (UniversalPayloadEntry, FileBinary, AddSectionName, Alignmen= t =3D 16):=0D + with open(UniversalPayloadEntry,'rb+') as f:=0D + UPLEntry =3D f.read()=0D + SectionNameOffset, ElfHeaderOffset, SectionHeaderEntrySize, Sectio= nHeaderEntryNumber, _, StringIndexNumber, EI_CLASS =3D FindSection(UPLEntry= , AddSectionName)=0D + # If elf is 64-bit objects.=0D + if (EI_CLASS =3D=3D 2):=0D + # Remove section if it exists.=0D + if (SectionNameOffset !=3D -1):=0D + RemoveSection64(UniversalPayloadEntry, AddSectionName)=0D + # Add section.=0D + NewUPLEntry =3D AddSection64(UniversalPayloadEntry, AddSectionName= , ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, String= IndexNumber, FileBinary, Alignment)=0D + # If elf is 32-bit objects.=0D + else:=0D + # Remove section if it exists.=0D + if (SectionNameOffset !=3D -1):=0D + RemoveSection32(UniversalPayloadEntry, AddSectionName)=0D + # Add section.=0D + NewUPLEntry =3D AddSection32(UniversalPayloadEntry, AddSectionName= , ElfHeaderOffset, SectionHeaderEntrySize, SectionHeaderEntryNumber, String= IndexNumber, FileBinary, Alignment)=0D + with open(UniversalPayloadEntry,'wb') as f:=0D + f.write(NewUPLEntry)=0D + return 0=0D 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=0D +# Python 'Tools' package initialization file.=0D +#=0D +# @copyright=0D +# INTEL CONFIDENTIAL=0D +#=0D +# Copyright (C) 2023 Intel Corporation=0D +#=0D +# This software and the related documents are Intel copyrighted materials= , and your=0D +# use of them is governed by the express license under which they were pr= ovided to=0D +# you ("License"). Unless the License provides otherwise, you may not use= , modify,=0D +# copy, publish, distribute, disclose or transmit this software or the re= lated=0D +# documents without Intel's prior written permission.=0D +#=0D +# This software and the related documents are provided as is, with no exp= ress or=0D +# implied warranties, other than those that are expressly stated in the L= icense.=0D +#=0D +# @par Specification=0D +##=0D 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=0D import sys=0D from ctypes import *=0D -=0D +from Tools.ElfFv import ReplaceFv=0D sys.dont_write_bytecode =3D True=0D =0D class UPLD_INFO_HEADER(LittleEndianStructure):=0D @@ -36,106 +36,56 @@ class UPLD_INFO_HEADER(LittleEndianStructure): self.ImageId =3D b'UEFI'=0D self.ProducerId =3D b'INTEL'=0D =0D -def GenSpecRevision (Argument):=0D - try:=0D - (MajorStr, MinorStr) =3D Argument.split('.')=0D - except:=0D - raise argparse.ArgumentTypeError ('{} is not a valid SpecRevision = format (Major[8-bits].Minor[8-bits]).'.format (Argument))=0D - #=0D - # Spec Revision Bits 15 : 8 - Major Version. Bits 7 : 0 - Minor Versio= n.=0D - #=0D - if len(MinorStr) > 0 and len(MinorStr) < 3:=0D - try:=0D - Minor =3D int(MinorStr, 16) if len(MinorStr) =3D=3D 2 else (in= t(MinorStr, 16) << 4)=0D - except:=0D - raise argparse.ArgumentTypeError ('{} Minor version of SpecRev= ision is not a valid integer value.'.format (Argument))=0D - else:=0D - raise argparse.ArgumentTypeError ('{} is not a valid SpecRevision = format (Major[8-bits].Minor[8-bits]).'.format (Argument))=0D +def BuildUniversalPayload(Args):=0D + def RunCommand(cmd):=0D + print(cmd)=0D + p =3D subprocess.Popen(cmd, shell=3DTrue, stdout=3Dsubprocess.PIPE= , stderr=3Dsubprocess.STDOUT,cwd=3Dos.environ['WORKSPACE'])=0D + while True:=0D + line =3D p.stdout.readline()=0D + if not line:=0D + break=0D + print(line.strip().decode(errors=3D'ignore'))=0D +=0D + p.communicate()=0D + if p.returncode !=3D 0:=0D + print("- Failed - error happened when run command: %s"%cmd)=0D + raise Exception("ERROR: when run command: %s"%cmd)=0D =0D - if len(MajorStr) > 0 and len(MajorStr) < 3:=0D - try:=0D - Major =3D int(MajorStr, 16)=0D - except:=0D - raise argparse.ArgumentTypeError ('{} Major version of SpecRev= ision is not a valid integer value.'.format (Argument))=0D - else:=0D - raise argparse.ArgumentTypeError ('{} is not a valid SpecRevision = format (Major[8-bits].Minor[8-bits]).'.format (Argument))=0D -=0D - return int('0x{0:02x}{1:02x}'.format(Major, Minor), 0)=0D -=0D -def Validate32BitInteger (Argument):=0D - try:=0D - Value =3D int (Argument, 0)=0D - except:=0D - raise argparse.ArgumentTypeError ('{} is not a valid integer value= .'.format (Argument))=0D - if Value < 0:=0D - raise argparse.ArgumentTypeError ('{} is a negative value.'.format= (Argument))=0D - if Value > 0xffffffff:=0D - raise argparse.ArgumentTypeError ('{} is larger than 32-bits.'.for= mat (Argument))=0D - return Value=0D -=0D -def RunCommand(cmd):=0D - print(cmd)=0D - p =3D subprocess.Popen(cmd, shell=3DTrue, stdout=3Dsubprocess.PIPE, st= derr=3Dsubprocess.STDOUT,cwd=3Dos.environ['WORKSPACE'])=0D - while True:=0D - line =3D p.stdout.readline()=0D - if not line:=0D - break=0D - print(line.strip().decode(errors=3D'ignore'))=0D -=0D - p.communicate()=0D - if p.returncode !=3D 0:=0D - print("- Failed - error happened when run command: %s"%cmd)=0D - raise Exception("ERROR: when run command: %s"%cmd)=0D -=0D -def BuildUniversalPayload(Args, MacroList):=0D BuildTarget =3D Args.Target=0D ToolChain =3D Args.ToolChain=0D Quiet =3D "--quiet" if Args.Quiet else ""=0D ElfToolChain =3D 'CLANGDWARF'=0D BuildDir =3D os.path.join(os.environ['WORKSPACE'], os.path.normpat= h("Build/UefiPayloadPkgX64"))=0D + BuildModule =3D ""=0D + BuildArch =3D ""=0D if Args.Arch =3D=3D 'X64':=0D BuildArch =3D "X64"=0D - ObjCopyFlag =3D "elf64-x86-64"=0D EntryOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ElfToolChain), os.path.normpath("X64/UefiPayloadPkg/UefiPayloadEntry/U= niversalPayloadEntry/DEBUG/UniversalPayloadEntry.dll"))=0D else:=0D BuildArch =3D "IA32 -a X64"=0D - ObjCopyFlag =3D "elf32-i386"=0D EntryOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ElfToolChain), os.path.normpath("IA32/UefiPayloadPkg/UefiPayloadEntry/= UniversalPayloadEntry/DEBUG/UniversalPayloadEntry.dll"))=0D =0D if Args.PreBuildUplBinary is not None:=0D EntryOutputDir =3D os.path.abspath(Args.PreBuildUplBinary)=0D - EntryModuleInf =3D os.path.normpath("UefiPayloadPkg/UefiPayloadEntry/U= niversalPayloadEntry.inf")=0D DscPath =3D os.path.normpath("UefiPayloadPkg/UefiPayloadPkg.dsc")=0D - DxeFvOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTarget,= ToolChain), os.path.normpath("FV/DXEFV.Fv"))=0D - BdsFvOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTarget,= ToolChain), os.path.normpath("FV/BDSFV.Fv"))=0D - NetworkFvOutputDir =3D os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/NETWORKFV.Fv"))=0D - PayloadReportPath =3D os.path.join(BuildDir, "UefiUniversalPayload.txt= ")=0D ModuleReportPath =3D os.path.join(BuildDir, "UefiUniversalPayloadEntry= .txt")=0D UpldInfoFile =3D os.path.join(BuildDir, "UniversalPayloadInfo.bin")=0D =0D - if "CLANG_BIN" in os.environ:=0D - LlvmObjcopyPath =3D os.path.join(os.environ["CLANG_BIN"], "llvm-ob= jcopy")=0D - else:=0D - LlvmObjcopyPath =3D "llvm-objcopy"=0D - try:=0D - RunCommand('"%s" --version'%LlvmObjcopyPath)=0D - except:=0D - print("- Failed - Please check if LLVM is installed or if CLANG_BI= N is set correctly")=0D - sys.exit(1)=0D -=0D Pcds =3D ""=0D if (Args.pcd !=3D None):=0D for PcdItem in Args.pcd:=0D Pcds +=3D " --pcd {}".format (PcdItem)=0D =0D Defines =3D ""=0D - for key in MacroList:=0D - Defines +=3D" -D {0}=3D{1}".format(key, MacroList[key])=0D + if (Args.Macro !=3D None):=0D + for MacroItem in Args.Macro:=0D + Defines +=3D " -D {}".format (MacroItem)=0D =0D #=0D # Building DXE core and DXE drivers as DXEFV.=0D #=0D if Args.BuildEntryOnly =3D=3D False:=0D + PayloadReportPath =3D os.path.join(BuildDir, "UefiUniversalPayload= .txt")=0D BuildPayload =3D "build -p {} -b {} -a X64 -t {} -y {} {}".format = (DscPath, BuildTarget, ToolChain, PayloadReportPath, Quiet)=0D BuildPayload +=3D Pcds=0D BuildPayload +=3D Defines=0D @@ -144,6 +94,7 @@ def BuildUniversalPayload(Args, MacroList): # Building Universal Payload entry.=0D #=0D if Args.PreBuildUplBinary is None:=0D + EntryModuleInf =3D os.path.normpath("UefiPayloadPkg/UefiPayloadEnt= ry/UniversalPayloadEntry.inf")=0D BuildModule =3D "build -p {} -b {} -a {} -m {} -t {} -y {} {}".for= mat (DscPath, BuildTarget, BuildArch, EntryModuleInf, ElfToolChain, ModuleR= eportPath, Quiet)=0D BuildModule +=3D Pcds=0D BuildModule +=3D Defines=0D @@ -151,59 +102,80 @@ def BuildUniversalPayload(Args, MacroList): #=0D # Buid Universal Payload Information Section ".upld_info"=0D #=0D - upld_info_hdr =3D UPLD_INFO_HEADER()=0D + upld_info_hdr =3D UPLD_INFO_HEADER()=0D upld_info_hdr.SpecRevision =3D Args.SpecRevision=0D - upld_info_hdr.Revision =3D Args.Revision=0D - upld_info_hdr.ProducerId =3D Args.ProducerId.encode()[:16]=0D - upld_info_hdr.ImageId =3D Args.ImageId.encode()[:16]=0D - upld_info_hdr.Attribute |=3D 1 if BuildTarget =3D=3D "DEBUG" else 0=0D + upld_info_hdr.Revision =3D Args.Revision=0D + upld_info_hdr.ProducerId =3D Args.ProducerId.encode()[:16]=0D + upld_info_hdr.ImageId =3D Args.ImageId.encode()[:16]=0D + upld_info_hdr.Attribute |=3D 1 if BuildTarget =3D=3D "DEBUG" else 0= =0D fp =3D open(UpldInfoFile, 'wb')=0D fp.write(bytearray(upld_info_hdr))=0D fp.close()=0D =0D + MultiFvList =3D []=0D if Args.BuildEntryOnly =3D=3D False:=0D - #=0D - # Copy the DXEFV as a section in elf format Universal Payload entr= y.=0D - #=0D - remove_section =3D '"{}" -I {} -O {} --remove-section .upld_info -= -remove-section .upld.uefi_fv --remove-section .upld.bds_fv {}'.format (=0D - LlvmObjcopyPath,=0D - ObjCopyFlag,=0D - ObjCopyFlag,=0D - EntryOutputDir=0D - )=0D - add_section =3D '"{}" -I {} -O {} --add-section .upld_info=3D{}= --add-section .upld.uefi_fv=3D{} --add-section .upld.bds_fv=3D{} {}'.forma= t (=0D - LlvmObjcopyPath,=0D - ObjCopyFlag,=0D - ObjCopyFlag,=0D - UpldInfoFile,=0D - DxeFvOutputDir,=0D - BdsFvOutputDir,=0D - EntryOutputDir=0D - )=0D - 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 (=0D - LlvmObjcopyPath,=0D - ObjCopyFlag,=0D - ObjCopyFlag,=0D - EntryOutputDir=0D - )=0D - #=0D - # Append network fv to sections if exists=0D - #=0D - if os.path.isfile(NetworkFvOutputDir):=0D - index =3D remove_section.find(EntryOutputDir)=0D - remove_section =3D remove_section[:index] + '--remove-section = .upld.network_fv ' + remove_section[index:]=0D - index =3D add_section.find(EntryOutputDir)=0D - add_section =3D add_section[:index] + '--add-section .upld.net= work_fv=3D' + NetworkFvOutputDir + ' ' + add_section[index:]=0D - index =3D set_section.find(EntryOutputDir)=0D - set_section =3D set_section[:index] + '--set-section-alignment= .upld.network_fv=3D16 ' + set_section[index:]=0D -=0D - RunCommand(remove_section)=0D - RunCommand(add_section)=0D - RunCommand(set_section)=0D + MultiFvList =3D [=0D + ['uefi_fv', os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/DXEFV.Fv")) ],=0D + ['bds_fv', os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/BDSFV.Fv")) ],=0D + ['network_fv', os.path.join(BuildDir, "{}_{}".format (BuildTar= get, ToolChain), os.path.normpath("FV/NETWORKFV.Fv")) ],=0D + ]=0D + AddSectionName =3D '.upld_info'=0D + ReplaceFv (EntryOutputDir, UpldInfoFile, AddSectionName, Alignment= =3D 4)=0D =0D shutil.copy (EntryOutputDir, os.path.join(BuildDir, 'UniversalPayload.= elf'))=0D =0D + return MultiFvList, os.path.join(BuildDir, 'UniversalPayload.elf')=0D +=0D def main():=0D + def ValidateSpecRevision (Argument):=0D + try:=0D + (MajorStr, MinorStr) =3D Argument.split('.')=0D + except:=0D + raise argparse.ArgumentTypeError ('{} is not a valid SpecRevis= ion format (Major[8-bits].Minor[8-bits]).'.format (Argument))=0D + #=0D + # Spec Revision Bits 15 : 8 - Major Version. Bits 7 : 0 - Minor Ve= rsion.=0D + #=0D + if len(MinorStr) > 0 and len(MinorStr) < 3:=0D + try:=0D + Minor =3D int(MinorStr, 16) if len(MinorStr) =3D=3D 2 else= (int(MinorStr, 16) << 4)=0D + except:=0D + raise argparse.ArgumentTypeError ('{} Minor version of Spe= cRevision is not a valid integer value.'.format (Argument))=0D + else:=0D + raise argparse.ArgumentTypeError ('{} is not a valid SpecRevis= ion format (Major[8-bits].Minor[8-bits]).'.format (Argument))=0D +=0D + if len(MajorStr) > 0 and len(MajorStr) < 3:=0D + try:=0D + Major =3D int(MajorStr, 16)=0D + except:=0D + raise argparse.ArgumentTypeError ('{} Major version of Spe= cRevision is not a valid integer value.'.format (Argument))=0D + else:=0D + raise argparse.ArgumentTypeError ('{} is not a valid SpecRevis= ion format (Major[8-bits].Minor[8-bits]).'.format (Argument))=0D +=0D + return int('0x{0:02x}{1:02x}'.format(Major, Minor), 0)=0D +=0D + def Validate32BitInteger (Argument):=0D + try:=0D + Value =3D int (Argument, 0)=0D + except:=0D + raise argparse.ArgumentTypeError ('{} is not a valid integer v= alue.'.format (Argument))=0D + if Value < 0:=0D + raise argparse.ArgumentTypeError ('{} is a negative value.'.fo= rmat (Argument))=0D + if Value > 0xffffffff:=0D + raise argparse.ArgumentTypeError ('{} is larger than 32-bits.'= .format (Argument))=0D + return Value=0D +=0D + def ValidateAddFv (Argument):=0D + Value =3D Argument.split ("=3D")=0D + if len (Value) !=3D 2:=0D + raise argparse.ArgumentTypeError ('{} is incorrect format with= "xxx_fv=3Dxxx.fv"'.format (Argument))=0D + if Value[0][-3:] !=3D "_fv":=0D + raise argparse.ArgumentTypeError ('{} is incorrect format with= "xxx_fv=3Dxxx.fv"'.format (Argument))=0D + if Value[1][-3:].lower () !=3D ".fv":=0D + raise argparse.ArgumentTypeError ('{} is incorrect format with= "xxx_fv=3Dxxx.fv"'.format (Argument))=0D + if os.path.exists (Value[1]) =3D=3D False:=0D + raise argparse.ArgumentTypeError ('File {} is not found.'.form= at (Value[1]))=0D + return Value=0D +=0D parser =3D argparse.ArgumentParser(description=3D'For building Univers= al Payload')=0D parser.add_argument('-t', '--ToolChain')=0D parser.add_argument('-b', '--Target', default=3D'DEBUG')=0D @@ -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')=0D parser.add_argument('-q', '--Quiet', action=3D'store_true', help=3D'Di= sable all build messages except FATAL ERRORS.')=0D parser.add_argument("-p", "--pcd", action=3D"append")=0D - 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.')=0D + 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.')=0D parser.add_argument("-r", "--Revision", type=3DValidate32BitInteger, d= efault =3D'0x0000010105', help=3D'Revision of the Payload binary. Major.Min= or.Revision.Build')=0D parser.add_argument("-o", "--ProducerId", default =3D'INTEL', help=3D'= A null-terminated OEM-supplied string that identifies the payload producer = (16 bytes maximal).')=0D parser.add_argument("-e", "--BuildEntryOnly", action=3D'store_true', h= elp=3D'Build UniversalPayload Entry file')=0D parser.add_argument("-pb", "--PreBuildUplBinary", default=3DNone, help= =3D'Specify the UniversalPayload file')=0D - MacroList =3D {}=0D + parser.add_argument("-sk", "--SkipBuild", action=3D'store_true', help= =3D'Skip UniversalPayload build')=0D + parser.add_argument("-af", "--AddFv", type=3DValidateAddFv, action=3D'= append', help=3D'Add or replace specific FV into payload, Ex: uefi_fv=3DXXX= .fv')=0D args =3D parser.parse_args()=0D - if args.Macro is not None:=0D - for Argument in args.Macro:=0D - if Argument.count('=3D') !=3D 1:=0D - print("Unknown variable passed in: %s"%Argument)=0D - raise Exception("ERROR: Unknown variable passed in: %s"%Ar= gument)=0D - tokens =3D Argument.strip().split('=3D')=0D - MacroList[tokens[0].upper()] =3D tokens[1]=0D - BuildUniversalPayload(args, MacroList)=0D - print ("Successfully build Universal Payload")=0D +=0D + MultiFvList =3D []=0D + UniversalPayloadBinary =3D args.PreBuildUplBinary=0D + if (args.SkipBuild =3D=3D False):=0D + MultiFvList, UniversalPayloadBinary =3D BuildUniversalPayload(args= )=0D +=0D + if (args.AddFv !=3D None):=0D + for (SectionName, SectionFvFile) in args.AddFv:=0D + MultiFvList.append ([SectionName, SectionFvFile])=0D +=0D + if (UniversalPayloadBinary !=3D None):=0D + for (SectionName, SectionFvFile) in MultiFvList:=0D + if os.path.exists (SectionFvFile) =3D=3D False:=0D + continue=0D + print ("Patch {}=3D{} into {}".format (SectionName, SectionFvF= ile, UniversalPayloadBinary))=0D + ReplaceFv (UniversalPayloadBinary, SectionFvFile, '.upld.{}'.f= ormat (SectionName))=0D +=0D + print ("\nSuccessfully build Universal Payload")=0D =0D if __name__ =3D=3D '__main__':=0D main()=0D --=20 2.39.1.windows.1