BaseTool: Fixed Pcd issues.

1. Check variable offset when merging Hii Pcds
2. Fixed the issue of Hii value inherit with default store.
3. Error handling for incorrect structure pcd declare.

Contributed-under: TianoCore Contribution Agreement 1.1
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:
Feng, Bob C 2018-02-07 10:01:59 +08:00 committed by Liming Gao
parent c60d751b73
commit 8aa4db4b80
4 changed files with 100 additions and 79 deletions

View File

@ -104,10 +104,27 @@ class VariableMgr(object):
for data_byte in pack(data_flag,int(data,16) if data.upper().startswith('0X') else int(data)):
value_list += [hex(unpack("B",data_byte)[0])]
newvalue[int(item.var_offset,16) if item.var_offset.upper().startswith("0X") else int(item.var_offset)] = value_list
newvaluestr = "{" + ",".join(reduce(lambda x,y: x+y, [newvalue[k] for k in sorted(newvalue.keys())] )) +"}"
try:
newvaluestr = "{" + ",".join(self.assemble_variable(newvalue)) +"}"
except:
EdkLogger.error("build", AUTOGEN_ERROR, "Variable offset conflict in PCDs: %s \n" % (" and ".join([item.pcdname for item in sku_var_info_offset_list])))
n = sku_var_info_offset_list[0]
indexedvarinfo[key] = [var_info(n.pcdindex,n.pcdname,n.defaultstoragename,n.skuname,n.var_name, n.var_guid, "0x00",n.var_attribute,newvaluestr , newvaluestr , "VOID*")]
self.VarInfo = [item[0] for item in indexedvarinfo.values()]
def assemble_variable(self, valuelist):
ordered_value = [valuelist[k] for k in sorted(valuelist.keys())]
ordered_offset = sorted(valuelist.keys())
var_value = []
num = 0
for offset in ordered_offset:
if offset < len(var_value):
raise
for _ in xrange(offset - len(var_value)):
var_value.append('0x00')
var_value += ordered_value[num]
num +=1
return var_value
def process_variable_data(self):
var_data = dict()

View File

@ -114,6 +114,7 @@ class StructurePcd(PcdClassObject):
if validateranges is None: validateranges=[]
if validlists is None: validlists=[]
if expressions is None : expressions=[]
if Packages is None : Packages = []
super(StructurePcd, self).__init__(Name, Guid, Type, DatumType, Value, Token, MaxDatumSize, SkuInfoList, IsOverrided, GuidValue, validateranges, validlists, expressions)
self.StructuredPcdIncludeFile = [] if StructuredPcdIncludeFile is None else StructuredPcdIncludeFile
self.PackageDecs = Packages

View File

