Sync BaseTools Trunk (version r2387) to EDKII main trunk.
Signed-off-by: lgao4 Reviewed-by: gikidy git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12602 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -79,11 +79,11 @@ class AprioriSection (AprioriSectionClassObject):
|
||||
InfFileName = GenFdsGlobalVariable.MacroExtend(InfFileName, Dict, Arch)
|
||||
|
||||
if Arch != None:
|
||||
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), Arch]
|
||||
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
Guid = Inf.Guid
|
||||
|
||||
else:
|
||||
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), 'COMMON']
|
||||
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
Guid = Inf.Guid
|
||||
|
||||
self.BinFileList = Inf.Module.Binaries
|
||||
|
@@ -39,7 +39,10 @@ class DepexSection (DepexSectionClassObject):
|
||||
|
||||
def __FindGuidValue(self, CName):
|
||||
for Arch in GenFdsGlobalVariable.ArchList:
|
||||
for PkgDb in GenFdsGlobalVariable.WorkSpace.PackageList:
|
||||
for PkgDb in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,
|
||||
Arch,
|
||||
GenFdsGlobalVariable.TargetName,
|
||||
GenFdsGlobalVariable.ToolChainTag):
|
||||
if CName in PkgDb.Ppis:
|
||||
return PkgDb.Ppis[CName]
|
||||
if CName in PkgDb.Protocols:
|
||||
|
@@ -71,11 +71,11 @@ class FD(FDClassObject):
|
||||
|
||||
for RegionObj in self.RegionList :
|
||||
if RegionObj.RegionType == 'CAPSULE':
|
||||
continue
|
||||
continue
|
||||
if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
|
||||
pass
|
||||
pass
|
||||
elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
|
||||
pass
|
||||
pass
|
||||
elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
|
||||
GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
|
||||
PadRegion = Region.Region()
|
||||
@@ -88,7 +88,7 @@ class FD(FDClassObject):
|
||||
# Call each region's AddToBuffer function
|
||||
#
|
||||
if PreviousRegionSize > self.Size:
|
||||
pass
|
||||
pass
|
||||
GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
|
||||
RegionObj.AddToBuffer (TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFds.ImageBinDict, self.vtfRawDict, self.DefineVarDict)
|
||||
|
||||
|
@@ -15,6 +15,8 @@
|
||||
##
|
||||
# Import Modules
|
||||
#
|
||||
import re
|
||||
|
||||
import Fd
|
||||
import Region
|
||||
import Fv
|
||||
@@ -45,6 +47,8 @@ from Common.BuildToolError import *
|
||||
from Common import EdkLogger
|
||||
from Common.Misc import PathClass
|
||||
from Common.String import NormPath
|
||||
import Common.GlobalData as GlobalData
|
||||
from Common.Expression import *
|
||||
from Common import GlobalData
|
||||
|
||||
import re
|
||||
@@ -68,6 +72,9 @@ T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_
|
||||
|
||||
SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
|
||||
|
||||
RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
|
||||
RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
|
||||
|
||||
IncludeFileList = []
|
||||
# Macro passed from command line, which has greatest priority and can NOT be overridden by those in FDF
|
||||
InputMacroDict = {}
|
||||
@@ -211,6 +218,10 @@ class FdfParser:
|
||||
if GenFdsGlobalVariable.WorkSpaceDir == '':
|
||||
GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")
|
||||
|
||||
InputMacroDict.update(GlobalData.gPlatformDefines)
|
||||
InputMacroDict.update(GlobalData.gGlobalDefines)
|
||||
InputMacroDict.update(GlobalData.gCommandLineDefines)
|
||||
|
||||
## __IsWhiteSpace() method
|
||||
#
|
||||
# Whether char at current FileBufferPos is whitespace
|
||||
@@ -317,10 +328,10 @@ class FdfParser:
|
||||
#
|
||||
def __GetOneChar(self):
|
||||
if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
|
||||
self.CurrentLineNumber += 1
|
||||
self.CurrentOffsetWithinLine = 0
|
||||
self.CurrentLineNumber += 1
|
||||
self.CurrentOffsetWithinLine = 0
|
||||
else:
|
||||
self.CurrentOffsetWithinLine += 1
|
||||
self.CurrentOffsetWithinLine += 1
|
||||
|
||||
## __CurrentChar() method
|
||||
#
|
||||
@@ -564,7 +575,7 @@ class FdfParser:
|
||||
self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)
|
||||
|
||||
self.Rewind()
|
||||
|
||||
|
||||
def __GetIfListCurrentItemStat(self, IfList):
|
||||
if len(IfList) == 0:
|
||||
return True
|
||||
@@ -574,8 +585,7 @@ class FdfParser:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
||||
## PreprocessConditionalStatement() method
|
||||
#
|
||||
# Preprocess conditional statement.
|
||||
@@ -586,9 +596,10 @@ class FdfParser:
|
||||
def PreprocessConditionalStatement(self):
|
||||
# IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
|
||||
IfList = []
|
||||
RegionLayoutLine = 0
|
||||
while self.__GetNextToken():
|
||||
if self.__Token == 'DEFINE':
|
||||
if self.__GetIfListCurrentItemStat(IfList):
|
||||
if self.__GetIfListCurrentItemStat(IfList):
|
||||
DefineLine = self.CurrentLineNumber - 1
|
||||
DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE')
|
||||
if not self.__GetNextToken():
|
||||
@@ -609,60 +620,48 @@ class FdfParser:
|
||||
MacProfile.MacroName = Macro
|
||||
MacProfile.MacroValue = Value
|
||||
AllMacroList.append(MacProfile)
|
||||
InputMacroDict[MacProfile.MacroName] = MacProfile.MacroValue
|
||||
self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
|
||||
elif self.__Token == 'SET':
|
||||
PcdPair = self.__GetNextPcdName()
|
||||
PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])
|
||||
if not self.__IsToken( "="):
|
||||
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
|
||||
|
||||
if not self.__GetNextToken():
|
||||
raise Warning("expected value", self.FileName, self.CurrentLineNumber)
|
||||
|
||||
Value = self.__Token
|
||||
if Value.startswith("{"):
|
||||
# deal with value with {}
|
||||
if not self.__SkipToToken( "}"):
|
||||
raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
|
||||
Value += self.__SkippedChars
|
||||
|
||||
InputMacroDict[PcdName] = Value
|
||||
elif self.__Token in ('!ifdef', '!ifndef', '!if'):
|
||||
IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
|
||||
IfList.append([IfStartPos, None, None])
|
||||
|
||||
CondLabel = self.__Token
|
||||
Expression = self.__GetExpression()
|
||||
|
||||
MacroName, NotFlag = self.__GetMacroName()
|
||||
NotDefineFlag = False
|
||||
if CondLabel == '!ifndef':
|
||||
NotDefineFlag = True
|
||||
if CondLabel == '!ifdef' or CondLabel == '!ifndef':
|
||||
if NotFlag:
|
||||
raise Warning("'NOT' operation not allowed for Macro name", self.FileName, self.CurrentLineNumber)
|
||||
|
||||
if CondLabel == '!if':
|
||||
|
||||
if not self.__GetNextOp():
|
||||
raise Warning("expected !endif", self.FileName, self.CurrentLineNumber)
|
||||
|
||||
if self.__Token in ('!=', '==', '>', '<', '>=', '<='):
|
||||
Op = self.__Token
|
||||
if not self.__GetNextToken():
|
||||
raise Warning("expected value", self.FileName, self.CurrentLineNumber)
|
||||
if self.__GetStringData():
|
||||
pass
|
||||
MacroValue = self.__Token
|
||||
ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue)
|
||||
if NotFlag:
|
||||
ConditionSatisfied = not ConditionSatisfied
|
||||
BranchDetermined = ConditionSatisfied
|
||||
else:
|
||||
self.CurrentOffsetWithinLine -= len(self.__Token)
|
||||
ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool')
|
||||
if NotFlag:
|
||||
ConditionSatisfied = not ConditionSatisfied
|
||||
BranchDetermined = ConditionSatisfied
|
||||
IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
|
||||
if ConditionSatisfied:
|
||||
self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
|
||||
|
||||
ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
|
||||
else:
|
||||
ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1)
|
||||
if NotDefineFlag:
|
||||
ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')
|
||||
if CondLabel == '!ifndef':
|
||||
ConditionSatisfied = not ConditionSatisfied
|
||||
BranchDetermined = ConditionSatisfied
|
||||
IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
|
||||
if ConditionSatisfied:
|
||||
self.__WipeOffArea.append((IfStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
|
||||
|
||||
BranchDetermined = ConditionSatisfied
|
||||
IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
|
||||
if ConditionSatisfied:
|
||||
self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
|
||||
elif self.__Token in ('!elseif', '!else'):
|
||||
ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token))
|
||||
if len(IfList) <= 0:
|
||||
raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)
|
||||
|
||||
if IfList[-1][1]:
|
||||
IfList[-1] = [ElseStartPos, False, True]
|
||||
self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
|
||||
@@ -670,27 +669,8 @@ class FdfParser:
|
||||
self.__WipeOffArea.append((IfList[-1][0], ElseStartPos))
|
||||
IfList[-1] = [ElseStartPos, True, IfList[-1][2]]
|
||||
if self.__Token == '!elseif':
|
||||
MacroName, NotFlag = self.__GetMacroName()
|
||||
if not self.__GetNextOp():
|
||||
raise Warning("expected !endif", self.FileName, self.CurrentLineNumber)
|
||||
|
||||
if self.__Token in ('!=', '==', '>', '<', '>=', '<='):
|
||||
Op = self.__Token
|
||||
if not self.__GetNextToken():
|
||||
raise Warning("expected value", self.FileName, self.CurrentLineNumber)
|
||||
if self.__GetStringData():
|
||||
pass
|
||||
MacroValue = self.__Token
|
||||
ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, Op, MacroValue)
|
||||
if NotFlag:
|
||||
ConditionSatisfied = not ConditionSatisfied
|
||||
|
||||
else:
|
||||
self.CurrentOffsetWithinLine -= len(self.__Token)
|
||||
ConditionSatisfied = self.__EvaluateConditional(MacroName, IfList[-1][0][0] + 1, None, 'Bool')
|
||||
if NotFlag:
|
||||
ConditionSatisfied = not ConditionSatisfied
|
||||
|
||||
Expression = self.__GetExpression()
|
||||
ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
|
||||
IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]
|
||||
|
||||
if IfList[-1][1]:
|
||||
@@ -699,8 +679,6 @@ class FdfParser:
|
||||
else:
|
||||
IfList[-1][2] = True
|
||||
self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
|
||||
|
||||
|
||||
elif self.__Token == '!endif':
|
||||
if IfList[-1][1]:
|
||||
self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
|
||||
@@ -708,106 +686,48 @@ class FdfParser:
|
||||
self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
|
||||
|
||||
IfList.pop()
|
||||
elif not IfList: # Don't use PCDs inside conditional directive
|
||||
if self.CurrentLineNumber <= RegionLayoutLine:
|
||||
# Don't try the same line twice
|
||||
continue
|
||||
RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
|
||||
if not RegionSize:
|
||||
RegionLayoutLine = self.CurrentLineNumber
|
||||
continue
|
||||
RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])
|
||||
if not RegionSizeGuid:
|
||||
RegionLayoutLine = self.CurrentLineNumber + 1
|
||||
continue
|
||||
InputMacroDict[RegionSizeGuid.group('base')] = RegionSize.group('base')
|
||||
InputMacroDict[RegionSizeGuid.group('size')] = RegionSize.group('size')
|
||||
RegionLayoutLine = self.CurrentLineNumber + 1
|
||||
|
||||
|
||||
if len(IfList) > 0:
|
||||
if IfList:
|
||||
raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)
|
||||
self.Rewind()
|
||||
|
||||
def __EvaluateConditional(self, Name, Line, Op = None, Value = None):
|
||||
|
||||
def __EvaluateConditional(self, Expression, Line, Op = None, Value = None):
|
||||
FileLineTuple = GetRealFileLine(self.FileName, Line)
|
||||
if Name in InputMacroDict:
|
||||
MacroValue = InputMacroDict[Name]
|
||||
if Op == None:
|
||||
if Value == 'Bool' and MacroValue == None or MacroValue.upper() == 'FALSE':
|
||||
return False
|
||||
return True
|
||||
elif Op == '!=':
|
||||
if Value != MacroValue:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif Op == '==':
|
||||
if Value == MacroValue:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(MacroValue) or (MacroValue != None and MacroValue.isdigit())):
|
||||
InputVal = long(Value, 0)
|
||||
MacroVal = long(MacroValue, 0)
|
||||
if Op == '>':
|
||||
if MacroVal > InputVal:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif Op == '>=':
|
||||
if MacroVal >= InputVal:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif Op == '<':
|
||||
if MacroVal < InputVal:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif Op == '<=':
|
||||
if MacroVal <= InputVal:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
raise Warning("Value %s is not a number", self.FileName, Line)
|
||||
|
||||
for Profile in AllMacroList:
|
||||
if Profile.MacroName == Name and Profile.DefinedAtLine <= FileLineTuple[1]:
|
||||
if Op == None:
|
||||
if Value == 'Bool' and Profile.MacroValue == None or Profile.MacroValue.upper() == 'FALSE':
|
||||
return False
|
||||
return True
|
||||
elif Op == '!=':
|
||||
if Value != Profile.MacroValue:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif Op == '==':
|
||||
if Value == Profile.MacroValue:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
if (self.__IsHex(Value) or Value.isdigit()) and (self.__IsHex(Profile.MacroValue) or (Profile.MacroValue != None and Profile.MacroValue.isdigit())):
|
||||
InputVal = long(Value, 0)
|
||||
MacroVal = long(Profile.MacroValue, 0)
|
||||
if Op == '>':
|
||||
if MacroVal > InputVal:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif Op == '>=':
|
||||
if MacroVal >= InputVal:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif Op == '<':
|
||||
if MacroVal < InputVal:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif Op == '<=':
|
||||
if MacroVal <= InputVal:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
raise Warning("Value %s is not a number", self.FileName, Line)
|
||||
|
||||
return False
|
||||
if Op == 'eval':
|
||||
try:
|
||||
return ValueExpression(Expression, InputMacroDict)()
|
||||
except SymbolNotFound:
|
||||
return False
|
||||
except WrnExpression, Excpt:
|
||||
#
|
||||
# Catch expression evaluation warning here. We need to report
|
||||
# the precise number of line and return the evaluation result
|
||||
#
|
||||
EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
|
||||
File=self.FileName, ExtraData=self.__CurrentLine(),
|
||||
Line=Line)
|
||||
return Excpt.result
|
||||
except Exception, Excpt:
|
||||
raise Warning("Invalid expression", *FileLineTuple)
|
||||
else:
|
||||
if Expression.startswith('$(') and Expression[-1] == ')':
|
||||
Expression = Expression[2:-1]
|
||||
return Expression in InputMacroDict
|
||||
|
||||
## __IsToken() method
|
||||
#
|
||||
@@ -866,6 +786,16 @@ class FdfParser:
|
||||
return True
|
||||
return False
|
||||
|
||||
def __GetExpression(self):
|
||||
Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]
|
||||
Index = len(Line) - 1
|
||||
while Line[Index] in ['\r', '\n']:
|
||||
Index -= 1
|
||||
ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]
|
||||
self.CurrentOffsetWithinLine += len(ExpressionString)
|
||||
ExpressionString = ExpressionString.strip()
|
||||
return ExpressionString
|
||||
|
||||
## __GetNextWord() method
|
||||
#
|
||||
# Get next C name from file lines
|
||||
@@ -1208,7 +1138,7 @@ class FdfParser:
|
||||
for Pos in self.__WipeOffArea:
|
||||
self.__ReplaceFragment(Pos[0], Pos[1])
|
||||
self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
|
||||
|
||||
|
||||
while self.__GetDefines():
|
||||
pass
|
||||
|
||||
@@ -2014,8 +1944,8 @@ class FdfParser:
|
||||
if not IsValidBaseAddrValue.match(self.__Token.upper()):
|
||||
raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
||||
Obj.FvBaseAddress = self.__Token
|
||||
return True
|
||||
|
||||
return True
|
||||
|
||||
## __GetFvForceRebase() method
|
||||
#
|
||||
# Get FvForceRebase for FV
|
||||
@@ -2047,7 +1977,8 @@ class FdfParser:
|
||||
Obj.FvForceRebase = None
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
||||
## __GetFvAttributes() method
|
||||
#
|
||||
# Get attributes for FV
|
||||
@@ -2475,6 +2406,7 @@ class FdfParser:
|
||||
if ErrorCode != 0:
|
||||
EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
|
||||
|
||||
|
||||
if not self.__IsToken( "}"):
|
||||
raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
|
||||
|
||||
|
@@ -71,7 +71,7 @@ class FileStatement (FileStatementClassObject) :
|
||||
|
||||
OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid)
|
||||
if not os.path.exists(OutputDir):
|
||||
os.makedirs(OutputDir)
|
||||
os.makedirs(OutputDir)
|
||||
|
||||
Dict.update(self.DefineVarDict)
|
||||
SectionAlignments = None
|
||||
@@ -98,7 +98,7 @@ class FileStatement (FileStatementClassObject) :
|
||||
SectionFiles = []
|
||||
Index = 0
|
||||
SectionAlignments = []
|
||||
for section in self.SectionList:
|
||||
for section in self.SectionList :
|
||||
Index = Index + 1
|
||||
SecIndex = '%d' %Index
|
||||
# process the inside FvImage from FvSection or GuidSection
|
||||
|
@@ -163,7 +163,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
||||
|
||||
if self.CurrentArch != None:
|
||||
|
||||
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch]
|
||||
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
#
|
||||
# Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
|
||||
#
|
||||
@@ -181,7 +181,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
||||
self.ShadowFromInfFile = Inf.Shadow
|
||||
|
||||
else:
|
||||
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON']
|
||||
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
self.BaseName = Inf.BaseName
|
||||
self.ModuleGuid = Inf.Guid
|
||||
self.ModuleType = Inf.ModuleType
|
||||
@@ -363,27 +363,27 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
||||
|
||||
InfFileKey = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))
|
||||
DscArchList = []
|
||||
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32']
|
||||
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
if PlatformDataBase != None:
|
||||
if InfFileKey in PlatformDataBase.Modules:
|
||||
DscArchList.append ('IA32')
|
||||
|
||||
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64']
|
||||
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
if PlatformDataBase != None:
|
||||
if InfFileKey in PlatformDataBase.Modules:
|
||||
DscArchList.append ('X64')
|
||||
|
||||
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF']
|
||||
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
if PlatformDataBase != None:
|
||||
if InfFileKey in (PlatformDataBase.Modules):
|
||||
DscArchList.append ('IPF')
|
||||
|
||||
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM']
|
||||
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
if PlatformDataBase != None:
|
||||
if InfFileKey in (PlatformDataBase.Modules):
|
||||
DscArchList.append ('ARM')
|
||||
|
||||
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC']
|
||||
PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
if PlatformDataBase != None:
|
||||
if InfFileKey in (PlatformDataBase.Modules):
|
||||
DscArchList.append ('EBC')
|
||||
|
@@ -48,7 +48,7 @@ class FV (FvClassObject):
|
||||
self.CapsuleName = None
|
||||
self.FvBaseAddress = None
|
||||
self.FvForceRebase = None
|
||||
|
||||
|
||||
## AddToBuffer()
|
||||
#
|
||||
# Generate Fv and add it to the Buffer
|
||||
@@ -83,13 +83,13 @@ class FV (FvClassObject):
|
||||
elif RegionData.upper() + 'fv' in GenFds.ImageBinDict.keys():
|
||||
continue
|
||||
elif self.UiFvName.upper() == RegionData.upper():
|
||||
GenFdsGlobalVariable.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self.CapsuleName, self.UiFvName.upper()))
|
||||
GenFdsGlobalVariable.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self.CapsuleName, self.UiFvName.upper()))
|
||||
|
||||
GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName)
|
||||
|
||||
if self.FvBaseAddress != None:
|
||||
BaseAddress = self.FvBaseAddress
|
||||
|
||||
BaseAddress = self.FvBaseAddress
|
||||
|
||||
self.__InitializeInf__(BaseAddress, BlockSize, BlockNum, ErasePloarity, VtfDict)
|
||||
#
|
||||
# First Process the Apriori section
|
||||
|
@@ -161,20 +161,22 @@ def main():
|
||||
if len(List) == 2:
|
||||
if List[0].strip() == "EFI_SOURCE":
|
||||
GlobalData.gEfiSource = List[1].strip()
|
||||
GlobalData.gGlobalDefines["EFI_SOURCE"] = GlobalData.gEfiSource
|
||||
continue
|
||||
elif List[0].strip() == "EDK_SOURCE":
|
||||
GlobalData.gEdkSource = List[1].strip()
|
||||
GlobalData.gGlobalDefines["EDK_SOURCE"] = GlobalData.gEdkSource
|
||||
continue
|
||||
elif List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]:
|
||||
GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip()
|
||||
else:
|
||||
GlobalData.gEdkGlobal[List[0].strip()] = List[1].strip()
|
||||
FdfParser.InputMacroDict[List[0].strip()] = List[1].strip()
|
||||
GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip()
|
||||
else:
|
||||
FdfParser.InputMacroDict[List[0].strip()] = ""
|
||||
GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE"
|
||||
os.environ["WORKSPACE"] = Workspace
|
||||
|
||||
"""call Workspace build create database"""
|
||||
os.environ["WORKSPACE"] = Workspace
|
||||
FdfParser.InputMacroDict["WORKSPACE"] = Workspace
|
||||
BuildWorkSpace = WorkspaceDatabase(':memory:', FdfParser.InputMacroDict)
|
||||
BuildWorkSpace = WorkspaceDatabase(None)
|
||||
BuildWorkSpace.InitDatabase()
|
||||
|
||||
#
|
||||
@@ -187,15 +189,15 @@ def main():
|
||||
ArchList = Options.archList.split(',')
|
||||
else:
|
||||
# EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH")
|
||||
ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList
|
||||
ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList
|
||||
|
||||
TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList) & set(ArchList)
|
||||
TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList) & set(ArchList)
|
||||
if len(TargetArchList) == 0:
|
||||
EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList)))
|
||||
|
||||
for Arch in ArchList:
|
||||
GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].OutputDirectory)
|
||||
GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].PlatformName
|
||||
GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].OutputDirectory)
|
||||
GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].PlatformName
|
||||
|
||||
if (Options.outputDir):
|
||||
OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir)
|
||||
@@ -276,7 +278,8 @@ def main():
|
||||
ExtraData="Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!\n",
|
||||
RaiseError=False
|
||||
)
|
||||
EdkLogger.quiet(traceback.format_exc())
|
||||
if Options.debug != None:
|
||||
EdkLogger.quiet(traceback.format_exc())
|
||||
ReturnCode = CODE_ERROR
|
||||
return ReturnCode
|
||||
|
||||
@@ -482,7 +485,7 @@ class GenFds :
|
||||
# @retval None
|
||||
#
|
||||
def PreprocessImage(BuildDb, DscFile):
|
||||
PcdDict = BuildDb.BuildObject[DscFile, 'COMMON'].Pcds
|
||||
PcdDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds
|
||||
PcdValue = ''
|
||||
for Key in PcdDict:
|
||||
PcdObj = PcdDict[Key]
|
||||
@@ -501,20 +504,20 @@ class GenFds :
|
||||
if Int64PcdValue > 0:
|
||||
TopAddress = Int64PcdValue
|
||||
|
||||
ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON'].Modules
|
||||
ModuleDict = BuildDb.BuildObject[DscFile, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules
|
||||
for Key in ModuleDict:
|
||||
ModuleObj = BuildDb.BuildObject[Key, 'COMMON']
|
||||
ModuleObj = BuildDb.BuildObject[Key, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
print ModuleObj.BaseName + ' ' + ModuleObj.ModuleType
|
||||
|
||||
def GenerateGuidXRefFile(BuildDb, ArchList):
|
||||
GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")
|
||||
GuidXRefFile = StringIO.StringIO('')
|
||||
for Arch in ArchList:
|
||||
PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch]
|
||||
PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
for ModuleFile in PlatformDataBase.Modules:
|
||||
Module = BuildDb.BuildObject[ModuleFile, Arch]
|
||||
Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))
|
||||
SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)
|
||||
SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)
|
||||
GuidXRefFile.close()
|
||||
GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)
|
||||
|
||||
|
@@ -117,7 +117,7 @@ class GenFdsGlobalVariable:
|
||||
if not BuildRuleDatabase:
|
||||
return {}
|
||||
|
||||
PathClassObj = PathClass(str(Inf.MetaFile).lstrip(GenFdsGlobalVariable.WorkSpaceDir),
|
||||
PathClassObj = PathClass(Inf.MetaFile.File,
|
||||
GenFdsGlobalVariable.WorkSpaceDir)
|
||||
Macro = {}
|
||||
Macro["WORKSPACE" ] = GenFdsGlobalVariable.WorkSpaceDir
|
||||
@@ -135,6 +135,7 @@ class GenFdsGlobalVariable:
|
||||
Macro["ARCH" ] = Arch
|
||||
Macro["TOOLCHAIN" ] = GenFdsGlobalVariable.ToolChainTag
|
||||
Macro["TOOLCHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag
|
||||
Macro["TOOL_CHAIN_TAG" ] = GenFdsGlobalVariable.ToolChainTag
|
||||
Macro["TARGET" ] = GenFdsGlobalVariable.TargetName
|
||||
|
||||
Macro["BUILD_DIR" ] = GenFdsGlobalVariable.OutputDirDict[Arch]
|
||||
@@ -280,8 +281,8 @@ class GenFdsGlobalVariable:
|
||||
FvAddressFile.writelines("[options]" + T_CHAR_LF)
|
||||
BsAddress = '0'
|
||||
for Arch in ArchList:
|
||||
if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress:
|
||||
BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].BsBaseAddress
|
||||
if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:
|
||||
BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress
|
||||
break
|
||||
|
||||
FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
|
||||
@@ -290,8 +291,8 @@ class GenFdsGlobalVariable:
|
||||
|
||||
RtAddress = '0'
|
||||
for Arch in ArchList:
|
||||
if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress:
|
||||
RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch].RtBaseAddress
|
||||
if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress:
|
||||
RtAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress
|
||||
|
||||
FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
|
||||
RtAddress + \
|
||||
@@ -345,10 +346,6 @@ class GenFdsGlobalVariable:
|
||||
@staticmethod
|
||||
def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
|
||||
GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=None):
|
||||
if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
|
||||
return
|
||||
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
|
||||
|
||||
Cmd = ["GenSec"]
|
||||
if Type not in [None, '']:
|
||||
Cmd += ["-s", Type]
|
||||
@@ -388,6 +385,13 @@ class GenFdsGlobalVariable:
|
||||
else:
|
||||
Cmd += ["-o", Output]
|
||||
Cmd += Input
|
||||
|
||||
CommandFile = Output + '.txt'
|
||||
SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
|
||||
if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
|
||||
return
|
||||
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
|
||||
|
||||
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
|
||||
|
||||
@staticmethod
|
||||
@@ -402,10 +406,6 @@ class GenFdsGlobalVariable:
|
||||
@staticmethod
|
||||
def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
|
||||
SectionAlign=None):
|
||||
if not GenFdsGlobalVariable.NeedsUpdate(Output, Input):
|
||||
return
|
||||
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
|
||||
|
||||
Cmd = ["GenFfs", "-t", Type, "-g", Guid]
|
||||
if Fixed == True:
|
||||
Cmd += ["-x"]
|
||||
@@ -419,6 +419,13 @@ class GenFdsGlobalVariable:
|
||||
Cmd += ("-i", Input[I])
|
||||
if SectionAlign not in [None, '', []] and SectionAlign[I] not in [None, '']:
|
||||
Cmd += ("-n", SectionAlign[I])
|
||||
|
||||
CommandFile = Output + '.txt'
|
||||
SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
|
||||
if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
|
||||
return
|
||||
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
|
||||
|
||||
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")
|
||||
|
||||
@staticmethod
|
||||
@@ -436,7 +443,7 @@ class GenFdsGlobalVariable:
|
||||
Cmd +=["-F", "FALSE"]
|
||||
elif ForceRebase == True:
|
||||
Cmd +=["-F", "TRUE"]
|
||||
|
||||
|
||||
if Capsule:
|
||||
Cmd += ["-c"]
|
||||
if Dump:
|
||||
@@ -653,25 +660,9 @@ class GenFdsGlobalVariable:
|
||||
TokenCName = PcdPair[1]
|
||||
|
||||
PcdValue = ''
|
||||
for Platform in GenFdsGlobalVariable.WorkSpace.PlatformList:
|
||||
#
|
||||
# Only process platform which match current build option.
|
||||
#
|
||||
if Platform.MetaFile == GenFdsGlobalVariable.ActivePlatform:
|
||||
PcdDict = Platform.Pcds
|
||||
for Key in PcdDict:
|
||||
PcdObj = PcdDict[Key]
|
||||
if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
|
||||
if PcdObj.Type != 'FixedAtBuild':
|
||||
EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
|
||||
if PcdObj.DatumType != 'VOID*':
|
||||
EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
|
||||
|
||||
PcdValue = PcdObj.DefaultValue
|
||||
return PcdValue
|
||||
|
||||
for Package in GenFdsGlobalVariable.WorkSpace.PackageList:
|
||||
PcdDict = Package.Pcds
|
||||
for Arch in GenFdsGlobalVariable.ArchList:
|
||||
Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
|
||||
PcdDict = Platform.Pcds
|
||||
for Key in PcdDict:
|
||||
PcdObj = PcdDict[Key]
|
||||
if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
|
||||
@@ -682,6 +673,22 @@ class GenFdsGlobalVariable:
|
||||
|
||||
PcdValue = PcdObj.DefaultValue
|
||||
return PcdValue
|
||||
|
||||
for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,
|
||||
Arch,
|
||||
GenFdsGlobalVariable.TargetName,
|
||||
GenFdsGlobalVariable.ToolChainTag):
|
||||
PcdDict = Package.Pcds
|
||||
for Key in PcdDict:
|
||||
PcdObj = PcdDict[Key]
|
||||
if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
|
||||
if PcdObj.Type != 'FixedAtBuild':
|
||||
EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
|
||||
if PcdObj.DatumType != 'VOID*':
|
||||
EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
|
||||
|
||||
PcdValue = PcdObj.DefaultValue
|
||||
return PcdValue
|
||||
|
||||
return PcdValue
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
## @file
|
||||
# section base class
|
||||
#
|
||||
# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2007-2011, 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
|
||||
|
Reference in New Issue
Block a user