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.

The patch is tested minplatform, Ovmf, structure pcd regression test
These tests are build pass. The patch also tested the following cases.
Our cases focused on PcdArraySize. 1.flexiable PcdArraySize.
 2.Fixed PcdArraySize, Pcd overall value exceeds the size of PcdArray.
 3.Fixed PcdArraySize, Pcd overall value Not exceeds the size of PcdArray.

Signed-off-by: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
Fan, ZhijuX
2019-05-09 17:19:56 +08:00
committed by Feng, Bob C
parent 70023bab7e
commit afe8c4110c
4 changed files with 219 additions and 75 deletions

View File

@ -10,10 +10,12 @@ 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
@ -62,6 +64,7 @@ class PcdClassObject(object):
self.expressions = expressions if expressions is not None else []
self.DscDefaultValue = None
self.DscRawValue = {}
self.DscRawValueInfo = {}
if IsDsc:
self.DscDefaultValue = Value
self.PcdValueFromComm = ""
@ -72,30 +75,47 @@ class PcdClassObject(object):
@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
@ -227,6 +247,7 @@ class PcdClassObject(object):
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]
@ -262,6 +283,7 @@ class StructurePcd(PcdClassObject):
self.PcdDefineLineNo = 0
self.PkgPath = ""
self.DefaultValueFromDec = ""
self.DefaultValueFromDecInfo = None
self.ValueChain = set()
self.PcdFieldValueFromComm = OrderedDict()
self.PcdFieldValueFromFdf = OrderedDict()
@ -277,8 +299,9 @@ class StructurePcd(PcdClassObject):
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()
@ -313,6 +336,7 @@ class StructurePcd(PcdClassObject):
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
@ -323,6 +347,7 @@ class StructurePcd(PcdClassObject):
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
@ -336,6 +361,7 @@ class StructurePcd(PcdClassObject):
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