BaseTools: enable FixedAtBuild (VOID*) PCD use in the [DEPEX] section
authorYunhua Feng <yunhuax.feng@intel.com>
Fri, 13 Jul 2018 09:05:20 +0000 (17:05 +0800)
committerYonghong Zhu <yonghong.zhu@intel.com>
Mon, 23 Jul 2018 00:56:37 +0000 (08:56 +0800)
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 <liming.gao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Yunhua Feng <yunhuax.feng@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
BaseTools/Source/Python/AutoGen/AutoGen.py
BaseTools/Source/Python/AutoGen/GenDepex.py
BaseTools/Source/Python/Workspace/InfBuildData.py
BaseTools/Source/Python/build/BuildReport.py

index a7af33d..06ff84b 100644 (file)
@@ -2752,6 +2752,10 @@ class ModuleAutoGen(AutoGen):
         self._FixedAtBuildPcds         = []\r
         self.ConstPcd                  = {}\r
 \r
+        ##Store the VOID* type FixedAtBuild Pcds\r
+        #\r
+        self._FixedPcdVoidTypeDict = {}\r
+\r
     def __repr__(self):\r
         return "%s [%s]" % (self.MetaFile, self.Arch)\r
 \r
@@ -2767,6 +2771,15 @@ class ModuleAutoGen(AutoGen):
 \r
         return self._FixedAtBuildPcds\r
 \r
+    def _GetFixedAtBuildVoidTypePcds(self):\r
+        if self._FixedPcdVoidTypeDict:\r
+            return self._FixedPcdVoidTypeDict\r
+        for Pcd in self.ModulePcdList:\r
+            if Pcd.Type == TAB_PCDS_FIXED_AT_BUILD and Pcd.DatumType == TAB_VOID:\r
+                if '{}.{}'.format(Pcd.TokenSpaceGuidCName, Pcd.TokenCName) not in self._FixedPcdVoidTypeDict:\r
+                    self._FixedPcdVoidTypeDict['{}.{}'.format(Pcd.TokenSpaceGuidCName, Pcd.TokenCName)] = Pcd.DefaultValue\r
+        return self._FixedPcdVoidTypeDict\r
+\r
     def _GetUniqueBaseName(self):\r
         BaseName = self.Name\r
         for Module in self.PlatformInfo.ModuleAutoGenList:\r
@@ -3036,7 +3049,7 @@ class ModuleAutoGen(AutoGen):
                 return self._DepexDict\r
 \r
             self._DepexDict[self.ModuleType] = []\r
-\r
+            self._GetFixedAtBuildVoidTypePcds()\r
             for ModuleType in self._DepexDict:\r
                 DepexList = self._DepexDict[ModuleType]\r
                 #\r
@@ -3048,7 +3061,21 @@ class ModuleAutoGen(AutoGen):
                         if DepexList != []:\r
                             DepexList.append('AND')\r
                         DepexList.append('(')\r
-                        DepexList.extend(D)\r
+                        #replace D with value if D is FixedAtBuild PCD\r
+                        NewList = []\r
+                        for item in D:\r
+                            if '.' not in item:\r
+                                NewList.append(item)\r
+                            else:\r
+                                if item not in self._FixedPcdVoidTypeDict:\r
+                                    EdkLogger.error("build", FORMAT_INVALID, "{} used in [Depex] section should be used as FixedAtBuild type and VOID* datum type in the module.".format(item))\r
+                                else:\r
+                                    Value = self._FixedPcdVoidTypeDict[item]\r
+                                    if len(Value.split(',')) != 16:\r
+                                        EdkLogger.error("build", FORMAT_INVALID,\r
+                                                        "{} used in [Depex] section should be used as FixedAtBuild type and VOID* datum type and 16 bytes in the module.".format(item))\r
+                                    NewList.append(Value)\r
+                        DepexList.extend(NewList)\r
                         if DepexList[-1] == 'END':  # no need of a END at this time\r
                             DepexList.pop()\r
                         DepexList.append(')')\r