@ -389,6 +389,8 @@ class DecBuildData(PackageBuildClassObject):
struct_pcd.AddDefaultValue(item.TokenCName, item.DefaultValue,self.MetaFile.File,LineNo)
struct_pcd.PackageDecs = dep_pkgs
if not struct_pcd.StructuredPcdIncludeFile:
EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "The structure Pcd %s.%s header file is not found in %s line %s \n" % (struct_pcd.TokenSpaceGuidCName, struct_pcd.TokenCName,self.MetaFile.File,LineNo ))
str_pcd_set.append(struct_pcd)
@ -423,11 +425,6 @@ class DecBuildData(PackageBuildClassObject):
continue
DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)
if DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]:
StructPattern = re.compile(r'[_a-zA-Z][0-9A-Za-z_]*$')
if StructPattern.match(DatumType) == None:
EdkLogger.error('build', FORMAT_INVALID, "DatumType only support BOOLEAN, UINT8, UINT16, UINT32, UINT64, VOID* or a valid struct name.", File=self.MetaFile, Line=LineNo)
validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)
PcdObj = PcdClassObject(
PcdCName,

View File

@ -1584,6 +1584,7 @@ class DscBuildData(PlatformBuildClassObject):
# OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1)
#
CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.DatumType)
CApp = CApp + "// Default Value in Dec \n"
for FieldList in [Pcd.DefaultValues]:
if not FieldList:
continue
@ -1611,31 +1612,34 @@ class DscBuildData(PlatformBuildClassObject):
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])
for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]
for FieldList in [inherit_OverrideValues.get(DefaultStoreName)]:
if not FieldList:
continue
for FieldName in FieldList:
FieldName = "." + FieldName
IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
if IsArray:
try:
Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
except BadExpression:
EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
(".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
Value, ValueSize = ParseFieldValue(Value)
CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
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])
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 %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName]
for defaultstorenameitem in storeset:
CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
for FieldList in [inherit_OverrideValues.get(defaultstorenameitem)]:
if not FieldList:
continue
for FieldName in FieldList:
FieldName = "." + FieldName
IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0])
if IsArray:
try:
Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True)
except BadExpression:
EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
(".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName.strip('.'))), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2]))
Value, ValueSize = ParseFieldValue(Value)
CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s) + ((%d %% __ARRAY_ELEMENT_SIZE(%s, %s)) ? 1 : 0)); // From %s Line %d Value %s\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip("."), FieldList[FieldName.strip(".")][1], FieldList[FieldName.strip(".")][2], FieldList[FieldName.strip(".")][0]);
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])
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 %d Value %s \n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1, FieldList[FieldName_ori][1], FieldList[FieldName_ori][2], FieldList[FieldName_ori][0])
if skuname == SkuName:
break
@ -1656,6 +1660,7 @@ class DscBuildData(PlatformBuildClassObject):
#
# Assign field values in PCD
#
CApp = CApp + "// Default value in Dec \n"
for FieldList in [Pcd.DefaultValues]:
if not FieldList:
continue
@ -1688,56 +1693,56 @@ class DscBuildData(PlatformBuildClassObject):
CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
for skuname in self.SkuIdMgr.GetSkuChain(SkuName):
inherit_OverrideValues = Pcd.SkuOverrideValues[skuname]
for FieldList in [Pcd.DefaultFromDSC,inherit_OverrideValues.get(DefaultStoreName)]:
if not FieldList:
continue
if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC:
IsArray = self.IsFieldValueAnArray(FieldList)
if IsArray:
storeset = [DefaultStoreName] if DefaultStoreName == 'STANDARD' else ['STANDARD', DefaultStoreName]
for defaultstorenameitem in storeset:
CApp = CApp + "// SkuName: %s, DefaultStoreName: %s \n" % (skuname, defaultstorenameitem)
for FieldList in [Pcd.DefaultFromDSC,inherit_OverrideValues.get(defaultstorenameitem)]:
if not FieldList:
continue
if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC:
IsArray = self.IsFieldValueAnArray(FieldList)
if IsArray:
try:
FieldList = ValueExpressionEx(FieldList, "VOID*")(True)
except BadExpression:
EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
Value, ValueSize = ParseFieldValue (FieldList)
if isinstance(Value, str):
CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC)
elif IsArray:
#
# Use memcpy() to copy value into field
#
CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC)
CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
continue
for FieldName in FieldList:
IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])
if IsArray:
try:
FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)
except BadExpression:
EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
(".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
try:
FieldList = ValueExpressionEx(FieldList, "VOID*")(True)
except BadExpression:
EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" %
(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList))
Value, ValueSize = ParseFieldValue (FieldList)
if isinstance(Value, str):
CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC)
elif IsArray:
#
# Use memcpy() to copy value into field
#
CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC)
CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize)
continue
for FieldName in FieldList:
IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0])
if IsArray:
try:
FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True)
except BadExpression:
EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " %
(".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldName)), FieldList[FieldName][1], FieldList[FieldName][2]))
try:
Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
except Exception:
EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))
if isinstance(Value, str):
CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
elif IsArray:
#
# Use memcpy() to copy value into field
#
CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
else:
if ValueSize > 4:
CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
Value, ValueSize = ParseFieldValue (FieldList[FieldName][0])
except Exception:
EdkLogger.error('Build', FORMAT_INVALID, "Invalid value format for %s. From %s Line %d " % (".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName,FieldName)),FieldList[FieldName][1], FieldList[FieldName][2]))
if isinstance(Value, str):
CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
elif IsArray:
#
# Use memcpy() to copy value into field
#
CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName)
CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize)
else:
CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
if ValueSize > 4:
CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
else:
CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0])
if skuname == SkuName:
break
#
@ -2350,6 +2355,7 @@ class DscBuildData(PlatformBuildClassObject):
for pcd in Pcds.values():
SkuInfoObj = pcd.SkuInfoList.values()[0]
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():
if (sku.DefaultValue == "" or sku.DefaultValue==None):