## @file
# This file is used to generate DEPEX file for module's dependency expression
#
# Copyright (c) 2007 - 2010, 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
#
# 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 os
import re
import traceback
from Common.BuildToolError import *
## Regular expression for matching "DEPENDENCY_START ... DEPENDENCY_END"
## 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:
'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
# op code that should not be the last one
# op code must not present at the same time
# op code that should be the first one if it presents
#
# open and close brace must be taken as individual tokens
#
## Constructor
#
# @param Expression The list or string of dependency expression
# @param ModuleType The type of the module using the dependency expression
#
else:
self.PostfixNotation = []
self.OpcodeList = []
if Optimize:
WellForm = ''
else:
return WellForm
## Split the expression string into token list
## Convert token list into postfix notation
Stack = []
LastToken = ''
if Token == "(":
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before open parentheses",
elif Token == ")":
if '(' not in Stack:
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operand before close parentheses",
break
if Token == "NOT":
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before NOT",
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operand before " + Token,
break
else:
# not OP, take it as GUID
EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before %s" % Token,
# check if OP is valid in this phase
if Token == "END":
break
else:
# there should not be parentheses in Stack
## Validate the dependency expression
EdkLogger.error("GenDepex", PARSER_ERROR, "Extra %s at the end of the dependency expression" % self.TokenList[-1],
EdkLogger.error("GenDepex", PARSER_ERROR, "Extra %s at the end of the dependency expression" % self.TokenList[-2],
## Simply optimize the dependency expression by removing duplicated operands
return
NewOperand = []
AllOperand = set()
continue
if Token == 'TRUE':
if Op == 'AND':
continue
else:
break
elif Token == 'FALSE':
if Op == 'OR':
continue
else:
break
# don't generate depex if only TRUE operand left
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.PostfixNotation = []
return
else:
while True:
if NewOperand == []:
break
self.PostfixNotation = []
## 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
#
## 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.
#
return False
else:
FilePath = ""
if File == None:
FilePath = "STDOUT"
else:
return FileChangeFlag
## Parse command line options
#
# @retval OptionParser
#
def GetOptions():
help="Specify the name of depex file to be generated")
help="The type of module for which the dependency expression serves")
help="The string of dependency expression. If this option presents, the input file will be ignored.")
help="Do some simple optimization on the expression.")
help="build with verbose information")
Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
help="build with little information")
return Parser.parse_args()
## Entrance method
#
# @retval 0 Tool was successful
# @retval 1 Tool failed
#
def Main():
# Set log level
else:
try:
DxsFile = ''
else:
else:
if Option.OutputFile != None:
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.
#
else:
except BaseException, X:
else:
return 1
return 0
if __name__ == '__main__':