[edk2-devel] [Patch V2] BaseTools: Correct the value assignment for StructurePcd

Fan, ZhijuX posted 1 patch 4 years, 11 months ago
Failed in applying to current master (apply log)
There is a newer version of this series
BaseTools/Source/Python/Common/Misc.py        |   1 +
.../Python/Workspace/BuildClassObject.py      |  78 ++++---
.../Source/Python/Workspace/DecBuildData.py   |   2 +-
.../Source/Python/Workspace/DscBuildData.py   | 211 ++++++++++++++----
4 files changed, 218 insertions(+), 74 deletions(-)
[edk2-devel] [Patch V2] BaseTools: Correct the value assignment for StructurePcd
Posted by Fan, ZhijuX 4 years, 11 months ago
BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=1752

This patch is to fix the code bug in StructurePcd overall
value assignment logic. If a Pcd Array size is fixed but the
size of actual value in Dsc or Dec is bigger than the Pcd
array size, the tool will report error about such setting and
stop build.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
---
 BaseTools/Source/Python/Common/Misc.py        |   1 +
 .../Python/Workspace/BuildClassObject.py      |  78 ++++---
 .../Source/Python/Workspace/DecBuildData.py   |   2 +-
 .../Source/Python/Workspace/DscBuildData.py   | 211 ++++++++++++++----
 4 files changed, 218 insertions(+), 74 deletions(-)

diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index c7daf5417c..526aa2dd54 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -40,10 +40,11 @@ from Common.Parsing import GetSplitValueList
 from Common.LongFilePathSupport import OpenLongFilePath as open
 from Common.MultipleWorkspace import MultipleWorkspace as mws
 from CommonDataClass.Exceptions import BadExpression
 from Common.caching import cached_property
 
+ArrayIndex = re.compile("\[\s*[0-9a-fA-FxX]*\s*\]")
 ## Regular expression used to find out place holders in string template
 gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)
 
 ## regular expressions for map file processing
 startPatternGeneral = re.compile("^Start[' ']+Length[' ']+Name[' ']+Class")
diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py
index b82af49236..b50e250cfb 100644
--- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
+++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
@@ -14,14 +14,16 @@
 from collections import OrderedDict, namedtuple
 from Common.DataType import *
 import collections
 import re
 from collections import OrderedDict
-from Common.Misc import CopyDict
+from Common.Misc import CopyDict,ArrayIndex
 import copy
+import Common.EdkLogger as EdkLogger
+from Common.BuildToolError import OPTION_VALUE_INVALID
 StructPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_\[\]]*$')
-ArrayIndex = re.compile("\[\s*[0-9a-fA-FxX]*\s*\]")
+
 ## PcdClassObject
 #
 # This Class is used for PcdObject
 #
 # @param object:             Inherited from object class
@@ -66,44 +68,62 @@ class PcdClassObject(object):
         self.validateranges = validateranges if validateranges is not None else []
         self.validlists = validlists if validlists is not None else []
         self.expressions = expressions if expressions is not None else []
         self.DscDefaultValue = None
         self.DscRawValue = {}
+        self.DscRawValueInfo = {}
         if IsDsc:
             self.DscDefaultValue = Value
         self.PcdValueFromComm = ""
         self.PcdValueFromFdf = ""
         self.CustomAttribute = {}
         self.UserDefinedDefaultStoresFlag = UserDefinedDefaultStoresFlag
         self._Capacity = None
 
     @property
     def Capacity(self):
-        self._Capacity = []
-        dimension = ArrayIndex.findall(self._DatumType)
-        for item in dimension:
-            maxsize = item.lstrip("[").rstrip("]").strip()
-            if not maxsize:
-                maxsize = "-1"
-            maxsize = str(int(maxsize,16)) if maxsize.startswith(("0x","0X")) else maxsize
-            self._Capacity.append(maxsize)
-        if hasattr(self, "SkuOverrideValues"):
-            for sku in self.SkuOverrideValues:
-                for defaultstore in self.SkuOverrideValues[sku]:
-                    fields = self.SkuOverrideValues[sku][defaultstore]
-                    for demesionattr in fields:
-                        deme = ArrayIndex.findall(demesionattr)
-                        for i in range(len(deme)-1):
-                            if int(deme[i].lstrip("[").rstrip("]").strip()) > int(self._Capacity[i]):
-                                print ("error")
-        if hasattr(self,"DefaultValues"):
-            for demesionattr in self.DefaultValues:
-                deme = ArrayIndex.findall(demesionattr)
-                for i in range(len(deme)-1):
-                    if int(deme[i].lstrip("[").rstrip("]").strip()) > int(self._Capacity[i]):
-                        print ("error")
+        if self._Capacity is None:
+            self._Capacity = []
+            dimension = ArrayIndex.findall(self._DatumType)
+            for item in dimension:
+                maxsize = item.lstrip("[").rstrip("]").strip()
+                if not maxsize:
+                    maxsize = "-1"
+                maxsize = str(int(maxsize,16)) if maxsize.startswith(("0x","0X")) else maxsize
+                self._Capacity.append(maxsize)
+            if hasattr(self, "SkuOverrideValues"):
+                for sku in self.SkuOverrideValues:
+                    for defaultstore in self.SkuOverrideValues[sku]:
+                        fields = self.SkuOverrideValues[sku][defaultstore]
+                        for demesionattr in fields:
+                            fieldinfo = fields[demesionattr]
+                            deme = ArrayIndex.findall(demesionattr)
+                            for i in range(len(deme)):
+                                if int(deme[i].lstrip("[").rstrip("]").strip()) >= int(self._Capacity[i]):
+                                    if self._Capacity[i] != "-1":
+                                        firstfieldinfo = list(fieldinfo.values())[0]
+                                        EdkLogger.error('Build', OPTION_VALUE_INVALID, "For Pcd %s, Array Index exceed the Array size. From %s Line %s \n " %
+                                    (".".join((self.TokenSpaceGuidCName, self.TokenCName)), firstfieldinfo[1],firstfieldinfo[2] ))
+            if hasattr(self,"DefaultValues"):
+                for demesionattr in self.DefaultValues:
+                    fieldinfo = self.DefaultValues[demesionattr]
+                    deme = ArrayIndex.findall(demesionattr)
+                    for i in range(len(deme)):
+                        if int(deme[i].lstrip("[").rstrip("]").strip()) >= int(self._Capacity[i]):
+                            if self._Capacity[i] != "-1":
+                                firstfieldinfo = list(fieldinfo.values())[0]
+                                EdkLogger.error('Build', OPTION_VALUE_INVALID, "For Pcd %s, Array Index exceed the Array size. From %s Line %s \n " %
+                                    (".".join((self.TokenSpaceGuidCName, self.TokenCName)), firstfieldinfo[1],firstfieldinfo[2] ))
         return self._Capacity
+
+    def PcdArraySize(self):
+        if self.Capacity[-1] == "-1":
+            return -1
+        size = 1
+        for de in self.Capacity:
+            size = size * int(de)
+        return size
     @property
     def DatumType(self):
         return self._DatumType
 
     @DatumType.setter
@@ -231,10 +251,11 @@ class PcdClassObject(object):
         new_pcd.IsFromDsc = self.IsFromDsc
         new_pcd.PcdValueFromComm = self.PcdValueFromComm
         new_pcd.PcdValueFromFdf = self.PcdValueFromFdf
         new_pcd.UserDefinedDefaultStoresFlag = self.UserDefinedDefaultStoresFlag
         new_pcd.DscRawValue = self.DscRawValue
+        new_pcd.DscRawValueInfo = self.DscRawValueInfo
         new_pcd.CustomAttribute = self.CustomAttribute
         new_pcd.validateranges = [item for item in self.validateranges]
         new_pcd.validlists = [item for item in self.validlists]
         new_pcd.expressions = [item for item in self.expressions]
         new_pcd.SkuInfoList = {key: copy.deepcopy(skuobj) for key,skuobj in self.SkuInfoList.items()}
@@ -266,10 +287,11 @@ class StructurePcd(PcdClassObject):
         self.SkuOverrideValues = OrderedDict()
         self.StructName = None
         self.PcdDefineLineNo = 0
         self.PkgPath = ""
         self.DefaultValueFromDec = ""
+        self.DefaultValueFromDecInfo = None
         self.ValueChain = set()
         self.PcdFieldValueFromComm = OrderedDict()
         self.PcdFieldValueFromFdf = OrderedDict()
         self.DefaultFromDSC=None
     def __repr__(self):
@@ -281,12 +303,13 @@ class StructurePcd(PcdClassObject):
         if FieldName in self.DefaultValues[DimensionAttr]:
             del self.DefaultValues[DimensionAttr][FieldName]
         self.DefaultValues[DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo]
         return self.DefaultValues[DimensionAttr][FieldName]
 
-    def SetDecDefaultValue(self, DefaultValue):
+    def SetDecDefaultValue(self, DefaultValue,decpath=None,lineno=None):
         self.DefaultValueFromDec = DefaultValue
+        self.DefaultValueFromDecInfo = (decpath,lineno)
     def AddOverrideValue (self, FieldName, Value, SkuName, DefaultStoreName, FileName="", LineNo=0, DimensionAttr = '-1'):
         if SkuName not in self.SkuOverrideValues:
             self.SkuOverrideValues[SkuName] = OrderedDict()
         if DefaultStoreName not in self.SkuOverrideValues[SkuName]:
             self.SkuOverrideValues[SkuName][DefaultStoreName] = OrderedDict()
