]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools: support private package definition
authorYonghong Zhu <yonghong.zhu@intel.com>
Tue, 10 May 2016 09:58:26 +0000 (17:58 +0800)
committerYonghong Zhu <yonghong.zhu@intel.com>
Wed, 18 May 2016 00:59:30 +0000 (08:59 +0800)
EDKII build spec and DEC spec updated to support private package
definition.
If GUID, Protocol or PPI is listed in a DEC file, where the  Private
modifier is used in the section tag ([Guids.common.Private] for example),
only modules within the package are permitted to use the GUID, Protocol
or PPI. If a module or library instance outside of the package attempts
to use the item, the build must fail with an appropriate error message.

Cc: Liming Gao <liming.gao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
BaseTools/Source/Python/AutoGen/AutoGen.py
BaseTools/Source/Python/Common/Misc.py
BaseTools/Source/Python/Workspace/MetaFileParser.py
BaseTools/Source/Python/Workspace/MetaFileTable.py
BaseTools/Source/Python/Workspace/WorkspaceDatabase.py

index 0664101008a8c83f68a7a1e1e9fe57aa82bdc939..8da441f6b9cb4f3d67bcd236a98d493b37c26501 100644 (file)
@@ -2174,7 +2174,7 @@ class PlatformAutoGen(AutoGen):
             for SkuId in PcdInModule.SkuInfoList:\r
                 Sku = PcdInModule.SkuInfoList[SkuId]\r
                 if Sku.VariableGuid == '': continue\r
-                Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList)\r
+                Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList, self.MetaFile.Path)\r
                 if Sku.VariableGuidValue == None:\r
                     PackageList = "\n\t".join([str(P) for P in self.PackageList])\r
                     EdkLogger.error(\r
@@ -3395,7 +3395,11 @@ class ModuleAutoGen(AutoGen):
                 PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir)\r
                 if PackageDir not in self._IncludePathList:\r
                     self._IncludePathList.append(PackageDir)\r
-                for Inc in Package.Includes:\r
+                IncludesList = Package.Includes\r
+                if Package._PrivateIncludes:\r
+                    if not self.MetaFile.Path.startswith(PackageDir):\r
+                        IncludesList = list(set(Package.Includes).difference(set(Package._PrivateIncludes)))\r
+                for Inc in IncludesList:\r
                     if Inc not in self._IncludePathList:\r
                         self._IncludePathList.append(str(Inc))\r
         return self._IncludePathList\r
@@ -3462,7 +3466,7 @@ class ModuleAutoGen(AutoGen):
             for SkuName in Pcd.SkuInfoList:\r
                 SkuInfo = Pcd.SkuInfoList[SkuName]\r
                 Name = ConvertStringToByteArray(SkuInfo.VariableName)\r
-                Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList)\r
+                Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList, self.MetaFile.Path)\r
                 if not Value:\r
                     continue\r
                 Guid = GuidStructureStringToGuidString(Value)\r
index 777450d81860a1e9e92daf9d9405c68315a82eba..c99716da7d950a674d6b2cf0a7daeb520f629563 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Common routines used by all tools\r
 #\r
-# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -794,13 +794,18 @@ def GetRelPath(Path1, Path2):
 #\r
 #   @param      CName           The CName of the GUID\r
 #   @param      PackageList     List of packages looking-up in\r
+#   @param      Inffile         The driver file\r
 #\r
 #   @retval     GuidValue   if the CName is found in any given package\r
 #   @retval     None        if the CName is not found in all given packages\r
 #\r
-def GuidValue(CName, PackageList):\r
+def GuidValue(CName, PackageList, Inffile = None):\r
     for P in PackageList:\r
-        if CName in P.Guids:\r
+        GuidKeys = P.Guids.keys()\r
+        if Inffile and P._PrivateGuids:\r
+            if not Inffile.startswith(P.MetaFile.Dir):\r
+                GuidKeys = (dict.fromkeys(x for x in P.Guids if x not in P._PrivateGuids)).keys()\r
+        if CName in GuidKeys:\r
             return P.Guids[CName]\r
     return None\r
 \r
@@ -808,13 +813,18 @@ def GuidValue(CName, PackageList):
 #\r
 #   @param      CName           The CName of the GUID\r
 #   @param      PackageList     List of packages looking-up in\r
