From a10def91653163dbc6a38a609a87b370e9035654 Mon Sep 17 00:00:00 2001 From: Yunhua Feng Date: Fri, 13 Jul 2018 17:05:20 +0800 Subject: [PATCH] BaseTools: enable FixedAtBuild (VOID*) PCD use in the [DEPEX] section V3: Add some invalid type and datum check V2: limit the PCD used in the [Depex] section should be used in the module The PCD item used in INF [Depex] section must be defined as FixedAtBuild type and VOID* datum type, and the size of the PCD must be 16 bytes. Fixes: https://bugzilla.tianocore.org/show_bug.cgi?id=443 Cc: Liming Gao Cc: Yonghong Zhu Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Yunhua Feng Reviewed-by: Yonghong Zhu --- BaseTools/Source/Python/AutoGen/AutoGen.py | 32 +++++++++++++++++-- BaseTools/Source/Python/AutoGen/GenDepex.py | 6 ++++ .../Source/Python/Workspace/InfBuildData.py | 20 +++++++++--- BaseTools/Source/Python/build/BuildReport.py | 7 +++- 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py index a7af33d520..06ff84b4cd 100644 --- a/BaseTools/Source/Python/AutoGen/AutoGen.py +++ b/BaseTools/Source/Python/AutoGen/AutoGen.py @@ -2752,6 +2752,10 @@ class ModuleAutoGen(AutoGen): self._FixedAtBuildPcds = [] self.ConstPcd = {} + ##Store the VOID* type FixedAtBuild Pcds + # + self._FixedPcdVoidTypeDict = {} + def __repr__(self): return "%s [%s]" % (self.MetaFile, self.Arch) @@ -2767,6 +2771,15 @@ class ModuleAutoGen(AutoGen): return self._FixedAtBuildPcds + def _GetFixedAtBuildVoidTypePcds(self): + if self._FixedPcdVoidTypeDict: + return self._FixedPcdVoidTypeDict + for Pcd in self.ModulePcdList: + if Pcd.Type == TAB_PCDS_FIXED_AT_BUILD and Pcd.DatumType == TAB_VOID: + if '{}.{}'.format(Pcd.TokenSpaceGuidCName, Pcd.TokenCName) not in self._FixedPcdVoidTypeDict: + self._FixedPcdVoidTypeDict['{}.{}'.format(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)] = Pcd.DefaultValue + return self._FixedPcdVoidTypeDict + def _GetUniqueBaseName(self): BaseName = self.Name for Module in self.PlatformInfo.ModuleAutoGenList: @@ -3036,7 +3049,7 @@ class ModuleAutoGen(AutoGen): return self._DepexDict self._DepexDict[self.ModuleType] = [] - + self._GetFixedAtBuildVoidTypePcds() for ModuleType in self._DepexDict: DepexList = self._DepexDict[ModuleType] # @@ -3048,7 +3061,21 @@ class ModuleAutoGen(AutoGen): if DepexList != []: DepexList.append('AND') DepexList.append('(') - DepexList.extend(D) + #replace D with value if D is FixedAtBuild PCD + NewList = [] + for item in D: + if '.' not in item: + NewList.append(item) + else: + if item not in self._FixedPcdVoidTypeDict: + EdkLogger.error("build", FORMAT_INVALID, "{} used in [Depex] section should be used as FixedAtBuild type and VOID* datum type in the module.".format(item)) + else: + Value = self._FixedPcdVoidTypeDict[item] + if len(Value.split(',')) != 16: + EdkLogger.error("build", FORMAT_INVALID, + "{} used in [Depex] section should be used as FixedAtBuild type and VOID* datum type and 16 bytes in the module.".format(item)) + NewList.append(Value) + DepexList.extend(NewList) if DepexList[-1] == 'END': # no need of a END at this time DepexList.pop() DepexList.append(')') @@ -4420,6 +4447,7 @@ class ModuleAutoGen(AutoGen): FixedAtBuildPcds = property(_GetFixedAtBuildPcds) UniqueBaseName = property(_GetUniqueBaseName) + FixedVoidTypePcds = property(_GetFixedAtBuildVoidTypePcds) # This acts like the main() function for the script, unless it is 'import'ed into another script. if __name__ == '__main__': diff --git a/BaseTools/Source/Python/AutoGen/GenDepex.py b/BaseTools/Source/Python/AutoGen/GenDepex.py index d3b1eae181..c12b6139e1 100644 --- a/BaseTools/Source/Python/AutoGen/GenDepex.py +++ b/BaseTools/Source/Python/AutoGen/GenDepex.py @@ -22,6 +22,8 @@ from struct import pack from Common.BuildToolError import * from Common.Misc import SaveFileOnChange from Common.Misc import GuidStructureStringToGuidString +from Common.Misc import GuidStructureByteArrayToGuidString +from Common.Misc import GuidStringToGuidStructureString from Common import EdkLogger as EdkLogger from Common.BuildVersion import gBUILD_VERSION from Common.DataType import * @@ -333,6 +335,10 @@ class DependencyExpression: def GetGuidValue(self, Guid): GuidValueString = Guid.replace("{", "").replace("}", "").replace(" ", "") GuidValueList = GuidValueString.split(",") + if len(GuidValueList) != 11 and len(GuidValueList) == 16: + GuidValueString = GuidStringToGuidStructureString(GuidStructureByteArrayToGuidString(Guid)) + GuidValueString = GuidValueString.replace("{", "").replace("}", "").replace(" ", "") + GuidValueList = GuidValueString.split(",") if len(GuidValueList) != 11: EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid GUID value string or opcode: %s" % Guid) return pack("1I2H8B", *(int(value, 16) for value in GuidValueList)) diff --git a/BaseTools/Source/Python/Workspace/InfBuildData.py b/BaseTools/Source/Python/Workspace/InfBuildData.py index f79ffe28d8..29e68aeb3b 100644 --- a/BaseTools/Source/Python/Workspace/InfBuildData.py +++ b/BaseTools/Source/Python/Workspace/InfBuildData.py @@ -912,12 +912,22 @@ class InfBuildData(ModuleBuildClassObject): ExtraData=Token, File=self.MetaFile, Line=Record[-1]) DepexList.append(Module.Guid) else: - # get the GUID value now - Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path) - if Value is None: - Value = PpiValue(Token, self.Packages, self.MetaFile.Path) + # it use the Fixed PCD format + if '.' in Token: + if tuple(Token.split('.')[::-1]) not in self.Pcds: + EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "PCD [{}] used in [Depex] section should be listed in module PCD section".format(Token), File=self.MetaFile, Line=Record[-1]) + else: + if self.Pcds[tuple(Token.split('.')[::-1])].DatumType != TAB_VOID: + EdkLogger.error('build', FORMAT_INVALID, "PCD [{}] used in [Depex] section should be VOID* datum type".format(Token), File=self.MetaFile, Line=Record[-1]) + Value = Token + else: + # get the GUID value now + Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path) if Value is None: - Value = GuidValue(Token, self.Packages, self.MetaFile.Path) + Value = PpiValue(Token, self.Packages, self.MetaFile.Path) + if Value is None: + Value = GuidValue(Token, self.Packages, self.MetaFile.Path) + if Value is None: PackageList = "\n\t".join(str(P) for P in self.Packages) EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py index 273e7d41b8..176a390fa3 100644 --- a/BaseTools/Source/Python/build/BuildReport.py +++ b/BaseTools/Source/Python/build/BuildReport.py @@ -280,7 +280,12 @@ class DepexParser(object): for Guid in Package.Guids: GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid]) self._GuidDb[GuidValue.upper()] = Guid - + for Ma in Pa.ModuleAutoGenList: + for Pcd in Ma.FixedVoidTypePcds: + PcdValue = Ma.FixedVoidTypePcds[Pcd] + if len(PcdValue.split(',')) == 16: + GuidValue = GuidStructureByteArrayToGuidString(PcdValue) + self._GuidDb[GuidValue.upper()] = Pcd ## # Parse the binary dependency expression files. # -- 2.39.2