@@ -317,20 +340,22 @@ class StructurePcd(PcdClassObject):
         self.IsFromDsc = PcdObject.IsFromDsc if PcdObject.IsFromDsc else self.IsFromDsc
         self.validateranges = PcdObject.validateranges if PcdObject.validateranges else self.validateranges
         self.validlists = PcdObject.validlists if PcdObject.validlists else self.validlists
         self.expressions = PcdObject.expressions if PcdObject.expressions else self.expressions
         self.DscRawValue = PcdObject.DscRawValue if PcdObject.DscRawValue else self.DscRawValue
+        self.DscRawValueInfo = PcdObject.DscRawValueInfo if PcdObject.DscRawValueInfo else self.DscRawValueInfo
         self.PcdValueFromComm = PcdObject.PcdValueFromComm if PcdObject.PcdValueFromComm else self.PcdValueFromComm
         self.PcdValueFromFdf = PcdObject.PcdValueFromFdf if PcdObject.PcdValueFromFdf else self.PcdValueFromFdf
         self.CustomAttribute = PcdObject.CustomAttribute if PcdObject.CustomAttribute else self.CustomAttribute
         self.UserDefinedDefaultStoresFlag = PcdObject.UserDefinedDefaultStoresFlag if PcdObject.UserDefinedDefaultStoresFlag else self.UserDefinedDefaultStoresFlag
         if isinstance(PcdObject, StructurePcd):
             self.StructuredPcdIncludeFile = PcdObject.StructuredPcdIncludeFile if PcdObject.StructuredPcdIncludeFile else self.StructuredPcdIncludeFile
             self.PackageDecs = PcdObject.PackageDecs if PcdObject.PackageDecs else self.PackageDecs
             self.DefaultValues = PcdObject.DefaultValues if PcdObject.DefaultValues else self.DefaultValues
             self.PcdMode = PcdObject.PcdMode if PcdObject.PcdMode else self.PcdMode
             self.DefaultValueFromDec = PcdObject.DefaultValueFromDec if PcdObject.DefaultValueFromDec else self.DefaultValueFromDec
+            self.DefaultValueFromDecInfo = PcdObject.DefaultValueFromDecInfo if PcdObject.DefaultValueFromDecInfo else self.DefaultValueFromDecInfo
             self.SkuOverrideValues = PcdObject.SkuOverrideValues if PcdObject.SkuOverrideValues else self.SkuOverrideValues
             self.StructName = PcdObject.DatumType if PcdObject.DatumType else self.StructName
             self.PcdDefineLineNo = PcdObject.PcdDefineLineNo if PcdObject.PcdDefineLineNo else self.PcdDefineLineNo
             self.PkgPath = PcdObject.PkgPath if PcdObject.PkgPath else self.PkgPath
             self.ValueChain = PcdObject.ValueChain if PcdObject.ValueChain else self.ValueChain
@@ -340,10 +365,11 @@ class StructurePcd(PcdClassObject):
     def __deepcopy__(self,memo):
         new_pcd = StructurePcd()
         self.sharedcopy(new_pcd)
 
         new_pcd.DefaultValueFromDec = self.DefaultValueFromDec
+        new_pcd.DefaultValueFromDecInfo = self.DefaultValueFromDecInfo
         new_pcd.PcdMode = self.PcdMode
         new_pcd.StructName = self.DatumType
         new_pcd.PcdDefineLineNo = self.PcdDefineLineNo
         new_pcd.PkgPath = self.PkgPath
         new_pcd.StructuredPcdIncludeFile = [item for item in self.StructuredPcdIncludeFile]
diff --git a/BaseTools/Source/Python/Workspace/DecBuildData.py b/BaseTools/Source/Python/Workspace/DecBuildData.py
index 149c057b70..ea0f816e27 100644
--- a/BaseTools/Source/Python/Workspace/DecBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DecBuildData.py
@@ -399,11 +399,11 @@ class DecBuildData(PackageBuildClassObject):
                     struct_pcd.copy(item)
                     struct_pcd.TokenValue = struct_pcd.TokenValue.strip("{").strip()
                     struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName = pcdname.split(".")
                     struct_pcd.PcdDefineLineNo = LineNo
                     struct_pcd.PkgPath = self.MetaFile.File
-                    struct_pcd.SetDecDefaultValue(item.DefaultValue)
+                    struct_pcd.SetDecDefaultValue(item.DefaultValue,self.MetaFile.File,LineNo)
                 else:
                     DemesionAttr, Fields = self.ParsePcdName(item.TokenCName)
                     struct_pcd.AddDefaultValue(Fields, item.DefaultValue, self.MetaFile.File, LineNo,DemesionAttr)
 
             struct_pcd.PackageDecs = dep_pkgs
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 1ffefe6e7e..7b8c9eedf6 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -31,21 +31,20 @@ from .MetaDataTable import *
 from .MetaFileTable import *
 from .MetaFileParser import *
 
 from .WorkspaceCommon import GetDeclaredPcd
 from Common.Misc import AnalyzeDscPcd
-from Common.Misc import ProcessDuplicatedInf,RemoveCComments
+from Common.Misc import ProcessDuplicatedInf,RemoveCComments,ArrayIndex
 import re
 from Common.Parsing import IsValidWord
 from Common.VariableAttributes import VariableAttributes
 import Common.GlobalData as GlobalData
 import subprocess
 from functools import reduce
 from Common.Misc import SaveFileOnChange
 from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
 from collections import OrderedDict, defaultdict
-from .BuildClassObject import ArrayIndex
 
 def _IsFieldValueAnArray (Value):
     Value = Value.strip()
     if Value.startswith(TAB_GUID) and Value.endswith(')'):
         return True
@@ -1681,21 +1680,21 @@ class DscBuildData(PlatformBuildClassObject):
                                     File=self.MetaFile, Line=Dummy4)
                 if int(MaxDatumSize, 0) < 0:
                     EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." % ".".join((TokenSpaceGuid, PcdCName)),
                                     File=self.MetaFile, Line=Dummy4)
             if (PcdCName, TokenSpaceGuid) in PcdValueDict:
-                PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)
+                PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize,Dummy4)
             else:
-                PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}
+                PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize,Dummy4)}
 
         for ((PcdCName, TokenSpaceGuid), PcdSetting) in PcdValueDict.items():
             if self.SkuIdMgr.SystemSkuId in PcdSetting:
-                PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]
+                PcdValue, DatumType, MaxDatumSize,_ = PcdSetting[self.SkuIdMgr.SystemSkuId]
             elif TAB_DEFAULT in PcdSetting:
-                PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_DEFAULT]
+                PcdValue, DatumType, MaxDatumSize,_  = PcdSetting[TAB_DEFAULT]
             elif TAB_COMMON in PcdSetting:
-                PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_COMMON]
+                PcdValue, DatumType, MaxDatumSize,_  = PcdSetting[TAB_COMMON]
             else:
                 PcdValue = None
                 DatumType = None
                 MaxDatumSize = None
 
@@ -1713,11 +1712,13 @@ class DscBuildData(PlatformBuildClassObject):
                                                 IsDsc=True)
             for SkuName in PcdValueDict[PcdCName, TokenSpaceGuid]:
                 Settings = PcdValueDict[PcdCName, TokenSpaceGuid][SkuName]
                 if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
                     Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
+                    Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
                 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = Settings[0]
+                Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Settings[3])
         return Pcds
 
     @staticmethod
     def GetStructurePcdMaxSize(str_pcd):
         pcd_default_value = str_pcd.DefaultValue
@@ -1766,28 +1767,45 @@ class DscBuildData(PlatformBuildClassObject):
         return Result
 
     def GenerateSizeFunction(self, Pcd):
         CApp = "// Default Value in Dec \n"
         CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
-        if Pcd.IsArray():
+
+        if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
+            CApp += "  *Size = (sizeof (%s) > *Size ? sizeof (%s) : *Size);\n" % (Pcd.DatumType,Pcd.DatumType)
+        else:
+            if "{CODE(" in Pcd.DefaultValueFromDec:
+                CApp += "  *Size = (sizeof (%s_%s_INIT_Value) > *Size ? sizeof (%s_%s_INIT_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Pcd.TokenSpaceGuidCName,Pcd.TokenCName)
             if Pcd.Type in PCD_DYNAMIC_TYPE_SET | PCD_DYNAMIC_EX_TYPE_SET:
                 for skuname in Pcd.SkuInfoList:
                     skuobj = Pcd.SkuInfoList[skuname]
                     if skuobj.VariableName:
                         for defaultstore in skuobj.DefaultStoreDict:
                             pcddef = self.GetPcdDscRawDefaultValue(Pcd,skuname,defaultstore)