@@ -4420,6 +4447,7 @@ class ModuleAutoGen(AutoGen):
 \r
     FixedAtBuildPcds         = property(_GetFixedAtBuildPcds)\r
     UniqueBaseName          = property(_GetUniqueBaseName)\r
+    FixedVoidTypePcds       = property(_GetFixedAtBuildVoidTypePcds)\r
 \r
 # This acts like the main() function for the script, unless it is 'import'ed into another script.\r
 if __name__ == '__main__':\r
index d3b1eae..c12b613 100644 (file)
@@ -22,6 +22,8 @@ from struct import pack
 from Common.BuildToolError import *\r
 from Common.Misc import SaveFileOnChange\r
 from Common.Misc import GuidStructureStringToGuidString\r
+from Common.Misc import GuidStructureByteArrayToGuidString\r
+from Common.Misc import GuidStringToGuidStructureString\r
 from Common import EdkLogger as EdkLogger\r
 from Common.BuildVersion import gBUILD_VERSION\r
 from Common.DataType import *\r
@@ -333,6 +335,10 @@ class DependencyExpression:
     def GetGuidValue(self, Guid):\r
         GuidValueString = Guid.replace("{", "").replace("}", "").replace(" ", "")\r
         GuidValueList = GuidValueString.split(",")\r
+        if len(GuidValueList) != 11 and len(GuidValueList) == 16:\r
+            GuidValueString = GuidStringToGuidStructureString(GuidStructureByteArrayToGuidString(Guid))\r
+            GuidValueString = GuidValueString.replace("{", "").replace("}", "").replace(" ", "")\r
+            GuidValueList = GuidValueString.split(",")\r
         if len(GuidValueList) != 11:\r
             EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid GUID value string or opcode: %s" % Guid)\r
         return pack("1I2H8B", *(int(value, 16) for value in GuidValueList))\r
index f79ffe2..29e68ae 100644 (file)
@@ -912,12 +912,22 @@ class InfBuildData(ModuleBuildClassObject):
                                             ExtraData=Token, File=self.MetaFile, Line=Record[-1])\r
                         DepexList.append(Module.Guid)\r
                     else:\r
-                        # get the GUID value now\r
-                        Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)\r
-                        if Value is None:\r
-                            Value = PpiValue(Token, self.Packages, self.MetaFile.Path)\r
+                        # it use the Fixed PCD format\r
+                        if '.' in Token:\r
+                            if tuple(Token.split('.')[::-1]) not in self.Pcds:\r
+                                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])\r
+                            else:\r
+                                if self.Pcds[tuple(Token.split('.')[::-1])].DatumType != TAB_VOID:\r
+                                    EdkLogger.error('build', FORMAT_INVALID, "PCD [{}] used in [Depex] section should be VOID* datum type".format(Token), File=self.MetaFile, Line=Record[-1])\r
+                            Value = Token\r
+                        else:\r
+                            # get the GUID value now\r
+                            Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)\r
                             if Value is None:\r
-                                Value = GuidValue(Token, self.Packages, self.MetaFile.Path)\r
+                                Value = PpiValue(Token, self.Packages, self.MetaFile.Path)\r
+                                if Value is None:\r
+                                    Value = GuidValue(Token, self.Packages, self.MetaFile.Path)\r
+\r
                         if Value is None:\r
                             PackageList = "\n\t".join(str(P) for P in self.Packages)\r
                             EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
index 273e7d4..176a390 100644 (file)
@@ -280,7 +280,12 @@ class DepexParser(object):
                 for Guid in Package.Guids:\r
                     GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid])\r
                     self._GuidDb[GuidValue.upper()] = Guid\r
-\r
+            for Ma in Pa.ModuleAutoGenList:\r
+                for Pcd in Ma.FixedVoidTypePcds:\r
+                    PcdValue = Ma.FixedVoidTypePcds[Pcd]\r
+                    if len(PcdValue.split(',')) == 16:\r
+                        GuidValue = GuidStructureByteArrayToGuidString(PcdValue)\r
+                        self._GuidDb[GuidValue.upper()] = Pcd\r
     ##\r
     # Parse the binary dependency expression files.\r
     #\r