summaryrefslogtreecommitdiff
path: root/BaseTools/Source/Python/AutoGen/GenDepex.py
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/Python/AutoGen/GenDepex.py')
-rw-r--r--BaseTools/Source/Python/AutoGen/GenDepex.py448
1 files changed, 0 insertions, 448 deletions
diff --git a/BaseTools/Source/Python/AutoGen/GenDepex.py b/BaseTools/Source/Python/AutoGen/GenDepex.py
deleted file mode 100644
index 5923a75ab7..0000000000
--- a/BaseTools/Source/Python/AutoGen/GenDepex.py
+++ /dev/null
@@ -1,448 +0,0 @@
-## @file
-# This file is used to generate DEPEX file for module's dependency expression
-#
-# Copyright (c) 2007 - 2014, 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.
-
-## Import Modules
-#
-import sys
-import Common.LongFilePathOs as os
-import re
-import traceback
-from Common.LongFilePathSupport import OpenLongFilePath as open
-from StringIO import StringIO
-from struct import pack
-from Common.BuildToolError import *
-from Common.Misc import SaveFileOnChange
-from Common.Misc import GuidStructureStringToGuidString
-from Common import EdkLogger as EdkLogger
-from Common.BuildVersion import gBUILD_VERSION
-
-## Regular expression for matching "DEPENDENCY_START ... DEPENDENCY_END"
-gStartClosePattern = re.compile(".*DEPENDENCY_START(.+)DEPENDENCY_END.*", re.S)
-
-## Mapping between module type and EFI phase
-gType2Phase = {
- "BASE" : None,
- "SEC" : "PEI",
- "PEI_CORE" : "PEI",
- "PEIM" : "PEI",
- "DXE_CORE" : "DXE",
- "DXE_DRIVER" : "DXE",
- "DXE_SMM_DRIVER" : "DXE",
- "DXE_RUNTIME_DRIVER": "DXE",
- "DXE_SAL_DRIVER" : "DXE",
- "UEFI_DRIVER" : "DXE",
- "UEFI_APPLICATION" : "DXE",
- "SMM_CORE" : "DXE",
-}
-
-## Convert dependency expression string into EFI internal representation
-#
-# DependencyExpression class is used to parse dependency expression string and
-# convert it into its binary form.
-#
-class DependencyExpression:
-
- ArchProtocols = set([
- '665e3ff6-46cc-11d4-9a38-0090273fc14d', # 'gEfiBdsArchProtocolGuid'
- '26baccb1-6f42-11d4-bce7-0080c73c8881', # 'gEfiCpuArchProtocolGuid'
- '26baccb2-6f42-11d4-bce7-0080c73c8881', # 'gEfiMetronomeArchProtocolGuid'
- '1da97072-bddc-4b30-99f1-72a0b56fff2a', # 'gEfiMonotonicCounterArchProtocolGuid'
- '27cfac87-46cc-11d4-9a38-0090273fc14d', # 'gEfiRealTimeClockArchProtocolGuid'
- '27cfac88-46cc-11d4-9a38-0090273fc14d', # 'gEfiResetArchProtocolGuid'
- 'b7dfb4e1-052f-449f-87be-9818fc91b733', # 'gEfiRuntimeArchProtocolGuid'
- 'a46423e3-4617-49f1-b9ff-d1bfa9115839', # 'gEfiSecurityArchProtocolGuid'
- '26baccb3-6f42-11d4-bce7-0080c73c8881', # 'gEfiTimerArchProtocolGuid'
- '6441f818-6362-4e44-b570-7dba31dd2453', # 'gEfiVariableWriteArchProtocolGuid'
- '1e5668e2-8481-11d4-bcf1-0080c73c8881', # 'gEfiVariableArchProtocolGuid'
- '665e3ff5-46cc-11d4-9a38-0090273fc14d' # 'gEfiWatchdogTimerArchProtocolGuid'
- ]
- )
-
- OpcodePriority = {
- "AND" : 1,
- "OR" : 1,
- "NOT" : 2,
- # "SOR" : 9,
- # "BEFORE": 9,
- # "AFTER" : 9,
- }
-
- Opcode = {
- "PEI" : {
- "PUSH" : 0x02,
- "AND" : 0x03,
- "OR" : 0x04,
- "NOT" : 0x05,
- "TRUE" : 0x06,
- "FALSE" : 0x07,
- "END" : 0x08
- },
-
- "DXE" : {
- "BEFORE": 0x00,
- "AFTER" : 0x01,
- "PUSH" : 0x02,
- "AND" : 0x03,
- "OR" : 0x04,
- "NOT" : 0x05,
- "TRUE" : 0x06,
- "FALSE" : 0x07,
- "END" : 0x08,
- "SOR" : 0x09
- }
- }
-
- # all supported op codes and operands
- SupportedOpcode = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "END", "SOR"]
- SupportedOperand = ["TRUE", "FALSE"]
-
- OpcodeWithSingleOperand = ['NOT', 'BEFORE', 'AFTER']
- OpcodeWithTwoOperand = ['AND', 'OR']
-
- # op code that should not be the last one
- NonEndingOpcode = ["AND", "OR", "NOT", 'SOR']
- # op code must not present at the same time
- ExclusiveOpcode = ["BEFORE", "AFTER"]
- # op code that should be the first one if it presents
- AboveAllOpcode = ["SOR", "BEFORE", "AFTER"]
-
- #
- # open and close brace must be taken as individual tokens
- #
- TokenPattern = re.compile("(\(|\)|\{[^{}]+\{?[^{}]+\}?[ ]*\}|\w+)")
-
- ## Constructor
- #
- # @param Expression The list or string of dependency expression
- # @param ModuleType The type of the module using the dependency expression
- #
- def __init__(self, Expression, ModuleType, Optimize=False):
- self.ModuleType = ModuleType
- self.Phase = gType2Phase[ModuleType]
- if type(Expression) == type([]):
- self.ExpressionString = " ".join(Expression)
- self.TokenList = Expression
- else:
- self.ExpressionString = Expression
- self.GetExpressionTokenList()
-
- self.PostfixNotation = []
- self.OpcodeList = []
-
- self.GetPostfixNotation()
- self.ValidateOpcode()
-
- EdkLogger.debug(EdkLogger.DEBUG_8, repr(self))
- if Optimize:
- self.Optimize()
- EdkLogger.debug(EdkLogger.DEBUG_8, "\n Optimized: " + repr(self))
-
- def __str__(self):
- return " ".join(self.TokenList)
-
- def __repr__(self):
- WellForm = ''
- for Token in self.PostfixNotation:
- if Token in self.SupportedOpcode:
- WellForm += "\n " + Token
- else:
- WellForm += ' ' + Token
- return WellForm
-
- ## Split the expression string into token list
- def GetExpressionTokenList(self):
- self.TokenList = self.TokenPattern.findall(self.ExpressionString)
-
- ## Convert token list into postfix notation
- def GetPostfixNotation(self):
- Stack = []
- LastToken = ''
- for Token in self.TokenList:
- if Token == "(":
- if LastToken not in self.SupportedOpcode + ['(', '', None]:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before open parentheses",
- ExtraData="Near %s" % LastToken)
- Stack.append(Token)
- elif Token == ")":
- if '(' not in Stack:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: mismatched parentheses",
- ExtraData=str(self))
- elif LastToken in self.SupportedOpcode + ['', None]:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operand before close parentheses",
- ExtraData="Near %s" % LastToken)
- while len(Stack) > 0:
- if Stack[-1] == '(':
- Stack.pop()
- break
- self.PostfixNotation.append(Stack.pop())
- elif Token in self.OpcodePriority:
- if Token == "NOT":
- if LastToken not in self.SupportedOpcode + ['(', '', None]:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before NOT",
- ExtraData="Near %s" % LastToken)
- elif LastToken in self.SupportedOpcode + ['(', '', None]:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operand before " + Token,
- ExtraData="Near %s" % LastToken)
-
- while len(Stack) > 0:
- if Stack[-1] == "(" or self.OpcodePriority[Token] >= self.OpcodePriority[Stack[-1]]:
- break
- self.PostfixNotation.append(Stack.pop())
- Stack.append(Token)
- self.OpcodeList.append(Token)
- else:
- if Token not in self.SupportedOpcode:
- # not OP, take it as GUID
- if LastToken not in self.SupportedOpcode + ['(', '', None]:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before %s" % Token,
- ExtraData="Near %s" % LastToken)
- if len(self.OpcodeList) == 0 or self.OpcodeList[-1] not in self.ExclusiveOpcode:
- if Token not in self.SupportedOperand:
- self.PostfixNotation.append("PUSH")
- # check if OP is valid in this phase
- elif Token in self.Opcode[self.Phase]:
- if Token == "END":
- break
- self.OpcodeList.append(Token)
- else:
- EdkLogger.error("GenDepex", PARSER_ERROR,
- "Opcode=%s doesn't supported in %s stage " % (Token, self.Phase),
- ExtraData=str(self))
- self.PostfixNotation.append(Token)
- LastToken = Token
-
- # there should not be parentheses in Stack
- if '(' in Stack or ')' in Stack:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: mismatched parentheses",
- ExtraData=str(self))
- while len(Stack) > 0:
- self.PostfixNotation.append(Stack.pop())
- if self.PostfixNotation[-1] != 'END':
- self.PostfixNotation.append("END")
-
- ## Validate the dependency expression
- def ValidateOpcode(self):
- for Op in self.AboveAllOpcode:
- if Op in self.PostfixNotation:
- if Op != self.PostfixNotation[0]:
- EdkLogger.error("GenDepex", PARSER_ERROR, "%s should be the first opcode in the expression" % Op,
- ExtraData=str(self))
- if len(self.PostfixNotation) < 3:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Missing operand for %s" % Op,
- ExtraData=str(self))
- for Op in self.ExclusiveOpcode:
- if Op in self.OpcodeList:
- if len(self.OpcodeList) > 1:
- EdkLogger.error("GenDepex", PARSER_ERROR, "%s should be the only opcode in the expression" % Op,
- ExtraData=str(self))
- if len(self.PostfixNotation) < 3:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Missing operand for %s" % Op,
- ExtraData=str(self))
- if self.TokenList[-1] != 'END' and self.TokenList[-1] in self.NonEndingOpcode:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Extra %s at the end of the dependency expression" % self.TokenList[-1],
- ExtraData=str(self))
- if self.TokenList[-1] == 'END' and self.TokenList[-2] in self.NonEndingOpcode:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Extra %s at the end of the dependency expression" % self.TokenList[-2],
- ExtraData=str(self))
- if "END" in self.TokenList and "END" != self.TokenList[-1]:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Extra expressions after END",
- ExtraData=str(self))
-
- ## Simply optimize the dependency expression by removing duplicated operands
- def Optimize(self):
- ValidOpcode = list(set(self.OpcodeList))
- if len(ValidOpcode) != 1 or ValidOpcode[0] not in ['AND', 'OR']:
- return
- Op = ValidOpcode[0]
- NewOperand = []
- AllOperand = set()
- for Token in self.PostfixNotation:
- if Token in self.SupportedOpcode or Token in NewOperand:
- continue
- AllOperand.add(Token)
- if Token == 'TRUE':
- if Op == 'AND':
- continue
- else:
- NewOperand.append(Token)
- break
- elif Token == 'FALSE':
- if Op == 'OR':
- continue
- else:
- NewOperand.append(Token)
- break
- NewOperand.append(Token)
-
- # don't generate depex if only TRUE operand left
- if self.ModuleType == 'PEIM' and len(NewOperand) == 1 and NewOperand[0] == 'TRUE':
- self.PostfixNotation = []
- return
-
- # don't generate depex if all operands are architecture protocols
- if self.ModuleType in ['UEFI_DRIVER', 'DXE_DRIVER', 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'DXE_SMM_DRIVER'] and \
- Op == 'AND' and \
- self.ArchProtocols == set([GuidStructureStringToGuidString(Guid) for Guid in AllOperand]):
- self.PostfixNotation = []
- return
-
- if len(NewOperand) == 0:
- self.TokenList = list(AllOperand)
- else:
- self.TokenList = []
- while True:
- self.TokenList.append(NewOperand.pop(0))
- if NewOperand == []:
- break
- self.TokenList.append(Op)
- self.PostfixNotation = []
- self.GetPostfixNotation()
-
-
- ## Convert a GUID value in C structure format into its binary form
- #
- # @param Guid The GUID value in C structure format
- #
- # @retval array The byte array representing the GUID value
- #
- def GetGuidValue(self, Guid):
- GuidValueString = Guid.replace("{", "").replace("}", "").replace(" ", "")
- GuidValueList = GuidValueString.split(",")
- if len(GuidValueList) != 11:
- EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid GUID value string or opcode: %s" % Guid)
- return pack("1I2H8B", *(int(value, 16) for value in GuidValueList))
-
- ## Save the binary form of dependency expression in file
- #
- # @param File The path of file. If None is given, put the data on console
- #
- # @retval True If the file doesn't exist or file is changed
- # @retval False If file exists and is not changed.
- #
- def Generate(self, File=None):
- Buffer = StringIO()
- if len(self.PostfixNotation) == 0:
- return False
-
- for Item in self.PostfixNotation:
- if Item in self.Opcode[self.Phase]:
- Buffer.write(pack("B", self.Opcode[self.Phase][Item]))
- elif Item in self.SupportedOpcode:
- EdkLogger.error("GenDepex", FORMAT_INVALID,
- "Opcode [%s] is not expected in %s phase" % (Item, self.Phase),
- ExtraData=self.ExpressionString)
- else:
- Buffer.write(self.GetGuidValue(Item))
-
- FilePath = ""
- FileChangeFlag = True
- if File == None:
- sys.stdout.write(Buffer.getvalue())
- FilePath = "STDOUT"
- else:
- FileChangeFlag = SaveFileOnChange(File, Buffer.getvalue(), True)
-
- Buffer.close()
- return FileChangeFlag
-
-versionNumber = ("0.04" + " " + gBUILD_VERSION)
-__version__ = "%prog Version " + versionNumber
-__copyright__ = "Copyright (c) 2007-2010, Intel Corporation All rights reserved."
-__usage__ = "%prog [options] [dependency_expression_file]"
-
-## Parse command line options
-#
-# @retval OptionParser
-#
-def GetOptions():
- from optparse import OptionParser
-
- Parser = OptionParser(description=__copyright__, version=__version__, usage=__usage__)
-
- Parser.add_option("-o", "--output", dest="OutputFile", default=None, metavar="FILE",
- help="Specify the name of depex file to be generated")
- Parser.add_option("-t", "--module-type", dest="ModuleType", default=None,
- help="The type of module for which the dependency expression serves")
- Parser.add_option("-e", "--dependency-expression", dest="Expression", default="",
- help="The string of dependency expression. If this option presents, the input file will be ignored.")
- Parser.add_option("-m", "--optimize", dest="Optimize", default=False, action="store_true",
- help="Do some simple optimization on the expression.")
- Parser.add_option("-v", "--verbose", dest="verbose", default=False, action="store_true",
- help="build with verbose information")
- Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
- Parser.add_option("-q", "--quiet", dest="quiet", default=False, action="store_true",
- help="build with little information")
-
- return Parser.parse_args()
-
-
-## Entrance method
-#
-# @retval 0 Tool was successful
-# @retval 1 Tool failed
-#
-def Main():
- EdkLogger.Initialize()
- Option, Input = GetOptions()
-
- # Set log level
- if Option.quiet:
- EdkLogger.SetLevel(EdkLogger.QUIET)
- elif Option.verbose:
- EdkLogger.SetLevel(EdkLogger.VERBOSE)
- elif Option.debug != None:
- EdkLogger.SetLevel(Option.debug + 1)
- else:
- EdkLogger.SetLevel(EdkLogger.INFO)
-
- try:
- if Option.ModuleType == None or Option.ModuleType not in gType2Phase:
- EdkLogger.error("GenDepex", OPTION_MISSING, "Module type is not specified or supported")
-
- DxsFile = ''
- if len(Input) > 0 and Option.Expression == "":
- DxsFile = Input[0]
- DxsString = open(DxsFile, 'r').read().replace("\n", " ").replace("\r", " ")
- DxsString = gStartClosePattern.sub("\\1", DxsString)
- elif Option.Expression != "":
- if Option.Expression[0] == '"':
- DxsString = Option.Expression[1:-1]
- else:
- DxsString = Option.Expression
- else:
- EdkLogger.error("GenDepex", OPTION_MISSING, "No expression string or file given")
-
- Dpx = DependencyExpression(DxsString, Option.ModuleType, Option.Optimize)
- if Option.OutputFile != None:
- FileChangeFlag = Dpx.Generate(Option.OutputFile)
- if not FileChangeFlag and DxsFile:
- #
- # Touch the output file if its time stamp is older than the original
- # DXS file to avoid re-invoke this tool for the dependency check in build rule.
- #
- if os.stat(DxsFile)[8] > os.stat(Option.OutputFile)[8]:
- os.utime(Option.OutputFile, None)
- else:
- Dpx.Generate()
- except BaseException, X:
- EdkLogger.quiet("")
- if Option != None and Option.debug != None:
- EdkLogger.quiet(traceback.format_exc())
- else:
- EdkLogger.quiet(str(X))
- return 1
-
- return 0
-
-if __name__ == '__main__':
- sys.exit(Main())
-