mirror of https://github.com/acidanthera/audk.git
351 lines
12 KiB
Python
351 lines
12 KiB
Python
# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
|
|
# This program and the accompanying materials
|
|
# are licensed and made available under the terms and conditions of the BSD License
|
|
# which accompanies this distribution. The full text of the license may be found at
|
|
# http://opensource.org/licenses/bsd-license.php
|
|
#
|
|
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
#
|
|
# This file is used to collect the Variable checking information
|
|
#
|
|
|
|
# #
|
|
# Import Modules
|
|
#
|
|
import os
|
|
from Common.RangeExpression import RangeExpression
|
|
from Common.Misc import *
|
|
from StringIO import StringIO
|
|
from struct import pack
|
|
|
|
class VAR_CHECK_PCD_VARIABLE_TAB_CONTAINER(object):
|
|
def __init__(self):
|
|
self.var_check_info = []
|
|
|
|
def push_back(self, var_check_tab):
|
|
for tab in self.var_check_info:
|
|
if tab.equal(var_check_tab):
|
|
tab.merge(var_check_tab)
|
|
break
|
|
else:
|
|
self.var_check_info.append(var_check_tab)
|
|
|
|
def dump(self, dest, Phase):
|
|
|
|
FormatMap = {}
|
|
FormatMap[1] = "=B"
|
|
FormatMap[2] = "=H"
|
|
FormatMap[4] = "=L"
|
|
FormatMap[8] = "=Q"
|
|
|
|
if not os.path.isabs(dest):
|
|
return
|
|
if not os.path.exists(dest):
|
|
os.mkdir(dest)
|
|
BinFileName = "PcdVarCheck.bin"
|
|
BinFilePath = os.path.join(dest, BinFileName)
|
|
Buffer = ''
|
|
index = 0
|
|
for var_check_tab in self.var_check_info:
|
|
index += 1
|
|
realLength = 0
|
|
realLength += 32
|
|
Name = var_check_tab.Name[1:-1]
|
|
NameChars = Name.split(",")
|
|
realLength += len(NameChars)
|
|
if (index < len(self.var_check_info) and realLength % 4) or (index == len(self.var_check_info) and len(var_check_tab.validtab) > 0 and realLength % 4):
|
|
realLength += (4 - (realLength % 4))
|
|
itemIndex = 0
|
|
for item in var_check_tab.validtab:
|
|
itemIndex += 1
|
|
realLength += 5
|
|
for v_data in item.data:
|
|
if type(v_data) in (int, long):
|
|
realLength += item.StorageWidth
|
|
else:
|
|
realLength += item.StorageWidth
|
|
realLength += item.StorageWidth
|
|
if (index == len(self.var_check_info)) :
|
|
if (itemIndex < len(var_check_tab.validtab)) and realLength % 4:
|
|
realLength += (4 - (realLength % 4))
|
|
else:
|
|
if realLength % 4:
|
|
realLength += (4 - (realLength % 4))
|
|
var_check_tab.Length = realLength
|
|
realLength = 0
|
|
index = 0
|
|
for var_check_tab in self.var_check_info:
|
|
index += 1
|
|
|
|
b = pack("=H", var_check_tab.Revision)
|
|
Buffer += b
|
|
realLength += 2
|
|
|
|
b = pack("=H", var_check_tab.HeaderLength)
|
|
Buffer += b
|
|
realLength += 2
|
|
|
|
b = pack("=L", var_check_tab.Length)
|
|
Buffer += b
|
|
realLength += 4
|
|
|
|
b = pack("=B", var_check_tab.Type)
|
|
Buffer += b
|
|
realLength += 1
|
|
|
|
for i in range(0, 3):
|
|
b = pack("=B", var_check_tab.Reserved)
|
|
Buffer += b
|
|
realLength += 1
|
|
|
|
b = pack("=L", var_check_tab.Attributes)
|
|
Buffer += b
|
|
realLength += 4
|
|
|
|
Guid = var_check_tab.Guid
|
|
b = pack('=LHHBBBBBBBB',
|
|
Guid[0],
|
|
Guid[1],
|
|
Guid[2],
|
|
Guid[3],
|
|
Guid[4],
|
|
Guid[5],
|
|
Guid[6],
|
|
Guid[7],
|
|
Guid[8],
|
|
Guid[9],
|
|
Guid[10],
|
|
)
|
|
Buffer += b
|
|
realLength += 16
|
|
|
|
Name = var_check_tab.Name[1:-1]
|
|
NameChars = Name.split(",")
|
|
for NameChar in NameChars:
|
|
NameCharNum = int(NameChar, 16)
|
|
b = pack("=B", NameCharNum)
|
|
Buffer += b
|
|
realLength += 1
|
|
|
|
if (index < len(self.var_check_info) and realLength % 4) or (index == len(self.var_check_info) and len(var_check_tab.validtab) > 0 and realLength % 4):
|
|
for i in range(4 - (realLength % 4)):
|
|
b = pack("=B", var_check_tab.pad)
|
|
Buffer += b
|
|
realLength += 1
|
|
itemIndex = 0
|
|
for item in var_check_tab.validtab:
|
|
itemIndex += 1
|
|
|
|
b = pack("=B", item.Type)
|
|
Buffer += b
|
|
realLength += 1
|
|
|
|
b = pack("=B", item.Length)
|
|
Buffer += b
|
|
realLength += 1
|
|
|
|
b = pack("=H", int(item.VarOffset, 16))
|
|
Buffer += b
|
|
realLength += 2
|
|
|
|
b = pack("=B", item.StorageWidth)
|
|
Buffer += b
|
|
realLength += 1
|
|
for v_data in item.data:
|
|
if type(v_data) in (int, long):
|
|
b = pack(FormatMap[item.StorageWidth], v_data)
|
|
Buffer += b
|
|
realLength += item.StorageWidth
|
|
else:
|
|
b = pack(FormatMap[item.StorageWidth], v_data[0])
|
|
Buffer += b
|
|
realLength += item.StorageWidth
|
|
b = pack(FormatMap[item.StorageWidth], v_data[1])
|
|
Buffer += b
|
|
realLength += item.StorageWidth
|
|
|
|
if (index == len(self.var_check_info)) :
|
|
if (itemIndex < len(var_check_tab.validtab)) and realLength % 4:
|
|
for i in range(4 - (realLength % 4)):
|
|
b = pack("=B", var_check_tab.pad)
|
|
Buffer += b
|
|
realLength += 1
|
|
else:
|
|
if realLength % 4:
|
|
for i in range(4 - (realLength % 4)):
|
|
b = pack("=B", var_check_tab.pad)
|
|
Buffer += b
|
|
realLength += 1
|
|
|
|
DbFile = StringIO()
|
|
if Phase == 'DXE' and os.path.exists(BinFilePath):
|
|
BinFile = open(BinFilePath, "rb")
|
|
BinBuffer = BinFile.read()
|
|
BinFile.close()
|
|
BinBufferSize = len(BinBuffer)
|
|
if (BinBufferSize % 4):
|
|
for i in range(4 - (BinBufferSize % 4)):
|
|
b = pack("=B", VAR_CHECK_PCD_VARIABLE_TAB.pad)
|
|
BinBuffer += b
|
|
Buffer = BinBuffer + Buffer
|
|
DbFile.write(Buffer)
|
|
SaveFileOnChange(BinFilePath, DbFile.getvalue(), True)
|
|
|
|
|
|
class VAR_CHECK_PCD_VARIABLE_TAB(object):
|
|
pad = 0xDA
|
|
def __init__(self, TokenSpaceGuid, PcdCName):
|
|
self.Revision = 0x0001
|
|
self.HeaderLength = 0
|
|
self.Length = 0 # Length include this header
|
|
self.Type = 0
|
|
self.Reserved = 0
|
|
self.Attributes = 0x00000000
|
|
self.Guid = eval("[" + TokenSpaceGuid.replace("{", "").replace("}", "") + "]")
|
|
self.Name = PcdCName
|
|
self.validtab = []
|
|
|
|
def UpdateSize(self):
|
|
self.HeaderLength = 32 + len(self.Name.split(","))
|
|
self.Length = 32 + len(self.Name.split(",")) + self.GetValidTabLen()
|
|
|
|
def GetValidTabLen(self):
|
|
validtablen = 0
|
|
for item in self.validtab:
|
|
validtablen += item.Length
|
|
return validtablen
|
|
|
|
def SetAttributes(self, attributes):
|
|
self.Attributes = attributes
|
|
|
|
def push_back(self, valid_obj):
|
|
if valid_obj is not None:
|
|
self.validtab.append(valid_obj)
|
|
|
|
def equal(self, varchecktab):
|
|
if self.Guid == varchecktab.Guid and self.Name == varchecktab.Name:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
def merge(self, varchecktab):
|
|
for validobj in varchecktab.validtab:
|
|
if validobj in self.validtab:
|
|
continue
|
|
self.validtab.append(validobj)
|
|
self.UpdateSize()
|
|
|
|
|
|
class VAR_CHECK_PCD_VALID_OBJ(object):
|
|
def __init__(self, VarOffset, data, PcdDataType):
|
|
self.Type = 1
|
|
self.Length = 0 # Length include this header
|
|
self.VarOffset = VarOffset
|
|
self.StorageWidth = 0
|
|
self.PcdDataType = PcdDataType.strip()
|
|
self.rawdata = data
|
|
self.data = set()
|
|
self.ValidData = True
|
|
self.updateStorageWidth()
|
|
def updateStorageWidth(self):
|
|
if self.PcdDataType == "UINT8" or self.PcdDataType == "BOOLEAN":
|
|
self.StorageWidth = 1
|
|
elif self.PcdDataType == "UINT16":
|
|
self.StorageWidth = 2
|
|
elif self.PcdDataType == "UINT32":
|
|
self.StorageWidth = 4
|
|
elif self.PcdDataType == "UINT64":
|
|
self.StorageWidth = 8
|
|
else:
|
|
self.StorageWidth = 0
|
|
self.ValidData = False
|
|
|
|
def __eq__(self, validObj):
|
|
if self.VarOffset == validObj.VarOffset:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
class VAR_CHECK_PCD_VALID_LIST(VAR_CHECK_PCD_VALID_OBJ):
|
|
def __init__(self, VarOffset, validlist, PcdDataType):
|
|
super(VAR_CHECK_PCD_VALID_LIST, self).__init__(VarOffset, validlist, PcdDataType)
|
|
self.Type = 1
|
|
self.update_data()
|
|
self.update_size()
|
|
def update_data(self):
|
|
valid_num_list = []
|
|
data_list = []
|
|
for item in self.rawdata:
|
|
valid_num_list.extend(item.split(','))
|
|
|
|
for valid_num in valid_num_list:
|
|
valid_num = valid_num.strip()
|
|
|
|
if valid_num.startswith('0x') or valid_num.startswith('0X'):
|
|
data_list.append(int(valid_num, 16))
|
|
else:
|
|
data_list.append(int(valid_num))
|
|
|
|
|
|
self.data = set(data_list)
|
|
|
|
def update_size(self):
|
|
self.Length = 5 + len(self.data) * self.StorageWidth
|
|
|
|
|
|
class VAR_CHECK_PCD_VALID_RANGE(VAR_CHECK_PCD_VALID_OBJ):
|
|
def __init__(self, VarOffset, validrange, PcdDataType):
|
|
super(VAR_CHECK_PCD_VALID_RANGE, self).__init__(VarOffset, validrange, PcdDataType)
|
|
self.Type = 2
|
|
self.update_data()
|
|
self.update_size()
|
|
def update_data(self):
|
|
RangeExpr = ""
|
|
data_list = []
|
|
i = 0
|
|
for item in self.rawdata:
|
|
if i == 0:
|
|
RangeExpr = "( " + item + " )"
|
|
else:
|
|
RangeExpr = RangeExpr + "OR ( " + item + " )"
|
|
range_result = RangeExpression(RangeExpr, self.PcdDataType)(True)
|
|
for rangelist in range_result:
|
|
for obj in rangelist.pop():
|
|
data_list.append((obj.start, obj.end))
|
|
self.data = set(data_list)
|
|
|
|
def update_size(self):
|
|
self.Length = 5 + len(self.data) * 2 * self.StorageWidth
|
|
|
|
|
|
class VAR_VALID_OBJECT_FACTORY(object):
|
|
def __init__(self):
|
|
pass
|
|
@staticmethod
|
|
def Get_valid_object(PcdClass, VarOffset):
|
|
if PcdClass.validateranges:
|
|
return VAR_CHECK_PCD_VALID_RANGE(VarOffset, PcdClass.validateranges, PcdClass.DatumType)
|
|
if PcdClass.validlists:
|
|
return VAR_CHECK_PCD_VALID_LIST(VarOffset, PcdClass.validlists, PcdClass.DatumType)
|
|
else:
|
|
return None
|
|
|
|
if __name__ == "__main__":
|
|
class TestObj(object):
|
|
def __init__(self, number1):
|
|
self.number_1 = number1
|
|
def __eq__(self, testobj):
|
|
if self.number_1 == testobj.number_1:
|
|
return True
|
|
else:
|
|
return False
|
|
test1 = TestObj(1)
|
|
test2 = TestObj(2)
|
|
|
|
testarr = [test1, test2]
|
|
print TestObj(2) in testarr
|
|
print TestObj(2) == test2
|
|
|