2014-01-27 05:23:15 +00:00
## @file
# Trim files preprocessed by compiler
#
2018-04-10 09:12:49 +08:00
# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
2019-04-03 16:03:11 -07:00
# SPDX-License-Identifier: BSD-2-Clause-Patent
2014-01-27 05:23:15 +00:00
#
##
# Import Modules
#
2014-08-15 03:06:48 +00:00
import Common.LongFilePathOs as os
2014-01-27 05:23:15 +00:00
import sys
import re
2018-06-25 18:31:36 +08:00
from io import BytesIO
2019-03-28 10:12:31 +08:00
import codecs
2014-01-27 05:23:15 +00:00
from optparse import OptionParser
from optparse import make_option
from Common.BuildToolError import *
from Common.Misc import *
2018-04-27 00:57:56 +08:00
from Common.DataType import *
2014-01-27 05:23:15 +00:00
from Common.BuildVersion import gBUILD_VERSION
import Common.EdkLogger as EdkLogger
2014-08-15 03:06:48 +00:00
from Common.LongFilePathSupport import OpenLongFilePath as open
2014-01-27 05:23:15 +00:00
# Version and Copyright
__version_number__ = ( "0.10" + " " + gBUILD_VERSION )
__version__ = "%prog Version " + __version_number__
2018-07-05 17:40:04 +08:00
__copyright__ = "Copyright (c) 2007-2018, Intel Corporation. All rights reserved."
2014-01-27 05:23:15 +00:00
## Regular expression for matching Line Control directive like "#line xxx"
2023-12-06 12:27:02 -08:00
gLineControlDirective = re . compile ( r '^\s*#(?:line)?\s+([0-9]+)\s+"*([^"]*)"' )
2014-01-27 05:23:15 +00:00
## Regular expression for matching "typedef struct"
2023-12-06 12:27:02 -08:00
gTypedefPattern = re . compile ( r "^\s*typedef\s+struct(\s+\w+)?\s*[{]*$" , re . MULTILINE )
2014-01-27 05:23:15 +00:00
## Regular expression for matching "#pragma pack"
2023-12-06 12:27:02 -08:00
gPragmaPattern = re . compile ( r "^\s*#pragma\s+pack" , re . MULTILINE )
2016-02-17 14:58:02 +08:00
## Regular expression for matching "typedef"
2023-12-06 12:27:02 -08:00
gTypedef_SinglePattern = re . compile ( r "^\s*typedef" , re . MULTILINE )
2016-02-17 14:58:02 +08:00
## Regular expression for matching "typedef struct, typedef union, struct, union"
2023-12-06 12:27:02 -08:00
gTypedef_MulPattern = re . compile ( r "^\s*(typedef)?\s+(struct|union)(\s+\w+)?\s*[{]*$" , re . MULTILINE )
2014-01-27 05:23:15 +00:00
#
# The following number pattern match will only match if following criteria is met:
# There is leading non-(alphanumeric or _) character, and no following alphanumeric or _
# as the pattern is greedily match, so it is ok for the gDecNumberPattern or gHexNumberPattern to grab the maximum match
#
## Regular expression for matching HEX number
2023-12-06 12:27:02 -08:00
gHexNumberPattern = re . compile ( r "(?<=[^a-zA-Z0-9_])(0[xX])([0-9a-fA-F]+)(U(?=$|[^a-zA-Z0-9_]))?" )
2014-01-27 05:23:15 +00:00
## Regular expression for matching decimal number with 'U' postfix
2023-12-06 12:27:02 -08:00
gDecNumberPattern = re . compile ( r "(?<=[^a-zA-Z0-9_])([0-9]+)U(?=$|[^a-zA-Z0-9_])" )
2014-01-27 05:23:15 +00:00
## Regular expression for matching constant with 'ULL' 'LL' postfix
2023-12-06 12:27:02 -08:00
gLongNumberPattern = re . compile ( r "(?<=[^a-zA-Z0-9_])(0[xX][0-9a-fA-F]+|[0-9]+)U?LL(?=$|[^a-zA-Z0-9_])" )
2014-01-27 05:23:15 +00:00
## Regular expression for matching "Include ()" in asl file
2023-12-06 12:27:02 -08:00
gAslIncludePattern = re . compile ( r "^(\s*)[iI]nclude\s*\( \" ?([^ \" \(\)]+) \" \)" , re . MULTILINE )
2014-01-27 05:23:15 +00:00
## Regular expression for matching C style #include "XXX.asl" in asl file
gAslCIncludePattern = re . compile ( r '^(\s*)#include\s*[<"]\s*([- \\ /\w.]+)\s*([>"])' , re . MULTILINE )
## Patterns used to convert EDK conventions to EDK2 ECP conventions
2019-11-20 10:58:28 +08:00
## Regular expression for finding header file inclusions
gIncludePattern = re . compile ( r "^[ \t]*[%]?[ \t]*include(?:[ \t]*(?: \\ (?:\r\n|\r|\n))*[ \t]*)*(?:\(?[ \" <]?[ \t]*)([-\w. \\ /() \t]+)(?:[ \t]*[ \" >]?\)?)" , re . MULTILINE | re . UNICODE | re . IGNORECASE )
2014-01-27 05:23:15 +00:00
## file cache to avoid circular include in ASL file
gIncludedAslFile = []
## Trim preprocessed source code
#
# Remove extra content made by preprocessor. The preprocessor must enable the
# line number generation option when preprocessing.
#
# @param Source File to be trimmed
# @param Target File to store the trimmed content
# @param Convert If True, convert standard HEX format to MASM format
#
def TrimPreprocessedFile ( Source , Target , ConvertHex , TrimLong ):
CreateDirectory ( os . path . dirname ( Target ))
try :
2019-03-28 10:12:31 +08:00
with open ( Source , "r" ) as File :
Lines = File . readlines ()
2019-07-16 17:26:55 +08:00
except IOError :
2014-01-27 05:23:15 +00:00
EdkLogger . error ( "Trim" , FILE_OPEN_FAILURE , ExtraData = Source )
2019-08-01 21:23:43 +08:00
except :
2019-07-16 17:26:55 +08:00
EdkLogger . error ( "Trim" , AUTOGEN_ERROR , "TrimPreprocessedFile: Error while processing file" , File = Source )
2014-01-27 05:23:15 +00:00
PreprocessedFile = ""
InjectedFile = ""
LineIndexOfOriginalFile = None
NewLines = []
LineControlDirectiveFound = False
for Index in range ( len ( Lines )):
Line = Lines [ Index ]
#
# Find out the name of files injected by preprocessor from the lines
# with Line Control directive
#
MatchList = gLineControlDirective . findall ( Line )
if MatchList != []:
MatchList = MatchList [ 0 ]
if len ( MatchList ) == 2 :
LineNumber = int ( MatchList [ 0 ], 0 )
InjectedFile = MatchList [ 1 ]
2018-06-29 03:31:21 +08:00
InjectedFile = os . path . normpath ( InjectedFile )
InjectedFile = os . path . normcase ( InjectedFile )
2019-02-06 15:44:39 +08:00
# The first injected file must be the preprocessed file itself
2014-01-27 05:23:15 +00:00
if PreprocessedFile == "" :
PreprocessedFile = InjectedFile
LineControlDirectiveFound = True
continue
elif PreprocessedFile == "" or InjectedFile != PreprocessedFile :
continue
2018-03-27 04:25:43 +08:00
if LineIndexOfOriginalFile is None :
2014-01-27 05:23:15 +00:00
#
# Any non-empty lines must be from original preprocessed file.
# And this must be the first one.
#
LineIndexOfOriginalFile = Index
EdkLogger . verbose ( "Found original file content starting from line %d "
% ( LineIndexOfOriginalFile + 1 ))
2015-08-06 08:05:59 +00:00
if TrimLong :
Line = gLongNumberPattern . sub ( r "\1" , Line )
2014-01-27 05:23:15 +00:00
# convert HEX number format if indicated
if ConvertHex :
Line = gHexNumberPattern . sub ( r "0\2h" , Line )
else :
Line = gHexNumberPattern . sub ( r "\1\2" , Line )
# convert Decimal number format
Line = gDecNumberPattern . sub ( r "\1" , Line )
2018-03-27 04:25:43 +08:00
if LineNumber is not None :
2014-01-27 05:23:15 +00:00
EdkLogger . verbose ( "Got line directive: line= %d " % LineNumber )
# in case preprocessor removed some lines, like blank or comment lines
if LineNumber <= len ( NewLines ):
# possible?
NewLines [ LineNumber - 1 ] = Line
else :
if LineNumber > ( len ( NewLines ) + 1 ):
for LineIndex in range ( len ( NewLines ), LineNumber - 1 ):
2019-01-11 13:04:44 +08:00
NewLines . append ( TAB_LINE_BREAK )
2014-01-27 05:23:15 +00:00
NewLines . append ( Line )
LineNumber = None
EdkLogger . verbose ( "Now we have lines: %d " % len ( NewLines ))
else :
NewLines . append ( Line )
# in case there's no line directive or linemarker found
if ( not LineControlDirectiveFound ) and NewLines == []:
2016-02-17 14:58:02 +08:00
MulPatternFlag = False
SinglePatternFlag = False
Brace = 0
for Index in range ( len ( Lines )):
Line = Lines [ Index ]
2018-03-27 04:25:43 +08:00
if MulPatternFlag == False and gTypedef_MulPattern . search ( Line ) is None :
if SinglePatternFlag == False and gTypedef_SinglePattern . search ( Line ) is None :
2016-02-17 14:58:02 +08:00
# remove "#pragram pack" directive
2018-03-27 04:25:43 +08:00
if gPragmaPattern . search ( Line ) is None :
2016-02-17 14:58:02 +08:00
NewLines . append ( Line )
continue
elif SinglePatternFlag == False :
SinglePatternFlag = True
if Line . find ( ";" ) >= 0 :
SinglePatternFlag = False
elif MulPatternFlag == False :
# found "typedef struct, typedef union, union, struct", keep its position and set a flag
MulPatternFlag = True
# match { and } to find the end of typedef definition
if Line . find ( "{" ) >= 0 :
Brace += 1
elif Line . find ( "}" ) >= 0 :
Brace -= 1
# "typedef struct, typedef union, union, struct" must end with a ";"
if Brace == 0 and Line . find ( ";" ) >= 0 :
MulPatternFlag = False
2014-01-27 05:23:15 +00:00
# save to file
try :
2019-03-28 10:12:31 +08:00
with open ( Target , 'w' ) as File :
File . writelines ( NewLines )
2014-01-27 05:23:15 +00:00
except :
EdkLogger . error ( "Trim" , FILE_OPEN_FAILURE , ExtraData = Target )
## Trim preprocessed VFR file
#
# Remove extra content made by preprocessor. The preprocessor doesn't need to
# enable line number generation option when preprocessing.
#
# @param Source File to be trimmed
# @param Target File to store the trimmed content
#
def TrimPreprocessedVfr ( Source , Target ):
CreateDirectory ( os . path . dirname ( Target ))
2018-07-05 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
try :
2019-03-28 10:12:31 +08:00
with open ( Source , "r" ) as File :
Lines = File . readlines ()
2014-01-27 05:23:15 +00:00
except :
EdkLogger . error ( "Trim" , FILE_OPEN_FAILURE , ExtraData = Source )
# read whole file
FoundTypedef = False
Brace = 0
TypedefStart = 0
TypedefEnd = 0
for Index in range ( len ( Lines )):
Line = Lines [ Index ]
# don't trim the lines from "formset" definition to the end of file
if Line . strip () == 'formset' :
break
if FoundTypedef == False and ( Line . find ( '#line' ) == 0 or Line . find ( '# ' ) == 0 ):
# empty the line number directive if it's not aomong "typedef struct"
Lines [ Index ] = " \n "
continue
2018-03-27 04:25:43 +08:00
if FoundTypedef == False and gTypedefPattern . search ( Line ) is None :
2014-01-27 05:23:15 +00:00
# keep "#pragram pack" directive
2018-03-27 04:25:43 +08:00
if gPragmaPattern . search ( Line ) is None :
2014-01-27 05:23:15 +00:00
Lines [ Index ] = " \n "
continue
elif FoundTypedef == False :
# found "typedef struct", keept its position and set a flag
FoundTypedef = True
TypedefStart = Index
# match { and } to find the end of typedef definition
if Line . find ( "{" ) >= 0 :
Brace += 1
elif Line . find ( "}" ) >= 0 :
Brace -= 1
# "typedef struct" must end with a ";"
if Brace == 0 and Line . find ( ";" ) >= 0 :
FoundTypedef = False
TypedefEnd = Index
# keep all "typedef struct" except to GUID, EFI_PLABEL and PAL_CALL_RETURN
2018-04-27 00:57:56 +08:00
if Line . strip ( "} ; \r\n " ) in [ TAB_GUID , "EFI_PLABEL" , "PAL_CALL_RETURN" ]:
2014-01-27 05:23:15 +00:00
for i in range ( TypedefStart , TypedefEnd + 1 ):
Lines [ i ] = " \n "
# save all lines trimmed
try :
2019-03-28 10:12:31 +08:00
with open ( Target , 'w' ) as File :
File . writelines ( Lines )
2014-01-27 05:23:15 +00:00
except :
EdkLogger . error ( "Trim" , FILE_OPEN_FAILURE , ExtraData = Target )
2024-06-27 11:22:29 -07:00
# Create a banner to indicate the start and
# end of the included ASL file. Banner looks like:-
#
# /*************************************
# * @param *
# *************************************/
#
# @param Pathname File pathname to be included in the banner
#
def AddIncludeHeader ( Pathname ):
StartLine = "/*" + '*' * ( len ( Pathname ) + 4 )
EndLine = '*' * ( len ( Pathname ) + 4 ) + "*/"
Banner = ' \n ' + StartLine
Banner += ' \n ' + ( ' {0} {1} {0} ' . format ( '*' , Pathname ))
Banner += ' \n ' + EndLine + ' \n '
return Banner
2014-01-27 05:23:15 +00:00
## Read the content ASL file, including ASL included, recursively
#
# @param Source File to be read
# @param Indent Spaces before the Include() statement
# @param IncludePathList The list of external include file
# @param LocalSearchPath If LocalSearchPath is specified, this path will be searched
# first for the included file; otherwise, only the path specified
# in the IncludePathList will be searched.
#
2019-11-20 10:58:28 +08:00
def DoInclude ( Source , Indent = '' , IncludePathList = [], LocalSearchPath = None , IncludeFileList = None , filetype = None ):
2014-01-27 05:23:15 +00:00
NewFileContent = []
2019-11-20 10:58:28 +08:00
if IncludeFileList is None :
IncludeFileList = []
2014-01-27 05:23:15 +00:00
try :
#
# Search LocalSearchPath first if it is specified.
#
if LocalSearchPath :
SearchPathList = [ LocalSearchPath ] + IncludePathList
else :
SearchPathList = IncludePathList
2018-07-05 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
for IncludePath in SearchPathList :
IncludeFile = os . path . join ( IncludePath , Source )
if os . path . isfile ( IncludeFile ):
2019-03-28 10:12:31 +08:00
try :
with open ( IncludeFile , "r" ) as File :
F = File . readlines ()
2024-06-27 11:22:29 -07:00
except Exception :
2019-03-28 10:12:31 +08:00
with codecs . open ( IncludeFile , "r" , encoding = 'utf-8' ) as File :
F = File . readlines ()
2014-01-27 05:23:15 +00:00
break
else :
2024-06-27 11:22:29 -07:00
EdkLogger . error ( "Trim" , FILE_NOT_FOUND , ExtraData = "Failed to find include file %s " % Source )
2020-06-01 14:40:10 +08:00
return []
2024-06-27 11:22:29 -07:00
except Exception as e :
if str ( e ) == str ( FILE_NOT_FOUND ):
raise
else :
EdkLogger . error ( "Trim" , FILE_OPEN_FAILURE , ExtraData = Source )
2014-01-27 05:23:15 +00:00
2018-07-05 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
# avoid A "include" B and B "include" A
IncludeFile = os . path . abspath ( os . path . normpath ( IncludeFile ))
if IncludeFile in gIncludedAslFile :
EdkLogger . warn ( "Trim" , "Circular include" ,
ExtraData = " %s -> %s " % ( " -> " . join ( gIncludedAslFile ), IncludeFile ))
return []
gIncludedAslFile . append ( IncludeFile )
2019-11-20 10:58:28 +08:00
IncludeFileList . append ( IncludeFile . strip ())
2014-01-27 05:23:15 +00:00
for Line in F :
LocalSearchPath = None
2019-11-20 10:58:28 +08:00
if filetype == "ASL" :
Result = gAslIncludePattern . findall ( Line )
if len ( Result ) == 0 :
Result = gAslCIncludePattern . findall ( Line )
if len ( Result ) == 0 or os . path . splitext ( Result [ 0 ][ 1 ])[ 1 ] . lower () not in [ ".asl" , ".asi" ]:
NewFileContent . append ( " %s%s " % ( Indent , Line ))
continue
#
# We should first search the local directory if current file are using pattern #include "XXX"
#
if Result [ 0 ][ 2 ] == '"' :
LocalSearchPath = os . path . dirname ( IncludeFile )
CurrentIndent = Indent + Result [ 0 ][ 0 ]
IncludedFile = Result [ 0 ][ 1 ]
2024-06-27 11:22:29 -07:00
NewFileContent . append ( AddIncludeHeader ( IncludedFile + " --START" ))
2019-11-20 10:58:28 +08:00
NewFileContent . extend ( DoInclude ( IncludedFile , CurrentIndent , IncludePathList , LocalSearchPath , IncludeFileList , filetype ))
2024-06-27 11:22:29 -07:00
NewFileContent . append ( AddIncludeHeader ( IncludedFile + " --END" ))
2019-11-20 10:58:28 +08:00
NewFileContent . append ( " \n " )
elif filetype == "ASM" :
Result = gIncludePattern . findall ( Line )
if len ( Result ) == 0 :
2014-01-27 05:23:15 +00:00
NewFileContent . append ( " %s%s " % ( Indent , Line ))
continue
2019-11-20 10:58:28 +08:00
IncludedFile = Result [ 0 ]
IncludedFile = IncludedFile . strip ()
IncludedFile = os . path . normpath ( IncludedFile )
2024-06-27 11:22:29 -07:00
NewFileContent . append ( AddIncludeHeader ( IncludedFile + " --START" ))
2019-11-20 10:58:28 +08:00
NewFileContent . extend ( DoInclude ( IncludedFile , '' , IncludePathList , LocalSearchPath , IncludeFileList , filetype ))
2024-06-27 11:22:29 -07:00
NewFileContent . append ( AddIncludeHeader ( IncludedFile + " --END" ))
2019-11-20 10:58:28 +08:00
NewFileContent . append ( " \n " )
2014-01-27 05:23:15 +00:00
gIncludedAslFile . pop ()
return NewFileContent
## Trim ASL file
#
# Replace ASL include statement with the content the included file
#
# @param Source File to be trimmed
# @param Target File to store the trimmed content
2018-07-05 17:40:04 +08:00
# @param IncludePathFile The file to log the external include path
2014-01-27 05:23:15 +00:00
#
2019-11-20 10:58:28 +08:00
def TrimAslFile ( Source , Target , IncludePathFile , AslDeps = False ):
2014-01-27 05:23:15 +00:00
CreateDirectory ( os . path . dirname ( Target ))
2018-07-05 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
SourceDir = os . path . dirname ( Source )
if SourceDir == '' :
SourceDir = '.'
2018-07-05 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
#
# Add source directory as the first search directory
#
IncludePathList = [ SourceDir ]
2018-07-05 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
#
# If additional include path file is specified, append them all
# to the search directory list.
#
if IncludePathFile :
try :
LineNum = 0
2019-03-28 10:12:31 +08:00
with open ( IncludePathFile , 'r' ) as File :
FileLines = File . readlines ()
for Line in FileLines :
2014-01-27 05:23:15 +00:00
LineNum += 1
if Line . startswith ( "/I" ) or Line . startswith ( "-I" ):
IncludePathList . append ( Line [ 2 :] . strip ())
else :
EdkLogger . warn ( "Trim" , "Invalid include line in include list file." , IncludePathFile , LineNum )
except :
EdkLogger . error ( "Trim" , FILE_OPEN_FAILURE , ExtraData = IncludePathFile )
2019-11-20 10:58:28 +08:00
AslIncludes = []
Lines = DoInclude ( Source , '' , IncludePathList , IncludeFileList = AslIncludes , filetype = 'ASL' )
AslIncludes = [ item for item in AslIncludes if item != Source ]
2020-11-09 10:51:21 +08:00
SaveFileOnChange ( os . path . join ( os . path . dirname ( Target ), os . path . basename ( Source )) + ".trim.deps" , " \\\n " . join ([ Source + ":" ] + AslIncludes ), False )
2014-01-27 05:23:15 +00:00
#
# Undef MIN and MAX to avoid collision in ASL source code
#
Lines . insert ( 0 , "#undef MIN \n #undef MAX \n " )
# save all lines trimmed
try :
2019-03-28 10:12:31 +08:00
with open ( Target , 'w' ) as File :
File . writelines ( Lines )
2014-01-27 05:23:15 +00:00
except :
EdkLogger . error ( "Trim" , FILE_OPEN_FAILURE , ExtraData = Target )
2019-11-20 10:58:28 +08:00
## Trim ASM file
#
# Output ASM include statement with the content the included file
#
# @param Source File to be trimmed
# @param Target File to store the trimmed content
# @param IncludePathFile The file to log the external include path
#
def TrimAsmFile ( Source , Target , IncludePathFile ):
CreateDirectory ( os . path . dirname ( Target ))
SourceDir = os . path . dirname ( Source )
if SourceDir == '' :
SourceDir = '.'
#
# Add source directory as the first search directory
#
IncludePathList = [ SourceDir ]
#
# If additional include path file is specified, append them all
# to the search directory list.
#
if IncludePathFile :
try :
LineNum = 0
with open ( IncludePathFile , 'r' ) as File :
FileLines = File . readlines ()
for Line in FileLines :
LineNum += 1
if Line . startswith ( "/I" ) or Line . startswith ( "-I" ):
IncludePathList . append ( Line [ 2 :] . strip ())
else :
EdkLogger . warn ( "Trim" , "Invalid include line in include list file." , IncludePathFile , LineNum )
except :
EdkLogger . error ( "Trim" , FILE_OPEN_FAILURE , ExtraData = IncludePathFile )
AsmIncludes = []
Lines = DoInclude ( Source , '' , IncludePathList , IncludeFileList = AsmIncludes , filetype = 'ASM' )
AsmIncludes = [ item for item in AsmIncludes if item != Source ]
if AsmIncludes :
SaveFileOnChange ( os . path . join ( os . path . dirname ( Target ), os . path . basename ( Source )) + ".trim.deps" , " \\\n " . join ([ Source + ":" ] + AsmIncludes ), False )
# save all lines trimmed
try :
with open ( Target , 'w' ) as File :
File . writelines ( Lines )
except :
EdkLogger . error ( "Trim" , FILE_OPEN_FAILURE , ExtraData = Target )
2017-09-29 07:54:12 +08:00
def GenerateVfrBinSec ( ModuleName , DebugDir , OutputFile ):
VfrNameList = []
if os . path . isdir ( DebugDir ):
for CurrentDir , Dirs , Files in os . walk ( DebugDir ):
for FileName in Files :
Name , Ext = os . path . splitext ( FileName )
2018-04-10 09:12:49 +08:00
if Ext == '.c' and Name != 'AutoGen' :
2017-09-29 07:54:12 +08:00
VfrNameList . append ( Name + 'Bin' )
VfrNameList . append ( ModuleName + 'Strings' )
EfiFileName = os . path . join ( DebugDir , ModuleName + '.efi' )
MapFileName = os . path . join ( DebugDir , ModuleName + '.map' )
VfrUniOffsetList = GetVariableOffset ( MapFileName , EfiFileName , VfrNameList )
if not VfrUniOffsetList :
return
try :
2019-03-28 10:12:31 +08:00
fInputfile = open ( OutputFile , "wb+" )
2017-09-29 07:54:12 +08:00
except :
EdkLogger . error ( "Trim" , FILE_OPEN_FAILURE , "File open failed for %s " % OutputFile , None )
2018-06-25 18:31:36 +08:00
# Use a instance of BytesIO to cache data
2019-01-23 10:16:00 +08:00
fStringIO = BytesIO ()
2017-09-29 07:54:12 +08:00
for Item in VfrUniOffsetList :
if ( Item [ 0 ] . find ( "Strings" ) != - 1 ):
#
# UNI offset in image.
# GUID + Offset
# { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
#
2019-01-23 10:16:00 +08:00
UniGuid = b ' \xe0\xc5\x13\x89\xf6 3 \x86 M \x9b\xf1 C \xef\x89\xfc\x06 f'
fStringIO . write ( UniGuid )
2017-09-29 07:54:12 +08:00
UniValue = pack ( 'Q' , int ( Item [ 1 ], 16 ))
fStringIO . write ( UniValue )
else :
#
# VFR binary offset in image.
# GUID + Offset
# { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
#
2019-01-23 10:16:00 +08:00
VfrGuid = b ' \xb4 | \xbc\xd0 Gj_I \xaa\x11 q \x07 F \xda\x06\xa2 '
fStringIO . write ( VfrGuid )
2018-10-15 08:27:53 +08:00
type ( Item [ 1 ])
2017-09-29 07:54:12 +08:00
VfrValue = pack ( 'Q' , int ( Item [ 1 ], 16 ))
fStringIO . write ( VfrValue )
#
# write data into file.
#
try :
fInputfile . write ( fStringIO . getvalue ())
except :
EdkLogger . error ( "Trim" , FILE_WRITE_FAILURE , "Write data to file %s failed, please check whether the file been locked or using by other applications." % OutputFile , None )
fStringIO . close ()
fInputfile . close ()
2014-01-27 05:23:15 +00:00
## Parse command line options
#
# Using standard Python module optparse to parse command line option of this tool.
#
# @retval Options A optparse.Values object containing the parsed options
# @retval InputFile Path of file to be trimmed
#
def Options ():
OptionList = [
make_option ( "-s" , "--source-code" , dest = "FileType" , const = "SourceCode" , action = "store_const" ,
help = "The input file is preprocessed source code, including C or assembly code" ),
make_option ( "-r" , "--vfr-file" , dest = "FileType" , const = "Vfr" , action = "store_const" ,
help = "The input file is preprocessed VFR file" ),
2017-09-29 07:54:12 +08:00
make_option ( "--Vfr-Uni-Offset" , dest = "FileType" , const = "VfrOffsetBin" , action = "store_const" ,
help = "The input file is EFI image" ),
2019-11-20 10:58:28 +08:00
make_option ( "--asl-deps" , dest = "AslDeps" , const = "True" , action = "store_const" ,
help = "Generate Asl dependent files." ),
2014-01-27 05:23:15 +00:00
make_option ( "-a" , "--asl-file" , dest = "FileType" , const = "Asl" , action = "store_const" ,
help = "The input file is ASL file" ),
2019-11-20 10:58:28 +08:00
make_option ( "--asm-file" , dest = "FileType" , const = "Asm" , action = "store_const" ,
help = "The input file is asm file" ),
2014-01-27 05:23:15 +00:00
make_option ( "-c" , "--convert-hex" , dest = "ConvertHex" , action = "store_true" ,
help = "Convert standard hex format (0xabcd) to MASM format (abcdh)" ),
make_option ( "-l" , "--trim-long" , dest = "TrimLong" , action = "store_true" ,
help = "Remove postfix of long number" ),
make_option ( "-i" , "--include-path-file" , dest = "IncludePathFile" ,
help = "The input file is include path list to search for ASL include file" ),
make_option ( "-o" , "--output" , dest = "OutputFile" ,
help = "File to store the trimmed content" ),
2017-09-29 07:54:12 +08:00
make_option ( "--ModuleName" , dest = "ModuleName" , help = "The module's BASE_NAME" ),
make_option ( "--DebugDir" , dest = "DebugDir" ,
help = "Debug Output directory to store the output files" ),
2014-01-27 05:23:15 +00:00
make_option ( "-v" , "--verbose" , dest = "LogLevel" , action = "store_const" , const = EdkLogger . VERBOSE ,
help = "Run verbosely" ),
make_option ( "-d" , "--debug" , dest = "LogLevel" , type = "int" ,
help = "Run with debug information" ),
make_option ( "-q" , "--quiet" , dest = "LogLevel" , action = "store_const" , const = EdkLogger . QUIET ,
help = "Run quietly" ),
make_option ( "-?" , action = "help" , help = "show this help message and exit" ),
]
# use clearer usage to override default usage message
2017-09-29 07:54:12 +08:00
UsageString = "%prog [-s|-r|-a|--Vfr-Uni-Offset] [-c] [-v|-d <debug_level>|-q] [-i <include_path_file>] [-o <output_file>] [--ModuleName <ModuleName>] [--DebugDir <DebugDir>] [<input_file>]"
2014-01-27 05:23:15 +00:00
Parser = OptionParser ( description = __copyright__ , version = __version__ , option_list = OptionList , usage = UsageString )
Parser . set_defaults ( FileType = "Vfr" )
Parser . set_defaults ( ConvertHex = False )
Parser . set_defaults ( LogLevel = EdkLogger . INFO )
Options , Args = Parser . parse_args ()
# error check
2017-09-29 07:54:12 +08:00
if Options . FileType == 'VfrOffsetBin' :
if len ( Args ) == 0 :
return Options , ''
elif len ( Args ) > 1 :
EdkLogger . error ( "Trim" , OPTION_NOT_SUPPORTED , ExtraData = Parser . get_usage ())
2014-01-27 05:23:15 +00:00
if len ( Args ) == 0 :
EdkLogger . error ( "Trim" , OPTION_MISSING , ExtraData = Parser . get_usage ())
if len ( Args ) > 1 :
EdkLogger . error ( "Trim" , OPTION_NOT_SUPPORTED , ExtraData = Parser . get_usage ())
InputFile = Args [ 0 ]
return Options , InputFile
## Entrance method
#
# This method mainly dispatch specific methods per the command line options.
# If no error found, return zero value so the caller of this tool can know
# if it's executed successfully or not.
#
# @retval 0 Tool was successful
# @retval 1 Tool failed
#
def Main ():
try :
EdkLogger . Initialize ()
CommandOptions , InputFile = Options ()
if CommandOptions . LogLevel < EdkLogger . DEBUG_9 :
EdkLogger . SetLevel ( CommandOptions . LogLevel + 1 )
else :
EdkLogger . SetLevel ( CommandOptions . LogLevel )
2018-06-25 18:31:25 +08:00
except FatalError as X :
2014-01-27 05:23:15 +00:00
return 1
2018-07-05 17:40:04 +08:00
2014-01-27 05:23:15 +00:00
try :
if CommandOptions . FileType == "Vfr" :
2018-03-27 04:25:43 +08:00
if CommandOptions . OutputFile is None :
2014-01-27 05:23:15 +00:00
CommandOptions . OutputFile = os . path . splitext ( InputFile )[ 0 ] + '.iii'
TrimPreprocessedVfr ( InputFile , CommandOptions . OutputFile )
elif CommandOptions . FileType == "Asl" :
2018-03-27 04:25:43 +08:00
if CommandOptions . OutputFile is None :
2014-01-27 05:23:15 +00:00
CommandOptions . OutputFile = os . path . splitext ( InputFile )[ 0 ] + '.iii'
2019-11-20 10:58:28 +08:00
TrimAslFile ( InputFile , CommandOptions . OutputFile , CommandOptions . IncludePathFile , CommandOptions . AslDeps )
2017-09-29 07:54:12 +08:00
elif CommandOptions . FileType == "VfrOffsetBin" :
GenerateVfrBinSec ( CommandOptions . ModuleName , CommandOptions . DebugDir , CommandOptions . OutputFile )
2019-11-20 10:58:28 +08:00
elif CommandOptions . FileType == "Asm" :
TrimAsmFile ( InputFile , CommandOptions . OutputFile , CommandOptions . IncludePathFile )
2014-01-27 05:23:15 +00:00
else :
2018-03-27 04:25:43 +08:00
if CommandOptions . OutputFile is None :
2014-01-27 05:23:15 +00:00
CommandOptions . OutputFile = os . path . splitext ( InputFile )[ 0 ] + '.iii'
TrimPreprocessedFile ( InputFile , CommandOptions . OutputFile , CommandOptions . ConvertHex , CommandOptions . TrimLong )
2018-06-25 18:31:25 +08:00
except FatalError as X :
2014-01-27 05:23:15 +00:00
import platform
import traceback
2018-03-27 04:25:43 +08:00
if CommandOptions is not None and CommandOptions . LogLevel <= EdkLogger . DEBUG_9 :
2014-01-27 05:23:15 +00:00
EdkLogger . quiet ( "(Python %s on %s ) " % ( platform . python_version (), sys . platform ) + traceback . format_exc ())
return 1
except :
import traceback
import platform
EdkLogger . error (
" \n Trim" ,
CODE_ERROR ,
"Unknown fatal error when trimming [ %s ]" % InputFile ,
2019-05-21 10:06:52 +08:00
ExtraData = " \n (Please send email to %s for help, attaching following call stack trace!) \n " % MSG_EDKII_MAIL_ADDR ,
2014-01-27 05:23:15 +00:00
RaiseError = False
)
EdkLogger . quiet ( "(Python %s on %s ) " % ( platform . python_version (), sys . platform ) + traceback . format_exc ())
return 1
return 0
if __name__ == '__main__' :
r = Main ()
## 0-127 is a safe return range, and 1 is a standard default error
if r < 0 or r > 127 : r = 1
sys . exit ( r )