-                            if pcddef and "{CODE(" in pcddef:
-                                CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore)
+                            if pcddef:
+                                if "{CODE(" in pcddef:
+                                    CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore)
+                                else:
+                                    CApp += "  *Size = %s > *Size ? %s : *Size;\n" % (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
                     else:
                         pcddef = self.GetPcdDscRawDefaultValue(Pcd,skuname,TAB_DEFAULT_STORES_DEFAULT)
-                        if pcddef and "{CODE(" in pcddef:
-                            CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT)
+                        if pcddef:
+                            if  "{CODE(" in pcddef:
+                                CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT)
+                            else:
+                                CApp += "  *Size = %s > *Size ? %s : *Size;\n" % (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
             else:
                 pcddef = self.GetPcdDscRawDefaultValue(Pcd,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT)
-                if pcddef and "{CODE(" in pcddef:
-                    CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT)
+                if pcddef:
+                    if "{CODE(" in pcddef:
+                        CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" % (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT)
+                    else:
+                        CApp += "  *Size = %s > *Size ? %s : *Size;\n" % (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
+        ActualCap = []
         for index in Pcd.DefaultValues:
+            if index:
+                ActualCap.append(index)
             FieldList = Pcd.DefaultValues[index]
             if not FieldList:
                 continue
             for FieldName in FieldList:
                 FieldName = "." + FieldName
@@ -1804,22 +1822,24 @@ class DscBuildData(PlatformBuildClassObject):
                 else:
                     NewFieldName = ''
                     FieldName_ori = FieldName.strip('.')
                     while '[' in  FieldName:
                         NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
-                        ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
+                        Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
                         FieldName = FieldName.split(']', 1)[1]
                     FieldName = NewFieldName + FieldName
                     while '[' in FieldName and not Pcd.IsArray:
                         FieldName = FieldName.rsplit('[', 1)[0]
-                        CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
+                        CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
         for skuname in Pcd.SkuOverrideValues:
             if skuname == TAB_COMMON:
                 continue
             for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
                 CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
                 for index in Pcd.SkuOverrideValues[skuname][defaultstorenameitem]:
+                    if index:
+                        ActualCap.append(index)
                     for FieldList in [Pcd.SkuOverrideValues[skuname][defaultstorenameitem][index]]:
                         if not FieldList:
                             continue
                         for FieldName in FieldList:
                             FieldName = "." + FieldName
@@ -1836,16 +1856,16 @@ class DscBuildData(PlatformBuildClassObject):
                             else:
                                 NewFieldName = ''
                                 FieldName_ori = FieldName.strip('.')
                                 while '[' in  FieldName:
                                     NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
-                                    ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
+                                    Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
                                     FieldName = FieldName.split(']', 1)[1]
                                 FieldName = NewFieldName + FieldName
                                 while '[' in FieldName and not Pcd.IsArray:
                                     FieldName = FieldName.rsplit('[', 1)[0]
-                                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
+                                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
         if Pcd.PcdFieldValueFromFdf:
             CApp = CApp + "// From fdf \n"
         for FieldName in Pcd.PcdFieldValueFromFdf:
             FieldName = "." + FieldName
             IsArray = _IsFieldValueAnArray(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0])
@@ -1861,16 +1881,16 @@ class DscBuildData(PlatformBuildClassObject):
             else:
                 NewFieldName = ''
                 FieldName_ori = FieldName.strip('.')
                 while '[' in  FieldName:
                     NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
-                    ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
+                    Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
                     FieldName = FieldName.split(']', 1)[1]
                 FieldName = NewFieldName + FieldName
                 while '[' in FieldName:
                     FieldName = FieldName.rsplit('[', 1)[0]
-                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %s Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromFdf[FieldName_ori][1], Pcd.PcdFieldValueFromFdf[FieldName_ori][2], Pcd.PcdFieldValueFromFdf[FieldName_ori][0])
+                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %s Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, Pcd.PcdFieldValueFromFdf[FieldName_ori][1], Pcd.PcdFieldValueFromFdf[FieldName_ori][2], Pcd.PcdFieldValueFromFdf[FieldName_ori][0])
         if Pcd.PcdFieldValueFromComm:
             CApp = CApp + "// From Command Line \n"
         for FieldName in Pcd.PcdFieldValueFromComm:
             FieldName = "." + FieldName
             IsArray = _IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
@@ -1886,20 +1906,41 @@ class DscBuildData(PlatformBuildClassObject):
             else:
                 NewFieldName = ''
                 FieldName_ori = FieldName.strip('.')
                 while '[' in  FieldName:
                     NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
-                    ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
+                    Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
                     FieldName = FieldName.split(']', 1)[1]
                 FieldName = NewFieldName + FieldName
                 while '[' in FieldName and not Pcd.IsArray:
                     FieldName = FieldName.rsplit('[', 1)[0]
-                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0])
+                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2], Pcd.PcdFieldValueFromComm[FieldName_ori][0])
         if Pcd.GetPcdMaxSize():
             CApp = CApp + "  *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize())
+        ArraySizeByAssign = self.CalculateActualCap(ActualCap)
+        if ArraySizeByAssign > 1:
+            CApp = CApp + "  *Size = (%d > *Size ? %d : *Size); \n" % (ArraySizeByAssign, ArraySizeByAssign)
         CApp = CApp + "}\n"
         return CApp
+    def CalculateActualCap(self,ActualCap):
+        if not ActualCap:
+            return 1
+        maxsize = 1
+        for item in ActualCap:
+            index_elements = ArrayIndex.findall(item)
+            rt = 1
+            for index_e in index_elements:
+                index_num = index_e.lstrip("[").rstrip("]").strip()
+                if not index_num:
+                    # Not support flexiable pcd array assignment
+                    return 1
+                index_num = int(index_num,16) if index_num.startswith(("0x","0X")) else int(index_num)
+                rt = rt * (index_num+1)
+            if rt  >maxsize:
+                maxsize = rt
+
+        return maxsize
 
     @staticmethod
     def GenerateSizeStatments(Pcd,skuname,defaultstorename):
         if Pcd.IsArray():
             r_datatype = [Pcd.BaseDatumType]
@@ -1974,10 +2015,11 @@ class DscBuildData(PlatformBuildClassObject):
     def GenerateDefaultValueAssignFunction(self, Pcd):
         CApp = "// Default value in Dec \n"
         CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.BaseDatumType)
         CApp = CApp + '  UINT32  FieldSize;\n'
         CApp = CApp + '  CHAR8   *Value;\n'
+        CApp = CApp + ' UINT32 PcdArraySize;\n'
         DefaultValueFromDec = Pcd.DefaultValueFromDec
         IsArray = _IsFieldValueAnArray(Pcd.DefaultValueFromDec)
         if IsArray:
             try:
                 DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, TAB_VOID)(True)
@@ -1985,18 +2027,33 @@ class DscBuildData(PlatformBuildClassObject):
                 EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %
                                 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))
         DefaultValueFromDec = StringToArray(DefaultValueFromDec)
         Value, ValueSize = ParseFieldValue (DefaultValueFromDec)
         if IsArray:
-        #
-        # Use memcpy() to copy value into field
-        #
-            if "{CODE(" in Pcd.DefaultValueFromDec:
-                CApp = CApp + '  memcpy (Pcd, %s_%s_INIT_Value, sizeof(%s_%s_INIT_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+            #
+            # Use memcpy() to copy value into field
+            #
+            if Pcd.IsArray():
+                pcdarraysize = Pcd.PcdArraySize()
+                if "{CODE(" in Pcd.DefaultValueFromDec:
+                    if Pcd.Capacity[-1] != "-1":
+                        CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_INIT_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From  %s Line %s \n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1])
+                    CApp = CApp + ' PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+                    CApp = CApp + '  memcpy (Pcd, %s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+                else:
+                    if Pcd.Capacity[-1] != "-1":
+                        CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array capability %s"); // From %s Line %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1])
+                    CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
+                    CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
+                    CApp = CApp + '  memcpy (Pcd, Value, PcdArraySize);\n'
             else:
-                CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
-                CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
+                if "{CODE(" in Pcd.DefaultValueFromDec:
+                    CApp = CApp + '  PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+                    CApp = CApp + '  memcpy (Pcd, &%s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
+                else:
+                    CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultValueFromDec)
+                    CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
         elif isinstance(Value, str):
             CApp = CApp + '  Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)
         for index in Pcd.DefaultValues:
             FieldList = Pcd.DefaultValues[index]
             if not FieldList:
@@ -2050,18 +2107,33 @@ class DscBuildData(PlatformBuildClassObject):
                 pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)
         else:
             pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(TAB_DEFAULT_STORES_DEFAULT)
 
         return pcddefaultvalue
+    def GetPcdDscRawValueInfo(self,Pcd, SkuName,DefaultStoreName):
+        DscValueInfo = Pcd.DscRawValueInfo.get(SkuName, {}).get(DefaultStoreName)
+        if DscValueInfo:
+            dscfilepath,lineno = DscValueInfo
+        else:
+            dscfilepath = self.MetaFile.File
+            lineno = ""
+        return dscfilepath,lineno
+
     def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName):
         CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName, DefaultStoreName)
         CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName, DefaultStoreName, Pcd.BaseDatumType)
         CApp = CApp + '  UINT32  FieldSize;\n'
         CApp = CApp + '  CHAR8   *Value;\n'
+        CApp = CApp + ' UINT32 PcdArraySize;\n'
 
         CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)
         inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]
+        dscfilepath,lineno = self.GetPcdDscRawValueInfo(Pcd, SkuName, DefaultStoreName)
+        if lineno:
+            valuefrom = "%s Line %s" % (dscfilepath,str(lineno))
+        else:
+            valuefrom = dscfilepath
 
         pcddefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, SkuName, DefaultStoreName)
         if pcddefaultvalue:
             FieldList = pcddefaultvalue
             IsArray = _IsFieldValueAnArray(FieldList)
@@ -2075,37 +2147,75 @@ class DscBuildData(PlatformBuildClassObject):
             Value, ValueSize = ParseFieldValue (FieldList)
 
             if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
                 if isinstance(Value, str):
                     if "{CODE(" in Value:
-                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                        if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
+                            pcdarraysize = Pcd.PcdArraySize()
+                            CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType, valuefrom)
+                        CApp = CApp+ ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                        CApp = CApp + '  memcpy (Pcd, &%s_%s_%s_%s_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
                     else:
                         CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
                 elif IsArray:
-                #
-                # Use memcpy() to copy value into field
-                #
-                    if Pcd.IsArray() and "{CODE(" in pcddefaultvalue:
-                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                    #
+                    # Use memcpy() to copy value into field
+                    #
+                    if Pcd.IsArray():
+                        pcdarraysize = Pcd.PcdArraySize()
+                        if "{CODE(" in pcddefaultvalue:
+                            if Pcd.Capacity[-1] != "-1":
+                                CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From  %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
+                            CApp = CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                            CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                        else:
+                            if Pcd.Capacity[-1] != "-1":
+                                CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From  %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
+                            CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
+                            CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
+                            CApp = CApp + '  memcpy (Pcd, Value, PcdArraySize);\n'
                     else:
