X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FTrim%2FTrim.py;h=b512d15243f83225457b2dc099ac0c026142a5ed;hp=c0ede0335993690727bfef6b4d3fd0edcc96511e;hb=92beb1e4c73a40a708c7c0cade5c7cee314b3887;hpb=f51461c829c124288a930829a78e2a5a799f4039
diff --git a/BaseTools/Source/Python/Trim/Trim.py b/BaseTools/Source/Python/Trim/Trim.py
index c0ede03359..b512d15243 100644
--- a/BaseTools/Source/Python/Trim/Trim.py
+++ b/BaseTools/Source/Python/Trim/Trim.py
@@ -1,7 +1,7 @@
## @file
# Trim files preprocessed by compiler
#
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
# 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
@@ -14,21 +14,24 @@
##
# Import Modules
#
-import os
+import Common.LongFilePathOs as os
import sys
import re
+import StringIO
from optparse import OptionParser
from optparse import make_option
from Common.BuildToolError import *
from Common.Misc import *
+from Common.DataType import *
from Common.BuildVersion import gBUILD_VERSION
import Common.EdkLogger as EdkLogger
+from Common.LongFilePathSupport import OpenLongFilePath as open
# Version and Copyright
__version_number__ = ("0.10" + " " + gBUILD_VERSION)
__version__ = "%prog Version " + __version_number__
-__copyright__ = "Copyright (c) 2007-2010, Intel Corporation. All rights reserved."
+__copyright__ = "Copyright (c) 2007-2017, Intel Corporation. All rights reserved."
## Regular expression for matching Line Control directive like "#line xxx"
gLineControlDirective = re.compile('^\s*#(?:line)?\s+([0-9]+)\s+"*([^"]*)"')
@@ -36,6 +39,10 @@ gLineControlDirective = re.compile('^\s*#(?:line)?\s+([0-9]+)\s+"*([^"]*)"')
gTypedefPattern = re.compile("^\s*typedef\s+struct(\s+\w+)?\s*[{]*$", re.MULTILINE)
## Regular expression for matching "#pragma pack"
gPragmaPattern = re.compile("^\s*#pragma\s+pack", re.MULTILINE)
+## Regular expression for matching "typedef"
+gTypedef_SinglePattern = re.compile("^\s*typedef", re.MULTILINE)
+## Regular expression for matching "typedef struct, typedef union, struct, union"
+gTypedef_MulPattern = re.compile("^\s*(typedef)?\s+(struct|union)(\s+\w+)?\s*[{]*$", re.MULTILINE)
#
# The following number pattern match will only match if following criteria is met:
@@ -167,7 +174,7 @@ def TrimPreprocessedFile(Source, Target, ConvertHex, TrimLong):
elif PreprocessedFile == "" or InjectedFile != PreprocessedFile:
continue
- if LineIndexOfOriginalFile == None:
+ if LineIndexOfOriginalFile is None:
#
# Any non-empty lines must be from original preprocessed file.
# And this must be the first one.
@@ -176,18 +183,18 @@ def TrimPreprocessedFile(Source, Target, ConvertHex, TrimLong):
EdkLogger.verbose("Found original file content starting from line %d"
% (LineIndexOfOriginalFile + 1))
+ if TrimLong:
+ Line = gLongNumberPattern.sub(r"\1", Line)
# convert HEX number format if indicated
if ConvertHex:
Line = gHexNumberPattern.sub(r"0\2h", Line)
else:
Line = gHexNumberPattern.sub(r"\1\2", Line)
- if TrimLong:
- Line = gLongNumberPattern.sub(r"\1", Line)
# convert Decimal number format
Line = gDecNumberPattern.sub(r"\1", Line)
- if LineNumber != None:
+ if LineNumber is not None:
EdkLogger.verbose("Got line directive: line=%d" % LineNumber)
# in case preprocessor removed some lines, like blank or comment lines
if LineNumber <= len(NewLines):
@@ -205,7 +212,34 @@ def TrimPreprocessedFile(Source, Target, ConvertHex, TrimLong):
# in case there's no line directive or linemarker found
if (not LineControlDirectiveFound) and NewLines == []:
- NewLines = Lines
+ MulPatternFlag = False
+ SinglePatternFlag = False
+ Brace = 0
+ for Index in range(len(Lines)):
+ Line = Lines[Index]
+ if MulPatternFlag == False and gTypedef_MulPattern.search(Line) is None:
+ if SinglePatternFlag == False and gTypedef_SinglePattern.search(Line) is None:
+ # remove "#pragram pack" directive
+ if gPragmaPattern.search(Line) is None:
+ 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
# save to file
try:
@@ -249,9 +283,9 @@ def TrimPreprocessedVfr(Source, Target):
Lines[Index] = "\n"
continue
- if FoundTypedef == False and gTypedefPattern.search(Line) == None:
+ if FoundTypedef == False and gTypedefPattern.search(Line) is None:
# keep "#pragram pack" directive
- if gPragmaPattern.search(Line) == None:
+ if gPragmaPattern.search(Line) is None:
Lines[Index] = "\n"
continue
elif FoundTypedef == False:
@@ -270,7 +304,7 @@ def TrimPreprocessedVfr(Source, Target):
FoundTypedef = False
TypedefEnd = Index
# keep all "typedef struct" except to GUID, EFI_PLABEL and PAL_CALL_RETURN
- if Line.strip("} ;\r\n") in ["GUID", "EFI_PLABEL", "PAL_CALL_RETURN"]:
+ if Line.strip("} ;\r\n") in [TAB_GUID, "EFI_PLABEL", "PAL_CALL_RETURN"]:
for i in range(TypedefStart, TypedefEnd+1):
Lines[i] = "\n"
@@ -398,6 +432,68 @@ def TrimAslFile(Source, Target, IncludePathFile):
f.writelines(Lines)
f.close()
+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)
+ if Ext == '.c' and Name != 'AutoGen':
+ 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:
+ fInputfile = open(OutputFile, "wb+", 0)
+ except:
+ EdkLogger.error("Trim", FILE_OPEN_FAILURE, "File open failed for %s" %OutputFile, None)
+
+ # Use a instance of StringIO to cache data
+ fStringIO = StringIO.StringIO('')
+
+ 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 } }
+ #
+ UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
+ UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]
+ fStringIO.write(''.join(UniGuid))
+ 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 } };
+ #
+ VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
+ VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]
+ fStringIO.write(''.join(VfrGuid))
+ type (Item[1])
+ 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 ()
+
## Trim EDK source code file(s)
#
#
@@ -415,7 +511,7 @@ def TrimEdkSources(Source, Target):
for FileName in Files:
Dummy, Ext = os.path.splitext(FileName)
if Ext.upper() not in ['.C', '.H']: continue
- if Target == None or Target == '':
+ if Target is None or Target == '':
TrimEdkSourceCode(
os.path.join(CurrentDir, FileName),
os.path.join(CurrentDir, FileName)
@@ -473,7 +569,7 @@ def TrimEdkSourceCode(Source, Target):
NewLines = None
for Re,Repl in gImportCodePatterns:
- if NewLines == None:
+ if NewLines is None:
NewLines = Re.sub(Repl, Lines)
else:
NewLines = Re.sub(Repl, NewLines)
@@ -503,6 +599,8 @@ def Options():
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"),
+ make_option("--Vfr-Uni-Offset", dest="FileType", const="VfrOffsetBin", action="store_const",
+ help="The input file is EFI image"),
make_option("-a", "--asl-file", dest="FileType", const="Asl", action="store_const",
help="The input file is ASL file"),
make_option("-8", "--Edk-source-code", dest="FileType", const="EdkSourceCode", action="store_const",
@@ -517,6 +615,9 @@ def Options():
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"),
+ 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"),
make_option("-v", "--verbose", dest="LogLevel", action="store_const", const=EdkLogger.VERBOSE,
help="Run verbosely"),
make_option("-d", "--debug", dest="LogLevel", type="int",
@@ -527,7 +628,7 @@ def Options():
]
# use clearer usage to override default usage message
- UsageString = "%prog [-s|-r|-a] [-c] [-v|-d |-q] [-i ] [-o ] "
+ UsageString = "%prog [-s|-r|-a|--Vfr-Uni-Offset] [-c] [-v|-d |-q] [-i ] [-o ] [--ModuleName ] [--DebugDir ] []"
Parser = OptionParser(description=__copyright__, version=__version__, option_list=OptionList, usage=UsageString)
Parser.set_defaults(FileType="Vfr")
@@ -537,6 +638,11 @@ def Options():
Options, Args = Parser.parse_args()
# error check
+ if Options.FileType == 'VfrOffsetBin':
+ if len(Args) == 0:
+ return Options, ''
+ elif len(Args) > 1:
+ EdkLogger.error("Trim", OPTION_NOT_SUPPORTED, ExtraData=Parser.get_usage())
if len(Args) == 0:
EdkLogger.error("Trim", OPTION_MISSING, ExtraData=Parser.get_usage())
if len(Args) > 1:
@@ -562,28 +668,30 @@ def Main():
EdkLogger.SetLevel(CommandOptions.LogLevel + 1)
else:
EdkLogger.SetLevel(CommandOptions.LogLevel)
- except FatalError, X:
+ except FatalError as X:
return 1
try:
if CommandOptions.FileType == "Vfr":
- if CommandOptions.OutputFile == None:
+ if CommandOptions.OutputFile is None:
CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'
TrimPreprocessedVfr(InputFile, CommandOptions.OutputFile)
elif CommandOptions.FileType == "Asl":
- if CommandOptions.OutputFile == None:
+ if CommandOptions.OutputFile is None:
CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'
TrimAslFile(InputFile, CommandOptions.OutputFile, CommandOptions.IncludePathFile)
elif CommandOptions.FileType == "EdkSourceCode":
TrimEdkSources(InputFile, CommandOptions.OutputFile)
+ elif CommandOptions.FileType == "VfrOffsetBin":
+ GenerateVfrBinSec(CommandOptions.ModuleName, CommandOptions.DebugDir, CommandOptions.OutputFile)
else :
- if CommandOptions.OutputFile == None:
+ if CommandOptions.OutputFile is None:
CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'
TrimPreprocessedFile(InputFile, CommandOptions.OutputFile, CommandOptions.ConvertHex, CommandOptions.TrimLong)
- except FatalError, X:
+ except FatalError as X:
import platform
import traceback
- if CommandOptions != None and CommandOptions.LogLevel <= EdkLogger.DEBUG_9:
+ if CommandOptions is not None and CommandOptions.LogLevel <= EdkLogger.DEBUG_9:
EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
return 1
except:
@@ -593,7 +701,7 @@ def Main():
"\nTrim",
CODE_ERROR,
"Unknown fatal error when trimming [%s]" % InputFile,
- ExtraData="\n(Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!)\n",
+ ExtraData="\n(Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!)\n",
RaiseError=False
)
EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())