## @file\r
# Common routines used by all tools\r
#\r
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2015, 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
## Dictionary used to store dependencies of files\r
gDependencyDatabase = {} # arch : {file path : [dependent files list]}\r
\r
+def GetVariableOffset(mapfilepath, efifilepath, varnames):\r
+ """ Parse map file to get variable offset in current EFI file \r
+ @param mapfilepath Map file absolution path\r
+ @param efifilepath: EFI binary file full path\r
+ @param varnames iteratable container whose elements are variable names to be searched\r
+ \r
+ @return List whos elements are tuple with variable name and raw offset\r
+ """\r
+ lines = []\r
+ try:\r
+ f = open(mapfilepath, 'r')\r
+ lines = f.readlines()\r
+ f.close()\r
+ except:\r
+ return None\r
+ \r
+ if len(lines) == 0: return None\r
+ firstline = lines[0].strip()\r
+ if (firstline.startswith("Archive member included ") and\r
+ firstline.endswith(" file (symbol)")):\r
+ return _parseForGCC(lines, efifilepath, varnames)\r
+ return _parseGeneral(lines, efifilepath, varnames)\r
+\r
+def _parseForGCC(lines, efifilepath, varnames):\r
+ """ Parse map file generated by GCC linker """\r
+ status = 0\r
+ sections = []\r
+ varoffset = []\r
+ for line in lines:\r
+ line = line.strip()\r
+ # status machine transection\r
+ if status == 0 and line == "Memory Configuration":\r
+ status = 1\r
+ continue\r
+ elif status == 1 and line == 'Linker script and memory map':\r
+ status = 2\r
+ continue\r
+ elif status ==2 and line == 'START GROUP':\r
+ status = 3\r
+ continue\r
+\r
+ # status handler\r
+ if status == 2:\r
+ m = re.match('^([\w_\.]+) +([\da-fA-Fx]+) +([\da-fA-Fx]+)$', line)\r
+ if m != None:\r
+ sections.append(m.groups(0))\r
+ for varname in varnames:\r
+ m = re.match("^([\da-fA-Fx]+) +[_]*(%s)$" % varname, line)\r
+ if m != None:\r
+ varoffset.append((varname, int(m.groups(0)[0], 16) , int(sections[-1][1], 16), sections[-1][0]))\r
+\r
+ if not varoffset:\r
+ return []\r
+ # get section information from efi file\r
+ efisecs = PeImageClass(efifilepath).SectionHeaderList\r
+ if efisecs == None or len(efisecs) == 0:\r
+ return []\r
+ #redirection\r
+ redirection = 0\r
+ for efisec in efisecs:\r
+ for section in sections:\r
+ if section[0].strip() == efisec[0].strip() and section[0].strip() == '.text':\r
+ redirection = int(section[1], 16) - efisec[1]\r
+\r
+ ret = []\r
+ for var in varoffset:\r
+ for efisec in efisecs:\r
+ if var[1] >= efisec[1] and var[1] < efisec[1]+efisec[3]:\r
+ ret.append((var[0], hex(efisec[2] + var[1] - efisec[1] - redirection)))\r
+ return ret\r
+\r
+def _parseGeneral(lines, efifilepath, varnames):\r
+ status = 0 #0 - beginning of file; 1 - PE section definition; 2 - symbol table\r
+ secs = [] # key = section name\r
+ varoffset = []\r
+ secRe = re.compile('^([\da-fA-F]+):([\da-fA-F]+) +([\da-fA-F]+)[Hh]? +([.\w\$]+) +(\w+)', re.UNICODE)\r
+ symRe = re.compile('^([\da-fA-F]+):([\da-fA-F]+) +([\.:\\\\\w\?@\$]+) +([\da-fA-F]+)', re.UNICODE)\r
+\r
+ for line in lines:\r
+ line = line.strip()\r
+ if re.match("^Start[' ']+Length[' ']+Name[' ']+Class", line):\r
+ status = 1\r
+ continue\r
+ if re.match("^Address[' ']+Publics by Value[' ']+Rva\+Base", line):\r
+ status = 2\r
+ continue\r
+ if re.match("^entry point at", line):\r
+ status = 3\r
+ continue \r
+ if status == 1 and len(line) != 0:\r
+ m = secRe.match(line)\r
+ assert m != None, "Fail to parse the section in map file , line is %s" % line\r
+ sec_no, sec_start, sec_length, sec_name, sec_class = m.groups(0)\r
+ secs.append([int(sec_no, 16), int(sec_start, 16), int(sec_length, 16), sec_name, sec_class])\r
+ if status == 2 and len(line) != 0:\r
+ for varname in varnames:\r
+ m = symRe.match(line)\r
+ assert m != None, "Fail to parse the symbol in map file, line is %s" % line\r
+ sec_no, sym_offset, sym_name, vir_addr = m.groups(0)\r
+ sec_no = int(sec_no, 16)\r
+ sym_offset = int(sym_offset, 16)\r
+ vir_addr = int(vir_addr, 16)\r
+ m2 = re.match('^[_]*(%s)' % varname, sym_name)\r
+ if m2 != None:\r
+ # fond a binary pcd entry in map file\r
+ for sec in secs:\r
+ if sec[0] == sec_no and (sym_offset >= sec[1] and sym_offset < sec[1] + sec[2]):\r
+ varoffset.append([varname, sec[3], sym_offset, vir_addr, sec_no])\r
+\r
+ if not varoffset: return []\r
+\r
+ # get section information from efi file\r
+ efisecs = PeImageClass(efifilepath).SectionHeaderList\r
+ if efisecs == None or len(efisecs) == 0:\r
+ return []\r
+\r
+ ret = []\r
+ for var in varoffset:\r
+ index = 0\r
+ for efisec in efisecs:\r
+ index = index + 1\r
+ if var[1].strip() == efisec[0].strip():\r
+ ret.append((var[0], hex(efisec[2] + var[2])))\r
+ elif var[4] == index:\r
+ ret.append((var[0], hex(efisec[2] + var[2])))\r
+\r
+ return ret\r
+\r
## Routine to process duplicated INF\r
#\r
# This function is called by following two cases:\r
## @file\r
# process FFS generation from INF statement\r
#\r
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>\r
#\r
# This program and the accompanying materials\r
from Common.Misc import PathClass\r
from Common.Misc import GuidStructureByteArrayToGuidString\r
from Common.Misc import ProcessDuplicatedInf\r
+from Common.Misc import GetVariableOffset\r
from Common import EdkLogger\r
from Common.BuildToolError import *\r
from GuidSection import GuidSection\r
# @retval RetValue A list contain offset of UNI/INF object.\r
# \r
def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName):\r
- \r
- RetValue = []\r
- \r
MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map")\r
- try:\r
- fInputfile = open(MapFileName, "r", 0)\r
- try:\r
- FileLinesList = fInputfile.readlines()\r
- except:\r
- EdkLogger.error("GenFds", FILE_READ_FAILURE, "File read failed for %s" %MapFileName,None)\r
- finally:\r
- fInputfile.close()\r
- except:\r
- EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %MapFileName,None)\r
- \r
- IsHex = False\r
- for eachLine in FileLinesList:\r
- for eachName in VfrUniBaseName.values():\r
- if eachLine.find(eachName) != -1:\r
- eachLine = eachLine.strip()\r
- Element = eachLine.split()\r
- #\r
- # MSFT/ICC/EBC map file\r
- #\r
- if (len(Element) == 4):\r
- try:\r
- int (Element[2], 16)\r
- IsHex = True\r
- except:\r
- IsHex = False\r
- \r
- if IsHex:\r
- RetValue.append((eachName, Element[2]))\r
- IsHex = False\r
- #\r
- # GCC map file\r
- #\r
- elif (len(Element) == 2) and Element[0].startswith("0x"):\r
- RetValue.append((eachName, Element[0]))\r
- \r
- return RetValue\r
+ EfiFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".efi")\r
+ return GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values())\r
\r
## __GenUniVfrOffsetFile() method\r
#\r
## @file\r
# This file is used to parse meta files\r
#\r
-# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2008 - 2015, 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
self._SubsectionType = MODEL_UNKNOWN\r
\r
def __RetrievePcdValue(self):\r
- Records = self._RawTable.Query(MODEL_PCD_FEATURE_FLAG, BelongsToItem= -1.0)\r
- for TokenSpaceGuid, PcdName, Value, Dummy2, Dummy3, ID, Line in Records:\r
- Name = TokenSpaceGuid + '.' + PcdName\r
- ValList, Valid, Index = AnalyzeDscPcd(Value, MODEL_PCD_FEATURE_FLAG)\r
- self._Symbols[Name] = ValList[Index]\r
-\r
- Records = self._RawTable.Query(MODEL_PCD_FIXED_AT_BUILD, BelongsToItem= -1.0)\r
- for TokenSpaceGuid, PcdName, Value, Dummy2, Dummy3, ID, Line in Records:\r
- Name = TokenSpaceGuid + '.' + PcdName\r
- ValList, Valid, Index = AnalyzeDscPcd(Value, MODEL_PCD_FIXED_AT_BUILD)\r
- self._Symbols[Name] = ValList[Index]\r
-\r
Content = open(str(self.MetaFile), 'r').readlines()\r
GlobalData.gPlatformOtherPcds['DSCFILE'] = str(self.MetaFile)\r
for PcdType in (MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_DEFAULT, MODEL_PCD_DYNAMIC_HII,\r
if ValList[Index] == 'False':\r
ValList[Index] = '0'\r
\r
- GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue\r
+ if (not self._DirectiveEvalStack) or (False not in self._DirectiveEvalStack):\r
+ GlobalData.gPlatformPcds[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue\r
+ self._Symbols[TAB_SPLIT.join(self._ValueList[0:2])] = PcdValue\r
self._ValueList[2] = '|'.join(ValList)\r
\r
def __ProcessComponent(self):\r