-                        CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
-                        CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
+                        if "{CODE(" in pcddefaultvalue:
+                            CApp = CApp + '  PcdArraySize = %d < sizeof(%s) * %d ? %d: sizeof(%s) * %d;\n ' % (ValueSize,Pcd.BaseDatumType,pcdarraysize,ValueSize,Pcd.BaseDatumType,pcdarraysize)
+                            CApp = CApp + '  memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                        else:
+                            CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
+                            CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
             else:
                 if isinstance(Value, str):
                     if "{CODE(" in Value:
-                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                        if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
+                            pcdarraysize = Pcd.PcdArraySize()
+                            CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
+                        CApp = CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n '% (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                        CApp = CApp + '  memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
                     else:
                         CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
                 elif IsArray:
-                #
-                # Use memcpy() to copy value into field
-                #
-                    if Pcd.IsArray() and "{CODE(" in pcddefaultvalue:
-                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                    #
+                    # Use memcpy() to copy value into field
+                    #
+                    if Pcd.IsArray():
+                        pcdarraysize = Pcd.PcdArraySize()
+                        if "{CODE(" in pcddefaultvalue:
+                            if Pcd.Capacity[-1] != "-1":
+                                CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From  %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
+                            CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                            CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                        else:
+                            if Pcd.Capacity[-1] != "-1":
+                                CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array capability %s"); // From  %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
+                            CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
+                            CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else Pcd.DefaultValue)
+                            CApp = CApp + '  memcpy (Pcd, Value, PcdArraySize);\n'
                     else:
-                        CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
-                        CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
+                        if "{CODE(" in pcddefaultvalue:
+                            CApp = CApp + '  PcdArraySize = %d < sizeof(%s) * %d ? %d: sizeof(%s) * %d;\n ' % (ValueSize,Pcd.BaseDatumType,pcdarraysize,ValueSize,Pcd.BaseDatumType,pcdarraysize)
+                            CApp = CApp + '  memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
+                        else:
+                            CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
+                            CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
 
         inheritvalue = inherit_OverrideValues.get(DefaultStoreName)
         if not inheritvalue:
             inheritvalue = []
         for index in inheritvalue:
@@ -2327,10 +2437,13 @@ class DscBuildData(PlatformBuildClassObject):
             # the flexible array member.  The flexible array member must be the last field
             # in a structure.  The size formula for this case is:
             # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
             #
             CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd,SkuName,DefaultStoreName)
+            if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
+                CApp = CApp + '  OriginalSize = OriginalSize < sizeof(%s) * %d? OriginalSize:sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize(),Pcd.BaseDatumType,Pcd.PcdArraySize())
+                CApp = CApp + '  Size = sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize())
 
             #
             # Allocate and zero buffer for the PCD
             # Must handle cases where current value is smaller, larger, or same size
             # Always keep that larger one as the current size
@@ -2377,12 +2490,10 @@ class DscBuildData(PlatformBuildClassObject):
 
     def GenerateArrayAssignment(self, Pcd):
         CApp = ""
         if not Pcd:
             return CApp
-        if not Pcd.IsArray():
-            return CApp
         Demesion = ""
         for d in Pcd.Capacity:
             Demesion += "[]"
 
         Value = Pcd.DefaultValueFromDec
@@ -2770,11 +2881,13 @@ class DscBuildData(PlatformBuildClassObject):
                                                     None,
                                                     IsDsc=True)
 
             if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
                 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
+                Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
             Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
+            Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Dummy4)
 
         for pcd in Pcds.values():
             pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
             # Only fix the value while no value provided in DSC file.
             for sku in pcd.SkuInfoList.values():
@@ -2972,11 +3085,13 @@ class DscBuildData(PlatformBuildClassObject):
                 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObj
 
                 Pcds[PcdCName, TokenSpaceGuid].CustomAttribute['DscPosition'] = int(Dummy4)
             if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
                 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
+                Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
             Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][DefaultStore] = DefaultValue
+            Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][DefaultStore] = (self.MetaFile.File,Dummy4)
         for pcd in Pcds.values():
             pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
             pcd.DatumType = pcdDecObject.DatumType
             # Only fix the value while no value provided in DSC file.
             for sku in pcd.SkuInfoList.values():
@@ -3110,11 +3225,13 @@ class DscBuildData(PlatformBuildClassObject):
                                                 None,
                                                 IsDsc=True)
 
             if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
                 Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
+                Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
             Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = InitialValue
+            Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] = (self.MetaFile.File,Dummy4)
         for pcd in Pcds.values():
             pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
             pcd.DatumType = pcdDecObject.DatumType
             # Only fix the value while no value provided in DSC file.
             for sku in pcd.SkuInfoList.values():
-- 
2.18.0.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#40024): https://edk2.groups.io/g/devel/message/40024
Mute This Topic: https://groups.io/mt/31515987/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-

Re: [edk2-devel] [Patch V2] BaseTools: Correct the value assignment for StructurePcd
Posted by Liming Gao 4 years, 11 months ago
Please remove Contributed-under: TianoCore Contribution Agreement 1.1. 

Please list which test has been done for this change.

