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)): 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])] 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 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] 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*")] 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()] 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): def process_variable_data(self):
var_data = dict() var_data = dict()

View File

@ -114,6 +114,7 @@ class StructurePcd(PcdClassObject):
if validateranges is None: validateranges=[] if validateranges is None: validateranges=[]
if validlists is None: validlists=[] if validlists is None: validlists=[]
if expressions is None : expressions=[] 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) 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.StructuredPcdIncludeFile = [] if StructuredPcdIncludeFile is None else StructuredPcdIncludeFile
self.PackageDecs = Packages 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.AddDefaultValue(item.TokenCName, item.DefaultValue,self.MetaFile.File,LineNo)
struct_pcd.PackageDecs = dep_pkgs 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) str_pcd_set.append(struct_pcd)
@ -423,11 +425,6 @@ class DecBuildData(PackageBuildClassObject):
continue continue
DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting) 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) validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)
PcdObj = PcdClassObject( PcdObj = PcdClassObject(
PcdCName, PcdCName,

View File

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