+#   @param      Inffile         The driver file\r
 #\r
 #   @retval     GuidValue   if the CName is found in any given package\r
 #   @retval     None        if the CName is not found in all given packages\r
 #\r
-def ProtocolValue(CName, PackageList):\r
+def ProtocolValue(CName, PackageList, Inffile = None):\r
     for P in PackageList:\r
-        if CName in P.Protocols:\r
+        ProtocolKeys = P.Protocols.keys()\r
+        if Inffile and P._PrivateProtocols:\r
+            if not Inffile.startswith(P.MetaFile.Dir):\r
+                ProtocolKeys = (dict.fromkeys(x for x in P.Protocols if x not in P._PrivateProtocols)).keys()\r
+        if CName in ProtocolKeys:\r
             return P.Protocols[CName]\r
     return None\r
 \r
@@ -822,13 +832,18 @@ def ProtocolValue(CName, PackageList):
 #\r
 #   @param      CName           The CName of the GUID\r
 #   @param      PackageList     List of packages looking-up in\r
+#   @param      Inffile         The driver file\r
 #\r
 #   @retval     GuidValue   if the CName is found in any given package\r
 #   @retval     None        if the CName is not found in all given packages\r
 #\r
-def PpiValue(CName, PackageList):\r
+def PpiValue(CName, PackageList, Inffile = None):\r
     for P in PackageList:\r
-        if CName in P.Ppis:\r
+        PpiKeys = P.Ppis.keys()\r
+        if Inffile and P._PrivatePpis:\r
+            if not Inffile.startswith(P.MetaFile.Dir):\r
+                PpiKeys = (dict.fromkeys(x for x in P.Ppis if x not in P._PrivatePpis)).keys()\r
+        if CName in PpiKeys:\r
             return P.Ppis[CName]\r
     return None\r
 \r
index 209f47c9ebda7f3792d867ac7f988de76e5b2f06..82d874f8ddf99264fe5129a56debc14f282bf2af 100644 (file)
@@ -1722,6 +1722,7 @@ class DecParser(MetaFileParser):
         self._SectionName = ''\r
         self._SectionType = []\r
         ArchList = set()\r
+        PrivateList = set()\r
         Line = self._CurrentLine.replace("%s%s" % (TAB_COMMA_SPLIT, TAB_SPACE_SPLIT), TAB_COMMA_SPLIT)\r
         for Item in Line[1:-1].split(TAB_COMMA_SPLIT):\r
             if Item == '':\r
@@ -1757,8 +1758,14 @@ class DecParser(MetaFileParser):
             # S2 may be Platform or ModuleType\r
             if len(ItemList) > 2:\r
                 S2 = ItemList[2].upper()\r
+                # only Includes, GUIDs, PPIs, Protocols section have Private tag\r
+                if self._SectionName in [TAB_INCLUDES.upper(), TAB_GUIDS.upper(), TAB_PROTOCOLS.upper(), TAB_PPIS.upper()]:\r
+                    if S2 != 'PRIVATE':\r
+                        EdkLogger.error("Parser", FORMAT_INVALID, 'Please use keyword "Private" as section tag modifier.',\r
+                                        File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)\r
             else:\r
                 S2 = 'COMMON'\r
+            PrivateList.add(S2)\r
             if [S1, S2, self.DataType[self._SectionName]] not in self._Scope:\r
                 self._Scope.append([S1, S2, self.DataType[self._SectionName]])\r
 \r
@@ -1767,6 +1774,11 @@ class DecParser(MetaFileParser):
             EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",\r
                             File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)\r
 \r
+        # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute\r
+        if 'COMMON' in PrivateList and len(PrivateList) > 1:\r
+            EdkLogger.error('Parser', FORMAT_INVALID, "Can't mix section tags without the Private attribute with section tags with the Private attribute",\r
+                            File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)\r
+\r
     ## [guids], [ppis] and [protocols] section parser\r
     @ParseMacro\r
     def _GuidParser(self):\r
index 449e56efcc16408b89faafe41cbb8c906ca760da..ab1807046e49b25087f7105139741b6c8253319d 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to create/update/query/erase a meta file table\r
 #\r
-# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -218,7 +218,7 @@ class PackageTable(MetaFileTable):
     #\r
     def Query(self, Model, Arch=None):\r
         ConditionString = "Model=%s AND Enabled>=0" % Model\r