> -----Original Message-----
> From: Fan, ZhijuX
> Sent: Monday, May 6, 2019 10:38 AM
> To: devel@edk2.groups.io
> Cc: Gao, Liming <liming.gao@intel.com>
> Subject: [Patch V2] BaseTools: Correct the value assignment for StructurePcd
> 
> BZ:https://bugzilla.tianocore.org/show_bug.cgi?id=1752
> 
> This patch is to fix the code bug in StructurePcd overall
> value assignment logic. If a Pcd Array size is fixed but the
> size of actual value in Dsc or Dec is bigger than the Pcd
> array size, the tool will report error about such setting and
> stop build.
> 
> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Bob Feng <bob.c.feng@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> ---
>  BaseTools/Source/Python/Common/Misc.py        |   1 +
>  .../Python/Workspace/BuildClassObject.py      |  78 ++++---
>  .../Source/Python/Workspace/DecBuildData.py   |   2 +-
>  .../Source/Python/Workspace/DscBuildData.py   | 211 ++++++++++++++----
>  4 files changed, 218 insertions(+), 74 deletions(-)
> 
> diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
> index c7daf5417c..526aa2dd54 100644
> --- a/BaseTools/Source/Python/Common/Misc.py
> +++ b/BaseTools/Source/Python/Common/Misc.py
> @@ -40,10 +40,11 @@ from Common.Parsing import GetSplitValueList
>  from Common.LongFilePathSupport import OpenLongFilePath as open
>  from Common.MultipleWorkspace import MultipleWorkspace as mws
>  from CommonDataClass.Exceptions import BadExpression
>  from Common.caching import cached_property
> 
> +ArrayIndex = re.compile("\[\s*[0-9a-fA-FxX]*\s*\]")
>  ## Regular expression used to find out place holders in string template
>  gPlaceholderPattern = re.compile("\$\{([^$()\s]+)\}", re.MULTILINE | re.UNICODE)
> 
>  ## regular expressions for map file processing
>  startPatternGeneral = re.compile("^Start[' ']+Length[' ']+Name[' ']+Class")
> diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py
> index b82af49236..b50e250cfb 100644
> --- a/BaseTools/Source/Python/Workspace/BuildClassObject.py
> +++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py
> @@ -14,14 +14,16 @@
>  from collections import OrderedDict, namedtuple
>  from Common.DataType import *
>  import collections
>  import re
>  from collections import OrderedDict
> -from Common.Misc import CopyDict
> +from Common.Misc import CopyDict,ArrayIndex
>  import copy
> +import Common.EdkLogger as EdkLogger
> +from Common.BuildToolError import OPTION_VALUE_INVALID
>  StructPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_\[\]]*$')
> -ArrayIndex = re.compile("\[\s*[0-9a-fA-FxX]*\s*\]")
> +
>  ## PcdClassObject
>  #
>  # This Class is used for PcdObject
>  #
>  # @param object:             Inherited from object class
> @@ -66,44 +68,62 @@ class PcdClassObject(object):
>          self.validateranges = validateranges if validateranges is not None else []
>          self.validlists = validlists if validlists is not None else []
>          self.expressions = expressions if expressions is not None else []
>          self.DscDefaultValue = None
>          self.DscRawValue = {}
> +        self.DscRawValueInfo = {}
>          if IsDsc:
>              self.DscDefaultValue = Value
>          self.PcdValueFromComm = ""
>          self.PcdValueFromFdf = ""
>          self.CustomAttribute = {}
>          self.UserDefinedDefaultStoresFlag = UserDefinedDefaultStoresFlag
>          self._Capacity = None
> 
>      @property
>      def Capacity(self):
> -        self._Capacity = []
> -        dimension = ArrayIndex.findall(self._DatumType)
> -        for item in dimension:
> -            maxsize = item.lstrip("[").rstrip("]").strip()
> -            if not maxsize:
> -                maxsize = "-1"
> -            maxsize = str(int(maxsize,16)) if maxsize.startswith(("0x","0X")) else maxsize
> -            self._Capacity.append(maxsize)
> -        if hasattr(self, "SkuOverrideValues"):
> -            for sku in self.SkuOverrideValues:
> -                for defaultstore in self.SkuOverrideValues[sku]:
> -                    fields = self.SkuOverrideValues[sku][defaultstore]
> -                    for demesionattr in fields:
> -                        deme = ArrayIndex.findall(demesionattr)
> -                        for i in range(len(deme)-1):
> -                            if int(deme[i].lstrip("[").rstrip("]").strip()) > int(self._Capacity[i]):
> -                                print ("error")
> -        if hasattr(self,"DefaultValues"):
> -            for demesionattr in self.DefaultValues:
> -                deme = ArrayIndex.findall(demesionattr)
> -                for i in range(len(deme)-1):
> -                    if int(deme[i].lstrip("[").rstrip("]").strip()) > int(self._Capacity[i]):
> -                        print ("error")
> +        if self._Capacity is None:
> +            self._Capacity = []
> +            dimension = ArrayIndex.findall(self._DatumType)
> +            for item in dimension:
> +                maxsize = item.lstrip("[").rstrip("]").strip()
> +                if not maxsize:
> +                    maxsize = "-1"
> +                maxsize = str(int(maxsize,16)) if maxsize.startswith(("0x","0X")) else maxsize
> +                self._Capacity.append(maxsize)
> +            if hasattr(self, "SkuOverrideValues"):
> +                for sku in self.SkuOverrideValues:
> +                    for defaultstore in self.SkuOverrideValues[sku]:
> +                        fields = self.SkuOverrideValues[sku][defaultstore]
> +                        for demesionattr in fields:
> +                            fieldinfo = fields[demesionattr]
> +                            deme = ArrayIndex.findall(demesionattr)
> +                            for i in range(len(deme)):
> +                                if int(deme[i].lstrip("[").rstrip("]").strip()) >= int(self._Capacity[i]):
> +                                    if self._Capacity[i] != "-1":
> +                                        firstfieldinfo = list(fieldinfo.values())[0]
> +                                        EdkLogger.error('Build', OPTION_VALUE_INVALID, "For Pcd %s, Array Index exceed the
> Array size. From %s Line %s \n " %
> +                                    (".".join((self.TokenSpaceGuidCName, self.TokenCName)), firstfieldinfo[1],firstfieldinfo[2] ))
> +            if hasattr(self,"DefaultValues"):
> +                for demesionattr in self.DefaultValues:
> +                    fieldinfo = self.DefaultValues[demesionattr]
> +                    deme = ArrayIndex.findall(demesionattr)
> +                    for i in range(len(deme)):
> +                        if int(deme[i].lstrip("[").rstrip("]").strip()) >= int(self._Capacity[i]):
> +                            if self._Capacity[i] != "-1":
> +                                firstfieldinfo = list(fieldinfo.values())[0]
> +                                EdkLogger.error('Build', OPTION_VALUE_INVALID, "For Pcd %s, Array Index exceed the Array size.
> From %s Line %s \n " %
> +                                    (".".join((self.TokenSpaceGuidCName, self.TokenCName)), firstfieldinfo[1],firstfieldinfo[2] ))
>          return self._Capacity
> +
> +    def PcdArraySize(self):
> +        if self.Capacity[-1] == "-1":
> +            return -1
> +        size = 1
> +        for de in self.Capacity:
> +            size = size * int(de)
> +        return size
>      @property
>      def DatumType(self):
>          return self._DatumType
> 
>      @DatumType.setter
> @@ -231,10 +251,11 @@ class PcdClassObject(object):
>          new_pcd.IsFromDsc = self.IsFromDsc
>          new_pcd.PcdValueFromComm = self.PcdValueFromComm
>          new_pcd.PcdValueFromFdf = self.PcdValueFromFdf
>          new_pcd.UserDefinedDefaultStoresFlag = self.UserDefinedDefaultStoresFlag
>          new_pcd.DscRawValue = self.DscRawValue
> +        new_pcd.DscRawValueInfo = self.DscRawValueInfo
>          new_pcd.CustomAttribute = self.CustomAttribute
>          new_pcd.validateranges = [item for item in self.validateranges]
>          new_pcd.validlists = [item for item in self.validlists]
>          new_pcd.expressions = [item for item in self.expressions]
>          new_pcd.SkuInfoList = {key: copy.deepcopy(skuobj) for key,skuobj in self.SkuInfoList.items()}
> @@ -266,10 +287,11 @@ class StructurePcd(PcdClassObject):
>          self.SkuOverrideValues = OrderedDict()
>          self.StructName = None
>          self.PcdDefineLineNo = 0
>          self.PkgPath = ""
>          self.DefaultValueFromDec = ""
> +        self.DefaultValueFromDecInfo = None
>          self.ValueChain = set()
>          self.PcdFieldValueFromComm = OrderedDict()
>          self.PcdFieldValueFromFdf = OrderedDict()
>          self.DefaultFromDSC=None
>      def __repr__(self):
> @@ -281,12 +303,13 @@ class StructurePcd(PcdClassObject):
>          if FieldName in self.DefaultValues[DimensionAttr]:
>              del self.DefaultValues[DimensionAttr][FieldName]
>          self.DefaultValues[DimensionAttr][FieldName] = [Value.strip(), FileName, LineNo]
>          return self.DefaultValues[DimensionAttr][FieldName]
> 
> -    def SetDecDefaultValue(self, DefaultValue):
> +    def SetDecDefaultValue(self, DefaultValue,decpath=None,lineno=None):
>          self.DefaultValueFromDec = DefaultValue
> +        self.DefaultValueFromDecInfo = (decpath,lineno)
>      def AddOverrideValue (self, FieldName, Value, SkuName, DefaultStoreName, FileName="", LineNo=0, DimensionAttr = '-1'):
>          if SkuName not in self.SkuOverrideValues:
>              self.SkuOverrideValues[SkuName] = OrderedDict()
>          if DefaultStoreName not in self.SkuOverrideValues[SkuName]:
>              self.SkuOverrideValues[SkuName][DefaultStoreName] = OrderedDict()
> @@ -317,20 +340,22 @@ class StructurePcd(PcdClassObject):
>          self.IsFromDsc = PcdObject.IsFromDsc if PcdObject.IsFromDsc else self.IsFromDsc
>          self.validateranges = PcdObject.validateranges if PcdObject.validateranges else self.validateranges
>          self.validlists = PcdObject.validlists if PcdObject.validlists else self.validlists
>          self.expressions = PcdObject.expressions if PcdObject.expressions else self.expressions
>          self.DscRawValue = PcdObject.DscRawValue if PcdObject.DscRawValue else self.DscRawValue
> +        self.DscRawValueInfo = PcdObject.DscRawValueInfo if PcdObject.DscRawValueInfo else self.DscRawValueInfo
>          self.PcdValueFromComm = PcdObject.PcdValueFromComm if PcdObject.PcdValueFromComm else self.PcdValueFromComm
>          self.PcdValueFromFdf = PcdObject.PcdValueFromFdf if PcdObject.PcdValueFromFdf else self.PcdValueFromFdf
>          self.CustomAttribute = PcdObject.CustomAttribute if PcdObject.CustomAttribute else self.CustomAttribute
>          self.UserDefinedDefaultStoresFlag = PcdObject.UserDefinedDefaultStoresFlag if PcdObject.UserDefinedDefaultStoresFlag else
> self.UserDefinedDefaultStoresFlag
>          if isinstance(PcdObject, StructurePcd):
>              self.StructuredPcdIncludeFile = PcdObject.StructuredPcdIncludeFile if PcdObject.StructuredPcdIncludeFile else
> self.StructuredPcdIncludeFile
>              self.PackageDecs = PcdObject.PackageDecs if PcdObject.PackageDecs else self.PackageDecs
>              self.DefaultValues = PcdObject.DefaultValues if PcdObject.DefaultValues else self.DefaultValues
>              self.PcdMode = PcdObject.PcdMode if PcdObject.PcdMode else self.PcdMode
>              self.DefaultValueFromDec = PcdObject.DefaultValueFromDec if PcdObject.DefaultValueFromDec else
> self.DefaultValueFromDec
> +            self.DefaultValueFromDecInfo = PcdObject.DefaultValueFromDecInfo if PcdObject.DefaultValueFromDecInfo else
> self.DefaultValueFromDecInfo
>              self.SkuOverrideValues = PcdObject.SkuOverrideValues if PcdObject.SkuOverrideValues else self.SkuOverrideValues
>              self.StructName = PcdObject.DatumType if PcdObject.DatumType else self.StructName
>              self.PcdDefineLineNo = PcdObject.PcdDefineLineNo if PcdObject.PcdDefineLineNo else self.PcdDefineLineNo
>              self.PkgPath = PcdObject.PkgPath if PcdObject.PkgPath else self.PkgPath
>              self.ValueChain = PcdObject.ValueChain if PcdObject.ValueChain else self.ValueChain
> @@ -340,10 +365,11 @@ class StructurePcd(PcdClassObject):
>      def __deepcopy__(self,memo):
>          new_pcd = StructurePcd()
>          self.sharedcopy(new_pcd)
> 
>          new_pcd.DefaultValueFromDec = self.DefaultValueFromDec
> +        new_pcd.DefaultValueFromDecInfo = self.DefaultValueFromDecInfo
>          new_pcd.PcdMode = self.PcdMode
>          new_pcd.StructName = self.DatumType
>          new_pcd.PcdDefineLineNo = self.PcdDefineLineNo
>          new_pcd.PkgPath = self.PkgPath
>          new_pcd.StructuredPcdIncludeFile = [item for item in self.StructuredPcdIncludeFile]
> diff --git a/BaseTools/Source/Python/Workspace/DecBuildData.py b/BaseTools/Source/Python/Workspace/DecBuildData.py
> index 149c057b70..ea0f816e27 100644
> --- a/BaseTools/Source/Python/Workspace/DecBuildData.py
> +++ b/BaseTools/Source/Python/Workspace/DecBuildData.py
> @@ -399,11 +399,11 @@ class DecBuildData(PackageBuildClassObject):
>                      struct_pcd.copy(item)
>                      struct_pcd.TokenValue = struct_pcd.TokenValue.strip("{").strip()
>                      struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName = pcdname.split(".")
>                      struct_pcd.PcdDefineLineNo = LineNo
>                      struct_pcd.PkgPath = self.MetaFile.File
> -                    struct_pcd.SetDecDefaultValue(item.DefaultValue)
> +                    struct_pcd.SetDecDefaultValue(item.DefaultValue,self.MetaFile.File,LineNo)
>                  else:
>                      DemesionAttr, Fields = self.ParsePcdName(item.TokenCName)
>                      struct_pcd.AddDefaultValue(Fields, item.DefaultValue, self.MetaFile.File, LineNo,DemesionAttr)
> 
>              struct_pcd.PackageDecs = dep_pkgs
> diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
> index 1ffefe6e7e..7b8c9eedf6 100644
> --- a/BaseTools/Source/Python/Workspace/DscBuildData.py
> +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
> @@ -31,21 +31,20 @@ from .MetaDataTable import *
>  from .MetaFileTable import *
>  from .MetaFileParser import *
> 
>  from .WorkspaceCommon import GetDeclaredPcd
>  from Common.Misc import AnalyzeDscPcd
> -from Common.Misc import ProcessDuplicatedInf,RemoveCComments
> +from Common.Misc import ProcessDuplicatedInf,RemoveCComments,ArrayIndex
>  import re
>  from Common.Parsing import IsValidWord
>  from Common.VariableAttributes import VariableAttributes
>  import Common.GlobalData as GlobalData
>  import subprocess
>  from functools import reduce
>  from Common.Misc import SaveFileOnChange
>  from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject
>  from collections import OrderedDict, defaultdict
> -from .BuildClassObject import ArrayIndex
> 
>  def _IsFieldValueAnArray (Value):
>      Value = Value.strip()
>      if Value.startswith(TAB_GUID) and Value.endswith(')'):
>          return True
> @@ -1681,21 +1680,21 @@ class DscBuildData(PlatformBuildClassObject):
>                                      File=self.MetaFile, Line=Dummy4)
>                  if int(MaxDatumSize, 0) < 0:
>                      EdkLogger.error('build', FORMAT_INVALID, "The size value can't be set to negative value for %s." %
> ".".join((TokenSpaceGuid, PcdCName)),
>                                      File=self.MetaFile, Line=Dummy4)
>              if (PcdCName, TokenSpaceGuid) in PcdValueDict:
> -                PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize)
> +                PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue, DatumType, MaxDatumSize,Dummy4)
>              else:
> -                PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize)}
> +                PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue, DatumType, MaxDatumSize,Dummy4)}
> 
>          for ((PcdCName, TokenSpaceGuid), PcdSetting) in PcdValueDict.items():
>              if self.SkuIdMgr.SystemSkuId in PcdSetting:
> -                PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId]
> +                PcdValue, DatumType, MaxDatumSize,_ = PcdSetting[self.SkuIdMgr.SystemSkuId]
>              elif TAB_DEFAULT in PcdSetting:
> -                PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_DEFAULT]
> +                PcdValue, DatumType, MaxDatumSize,_  = PcdSetting[TAB_DEFAULT]
>              elif TAB_COMMON in PcdSetting:
> -                PcdValue, DatumType, MaxDatumSize = PcdSetting[TAB_COMMON]
> +                PcdValue, DatumType, MaxDatumSize,_  = PcdSetting[TAB_COMMON]
>              else:
>                  PcdValue = None
>                  DatumType = None
>                  MaxDatumSize = None
> 
> @@ -1713,11 +1712,13 @@ class DscBuildData(PlatformBuildClassObject):
>                                                  IsDsc=True)
>              for SkuName in PcdValueDict[PcdCName, TokenSpaceGuid]:
>                  Settings = PcdValueDict[PcdCName, TokenSpaceGuid][SkuName]
>                  if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
>                      Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
> +                    Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
>                  Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = Settings[0]
> +                Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] =
> (self.MetaFile.File,Settings[3])
>          return Pcds
> 
>      @staticmethod
>      def GetStructurePcdMaxSize(str_pcd):
>          pcd_default_value = str_pcd.DefaultValue
> @@ -1766,28 +1767,45 @@ class DscBuildData(PlatformBuildClassObject):
>          return Result
> 
>      def GenerateSizeFunction(self, Pcd):
>          CApp = "// Default Value in Dec \n"
>          CApp = CApp + "void Cal_%s_%s_Size(UINT32 *Size){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> -        if Pcd.IsArray():
> +
> +        if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
> +            CApp += "  *Size = (sizeof (%s) > *Size ? sizeof (%s) : *Size);\n" % (Pcd.DatumType,Pcd.DatumType)
> +        else:
> +            if "{CODE(" in Pcd.DefaultValueFromDec:
> +                CApp += "  *Size = (sizeof (%s_%s_INIT_Value) > *Size ? sizeof (%s_%s_INIT_Value) : *Size);\n" %
> (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,Pcd.TokenSpaceGuidCName,Pcd.TokenCName)
>              if Pcd.Type in PCD_DYNAMIC_TYPE_SET | PCD_DYNAMIC_EX_TYPE_SET:
>                  for skuname in Pcd.SkuInfoList:
>                      skuobj = Pcd.SkuInfoList[skuname]
>                      if skuobj.VariableName:
>                          for defaultstore in skuobj.DefaultStoreDict:
>                              pcddef = self.GetPcdDscRawDefaultValue(Pcd,skuname,defaultstore)
> -                            if pcddef and "{CODE(" in pcddef:
> -                                CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" %
> (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore)
> +                            if pcddef:
> +                                if "{CODE(" in pcddef:
> +                                    CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) :
> *Size);\n" %
> (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,defaultstore)
> +                                else:
> +                                    CApp += "  *Size = %s > *Size ? %s : *Size;\n" %
> (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
>                      else:
>                          pcddef = self.GetPcdDscRawDefaultValue(Pcd,skuname,TAB_DEFAULT_STORES_DEFAULT)
> -                        if pcddef and "{CODE(" in pcddef:
> -                            CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" %
> (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,sku
> name,TAB_DEFAULT_STORES_DEFAULT)
> +                        if pcddef:
> +                            if  "{CODE(" in pcddef:
> +                                CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" %
> (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,skuname,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,sku
> name,TAB_DEFAULT_STORES_DEFAULT)
> +                            else:
> +                                CApp += "  *Size = %s > *Size ? %s : *Size;\n" %
> (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
>              else:
>                  pcddef = self.GetPcdDscRawDefaultValue(Pcd,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT)
> -                if pcddef and "{CODE(" in pcddef:
> -                    CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" %
> (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,
> TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT)
> +                if pcddef:
> +                    if "{CODE(" in pcddef:
> +                        CApp += "  *Size = (sizeof (%s_%s_%s_%s_Value) > *Size ? sizeof (%s_%s_%s_%s_Value) : *Size);\n" %
> (Pcd.TokenSpaceGuidCName,Pcd.TokenCName,TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT,Pcd.TokenSpaceGuidCName,Pcd.TokenCName,
> TAB_DEFAULT,TAB_DEFAULT_STORES_DEFAULT)
> +                    else:
> +                        CApp += "  *Size = %s > *Size ? %s : *Size;\n" %
> (self.GetStructurePcdMaxSize(Pcd),self.GetStructurePcdMaxSize(Pcd))
> +        ActualCap = []
>          for index in Pcd.DefaultValues:
> +            if index:
> +                ActualCap.append(index)
>              FieldList = Pcd.DefaultValues[index]
>              if not FieldList:
>                  continue
>              for FieldName in FieldList:
>                  FieldName = "." + FieldName
> @@ -1804,22 +1822,24 @@ class DscBuildData(PlatformBuildClassObject):
>                  else:
>                      NewFieldName = ''
>                      FieldName_ori = FieldName.strip('.')
>                      while '[' in  FieldName:
>                          NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
> -                        ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
> +                        Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
>                          FieldName = FieldName.split(']', 1)[1]
>                      FieldName = NewFieldName + FieldName
>                      while '[' in FieldName and not Pcd.IsArray:
>                          FieldName = FieldName.rsplit('[', 1)[0]
> -                        CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType,
> FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
> +                        CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s\n' % (Pcd.DatumType,
> FieldName.strip("."), Array_Index + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
>          for skuname in Pcd.SkuOverrideValues:
>              if skuname == TAB_COMMON:
>                  continue
>              for defaultstorenameitem in Pcd.SkuOverrideValues[skuname]:
>                  CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
>                  for index in Pcd.SkuOverrideValues[skuname][defaultstorenameitem]:
> +                    if index:
> +                        ActualCap.append(index)
>                      for FieldList in [Pcd.SkuOverrideValues[skuname][defaultstorenameitem][index]]:
>                          if not FieldList:
>                              continue
>                          for FieldName in FieldList:
>                              FieldName = "." + FieldName
> @@ -1836,16 +1856,16 @@ class DscBuildData(PlatformBuildClassObject):
>                              else:
>                                  NewFieldName = ''
>                                  FieldName_ori = FieldName.strip('.')
>                                  while '[' in  FieldName:
>                                      NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
> -                                    ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
> +                                    Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
>                                      FieldName = FieldName.split(']', 1)[1]
>                                  FieldName = NewFieldName + FieldName
>                                  while '[' in FieldName and not Pcd.IsArray:
>                                      FieldName = FieldName.rsplit('[', 1)[0]
> -                                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' %
> (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
> +                                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' %
> (Pcd.DatumType, FieldName.strip("."), Array_Index + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2],
> FieldList[FieldName_ori][0])
>          if Pcd.PcdFieldValueFromFdf:
>              CApp = CApp + "// From fdf \n"
>          for FieldName in Pcd.PcdFieldValueFromFdf:
>              FieldName = "." + FieldName
>              IsArray = _IsFieldValueAnArray(Pcd.PcdFieldValueFromFdf[FieldName.strip(".")][0])
> @@ -1861,16 +1881,16 @@ class DscBuildData(PlatformBuildClassObject):
>              else:
>                  NewFieldName = ''
>                  FieldName_ori = FieldName.strip('.')
>                  while '[' in  FieldName:
>                      NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
> -                    ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
> +                    Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
>                      FieldName = FieldName.split(']', 1)[1]
>                  FieldName = NewFieldName + FieldName
>                  while '[' in FieldName:
>                      FieldName = FieldName.rsplit('[', 1)[0]
> -                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %s Value %s \n' % (Pcd.DatumType,
> FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromFdf[FieldName_ori][1], Pcd.PcdFieldValueFromFdf[FieldName_ori][2],
> Pcd.PcdFieldValueFromFdf[FieldName_ori][0])
> +                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %s Value %s \n' % (Pcd.DatumType,
> FieldName.strip("."), Array_Index + 1, Pcd.PcdFieldValueFromFdf[FieldName_ori][1], Pcd.PcdFieldValueFromFdf[FieldName_ori][2],
> Pcd.PcdFieldValueFromFdf[FieldName_ori][0])
>          if Pcd.PcdFieldValueFromComm:
>              CApp = CApp + "// From Command Line \n"
>          for FieldName in Pcd.PcdFieldValueFromComm:
>              FieldName = "." + FieldName
>              IsArray = _IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0])
> @@ -1886,20 +1906,41 @@ class DscBuildData(PlatformBuildClassObject):
>              else:
>                  NewFieldName = ''
>                  FieldName_ori = FieldName.strip('.')
>                  while '[' in  FieldName:
>                      NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]'
> -                    ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0])
> +                    Array_Index = int(FieldName.split('[', 1)[1].split(']', 1)[0])
>                      FieldName = FieldName.split(']', 1)[1]
>                  FieldName = NewFieldName + FieldName
>                  while '[' in FieldName and not Pcd.IsArray:
>                      FieldName = FieldName.rsplit('[', 1)[0]
> -                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType,
> FieldName.strip("."), ArrayIndex + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2],
> Pcd.PcdFieldValueFromComm[FieldName_ori][0])
> +                    CApp = CApp + '  __FLEXIBLE_SIZE(*Size, %s, %s, %d); // From %s Line %d Value %s \n' % (Pcd.DatumType,
> FieldName.strip("."), Array_Index + 1, Pcd.PcdFieldValueFromComm[FieldName_ori][1], Pcd.PcdFieldValueFromComm[FieldName_ori][2],
> Pcd.PcdFieldValueFromComm[FieldName_ori][0])
>          if Pcd.GetPcdMaxSize():
>              CApp = CApp + "  *Size = (%d > *Size ? %d : *Size); // The Pcd maxsize is %d \n" % (Pcd.GetPcdMaxSize(),
> Pcd.GetPcdMaxSize(), Pcd.GetPcdMaxSize())
> +        ArraySizeByAssign = self.CalculateActualCap(ActualCap)
> +        if ArraySizeByAssign > 1:
> +            CApp = CApp + "  *Size = (%d > *Size ? %d : *Size); \n" % (ArraySizeByAssign, ArraySizeByAssign)
>          CApp = CApp + "}\n"
>          return CApp
> +    def CalculateActualCap(self,ActualCap):
> +        if not ActualCap:
> +            return 1
> +        maxsize = 1
> +        for item in ActualCap:
> +            index_elements = ArrayIndex.findall(item)
> +            rt = 1
> +            for index_e in index_elements:
> +                index_num = index_e.lstrip("[").rstrip("]").strip()
> +                if not index_num:
> +                    # Not support flexiable pcd array assignment
> +                    return 1
> +                index_num = int(index_num,16) if index_num.startswith(("0x","0X")) else int(index_num)
> +                rt = rt * (index_num+1)
> +            if rt  >maxsize:
> +                maxsize = rt
> +
> +        return maxsize
> 
>      @staticmethod
>      def GenerateSizeStatments(Pcd,skuname,defaultstorename):
>          if Pcd.IsArray():
>              r_datatype = [Pcd.BaseDatumType]
> @@ -1974,10 +2015,11 @@ class DscBuildData(PlatformBuildClassObject):
>      def GenerateDefaultValueAssignFunction(self, Pcd):
>          CApp = "// Default value in Dec \n"
>          CApp = CApp + "void Assign_%s_%s_Default_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,
> Pcd.BaseDatumType)
>          CApp = CApp + '  UINT32  FieldSize;\n'
>          CApp = CApp + '  CHAR8   *Value;\n'
> +        CApp = CApp + ' UINT32 PcdArraySize;\n'
>          DefaultValueFromDec = Pcd.DefaultValueFromDec
>          IsArray = _IsFieldValueAnArray(Pcd.DefaultValueFromDec)
>          if IsArray:
>              try:
>                  DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, TAB_VOID)(True)
> @@ -1985,18 +2027,33 @@ class DscBuildData(PlatformBuildClassObject):
>                  EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" %
>                                  (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec))
>          DefaultValueFromDec = StringToArray(DefaultValueFromDec)
>          Value, ValueSize = ParseFieldValue (DefaultValueFromDec)
>          if IsArray:
> -        #
> -        # Use memcpy() to copy value into field
> -        #
> -            if "{CODE(" in Pcd.DefaultValueFromDec:
> -                CApp = CApp + '  memcpy (Pcd, %s_%s_INIT_Value, sizeof(%s_%s_INIT_Value));\n' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> +            #
> +            # Use memcpy() to copy value into field
> +            #
> +            if Pcd.IsArray():
> +                pcdarraysize = Pcd.PcdArraySize()
> +                if "{CODE(" in Pcd.DefaultValueFromDec:
> +                    if Pcd.Capacity[-1] != "-1":
> +                        CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_INIT_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dec
> exceed the array capability %s"); // From  %s Line %s \n ' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1])
> +                    CApp = CApp + ' PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> +                    CApp = CApp + '  memcpy (Pcd, %s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName)
> +                else:
> +                    if Pcd.Capacity[-1] != "-1":
> +                        CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dec exceed the array
> capability %s"); // From %s Line %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,Pcd.DatumType,Pcd.DefaultValueFromDecInfo[0],Pcd.DefaultValueFromDecInfo[1])
> +                    CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
> +                    CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value,
> ValueSize), Pcd.DefaultValueFromDec)
> +                    CApp = CApp + '  memcpy (Pcd, Value, PcdArraySize);\n'
>              else:
> -                CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value, ValueSize),
> Pcd.DefaultValueFromDec)
> -                CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
> +                if "{CODE(" in Pcd.DefaultValueFromDec:
> +                    CApp = CApp + '  PcdArraySize = sizeof(%s_%s_INIT_Value);\n ' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
> +                    CApp = CApp + '  memcpy (Pcd, &%s_%s_INIT_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName)
> +                else:
> +                    CApp = CApp + '  Value     = %s; // From DEC Default Value %s\n' % (DscBuildData.IntToCString(Value,
> ValueSize), Pcd.DefaultValueFromDec)
> +                    CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
>          elif isinstance(Value, str):
>              CApp = CApp + '  Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec)
>          for index in Pcd.DefaultValues:
>              FieldList = Pcd.DefaultValues[index]
>              if not FieldList:
> @@ -2050,18 +2107,33 @@ class DscBuildData(PlatformBuildClassObject):
>                  pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName)
>          else:
>              pcddefaultvalue = Pcd.DscRawValue.get(SkuName, {}).get(TAB_DEFAULT_STORES_DEFAULT)
> 
>          return pcddefaultvalue
> +    def GetPcdDscRawValueInfo(self,Pcd, SkuName,DefaultStoreName):
> +        DscValueInfo = Pcd.DscRawValueInfo.get(SkuName, {}).get(DefaultStoreName)
> +        if DscValueInfo:
> +            dscfilepath,lineno = DscValueInfo
> +        else:
> +            dscfilepath = self.MetaFile.File
> +            lineno = ""
> +        return dscfilepath,lineno
> +
>      def GenerateInitValueFunction(self, Pcd, SkuName, DefaultStoreName):
>          CApp = "// Value in Dsc for Sku: %s, DefaultStore %s\n" % (SkuName, DefaultStoreName)
>          CApp = CApp + "void Assign_%s_%s_%s_%s_Value(%s *Pcd){\n" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, SkuName,
> DefaultStoreName, Pcd.BaseDatumType)
>          CApp = CApp + '  UINT32  FieldSize;\n'
>          CApp = CApp + '  CHAR8   *Value;\n'
> +        CApp = CApp + ' UINT32 PcdArraySize;\n'
> 
>          CApp = CApp + "// SkuName: %s,  DefaultStoreName: %s \n" % (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT)
>          inherit_OverrideValues = Pcd.SkuOverrideValues[SkuName]
> +        dscfilepath,lineno = self.GetPcdDscRawValueInfo(Pcd, SkuName, DefaultStoreName)
> +        if lineno:
> +            valuefrom = "%s Line %s" % (dscfilepath,str(lineno))
> +        else:
> +            valuefrom = dscfilepath
> 
>          pcddefaultvalue = self.GetPcdDscRawDefaultValue(Pcd, SkuName, DefaultStoreName)
>          if pcddefaultvalue:
>              FieldList = pcddefaultvalue
>              IsArray = _IsFieldValueAnArray(FieldList)
> @@ -2075,37 +2147,75 @@ class DscBuildData(PlatformBuildClassObject):
>              Value, ValueSize = ParseFieldValue (FieldList)
> 
>              if (SkuName, DefaultStoreName) == (TAB_DEFAULT, TAB_DEFAULT_STORES_DEFAULT):
>                  if isinstance(Value, str):
>                      if "{CODE(" in Value:
> -                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,
> DefaultStoreName)
> +                        if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
> +                            pcdarraysize = Pcd.PcdArraySize()
> +                            CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc
> exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,
> DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType, valuefrom)
> +                        CApp = CApp+ ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName, DefaultStoreName)
> +                        CApp = CApp + '  memcpy (Pcd, &%s_%s_%s_%s_Value,PcdArraySize);\n ' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName, DefaultStoreName)
>                      else:
>                          CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value,
> Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else
> Pcd.DefaultValue)
>                  elif IsArray:
> -                #
> -                # Use memcpy() to copy value into field
> -                #
> -                    if Pcd.IsArray() and "{CODE(" in pcddefaultvalue:
> -                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,
> DefaultStoreName)
> +                    #
> +                    # Use memcpy() to copy value into field
> +                    #
> +                    if Pcd.IsArray():
> +                        pcdarraysize = Pcd.PcdArraySize()
> +                        if "{CODE(" in pcddefaultvalue:
> +                            if Pcd.Capacity[-1] != "-1":
> +                                CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value
> in Dsc exceed the array capability %s"); // From  %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,
> DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
> +                            CApp = CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName, DefaultStoreName)
> +                            CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName, DefaultStoreName)
> +                        else:
> +                            if Pcd.Capacity[-1] != "-1":
> +                                CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array
> capability %s"); // From  %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,Pcd.DatumType,valuefrom)
> +                            CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
> +                            CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value,
> ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else
> Pcd.DefaultValue)
> +                            CApp = CApp + '  memcpy (Pcd, Value, PcdArraySize);\n'
>                      else:
> -                        CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value,
> ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else
> Pcd.DefaultValue)
> -                        CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
> +                        if "{CODE(" in pcddefaultvalue:
> +                            CApp = CApp + '  PcdArraySize = %d < sizeof(%s) * %d ? %d: sizeof(%s) * %d;\n ' %
> (ValueSize,Pcd.BaseDatumType,pcdarraysize,ValueSize,Pcd.BaseDatumType,pcdarraysize)
> +                            CApp = CApp + '  memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
> +                        else:
> +                            CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value,
> ValueSize), Pcd.DefaultFromDSC.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else
> Pcd.DefaultValue)
> +                            CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
>              else:
>                  if isinstance(Value, str):
>                      if "{CODE(" in Value:
> -                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,
> DefaultStoreName)
> +                        if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
> +                            pcdarraysize = Pcd.PcdArraySize()
> +                            CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value in Dsc
> exceed the array capability %s"); // From %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,
> DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
> +                        CApp = CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n '% (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName, DefaultStoreName)
> +                        CApp = CApp + '  memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName, DefaultStoreName)
>                      else:
>                          CApp = CApp + '  Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DscRawValue.get(SkuName,
> {}).get(DefaultStoreName))
>                  elif IsArray:
> -                #
> -                # Use memcpy() to copy value into field
> -                #
> -                    if Pcd.IsArray() and "{CODE(" in pcddefaultvalue:
> -                        CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, sizeof(%s_%s_%s_%s_Value));\n' %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,
> DefaultStoreName)
> +                    #
> +                    # Use memcpy() to copy value into field
> +                    #
> +                    if Pcd.IsArray():
> +                        pcdarraysize = Pcd.PcdArraySize()
> +                        if "{CODE(" in pcddefaultvalue:
> +                            if Pcd.Capacity[-1] != "-1":
> +                                CApp = CApp + '__STATIC_ASSERT(sizeof(%s_%s_%s_%s_Value) < %d * sizeof(%s), "Pcd %s.%s Value
> in Dsc exceed the array capability %s"); // From  %s \n' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName,
> DefaultStoreName,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName, Pcd.TokenCName,Pcd.DatumType,valuefrom)
> +                            CApp + ' PcdArraySize = sizeof(%s_%s_%s_%s_Value);\n ' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName, DefaultStoreName)
> +                            CApp = CApp + '  memcpy (Pcd, %s_%s_%s_%s_Value, PcdArraySize);\n' % (Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,SkuName, DefaultStoreName)
> +                        else:
> +                            if Pcd.Capacity[-1] != "-1":
> +                                CApp = CApp + '__STATIC_ASSERT(%d < %d * sizeof(%s), "Pcd %s.%s Value in Dsc exceed the array
> capability %s"); // From  %s \n' % (ValueSize,pcdarraysize,Pcd.BaseDatumType,Pcd.TokenSpaceGuidCName,
> Pcd.TokenCName,Pcd.DatumType,valuefrom)
> +                            CApp = CApp + ' PcdArraySize = %d;\n' % ValueSize
> +                            CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value,
> ValueSize), Pcd.DscRawValue.get(TAB_DEFAULT, {}).get(TAB_DEFAULT_STORES_DEFAULT, Pcd.DefaultValue) if Pcd.DefaultFromDSC else
> Pcd.DefaultValue)
> +                            CApp = CApp + '  memcpy (Pcd, Value, PcdArraySize);\n'
>                      else:
> -                        CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value,
> ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
> -                        CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
> +                        if "{CODE(" in pcddefaultvalue:
> +                            CApp = CApp + '  PcdArraySize = %d < sizeof(%s) * %d ? %d: sizeof(%s) * %d;\n ' %
> (ValueSize,Pcd.BaseDatumType,pcdarraysize,ValueSize,Pcd.BaseDatumType,pcdarraysize)
> +                            CApp = CApp + '  memcpy (Pcd, &%s_%s_%s_%s_Value, PcdArraySize);\n' %
> (Pcd.TokenSpaceGuidCName, Pcd.TokenCName,SkuName, DefaultStoreName)
> +                        else:
> +                            CApp = CApp + '  Value     = %s; // From DSC Default Value %s\n' % (DscBuildData.IntToCString(Value,
> ValueSize), Pcd.DscRawValue.get(SkuName, {}).get(DefaultStoreName))
> +                            CApp = CApp + '  memcpy (Pcd, Value, %d);\n' % (ValueSize)
> 
>          inheritvalue = inherit_OverrideValues.get(DefaultStoreName)
>          if not inheritvalue:
>              inheritvalue = []
>          for index in inheritvalue:
> @@ -2327,10 +2437,13 @@ class DscBuildData(PlatformBuildClassObject):
>              # the flexible array member.  The flexible array member must be the last field
>              # in a structure.  The size formula for this case is:
>              # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
>              #
>              CApp = CApp + DscBuildData.GenerateSizeStatments(Pcd,SkuName,DefaultStoreName)
> +            if Pcd.IsArray() and Pcd.Capacity[-1] != "-1":
> +                CApp = CApp + '  OriginalSize = OriginalSize < sizeof(%s) * %d? OriginalSize:sizeof(%s) * %d; \n' %
> (Pcd.BaseDatumType,Pcd.PcdArraySize(),Pcd.BaseDatumType,Pcd.PcdArraySize())
> +                CApp = CApp + '  Size = sizeof(%s) * %d; \n' % (Pcd.BaseDatumType,Pcd.PcdArraySize())
> 
>              #
>              # Allocate and zero buffer for the PCD
>              # Must handle cases where current value is smaller, larger, or same size
>              # Always keep that larger one as the current size
> @@ -2377,12 +2490,10 @@ class DscBuildData(PlatformBuildClassObject):
> 
>      def GenerateArrayAssignment(self, Pcd):
>          CApp = ""
>          if not Pcd:
>              return CApp
> -        if not Pcd.IsArray():
> -            return CApp
>          Demesion = ""
>          for d in Pcd.Capacity:
>              Demesion += "[]"
> 
>          Value = Pcd.DefaultValueFromDec
> @@ -2770,11 +2881,13 @@ class DscBuildData(PlatformBuildClassObject):
>                                                      None,
>                                                      IsDsc=True)
> 
>              if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
>                  Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
> +                Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
>              Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = PcdValue
> +            Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] =
> (self.MetaFile.File,Dummy4)
> 
>          for pcd in Pcds.values():
>              pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
>              # Only fix the value while no value provided in DSC file.
>              for sku in pcd.SkuInfoList.values():
> @@ -2972,11 +3085,13 @@ class DscBuildData(PlatformBuildClassObject):
>                  Pcds[PcdCName, TokenSpaceGuid] = PcdClassObj
> 
>                  Pcds[PcdCName, TokenSpaceGuid].CustomAttribute['DscPosition'] = int(Dummy4)
>              if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
>                  Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
> +                Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
>              Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][DefaultStore] = DefaultValue
> +            Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][DefaultStore] = (self.MetaFile.File,Dummy4)
>          for pcd in Pcds.values():
>              pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
>              pcd.DatumType = pcdDecObject.DatumType
>              # Only fix the value while no value provided in DSC file.
>              for sku in pcd.SkuInfoList.values():
> @@ -3110,11 +3225,13 @@ class DscBuildData(PlatformBuildClassObject):
>                                                  None,
>                                                  IsDsc=True)
> 
>              if SkuName not in Pcds[PcdCName, TokenSpaceGuid].DscRawValue:
>                  Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName] = {}
> +                Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName] = {}
>              Pcds[PcdCName, TokenSpaceGuid].DscRawValue[SkuName][TAB_DEFAULT_STORES_DEFAULT] = InitialValue
> +            Pcds[PcdCName, TokenSpaceGuid].DscRawValueInfo[SkuName][TAB_DEFAULT_STORES_DEFAULT] =
> (self.MetaFile.File,Dummy4)
>          for pcd in Pcds.values():
>              pcdDecObject = self._DecPcds[pcd.TokenCName, pcd.TokenSpaceGuidCName]
>              pcd.DatumType = pcdDecObject.DatumType
>              # Only fix the value while no value provided in DSC file.
>              for sku in pcd.SkuInfoList.values():
> --
> 2.18.0.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#40224): https://edk2.groups.io/g/devel/message/40224
Mute This Topic: https://groups.io/mt/31515987/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-