diff options
-rwxr-xr-x | BaseTools/Scripts/UpdateBuildVersions.py | 6 | ||||
-rw-r--r-- | BaseTools/Source/Python/Common/Misc.py | 130 | ||||
-rw-r--r-- | BaseTools/Source/Python/GenFds/FfsInfStatement.py | 45 | ||||
-rw-r--r-- | BaseTools/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.<BR>
+# Copyright (c) 2014 - 2015, 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
@@ -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.<BR>
+# Copyright (c) 2007 - 2015, 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
@@ -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.<BR>
+# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>
#
# 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.<BR>
+# Copyright (c) 2008 - 2015, 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
@@ -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):
|