-        ValueString = "Value1,Value2,Value3,Scope1,ID,StartLine"\r
+        ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"\r
 \r
         if Arch != None and Arch != 'COMMON':\r
             ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch\r
index 7cd00046888303f9aef35abfde1cb4348d4504ad..5168e838a8bc08657833607e8dbc76ca612ac9b4 100644 (file)
@@ -1328,6 +1328,10 @@ class DecBuildData(PackageBuildClassObject):
         self._LibraryClasses    = None\r
         self._Pcds              = None\r
         self.__Macros           = None\r
+        self._PrivateProtocols  = None\r
+        self._PrivatePpis       = None\r
+        self._PrivateGuids      = None\r
+        self._PrivateIncludes   = None\r
 \r
     ## Get current effective macros\r
     def _GetMacros(self):\r
@@ -1402,21 +1406,30 @@ class DecBuildData(PackageBuildClassObject):
             # protocol defition for given ARCH\r
             #\r
             ProtocolDict = tdict(True)\r
+            PrivateProtocolDict = tdict(True)\r
             NameList = []\r
+            PrivateNameList = []\r
             # find out all protocol definitions for specific and 'common' arch\r
             RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]\r
-            for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
+            for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
+                if PrivateFlag == 'PRIVATE':\r
+                    if Name not in PrivateNameList:\r
+                        PrivateNameList.append(Name)\r
+                        PrivateProtocolDict[Arch, Name] = Guid\r
                 if Name not in NameList:\r
                     NameList.append(Name)\r
                 ProtocolDict[Arch, Name] = Guid\r
             # use sdict to keep the order\r
             self._Protocols = sdict()\r
+            self._PrivateProtocols = sdict()\r
             for Name in NameList:\r
                 #\r
                 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
                 # will automatically turn to 'common' ARCH for trying\r
                 #\r
                 self._Protocols[Name] = ProtocolDict[self._Arch, Name]\r
+            for Name in PrivateNameList:\r
+                self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name]\r
         return self._Protocols\r
 \r
     ## Retrieve PPI definitions (name/value pairs)\r
@@ -1427,21 +1440,30 @@ class DecBuildData(PackageBuildClassObject):
             # PPI defition for given ARCH\r
             #\r
             PpiDict = tdict(True)\r
+            PrivatePpiDict = tdict(True)\r
             NameList = []\r
+            PrivateNameList = []\r
             # find out all PPI definitions for specific arch and 'common' arch\r
             RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]\r
-            for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
+            for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
+                if PrivateFlag == 'PRIVATE':\r
+                    if Name not in PrivateNameList:\r
+                        PrivateNameList.append(Name)\r
+                        PrivatePpiDict[Arch, Name] = Guid\r
                 if Name not in NameList:\r
                     NameList.append(Name)\r
                 PpiDict[Arch, Name] = Guid\r
             # use sdict to keep the order\r
             self._Ppis = sdict()\r
+            self._PrivatePpis = sdict()\r
             for Name in NameList:\r
                 #\r
                 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
                 # will automatically turn to 'common' ARCH for trying\r
                 #\r
                 self._Ppis[Name] = PpiDict[self._Arch, Name]\r
+            for Name in PrivateNameList:\r
+                self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name]\r
         return self._Ppis\r
 \r
     ## Retrieve GUID definitions (name/value pairs)\r
@@ -1452,27 +1474,37 @@ class DecBuildData(PackageBuildClassObject):
             # GUID defition for given ARCH\r
             #\r
             GuidDict = tdict(True)\r
+            PrivateGuidDict = tdict(True)\r
             NameList = []\r
+            PrivateNameList = []\r
             # find out all protocol definitions for specific and 'common' arch\r
             RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]\r
-            for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:\r
+            for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
+                if PrivateFlag == 'PRIVATE':\r
+                    if Name not in PrivateNameList:\r
+                        PrivateNameList.append(Name)\r
+                        PrivateGuidDict[Arch, Name] = Guid\r
                 if Name not in NameList:\r
                     NameList.append(Name)\r
                 GuidDict[Arch, Name] = Guid\r
             # use sdict to keep the order\r
             self._Guids = sdict()\r
