From 22a99b87c4d29ebaa8713ac8f04d9d0c11c3add5 Mon Sep 17 00:00:00 2001 From: Yingke Liu Date: Fri, 6 Feb 2015 03:40:27 +0000 Subject: [PATCH] 1. Update UpdateBuildVersion.py; 2. Generate correct HII data offset. 3. Fixed a bug for incorrect PCD value used in conditional statement. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Yingke Liu Reviewed-by: Liming Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16784 6f19259b-4bc3-4df7-8a09-765794883524 --- BaseTools/Scripts/UpdateBuildVersions.py | 6 +- BaseTools/Source/Python/Common/Misc.py | 130 +++++++++++++++++- .../Source/Python/GenFds/FfsInfStatement.py | 45 +----- .../Source/Python/Workspace/MetaFileParser.py | 18 +-- 4 files changed, 140 insertions(+), 59 deletions(-) diff --git a/BaseTools/Scripts/UpdateBuildVersions.py b/BaseTools/Scripts/UpdateBuildVersions.py index e9c069724e..e62030aa9f 100755 --- a/BaseTools/Scripts/UpdateBuildVersions.py +++ b/BaseTools/Scripts/UpdateBuildVersions.py @@ -6,7 +6,7 @@ # If SVN is available, the tool will obtain the current checked out version of # the source tree for including the the --version commands. -# Copyright (c) 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2014 - 2015, 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 @@ -32,8 +32,8 @@ from types import IntType, ListType SYS_ENV_ERR = "ERROR : %s system environment variable must be set prior to running this tool.\n" __execname__ = "UpdateBuildVersions.py" -SVN_REVISION = "$Revision: 3 $" -SVN_REVISION = SVN_REVISION.replace("$Revision:", "").replace("$", "").strip() +SVN_REVISION = "$LastChangedRevision: 3 $" +SVN_REVISION = SVN_REVISION.replace("$LastChangedRevision:", "").replace("$", "").strip() __copyright__ = "Copyright (c) 2014, Intel Corporation. All rights reserved." VERSION_NUMBER = "0.7.0" __version__ = "Version %s.%s" % (VERSION_NUMBER, SVN_REVISION) diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py index 19a1319639..96ee30b2bf 100644 --- a/BaseTools/Source/Python/Common/Misc.py +++ b/BaseTools/Source/Python/Common/Misc.py @@ -1,7 +1,7 @@ ## @file # Common routines used by all tools # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2015, 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 @@ -44,6 +44,134 @@ gFileTimeStampCache = {} # {file path : file time stamp} ## Dictionary used to store dependencies of files gDependencyDatabase = {} # arch : {file path : [dependent files list]} +def GetVariableOffset(mapfilepath, efifilepath, varnames): + """ Parse map file to get variable offset in current EFI file + @param mapfilepath Map file absolution path + @param efifilepath: EFI binary file full path + @param varnames iteratable container whose elements are variable names to be searched + + @return List whos elements are tuple with variable name and raw offset + """ + lines = [] + try: + f = open(mapfilepath, 'r') + lines = f.readlines() + f.close() + except: + return None + + if len(lines) == 0: return None + firstline = lines[0].strip() + if (firstline.startswith("Archive member included ") and + firstline.endswith(" file (symbol)")): + return _parseForGCC(lines, efifilepath, varnames) + return _parseGeneral(lines, efifilepath, varnames) + +def _parseForGCC(lines, efifilepath, varnames): + """ Parse map file generated by GCC linker """ + status = 0 + sections = [] + varoffset = [] + for line in lines: + line = line.strip() + # status machine transection + if status == 0 and line == "Memory Configuration": + status = 1 + continue + elif status == 1 and line == 'Linker script and memory map': + status = 2 + continue + elif status ==2 and line == 'START GROUP': + status = 3 + continue + + # status handler + if status == 2: + m = re.match('^([\w_\.]+) +([\da-fA-Fx]+) +([\da-fA-Fx]+)$', line) + if m != None: + sections.append(m.groups(0)) + for varname in varnames: + m = re.match("^([\da-fA-Fx]+) +[_]*(%s)$" % varname, line) + if m != None: + varoffset.append((varname, int(m.groups(0)[0], 16) , int(sections[-1][1], 16), sections[-1][0])) + + if not varoffset: + return [] + # get section information from efi file + efisecs = PeImageClass(efifilepath).SectionHeaderList + if efisecs == None or len(efisecs) == 0: + return [] + #redirection + redirection = 0 + for efisec in efisecs: + for section in sections: + if section[0].strip() == efisec[0].strip() and section[0].strip() == '.text': + redirection = int(section[1], 16) - efisec[1] + + ret = [] + for var in varoffset: + for efisec in efisecs: + if var[1] >= efisec[1] and var[1] < efisec[1]+efisec[3]: + ret.append((var[0], hex(efisec[2] + var[1] - efisec[1] - redirection))) + return ret + +def _parseGeneral(lines, efifilepath, varnames): + status = 0 #0 - beginning of file; 1 - PE section definition; 2 - symbol table + secs = [] # key = section name + varoffset = [] + secRe = re.compile('^([\da-fA-F]+):([\da-fA-F]+) +([\da-fA-F]+)[Hh]? +([.\w\$]+) +(\w+)', re.UNICODE) + symRe = re.compile('^([\da-fA-F]+):([\da-fA-F]+) +([\.:\\\\\w\?@\$]+) +([\da-fA-F]+)', re.UNICODE) + + for line in lines: + line = line.strip() + if re.match("^Start[' ']+Length[' ']+Name[' ']+Class", line): + status = 1 + continue + if re.match("^Address[' ']+Publics by Value[' ']+Rva\+Base", line): + status = 2 + continue + if re.match("^entry point at", line): + status = 3 + continue + if status == 1 and len(line) != 0: + m = secRe.match(line) + assert m != None, "Fail to parse the section in map file , line is %s" % line + sec_no, sec_start, sec_length, sec_name, sec_class = m.groups(0) + secs.append([int(sec_no, 16), int(sec_start, 16), int(sec_length, 16), sec_name, sec_class]) + if status == 2 and len(line) != 0: + for varname in varnames: + m = symRe.match(line) + assert m != None, "Fail to parse the symbol in map file, line is %s" % line + sec_no, sym_offset, sym_name, vir_addr = m.groups(0) + sec_no = int(sec_no, 16) + sym_offset = int(sym_offset, 16) + vir_addr = int(vir_addr, 16) + m2 = re.match('^[_]*(%s)' % varname, sym_name) + if m2 != None: + # fond a binary pcd entry in map file + for sec in secs: + if sec[0] == sec_no and (sym_offset >= sec[1] and sym_offset < sec[1] + sec[2]): + varoffset.append([varname, sec[3], sym_offset, vir_addr, sec_no]) + + if not varoffset: return [] + + # get section information from efi file + efisecs = PeImageClass(efifilepath).SectionHeaderList + if efisecs == None or len(efisecs) == 0: + return [] + + ret = [] + for var in varoffset: + index = 0 + for efisec in efisecs: + index = index + 1 + if var[1].strip() == efisec[0].strip(): + ret.append((var[0], hex(efisec[2] + var[2]))) + elif var[4] == index: + ret.append((var[0], hex(efisec[2] + var[2]))) + + return ret + ## Routine to process duplicated INF # # This function is called by following two cases: diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py index 040d2ebcd4..29dc75f433 100644 --- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -1,7 +1,7 @@ ## @file # process FFS generation from INF statement # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
# # This program and the accompanying materials @@ -32,6 +32,7 @@ from Common.String import * from Common.Misc import PathClass from Common.Misc import GuidStructureByteArrayToGuidString from Common.Misc import ProcessDuplicatedInf +from Common.Misc import GetVariableOffset from Common import EdkLogger from Common.BuildToolError import * from GuidSection import GuidSection @@ -988,47 +989,9 @@ class FfsInfStatement(FfsInfStatementClassObject): # @retval RetValue A list contain offset of UNI/INF object. # def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName): - - RetValue = [] - MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map") - try: - fInputfile = open(MapFileName, "r", 0) - try: - FileLinesList = fInputfile.readlines() - except: - EdkLogger.error("GenFds", FILE_READ_FAILURE, "File read failed for %s" %MapFileName,None) - finally: - fInputfile.close() - except: - EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %MapFileName,None) - - IsHex = False - for eachLine in FileLinesList: - for eachName in VfrUniBaseName.values(): - if eachLine.find(eachName) != -1: - eachLine = eachLine.strip() - Element = eachLine.split() - # - # MSFT/ICC/EBC map file - # - if (len(Element) == 4): - try: - int (Element[2], 16) - IsHex = True - except: - IsHex = False - - if IsHex: - RetValue.append((eachName, Element[2])) - IsHex = False - # - # GCC map file - # - elif (len(Element) == 2) and Element[0].startswith("0x"): - RetValue.append((eachName, Element[0])) - - return RetValue + EfiFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".efi") + return GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values()) ## __GenUniVfrOffsetFile() method # diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py index 53b44f4403..f96c73c1db 100644 --- a/BaseTools/Source/Python/Workspace/MetaFileParser.py +++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py @@ -1,7 +1,7 @@ ## @file # This file is used to parse meta files # -# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2008 - 2015, 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 @@ -1338,18 +1338,6 @@ class DscParser(MetaFileParser): self._SubsectionType = MODEL_UNKNOWN def __RetrievePcdValue(self): - Records = self._RawTable.Query(MODEL_PCD_FEATURE_FLAG, BelongsToItem= -1.0) - for TokenSpaceGuid, PcdName, Value, Dummy2, Dummy3, ID, Line in Records: - Name = TokenSpaceGuid + '.' + PcdName - ValList, Valid, Index = AnalyzeDscPcd(Value, MODEL_PCD_FEATURE_FLAG) - self._Symbols[Name] = ValList[Index] - - Records = self._RawTable.Query(MODEL_PCD_FIXED_AT_BUILD, BelongsToItem= -1.0) - for TokenSpaceGuid, PcdName, Value, Dummy2, Dummy3, ID, Line in Records: - Name = TokenSpaceGuid + '.' + PcdName - ValList, Valid, Index = AnalyzeDscPcd(Value, MODEL_PCD_FIXED_AT_BUILD) - self._Symbols[Name] = ValList[Index] - Content = open(str(self.MetaFile), 'r').readlines() GlobalData.gPlatformOtherPcds['DSCFILE'] = str(self.MetaFile) for PcdType in (MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_HII, @@ -1542,7 +1530,9 @@ class DscParser(MetaFileParser): if ValList[Index] == 'False': ValList[Index] = '0' - GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue + if (not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack): + GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue + self._Symbols[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue self._ValueList[2] = '|'.join(ValList) def __ProcessComponent(self): -- 2.39.2