## @file\r
# Trim files preprocessed by compiler\r
#\r
-# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
# which accompanies this distribution. The full text of the license may be found at\r
import Common.LongFilePathOs as os\r
import sys\r
import re\r
+from io import BytesIO\r
\r
from optparse import OptionParser\r
from optparse import make_option\r
from Common.BuildToolError import *\r
from Common.Misc import *\r
+from Common.DataType import *\r
from Common.BuildVersion import gBUILD_VERSION\r
import Common.EdkLogger as EdkLogger\r
from Common.LongFilePathSupport import OpenLongFilePath as open\r
# Version and Copyright\r
__version_number__ = ("0.10" + " " + gBUILD_VERSION)\r
__version__ = "%prog Version " + __version_number__\r
-__copyright__ = "Copyright (c) 2007-2016, Intel Corporation. All rights reserved."\r
+__copyright__ = "Copyright (c) 2007-2018, Intel Corporation. All rights reserved."\r
\r
## Regular expression for matching Line Control directive like "#line xxx"\r
gLineControlDirective = re.compile('^\s*#(?:line)?\s+([0-9]+)\s+"*([^"]*)"')\r
if len(MatchList) == 2:\r
LineNumber = int(MatchList[0], 0)\r
InjectedFile = MatchList[1]\r
+ InjectedFile = os.path.normpath(InjectedFile)\r
+ InjectedFile = os.path.normcase(InjectedFile)\r
# The first injetcted file must be the preprocessed file itself\r
if PreprocessedFile == "":\r
PreprocessedFile = InjectedFile\r
elif PreprocessedFile == "" or InjectedFile != PreprocessedFile:\r
continue\r
\r
- if LineIndexOfOriginalFile == None:\r
+ if LineIndexOfOriginalFile is None:\r
#\r
# Any non-empty lines must be from original preprocessed file.\r
# And this must be the first one.\r
# convert Decimal number format\r
Line = gDecNumberPattern.sub(r"\1", Line)\r
\r
- if LineNumber != None:\r
+ if LineNumber is not None:\r
EdkLogger.verbose("Got line directive: line=%d" % LineNumber)\r
# in case preprocessor removed some lines, like blank or comment lines\r
if LineNumber <= len(NewLines):\r
else:\r
if LineNumber > (len(NewLines) + 1):\r
for LineIndex in range(len(NewLines), LineNumber-1):\r
- NewLines.append(os.linesep)\r
+ NewLines.append(TAB_LINE_BREAK)\r
NewLines.append(Line)\r
LineNumber = None\r
EdkLogger.verbose("Now we have lines: %d" % len(NewLines))\r
Brace = 0\r
for Index in range(len(Lines)):\r
Line = Lines[Index]\r
- if MulPatternFlag == False and gTypedef_MulPattern.search(Line) == None:\r
- if SinglePatternFlag == False and gTypedef_SinglePattern.search(Line) == None:\r
+ if MulPatternFlag == False and gTypedef_MulPattern.search(Line) is None:\r
+ if SinglePatternFlag == False and gTypedef_SinglePattern.search(Line) is None:\r
# remove "#pragram pack" directive\r
- if gPragmaPattern.search(Line) == None:\r
+ if gPragmaPattern.search(Line) is None:\r
NewLines.append(Line)\r
continue\r
elif SinglePatternFlag == False:\r
#\r
def TrimPreprocessedVfr(Source, Target):\r
CreateDirectory(os.path.dirname(Target))\r
- \r
+\r
try:\r
- f = open (Source,'r')\r
+ f = open (Source, 'r')\r
except:\r
EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source)\r
# read whole file\r
Lines[Index] = "\n"\r
continue\r
\r
- if FoundTypedef == False and gTypedefPattern.search(Line) == None:\r
+ if FoundTypedef == False and gTypedefPattern.search(Line) is None:\r
# keep "#pragram pack" directive\r
- if gPragmaPattern.search(Line) == None:\r
+ if gPragmaPattern.search(Line) is None:\r
Lines[Index] = "\n"\r
continue\r
elif FoundTypedef == False:\r
FoundTypedef = False\r
TypedefEnd = Index\r
# keep all "typedef struct" except to GUID, EFI_PLABEL and PAL_CALL_RETURN\r
- if Line.strip("} ;\r\n") in ["GUID", "EFI_PLABEL", "PAL_CALL_RETURN"]:\r
+ if Line.strip("} ;\r\n") in [TAB_GUID, "EFI_PLABEL", "PAL_CALL_RETURN"]:\r
for i in range(TypedefStart, TypedefEnd+1):\r
Lines[i] = "\n"\r
\r
# save all lines trimmed\r
try:\r
- f = open (Target,'w')\r
+ f = open (Target, 'w')\r
except:\r
EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target)\r
f.writelines(Lines)\r
SearchPathList = [LocalSearchPath] + IncludePathList\r
else:\r
SearchPathList = IncludePathList\r
- \r
+\r
for IncludePath in SearchPathList:\r
IncludeFile = os.path.join(IncludePath, Source)\r
if os.path.isfile(IncludeFile):\r
except:\r
EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source)\r
\r
- \r
+\r
# avoid A "include" B and B "include" A\r
IncludeFile = os.path.abspath(os.path.normpath(IncludeFile))\r
if IncludeFile in gIncludedAslFile:\r
ExtraData= "%s -> %s" % (" -> ".join(gIncludedAslFile), IncludeFile))\r
return []\r
gIncludedAslFile.append(IncludeFile)\r
- \r
+\r
for Line in F:\r
LocalSearchPath = None\r
Result = gAslIncludePattern.findall(Line)\r
NewFileContent.append("%s%s" % (Indent, Line))\r
continue\r
#\r
- # We should first search the local directory if current file are using pattern #include "XXX" \r
+ # We should first search the local directory if current file are using pattern #include "XXX"\r
#\r
if Result[0][2] == '"':\r
LocalSearchPath = os.path.dirname(IncludeFile)\r
#\r
# @param Source File to be trimmed\r
# @param Target File to store the trimmed content\r
-# @param IncludePathFile The file to log the external include path \r
+# @param IncludePathFile The file to log the external include path\r
#\r
def TrimAslFile(Source, Target, IncludePathFile):\r
CreateDirectory(os.path.dirname(Target))\r
- \r
+\r
SourceDir = os.path.dirname(Source)\r
if SourceDir == '':\r
SourceDir = '.'\r
- \r
+\r
#\r
# Add source directory as the first search directory\r
#\r
IncludePathList = [SourceDir]\r
- \r
+\r
#\r
# If additional include path file is specified, append them all\r
# to the search directory list.\r
if IncludePathFile:\r
try:\r
LineNum = 0\r
- for Line in open(IncludePathFile,'r'):\r
+ for Line in open(IncludePathFile, 'r'):\r
LineNum += 1\r
if Line.startswith("/I") or Line.startswith ("-I"):\r
IncludePathList.append(Line[2:].strip())\r
\r
# save all lines trimmed\r
try:\r
- f = open (Target,'w')\r
+ f = open (Target, 'w')\r
except:\r
EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target)\r
\r
f.writelines(Lines)\r
f.close()\r
\r
+def GenerateVfrBinSec(ModuleName, DebugDir, OutputFile):\r
+ VfrNameList = []\r
+ if os.path.isdir(DebugDir):\r
+ for CurrentDir, Dirs, Files in os.walk(DebugDir):\r
+ for FileName in Files:\r
+ Name, Ext = os.path.splitext(FileName)\r
+ if Ext == '.c' and Name != 'AutoGen':\r
+ VfrNameList.append (Name + 'Bin')\r
+\r
+ VfrNameList.append (ModuleName + 'Strings')\r
+\r
+ EfiFileName = os.path.join(DebugDir, ModuleName + '.efi')\r
+ MapFileName = os.path.join(DebugDir, ModuleName + '.map')\r
+ VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrNameList)\r
+\r
+ if not VfrUniOffsetList:\r
+ return\r
+\r
+ try:\r
+ fInputfile = open(OutputFile, "wb+", 0)\r
+ except:\r
+ EdkLogger.error("Trim", FILE_OPEN_FAILURE, "File open failed for %s" %OutputFile, None)\r
+\r
+ # Use a instance of BytesIO to cache data\r
+ fStringIO = BytesIO('')\r
+\r
+ for Item in VfrUniOffsetList:\r
+ if (Item[0].find("Strings") != -1):\r
+ #\r
+ # UNI offset in image.\r
+ # GUID + Offset\r
+ # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }\r
+ #\r
+ UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]\r
+ UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]\r
+ fStringIO.write(''.join(UniGuid))\r
+ UniValue = pack ('Q', int (Item[1], 16))\r
+ fStringIO.write (UniValue)\r
+ else:\r
+ #\r
+ # VFR binary offset in image.\r
+ # GUID + Offset\r
+ # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };\r
+ #\r
+ VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]\r
+ VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]\r
+ fStringIO.write(''.join(VfrGuid))\r
+ type (Item[1])\r
+ VfrValue = pack ('Q', int (Item[1], 16))\r
+ fStringIO.write (VfrValue)\r
+\r
+ #\r
+ # write data into file.\r
+ #\r
+ try :\r
+ fInputfile.write (fStringIO.getvalue())\r
+ except:\r
+ 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)\r
+\r
+ fStringIO.close ()\r
+ fInputfile.close ()\r
+\r
## Trim EDK source code file(s)\r
#\r
#\r
for FileName in Files:\r
Dummy, Ext = os.path.splitext(FileName)\r
if Ext.upper() not in ['.C', '.H']: continue\r
- if Target == None or Target == '':\r
+ if Target is None or Target == '':\r
TrimEdkSourceCode(\r
os.path.join(CurrentDir, FileName),\r
os.path.join(CurrentDir, FileName)\r
CreateDirectory(os.path.dirname(Target))\r
\r
try:\r
- f = open (Source,'rb')\r
+ f = open (Source, 'rb')\r
except:\r
EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source)\r
# read whole file\r
f.close()\r
\r
NewLines = None\r
- for Re,Repl in gImportCodePatterns:\r
- if NewLines == None:\r
+ for Re, Repl in gImportCodePatterns:\r
+ if NewLines is None:\r
NewLines = Re.sub(Repl, Lines)\r
else:\r
NewLines = Re.sub(Repl, NewLines)\r
return\r
\r
try:\r
- f = open (Target,'wb')\r
+ f = open (Target, 'wb')\r
except:\r
EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target)\r
f.write(NewLines)\r
help="The input file is preprocessed source code, including C or assembly code"),\r
make_option("-r", "--vfr-file", dest="FileType", const="Vfr", action="store_const",\r
help="The input file is preprocessed VFR file"),\r
+ make_option("--Vfr-Uni-Offset", dest="FileType", const="VfrOffsetBin", action="store_const",\r
+ help="The input file is EFI image"),\r
make_option("-a", "--asl-file", dest="FileType", const="Asl", action="store_const",\r
help="The input file is ASL file"),\r
make_option("-8", "--Edk-source-code", dest="FileType", const="EdkSourceCode", action="store_const",\r
help="The input file is include path list to search for ASL include file"),\r
make_option("-o", "--output", dest="OutputFile",\r
help="File to store the trimmed content"),\r
+ make_option("--ModuleName", dest="ModuleName", help="The module's BASE_NAME"),\r
+ make_option("--DebugDir", dest="DebugDir",\r
+ help="Debug Output directory to store the output files"),\r
make_option("-v", "--verbose", dest="LogLevel", action="store_const", const=EdkLogger.VERBOSE,\r
help="Run verbosely"),\r
make_option("-d", "--debug", dest="LogLevel", type="int",\r
]\r
\r
# use clearer usage to override default usage message\r
- UsageString = "%prog [-s|-r|-a] [-c] [-v|-d <debug_level>|-q] [-i <include_path_file>] [-o <output_file>] <input_file>"\r
+ 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>]"\r
\r
Parser = OptionParser(description=__copyright__, version=__version__, option_list=OptionList, usage=UsageString)\r
Parser.set_defaults(FileType="Vfr")\r
Options, Args = Parser.parse_args()\r
\r
# error check\r
+ if Options.FileType == 'VfrOffsetBin':\r
+ if len(Args) == 0:\r
+ return Options, ''\r
+ elif len(Args) > 1:\r
+ EdkLogger.error("Trim", OPTION_NOT_SUPPORTED, ExtraData=Parser.get_usage())\r
if len(Args) == 0:\r
EdkLogger.error("Trim", OPTION_MISSING, ExtraData=Parser.get_usage())\r
if len(Args) > 1:\r
EdkLogger.SetLevel(CommandOptions.LogLevel + 1)\r
else:\r
EdkLogger.SetLevel(CommandOptions.LogLevel)\r
- except FatalError, X:\r
+ except FatalError as X:\r
return 1\r
- \r
+\r
try:\r
if CommandOptions.FileType == "Vfr":\r
- if CommandOptions.OutputFile == None:\r
+ if CommandOptions.OutputFile is None:\r
CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'\r
TrimPreprocessedVfr(InputFile, CommandOptions.OutputFile)\r
elif CommandOptions.FileType == "Asl":\r
- if CommandOptions.OutputFile == None:\r
+ if CommandOptions.OutputFile is None:\r
CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'\r
TrimAslFile(InputFile, CommandOptions.OutputFile, CommandOptions.IncludePathFile)\r
elif CommandOptions.FileType == "EdkSourceCode":\r
TrimEdkSources(InputFile, CommandOptions.OutputFile)\r
+ elif CommandOptions.FileType == "VfrOffsetBin":\r
+ GenerateVfrBinSec(CommandOptions.ModuleName, CommandOptions.DebugDir, CommandOptions.OutputFile)\r
else :\r
- if CommandOptions.OutputFile == None:\r
+ if CommandOptions.OutputFile is None:\r
CommandOptions.OutputFile = os.path.splitext(InputFile)[0] + '.iii'\r
TrimPreprocessedFile(InputFile, CommandOptions.OutputFile, CommandOptions.ConvertHex, CommandOptions.TrimLong)\r
- except FatalError, X:\r
+ except FatalError as X:\r
import platform\r
import traceback\r
- if CommandOptions != None and CommandOptions.LogLevel <= EdkLogger.DEBUG_9:\r
+ if CommandOptions is not None and CommandOptions.LogLevel <= EdkLogger.DEBUG_9:\r
EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())\r
return 1\r
except:\r