+            self._PrivateGuids = sdict()\r
             for Name in NameList:\r
                 #\r
                 # limit the ARCH to self._Arch, if no self._Arch found, tdict\r
                 # will automatically turn to 'common' ARCH for trying\r
                 #\r
                 self._Guids[Name] = GuidDict[self._Arch, Name]\r
+            for Name in PrivateNameList:\r
+                self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name]\r
         return self._Guids\r
 \r
     ## Retrieve public include paths declared in this package\r
     def _GetInclude(self):\r
         if self._Includes == None:\r
             self._Includes = []\r
+            self._PrivateIncludes = []\r
             RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]\r
             Macros = self._Macros\r
             Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
@@ -1487,6 +1519,9 @@ class DecBuildData(PackageBuildClassObject):
                 # avoid duplicate include path\r
                 if File not in self._Includes:\r
                     self._Includes.append(File)\r
+                if Record[4] == 'PRIVATE':\r
+                    if File not in self._PrivateIncludes:\r
+                        self._PrivateIncludes.append(File)\r
         return self._Includes\r
 \r
     ## Retrieve library class declarations (not used in build at present)\r
@@ -1500,7 +1535,7 @@ class DecBuildData(PackageBuildClassObject):
             LibraryClassSet = set()\r
             RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]\r
             Macros = self._Macros\r
-            for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList:\r
+            for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:\r
                 File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)\r
                 # check the file validation\r
                 ErrorCode, ErrorInfo = File.Validate()\r
@@ -1536,7 +1571,7 @@ class DecBuildData(PackageBuildClassObject):
         PcdSet = set()\r
         # find out all PCDs of the 'type'\r
         RecordList = self._RawData[Type, self._Arch]\r
-        for TokenSpaceGuid, PcdCName, Setting, Arch, Dummy1, Dummy2 in RecordList:\r
+        for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:\r
             PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting\r
             PcdSet.add((PcdCName, TokenSpaceGuid))\r
 \r
@@ -2275,7 +2310,7 @@ class InfBuildData(ModuleBuildClassObject):
             RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 CName = Record[0]\r
-                Value = ProtocolValue(CName, self.Packages)\r
+                Value = ProtocolValue(CName, self.Packages, self.MetaFile.Path)\r
                 if Value == None:\r
                     PackageList = "\n\t".join([str(P) for P in self.Packages])\r
                     EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
@@ -2300,7 +2335,7 @@ class InfBuildData(ModuleBuildClassObject):
             RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 CName = Record[0]\r
-                Value = PpiValue(CName, self.Packages)\r
+                Value = PpiValue(CName, self.Packages, self.MetaFile.Path)\r
                 if Value == None:\r
                     PackageList = "\n\t".join([str(P) for P in self.Packages])\r
                     EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
@@ -2325,7 +2360,7 @@ class InfBuildData(ModuleBuildClassObject):
             RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 CName = Record[0]\r
-                Value = GuidValue(CName, self.Packages)\r
+                Value = GuidValue(CName, self.Packages, self.MetaFile.Path)\r
                 if Value == None:\r
                     PackageList = "\n\t".join([str(P) for P in self.Packages])\r
                     EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
@@ -2494,11 +2529,11 @@ class InfBuildData(ModuleBuildClassObject):
                         DepexList.append(Module.Guid)\r
                     else:\r
                         # get the GUID value now\r
-                        Value = ProtocolValue(Token, self.Packages)\r
+                        Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)\r
                         if Value == None:\r
-                            Value = PpiValue(Token, self.Packages)\r
+                            Value = PpiValue(Token, self.Packages, self.MetaFile.Path)\r
                             if Value == None:\r
-                                Value = GuidValue(Token, self.Packages)\r
+                                Value = GuidValue(Token, self.Packages, self.MetaFile.Path)\r
                         if Value == None:\r
                             PackageList = "\n\t".join([str(P) for P in self.Packages])\r
                             EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r
@@ -2541,7 +2576,7 @@ class InfBuildData(ModuleBuildClassObject):
             PcdList.append((PcdCName, TokenSpaceGuid))\r
             # get the guid value\r
             if TokenSpaceGuid not in self.Guids:\r
-                Value = GuidValue(TokenSpaceGuid, self.Packages)\r
+                Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)\r
                 if Value == None:\r
                     PackageList = "\n\t".join([str(P) for P in self.Packages])\r
                     EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,\r