From 8aa4db4b807ea7de395acd4018a139745327e374 Mon Sep 17 00:00:00 2001 From: "Feng, Bob C" Date: Wed, 7 Feb 2018 10:01:59 +0800 Subject: [PATCH] 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 Cc: Liming Gao Reviewed-by: Liming Gao --- BaseTools/Source/Python/AutoGen/GenVar.py | 19 ++- .../Python/Workspace/BuildClassObject.py | 1 + .../Source/Python/Workspace/DecBuildData.py | 7 +- .../Source/Python/Workspace/DscBuildData.py | 152 +++++++++--------- 4 files changed, 100 insertions(+), 79 deletions(-) diff --git a/BaseTools/Source/Python/AutoGen/GenVar.py b/BaseTools/Source/Python/AutoGen/GenVar.py index 1389d7ff62..d222e6ed5e 100644 --- a/BaseTools/Source/Python/AutoGen/GenVar.py +++ b/BaseTools/Source/Python/AutoGen/GenVar.py @@ -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() diff --git a/BaseTools/Source/Python/Workspace/BuildClassObject.py b/BaseTools/Source/Python/Workspace/BuildClassObject.py index 0e1161c96f..f499cbd58b 100644 --- a/BaseTools/Source/Python/Workspace/BuildClassObject.py +++ b/BaseTools/Source/Python/Workspace/BuildClassObject.py @@ -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 diff --git a/BaseTools/Source/Python/Workspace/DecBuildData.py b/BaseTools/Source/Python/Workspace/DecBuildData.py index 2266b0b7a6..99c3bf14f1 100644 --- a/BaseTools/Source/Python/Workspace/DecBuildData.py +++ b/BaseTools/Source/Python/Workspace/DecBuildData.py @@ -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, diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index d9165f2ac7..01592e147e 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -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):