diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GuidSection.py')
-rwxr-xr-x | src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GuidSection.py | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GuidSection.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GuidSection.py new file mode 100755 index 00000000..3e7d9673 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/GenFds/GuidSection.py @@ -0,0 +1,278 @@ +## @file +# process GUIDed section generation +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2018, Hewlett Packard Enterprise Development, L.P.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import Section +import subprocess +from .Ffs import SectionSuffix +import Common.LongFilePathOs as os +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from .GenFdsGlobalVariable import FindExtendTool +from CommonDataClass.FdfClass import GuidSectionClassObject +import sys +from Common import EdkLogger +from Common.BuildToolError import * +from .FvImageSection import FvImageSection +from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.DataType import * + +## generate GUIDed section +# +# +class GuidSection(GuidSectionClassObject) : + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + GuidSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate GUIDed section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict=None, IsMakefile=False): + # + # Generate all section + # + self.KeyStringList = KeyStringList + self.CurrentArchList = GenFdsGlobalVariable.ArchList + if FfsInf is not None: + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + self.NameGuid = FfsInf.__ExtendMacro__(self.NameGuid) + self.SectionType = FfsInf.__ExtendMacro__(self.SectionType) + self.CurrentArchList = [FfsInf.CurrentArch] + + SectFile = tuple() + SectAlign = [] + Index = 0 + MaxAlign = None + if Dict is None: + Dict = {} + if self.FvAddr != []: + FvAddrIsSet = True + else: + FvAddrIsSet = False + + if self.ProcessRequired in ("TRUE", "1"): + if self.FvAddr != []: + #no use FvAddr when the image is processed. + self.FvAddr = [] + if self.FvParentAddr is not None: + #no use Parent Addr when the image is processed. + self.FvParentAddr = None + + for Sect in self.SectionList: + Index = Index + 1 + SecIndex = '%s.%d' % (SecNum, Index) + # set base address for inside FvImage + if isinstance(Sect, FvImageSection): + if self.FvAddr != []: + Sect.FvAddr = self.FvAddr.pop(0) + self.IncludeFvSection = True + elif isinstance(Sect, GuidSection): + Sect.FvAddr = self.FvAddr + Sect.FvParentAddr = self.FvParentAddr + ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile) + if isinstance(Sect, GuidSection): + if Sect.IncludeFvSection: + self.IncludeFvSection = Sect.IncludeFvSection + + if align is not None: + if MaxAlign is None: + MaxAlign = align + if GenFdsGlobalVariable.GetAlignment (align) > GenFdsGlobalVariable.GetAlignment (MaxAlign): + MaxAlign = align + if ReturnSectList != []: + if align is None: + align = "1" + for file in ReturnSectList: + SectFile += (file,) + SectAlign.append(align) + + if MaxAlign is not None: + if self.Alignment is None: + self.Alignment = MaxAlign + else: + if GenFdsGlobalVariable.GetAlignment (MaxAlign) > GenFdsGlobalVariable.GetAlignment (self.Alignment): + self.Alignment = MaxAlign + + OutputFile = OutputPath + \ + os.sep + \ + ModuleName + \ + SUP_MODULE_SEC + \ + SecNum + \ + SectionSuffix['GUIDED'] + OutputFile = os.path.normpath(OutputFile) + + ExternalTool = None + ExternalOption = None + if self.NameGuid is not None: + ExternalTool, ExternalOption = FindExtendTool(self.KeyStringList, self.CurrentArchList, self.NameGuid) + + # + # If not have GUID , call default + # GENCRC32 section + # + if self.NameGuid is None : + GenFdsGlobalVariable.VerboseLogger("Use GenSection function Generate CRC32 Section") + GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign, IsMakefile=IsMakefile) + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment + #or GUID not in External Tool List + elif ExternalTool is None: + EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % self.NameGuid) + else: + DummyFile = OutputFile + ".dummy" + # + # Call GenSection with DUMMY section type. + # + GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign, IsMakefile=IsMakefile) + # + # Use external tool process the Output + # + TempFile = OutputPath + \ + os.sep + \ + ModuleName + \ + SUP_MODULE_SEC + \ + SecNum + \ + '.tmp' + TempFile = os.path.normpath(TempFile) + # + # Remove temp file if its time stamp is older than dummy file + # Just in case the external tool fails at this time but succeeded before + # Error should be reported if the external tool does not generate a new output based on new input + # + if os.path.exists(TempFile) and os.path.exists(DummyFile) and os.path.getmtime(TempFile) < os.path.getmtime(DummyFile): + os.remove(TempFile) + + FirstCall = False + CmdOption = '-e' + if ExternalOption is not None: + CmdOption = CmdOption + ' ' + ExternalOption + if not GenFdsGlobalVariable.EnableGenfdsMultiThread: + if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr is not None: + #FirstCall is only set for the encapsulated flash FV image without process required attribute. + FirstCall = True + # + # Call external tool + # + ReturnValue = [1] + if FirstCall: + #first try to call the guided tool with -z option and CmdOption for the no process required guided tool. + GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue) + + # + # when no call or first call failed, ReturnValue are not 1. + # Call the guided tool with CmdOption + # + if ReturnValue[0] != 0: + FirstCall = False + ReturnValue[0] = 0 + GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption) + # + # There is external tool which does not follow standard rule which return nonzero if tool fails + # The output file has to be checked + # + + if not os.path.exists(TempFile) : + EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool) + + FileHandleIn = open(DummyFile, 'rb') + FileHandleIn.seek(0, 2) + InputFileSize = FileHandleIn.tell() + + FileHandleOut = open(TempFile, 'rb') + FileHandleOut.seek(0, 2) + TempFileSize = FileHandleOut.tell() + + Attribute = [] + HeaderLength = None + if self.ExtraHeaderSize != -1: + HeaderLength = str(self.ExtraHeaderSize) + + if self.ProcessRequired == "NONE" and HeaderLength is None: + if TempFileSize > InputFileSize: + FileHandleIn.seek(0) + BufferIn = FileHandleIn.read() + FileHandleOut.seek(0) + BufferOut = FileHandleOut.read() + if BufferIn == BufferOut[TempFileSize - InputFileSize:]: + HeaderLength = str(TempFileSize - InputFileSize) + #auto sec guided attribute with process required + if HeaderLength is None: + Attribute.append('PROCESSING_REQUIRED') + + FileHandleIn.close() + FileHandleOut.close() + + if FirstCall and 'PROCESSING_REQUIRED' in Attribute: + # Guided data by -z option on first call is the process required data. Call the guided tool with the real option. + GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption) + + # + # Call Gensection Add Section Header + # + if self.ProcessRequired in ("TRUE", "1"): + if 'PROCESSING_REQUIRED' not in Attribute: + Attribute.append('PROCESSING_REQUIRED') + + if self.AuthStatusValid in ("TRUE", "1"): + Attribute.append('AUTH_STATUS_VALID') + GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], + Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength) + + else: + #add input file for GenSec get PROCESSING_REQUIRED + GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption, IsMakefile=IsMakefile) + Attribute = [] + HeaderLength = None + if self.ExtraHeaderSize != -1: + HeaderLength = str(self.ExtraHeaderSize) + if self.AuthStatusValid in ("TRUE", "1"): + Attribute.append('AUTH_STATUS_VALID') + if self.ProcessRequired == "NONE" and HeaderLength is None: + GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], + Guid=self.NameGuid, GuidAttr=Attribute, + GuidHdrLen=HeaderLength, DummyFile=DummyFile, IsMakefile=IsMakefile) + else: + if self.ProcessRequired in ("TRUE", "1"): + if 'PROCESSING_REQUIRED' not in Attribute: + Attribute.append('PROCESSING_REQUIRED') + GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], + Guid=self.NameGuid, GuidAttr=Attribute, + GuidHdrLen=HeaderLength, IsMakefile=IsMakefile) + + OutputFileList = [] + OutputFileList.append(OutputFile) + if 'PROCESSING_REQUIRED' in Attribute: + # reset guided section alignment to none for the processed required guided data + self.Alignment = None + self.IncludeFvSection = False + self.ProcessRequired = "TRUE" + if IsMakefile and self.Alignment is not None and self.Alignment.strip() == '0': + self.Alignment = '1' + return OutputFileList, self.Alignment + + + |