summaryrefslogtreecommitdiffstats
path: root/UefiPayloadPkg/UniversalPayloadBuild.py
diff options
context:
space:
mode:
authorBruceX Wang <brucex.wang@intel.com>2023-04-26 14:32:01 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-04-28 05:54:26 +0000
commit95ef765839a8d0de52095e3dec3584fc347b94b2 (patch)
treec65b99b1e559e77f9c37093ff961a54fd6a4dbc0 /UefiPayloadPkg/UniversalPayloadBuild.py
parente5e1cd1a83e2e7aa2179db3de5fc00d76713ec6f (diff)
downloadedk2-95ef765839a8d0de52095e3dec3584fc347b94b2.tar.gz
edk2-95ef765839a8d0de52095e3dec3584fc347b94b2.tar.bz2
edk2-95ef765839a8d0de52095e3dec3584fc347b94b2.zip
UefiPayloadPkg: Clang dependency removal
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4426 Use Python to replace llvm-objcopy in UniversalPayloadBuild.py. 1. AddSection32() and AddSection64(): Make a section named <section> with the contents of <file>. 2. RemoveSection32() and RemoveSection64(): Remove <section>. 3. ReplaceFv (): remove the section before add the section if the file exists. Cc: Guo Dong <guo.dong@intel.com> Cc: Ray Ni <ray.ni@intel.com> Cc: Sean Rhodes <sean@starlabs.systems> Cc: James Lu <james.lu@intel.com> Signed-off-by: BruceX Wang <brucex.wang@intel.com> Reviewed-by: Gua Guo <gua.guo@intel.com>
Diffstat (limited to 'UefiPayloadPkg/UniversalPayloadBuild.py')
-rw-r--r--UefiPayloadPkg/UniversalPayloadBuild.py232
1 files changed, 107 insertions, 125 deletions
diff --git a/UefiPayloadPkg/UniversalPayloadBuild.py b/UefiPayloadPkg/UniversalPayloadBuild.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 = True
class UPLD_INFO_HEADER(LittleEndianStructure):
@@ -36,106 +36,56 @@ class UPLD_INFO_HEADER(LittleEndianStructure):
self.ImageId = b'UEFI'
self.ProducerId = b'INTEL'
-def GenSpecRevision (Argument):
- try:
- (MajorStr, MinorStr) = 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 Version.
- #
- if len(MinorStr) > 0 and len(MinorStr) < 3:
- try:
- Minor = int(MinorStr, 16) if len(MinorStr) == 2 else (int(MinorStr, 16) << 4)
- except:
- raise argparse.ArgumentTypeError ('{} Minor version of SpecRevision 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 = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,cwd=os.environ['WORKSPACE'])
+ while True:
+ line = p.stdout.readline()
+ if not line:
+ break
+ print(line.strip().decode(errors='ignore'))
+
+ p.communicate()
+ if p.returncode != 0:
+ print("- Failed - error happened when run command: %s"%cmd)
+ raise Exception("ERROR: when run command: %s"%cmd)
- if len(MajorStr) > 0 and len(MajorStr) < 3:
- try:
- Major = int(MajorStr, 16)
- except:
- raise argparse.ArgumentTypeError ('{} Major version of SpecRevision 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 = 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.'.format (Argument))
- return Value
-
-def RunCommand(cmd):
- print(cmd)
- p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,cwd=os.environ['WORKSPACE'])
- while True:
- line = p.stdout.readline()
- if not line:
- break
- print(line.strip().decode(errors='ignore'))
-
- p.communicate()
- if p.returncode != 0:
- print("- Failed - error happened when run command: %s"%cmd)
- raise Exception("ERROR: when run command: %s"%cmd)
-
-def BuildUniversalPayload(Args, MacroList):
BuildTarget = Args.Target
ToolChain = Args.ToolChain
Quiet = "--quiet" if Args.Quiet else ""
ElfToolChain = 'CLANGDWARF'
BuildDir = os.path.join(os.environ['WORKSPACE'], os.path.normpath("Build/UefiPayloadPkgX64"))
+ BuildModule = ""
+ BuildArch = ""
if Args.Arch == 'X64':
BuildArch = "X64"
- ObjCopyFlag = "elf64-x86-64"
EntryOutputDir = os.path.join(BuildDir, "{}_{}".format (BuildTarget, ElfToolChain), os.path.normpath("X64/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry/DEBUG/UniversalPayloadEntry.dll"))
else:
BuildArch = "IA32 -a X64"
- ObjCopyFlag = "elf32-i386"
EntryOutputDir = os.path.join(BuildDir, "{}_{}".format (BuildTarget, ElfToolChain), os.path.normpath("IA32/UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry/DEBUG/UniversalPayloadEntry.dll"))
if Args.PreBuildUplBinary is not None:
EntryOutputDir = os.path.abspath(Args.PreBuildUplBinary)
- EntryModuleInf = os.path.normpath("UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf")
DscPath = os.path.normpath("UefiPayloadPkg/UefiPayloadPkg.dsc")
- DxeFvOutputDir = os.path.join(BuildDir, "{}_{}".format (BuildTarget, ToolChain), os.path.normpath("FV/DXEFV.Fv"))
- BdsFvOutputDir = os.path.join(BuildDir, "{}_{}".format (BuildTarget, ToolChain), os.path.normpath("FV/BDSFV.Fv"))
- NetworkFvOutputDir = os.path.join(BuildDir, "{}_{}".format (BuildTarget, ToolChain), os.path.normpath("FV/NETWORKFV.Fv"))
- PayloadReportPath = os.path.join(BuildDir, "UefiUniversalPayload.txt")
ModuleReportPath = os.path.join(BuildDir, "UefiUniversalPayloadEntry.txt")
UpldInfoFile = os.path.join(BuildDir, "UniversalPayloadInfo.bin")
- if "CLANG_BIN" in os.environ:
- LlvmObjcopyPath = os.path.join(os.environ["CLANG_BIN"], "llvm-objcopy")
- else:
- LlvmObjcopyPath = "llvm-objcopy"
- try:
- RunCommand('"%s" --version'%LlvmObjcopyPath)
- except:
- print("- Failed - Please check if LLVM is installed or if CLANG_BIN is set correctly")
- sys.exit(1)
-
Pcds = ""
if (Args.pcd != None):
for PcdItem in Args.pcd:
Pcds += " --pcd {}".format (PcdItem)
Defines = ""
- for key in MacroList:
- Defines +=" -D {0}={1}".format(key, MacroList[key])
+ if (Args.Macro != None):
+ for MacroItem in Args.Macro:
+ Defines += " -D {}".format (MacroItem)
#
# Building DXE core and DXE drivers as DXEFV.
#
if Args.BuildEntryOnly == False:
+ PayloadReportPath = os.path.join(BuildDir, "UefiUniversalPayload.txt")
BuildPayload = "build -p {} -b {} -a X64 -t {} -y {} {}".format (DscPath, BuildTarget, ToolChain, PayloadReportPath, Quiet)
BuildPayload += Pcds
BuildPayload += Defines
@@ -144,6 +94,7 @@ def BuildUniversalPayload(Args, MacroList):
# Building Universal Payload entry.
#
if Args.PreBuildUplBinary is None:
+ EntryModuleInf = os.path.normpath("UefiPayloadPkg/UefiPayloadEntry/UniversalPayloadEntry.inf")
BuildModule = "build -p {} -b {} -a {} -m {} -t {} -y {} {}".format (DscPath, BuildTarget, BuildArch, EntryModuleInf, ElfToolChain, ModuleReportPath, Quiet)
BuildModule += Pcds
BuildModule += Defines
@@ -151,59 +102,80 @@ def BuildUniversalPayload(Args, MacroList):
#
# Buid Universal Payload Information Section ".upld_info"
#
- upld_info_hdr = UPLD_INFO_HEADER()
+ upld_info_hdr = UPLD_INFO_HEADER()
upld_info_hdr.SpecRevision = Args.SpecRevision
- upld_info_hdr.Revision = Args.Revision
- upld_info_hdr.ProducerId = Args.ProducerId.encode()[:16]
- upld_info_hdr.ImageId = Args.ImageId.encode()[:16]
- upld_info_hdr.Attribute |= 1 if BuildTarget == "DEBUG" else 0
+ upld_info_hdr.Revision = Args.Revision
+ upld_info_hdr.ProducerId = Args.ProducerId.encode()[:16]
+ upld_info_hdr.ImageId = Args.ImageId.encode()[:16]
+ upld_info_hdr.Attribute |= 1 if BuildTarget == "DEBUG" else 0
fp = open(UpldInfoFile, 'wb')
fp.write(bytearray(upld_info_hdr))
fp.close()
+ MultiFvList = []
if Args.BuildEntryOnly == False:
- #
- # Copy the DXEFV as a section in elf format Universal Payload entry.
- #
- remove_section = '"{}" -I {} -O {} --remove-section .upld_info --remove-section .upld.uefi_fv --remove-section .upld.bds_fv {}'.format (
- LlvmObjcopyPath,
- ObjCopyFlag,
- ObjCopyFlag,
- EntryOutputDir
- )
- add_section = '"{}" -I {} -O {} --add-section .upld_info={} --add-section .upld.uefi_fv={} --add-section .upld.bds_fv={} {}'.format (
- LlvmObjcopyPath,
- ObjCopyFlag,
- ObjCopyFlag,
- UpldInfoFile,
- DxeFvOutputDir,
- BdsFvOutputDir,
- EntryOutputDir
- )
- set_section = '"{}" -I {} -O {} --set-section-alignment .upld_info=4 --set-section-alignment .upld.uefi_fv=16 --set-section-alignment .upld.bds_fv=16 {}'.format (
- LlvmObjcopyPath,
- ObjCopyFlag,
- ObjCopyFlag,
- EntryOutputDir
- )
- #
- # Append network fv to sections if exists
- #
- if os.path.isfile(NetworkFvOutputDir):
- index = remove_section.find(EntryOutputDir)
- remove_section = remove_section[:index] + '--remove-section .upld.network_fv ' + remove_section[index:]
- index = add_section.find(EntryOutputDir)
- add_section = add_section[:index] + '--add-section .upld.network_fv=' + NetworkFvOutputDir + ' ' + add_section[index:]
- index = set_section.find(EntryOutputDir)
- set_section = set_section[:index] + '--set-section-alignment .upld.network_fv=16 ' + set_section[index:]
-
- RunCommand(remove_section)
- RunCommand(add_section)
- RunCommand(set_section)
+ MultiFvList = [
+ ['uefi_fv', os.path.join(BuildDir, "{}_{}".format (BuildTarget, ToolChain), os.path.normpath("FV/DXEFV.Fv")) ],
+ ['bds_fv', os.path.join(BuildDir, "{}_{}".format (BuildTarget, ToolChain), os.path.normpath("FV/BDSFV.Fv")) ],
+ ['network_fv', os.path.join(BuildDir, "{}_{}".format (BuildTarget, ToolChain), os.path.normpath("FV/NETWORKFV.Fv")) ],
+ ]
+ AddSectionName = '.upld_info'
+ ReplaceFv (EntryOutputDir, UpldInfoFile, AddSectionName, Alignment = 4)
shutil.copy (EntryOutputDir, os.path.join(BuildDir, 'UniversalPayload.elf'))
+ return MultiFvList, os.path.join(BuildDir, 'UniversalPayload.elf')
+
def main():
+ def ValidateSpecRevision (Argument):
+ try:
+ (MajorStr, MinorStr) = 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 Version.
+ #
+ if len(MinorStr) > 0 and len(MinorStr) < 3:
+ try:
+ Minor = int(MinorStr, 16) if len(MinorStr) == 2 else (int(MinorStr, 16) << 4)
+ except:
+ raise argparse.ArgumentTypeError ('{} Minor version of SpecRevision 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))
+
+ if len(MajorStr) > 0 and len(MajorStr) < 3:
+ try:
+ Major = int(MajorStr, 16)
+ except:
+ raise argparse.ArgumentTypeError ('{} Major version of SpecRevision 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 = 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.'.format (Argument))
+ return Value
+
+ def ValidateAddFv (Argument):
+ Value = Argument.split ("=")
+ if len (Value) != 2:
+ raise argparse.ArgumentTypeError ('{} is incorrect format with "xxx_fv=xxx.fv"'.format (Argument))
+ if Value[0][-3:] != "_fv":
+ raise argparse.ArgumentTypeError ('{} is incorrect format with "xxx_fv=xxx.fv"'.format (Argument))
+ if Value[1][-3:].lower () != ".fv":
+ raise argparse.ArgumentTypeError ('{} is incorrect format with "xxx_fv=xxx.fv"'.format (Argument))
+ if os.path.exists (Value[1]) == False:
+ raise argparse.ArgumentTypeError ('File {} is not found.'.format (Value[1]))
+ return Value
+
parser = argparse.ArgumentParser(description='For building Universal Payload')
parser.add_argument('-t', '--ToolChain')
parser.add_argument('-b', '--Target', default='DEBUG')
@@ -212,22 +184,32 @@ def main():
parser.add_argument('-i', '--ImageId', type=str, help='Specify payload ID (16 bytes maximal).', default ='UEFI')
parser.add_argument('-q', '--Quiet', action='store_true', help='Disable all build messages except FATAL ERRORS.')
parser.add_argument("-p", "--pcd", action="append")
- parser.add_argument("-s", "--SpecRevision", type=GenSpecRevision, default ='0.7', help='Indicates compliance with a revision of this specification in the BCD format.')
+ parser.add_argument("-s", "--SpecRevision", type=ValidateSpecRevision, default ='0.7', help='Indicates compliance with a revision of this specification in the BCD format.')
parser.add_argument("-r", "--Revision", type=Validate32BitInteger, default ='0x0000010105', help='Revision of the Payload binary. Major.Minor.Revision.Build')
parser.add_argument("-o", "--ProducerId", default ='INTEL', help='A null-terminated OEM-supplied string that identifies the payload producer (16 bytes maximal).')
parser.add_argument("-e", "--BuildEntryOnly", action='store_true', help='Build UniversalPayload Entry file')
parser.add_argument("-pb", "--PreBuildUplBinary", default=None, help='Specify the UniversalPayload file')
- MacroList = {}
+ parser.add_argument("-sk", "--SkipBuild", action='store_true', help='Skip UniversalPayload build')
+ parser.add_argument("-af", "--AddFv", type=ValidateAddFv, action='append', help='Add or replace specific FV into payload, Ex: uefi_fv=XXX.fv')
args = parser.parse_args()
- if args.Macro is not None:
- for Argument in args.Macro:
- if Argument.count('=') != 1:
- print("Unknown variable passed in: %s"%Argument)
- raise Exception("ERROR: Unknown variable passed in: %s"%Argument)
- tokens = Argument.strip().split('=')
- MacroList[tokens[0].upper()] = tokens[1]
- BuildUniversalPayload(args, MacroList)
- print ("Successfully build Universal Payload")
+
+ MultiFvList = []
+ UniversalPayloadBinary = args.PreBuildUplBinary
+ if (args.SkipBuild == False):
+ MultiFvList, UniversalPayloadBinary = BuildUniversalPayload(args)
+
+ if (args.AddFv != None):
+ for (SectionName, SectionFvFile) in args.AddFv:
+ MultiFvList.append ([SectionName, SectionFvFile])
+
+ if (UniversalPayloadBinary != None):
+ for (SectionName, SectionFvFile) in MultiFvList:
+ if os.path.exists (SectionFvFile) == False:
+ continue
+ print ("Patch {}={} into {}".format (SectionName, SectionFvFile, UniversalPayloadBinary))
+ ReplaceFv (UniversalPayloadBinary, SectionFvFile, '.upld.{}'.format (SectionName))
+
+ print ("\nSuccessfully build Universal Payload")
if __name__ == '__main__':
main()