1 ## @file 2 # parse FDF file 3 # 4 # Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR> 5 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR> 6 # 7 # This program and the accompanying materials 8 # are licensed and made available under the terms and conditions of the BSD License 9 # which accompanies this distribution. The full text of the license may be found at 10 # http://opensource.org/licenses/bsd-license.php 11 # 12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14 # 15 16 ## 17 # Import Modules 18 # 19 import re 20 21 import Fd 22 import Region 23 import Fv 24 import AprioriSection 25 import FfsInfStatement 26 import FfsFileStatement 27 import VerSection 28 import UiSection 29 import FvImageSection 30 import DataSection 31 import DepexSection 32 import CompressSection 33 import GuidSection 34 import Capsule 35 import CapsuleData 36 import Rule 37 import RuleComplexFile 38 import RuleSimpleFile 39 import EfiSection 40 import Vtf 41 import ComponentStatement 42 import OptionRom 43 import OptRomInfStatement 44 import OptRomFileStatement 45 46 from GenFdsGlobalVariable import GenFdsGlobalVariable 47 from Common.BuildToolError import * 48 from Common import EdkLogger 49 from Common.Misc import PathClass 50 from Common.String import NormPath 51 import Common.GlobalData as GlobalData 52 from Common.Expression import * 53 from Common import GlobalData 54 from Common.String import ReplaceMacro 55 import uuid 56 from Common.Misc import tdict 57 from Common.MultipleWorkspace import MultipleWorkspace as mws 58 import Common.LongFilePathOs as os 59 from Common.LongFilePathSupport import OpenLongFilePath as open 60 from Capsule import EFI_CERT_TYPE_PKCS7_GUID 61 from Capsule import EFI_CERT_TYPE_RSA2048_SHA256_GUID 62 63 ##define T_CHAR_SPACE ' ' 64 ##define T_CHAR_NULL '\0' 65 ##define T_CHAR_CR '\r' 66 ##define T_CHAR_TAB '\t' 67 ##define T_CHAR_LF '\n' 68 ##define T_CHAR_SLASH '/' 69 ##define T_CHAR_BACKSLASH '\\' 70 ##define T_CHAR_DOUBLE_QUOTE '\"' 71 ##define T_CHAR_SINGLE_QUOTE '\'' 72 ##define T_CHAR_STAR '*' 73 ##define T_CHAR_HASH '#' 74 75 (T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \ 76 T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \ 77 (' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#') 78 79 SEPERATOR_TUPLE = ('=', '|', ',', '{', '}') 80 81 RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*") 82 RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*") 83 RegionOffsetPcdPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*$") 84 ShortcutPcdPattern = re.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*") 85 86 AllIncludeFileList = [] 87 88 # Get the closest parent 89 def GetParentAtLine (Line): 90 for Profile in AllIncludeFileList: 91 if Profile.IsLineInFile(Line): 92 return Profile 93 return None 94 95 # Check include loop 96 def IsValidInclude (File, Line): 97 for Profile in AllIncludeFileList: 98 if Profile.IsLineInFile(Line) and Profile.FileName == File: 99 return False 100 101 return True 102 103 def GetRealFileLine (File, Line): 104 105 InsertedLines = 0 106 for Profile in AllIncludeFileList: 107 if Profile.IsLineInFile(Line): 108 return Profile.GetLineInFile(Line) 109 elif Line >= Profile.InsertStartLineNumber and Profile.Level == 1: 110 InsertedLines += Profile.GetTotalLines() 111 112 return (File, Line - InsertedLines) 113 114 ## The exception class that used to report error messages when parsing FDF 115 # 116 # Currently the "ToolName" is set to be "FDF Parser". 117 # 118 class Warning (Exception): 119 ## The constructor 120 # 121 # @param self The object pointer 122 # @param Str The message to record 123 # @param File The FDF name 124 # @param Line The Line number that error occurs 125 # 126 def __init__(self, Str, File = None, Line = None): 127 128 FileLineTuple = GetRealFileLine(File, Line) 129 self.FileName = FileLineTuple[0] 130 self.LineNumber = FileLineTuple[1] 131 self.OriginalLineNumber = Line 132 self.Message = Str 133 self.ToolName = 'FdfParser' 134 135 def __str__(self): 136 return self.Message 137 138 ## The MACRO class that used to record macro value data when parsing include file 139 # 140 # 141 class MacroProfile : 142 ## The constructor 143 # 144 # @param self The object pointer 145 # @param FileName The file that to be parsed 146 # 147 def __init__(self, FileName, Line): 148 self.FileName = FileName 149 self.DefinedAtLine = Line 150 self.MacroName = None 151 self.MacroValue = None 152 153 ## The Include file content class that used to record file data when parsing include file 154 # 155 # May raise Exception when opening file. 156 # 157 class IncludeFileProfile : 158 ## The constructor 159 # 160 # @param self The object pointer 161 # @param FileName The file that to be parsed 162 # 163 def __init__(self, FileName): 164 self.FileName = FileName 165 self.FileLinesList = [] 166 try: 167 fsock = open(FileName, "rb", 0) 168 try: 169 self.FileLinesList = fsock.readlines() 170 finally: 171 fsock.close() 172 173 except: 174 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName) 175 176 self.InsertStartLineNumber = None 177 self.InsertAdjust = 0 178 self.IncludeFileList = [] 179 self.Level = 1 # first level include file 180 181 def GetTotalLines(self): 182 TotalLines = self.InsertAdjust + len(self.FileLinesList) 183 184 for Profile in self.IncludeFileList: 185 TotalLines += Profile.GetTotalLines() 186 187 return TotalLines 188 189 def IsLineInFile(self, Line): 190 if Line >= self.InsertStartLineNumber and Line < self.InsertStartLineNumber + self.GetTotalLines(): 191 return True 192 193 return False 194 195 def GetLineInFile(self, Line): 196 if not self.IsLineInFile (Line): 197 return (self.FileName, -1) 198 199 InsertedLines = self.InsertStartLineNumber 200 201 for Profile in self.IncludeFileList: 202 if Profile.IsLineInFile(Line): 203 return Profile.GetLineInFile(Line) 204 elif Line >= Profile.InsertStartLineNumber: 205 InsertedLines += Profile.GetTotalLines() 206 207 return (self.FileName, Line - InsertedLines + 1) 208 209 210 211 ## The FDF content class that used to record file data when parsing FDF 212 # 213 # May raise Exception when opening file. 214 # 215 class FileProfile : 216 ## The constructor 217 # 218 # @param self The object pointer 219 # @param FileName The file that to be parsed 220 # 221 def __init__(self, FileName): 222 self.FileLinesList = [] 223 try: 224 fsock = open(FileName, "rb", 0) 225 try: 226 self.FileLinesList = fsock.readlines() 227 finally: 228 fsock.close() 229 230 except: 231 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName) 232 233 234 self.PcdDict = {} 235 self.InfList = [] 236 self.InfDict = {'ArchTBD':[]} 237 # ECC will use this Dict and List information 238 self.PcdFileLineDict = {} 239 self.InfFileLineList = [] 240 241 self.FdDict = {} 242 self.FdNameNotSet = False 243 self.FvDict = {} 244 self.CapsuleDict = {} 245 self.VtfList = [] 246 self.RuleDict = {} 247 self.OptRomDict = {} 248 self.FmpPayloadDict = {} 249 250 ## The syntax parser for FDF 251 # 252 # PreprocessFile method should be called prior to ParseFile 253 # CycleReferenceCheck method can detect cycles in FDF contents 254 # 255 # GetNext*** procedures mean these procedures will get next token first, then make judgement. 256 # Get*** procedures mean these procedures will make judgement on current token only. 257 # 258 class FdfParser: 259 ## The constructor 260 # 261 # @param self The object pointer 262 # @param FileName The file that to be parsed 263 # 264 def __init__(self, FileName): 265 self.Profile = FileProfile(FileName) 266 self.FileName = FileName 267 self.CurrentLineNumber = 1 268 self.CurrentOffsetWithinLine = 0 269 self.CurrentFdName = None 270 self.CurrentFvName = None 271 self.__Token = "" 272 self.__SkippedChars = "" 273 GlobalData.gFdfParser = self 274 275 # Used to section info 276 self.__CurSection = [] 277 # Key: [section name, UI name, arch] 278 # Value: {MACRO_NAME : MACRO_VALUE} 279 self.__MacroDict = tdict(True, 3) 280 self.__PcdDict = {} 281 282 self.__WipeOffArea = [] 283 if GenFdsGlobalVariable.WorkSpaceDir == '': 284 GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE") 285 286 ## __IsWhiteSpace() method 287 # 288 # Whether char at current FileBufferPos is whitespace 289 # 290 # @param self The object pointer 291 # @param Char The char to test 292 # @retval True The char is a kind of white space 293 # @retval False The char is NOT a kind of white space 294 # 295 def __IsWhiteSpace(self, Char): 296 if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF): 297 return True 298 else: 299 return False 300 301 ## __SkipWhiteSpace() method 302 # 303 # Skip white spaces from current char, return number of chars skipped 304 # 305 # @param self The object pointer 306 # @retval Count The number of chars skipped 307 # 308 def __SkipWhiteSpace(self): 309 Count = 0 310 while not self.__EndOfFile(): 311 Count += 1 312 if self.__CurrentChar() in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_LF, T_CHAR_SPACE, T_CHAR_TAB): 313 self.__SkippedChars += str(self.__CurrentChar()) 314 self.__GetOneChar() 315 316 else: 317 Count = Count - 1 318 return Count 319 320 ## __EndOfFile() method 321 # 322 # Judge current buffer pos is at file end 323 # 324 # @param self The object pointer 325 # @retval True Current File buffer position is at file end 326 # @retval False Current File buffer position is NOT at file end 327 # 328 def __EndOfFile(self): 329 NumberOfLines = len(self.Profile.FileLinesList) 330 SizeOfLastLine = len(self.Profile.FileLinesList[-1]) 331 if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1: 332 return True 333 elif self.CurrentLineNumber > NumberOfLines: 334 return True 335 else: 336 return False 337 338 ## __EndOfLine() method 339 # 340 # Judge current buffer pos is at line end 341 # 342 # @param self The object pointer 343 # @retval True Current File buffer position is at line end 344 # @retval False Current File buffer position is NOT at line end 345 # 346 def __EndOfLine(self): 347 if self.CurrentLineNumber > len(self.Profile.FileLinesList): 348 return True 349 SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) 350 if self.CurrentOffsetWithinLine >= SizeOfCurrentLine: 351 return True 352 else: 353 return False 354 355 ## Rewind() method 356 # 357 # Reset file data buffer to the initial state 358 # 359 # @param self The object pointer 360 # @param DestLine Optional new destination line number. 361 # @param DestOffset Optional new destination offset. 362 # 363 def Rewind(self, DestLine = 1, DestOffset = 0): 364 self.CurrentLineNumber = DestLine 365 self.CurrentOffsetWithinLine = DestOffset 366 367 ## __UndoOneChar() method 368 # 369 # Go back one char in the file buffer 370 # 371 # @param self The object pointer 372 # @retval True Successfully go back one char 373 # @retval False Not able to go back one char as file beginning reached 374 # 375 def __UndoOneChar(self): 376 377 if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0: 378 return False 379 elif self.CurrentOffsetWithinLine == 0: 380 self.CurrentLineNumber -= 1 381 self.CurrentOffsetWithinLine = len(self.__CurrentLine()) - 1 382 else: 383 self.CurrentOffsetWithinLine -= 1 384 return True 385 386 ## __GetOneChar() method 387 # 388 # Move forward one char in the file buffer 389 # 390 # @param self The object pointer 391 # 392 def __GetOneChar(self): 393 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1: 394 self.CurrentLineNumber += 1 395 self.CurrentOffsetWithinLine = 0 396 else: 397 self.CurrentOffsetWithinLine += 1 398 399 ## __CurrentChar() method 400 # 401 # Get the char pointed to by the file buffer pointer 402 # 403 # @param self The object pointer 404 # @retval Char Current char 405 # 406 def __CurrentChar(self): 407 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] 408 409 ## __NextChar() method 410 # 411 # Get the one char pass the char pointed to by the file buffer pointer 412 # 413 # @param self The object pointer 414 # @retval Char Next char 415 # 416 def __NextChar(self): 417 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1: 418 return self.Profile.FileLinesList[self.CurrentLineNumber][0] 419 else: 420 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1] 421 422 ## __SetCurrentCharValue() method 423 # 424 # Modify the value of current char 425 # 426 # @param self The object pointer 427 # @param Value The new value of current char 428 # 429 def __SetCurrentCharValue(self, Value): 430 self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value 431 432 ## __CurrentLine() method 433 # 434 # Get the list that contains current line contents 435 # 436 # @param self The object pointer 437 # @retval List current line contents 438 # 439 def __CurrentLine(self): 440 return self.Profile.FileLinesList[self.CurrentLineNumber - 1] 441 442 def __StringToList(self): 443 self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList] 444 self.Profile.FileLinesList[-1].append(' ') 445 446 def __ReplaceFragment(self, StartPos, EndPos, Value = ' '): 447 if StartPos[0] == EndPos[0]: 448 Offset = StartPos[1] 449 while Offset <= EndPos[1]: 450 self.Profile.FileLinesList[StartPos[0]][Offset] = Value 451 Offset += 1 452 return 453 454 Offset = StartPos[1] 455 while self.Profile.FileLinesList[StartPos[0]][Offset] not in ('\r', '\n'): 456 self.Profile.FileLinesList[StartPos[0]][Offset] = Value 457 Offset += 1 458 459 Line = StartPos[0] 460 while Line < EndPos[0]: 461 Offset = 0 462 while self.Profile.FileLinesList[Line][Offset] not in ('\r', '\n'): 463 self.Profile.FileLinesList[Line][Offset] = Value 464 Offset += 1 465 Line += 1 466 467 Offset = 0 468 while Offset <= EndPos[1]: 469 self.Profile.FileLinesList[EndPos[0]][Offset] = Value 470 Offset += 1 471 472 473 def __GetMacroName(self): 474 if not self.__GetNextToken(): 475 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber) 476 MacroName = self.__Token 477 NotFlag = False 478 if MacroName.startswith('!'): 479 NotFlag = True 480 MacroName = MacroName[1:].strip() 481 482 if not MacroName.startswith('$(') or not MacroName.endswith(')'): 483 raise Warning("Macro name expected(Please use '$(%(Token)s)' if '%(Token)s' is a macro.)" % {"Token" : MacroName}, 484 self.FileName, self.CurrentLineNumber) 485 MacroName = MacroName[2:-1] 486 return MacroName, NotFlag 487 488 def __SetMacroValue(self, Macro, Value): 489 if not self.__CurSection: 490 return 491 492 MacroDict = {} 493 if not self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]]: 494 self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]] = MacroDict 495 else: 496 MacroDict = self.__MacroDict[self.__CurSection[0], self.__CurSection[1], self.__CurSection[2]] 497 MacroDict[Macro] = Value 498 499 def __GetMacroValue(self, Macro): 500 # Highest priority 501 if Macro in GlobalData.gCommandLineDefines: 502 return GlobalData.gCommandLineDefines[Macro] 503 if Macro in GlobalData.gGlobalDefines: 504 return GlobalData.gGlobalDefines[Macro] 505 506 if self.__CurSection: 507 MacroDict = self.__MacroDict[ 508 self.__CurSection[0], 509 self.__CurSection[1], 510 self.__CurSection[2] 511 ] 512 if MacroDict and Macro in MacroDict: 513 return MacroDict[Macro] 514 515 # Lowest priority 516 if Macro in GlobalData.gPlatformDefines: 517 return GlobalData.gPlatformDefines[Macro] 518 return None 519 520 def __SectionHeaderParser(self, Section): 521 # [Defines] 522 # [FD.UiName]: use dummy instead if UI name is optional 523 # [FV.UiName] 524 # [Capsule.UiName] 525 # [Rule]: don't take rule section into account, macro is not allowed in this section 526 # [VTF.arch.UiName, arch] 527 # [OptionRom.DriverName] 528 self.__CurSection = [] 529 Section = Section.strip()[1:-1].upper().replace(' ', '').strip('.') 530 ItemList = Section.split('.') 531 Item = ItemList[0] 532 if Item == '' or Item == 'RULE': 533 return 534 535 if Item == 'DEFINES': 536 self.__CurSection = ['COMMON', 'COMMON', 'COMMON'] 537 elif Item == 'VTF' and len(ItemList) == 3: 538 UiName = ItemList[2] 539 Pos = UiName.find(',') 540 if Pos != -1: 541 UiName = UiName[:Pos] 542 self.__CurSection = ['VTF', UiName, ItemList[1]] 543 elif len(ItemList) > 1: 544 self.__CurSection = [ItemList[0], ItemList[1], 'COMMON'] 545 elif len(ItemList) > 0: 546 self.__CurSection = [ItemList[0], 'DUMMY', 'COMMON'] 547 548 ## PreprocessFile() method 549 # 550 # Preprocess file contents, replace comments with spaces. 551 # In the end, rewind the file buffer pointer to the beginning 552 # BUGBUG: No !include statement processing contained in this procedure 553 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1] 554 # 555 # @param self The object pointer 556 # 557 def PreprocessFile(self): 558 559 self.Rewind() 560 InComment = False 561 DoubleSlashComment = False 562 HashComment = False 563 # HashComment in quoted string " " is ignored. 564 InString = False 565 566 while not self.__EndOfFile(): 567 568 if self.__CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment: 569 InString = not InString 570 # meet new line, then no longer in a comment for // and '#' 571 if self.__CurrentChar() == T_CHAR_LF: 572 self.CurrentLineNumber += 1 573 self.CurrentOffsetWithinLine = 0 574 if InComment and DoubleSlashComment: 575 InComment = False 576 DoubleSlashComment = False 577 if InComment and HashComment: 578 InComment = False 579 HashComment = False 580 # check for */ comment end 581 elif InComment and not DoubleSlashComment and not HashComment and self.__CurrentChar() == T_CHAR_STAR and self.__NextChar() == T_CHAR_SLASH: 582 self.__SetCurrentCharValue(T_CHAR_SPACE) 583 self.__GetOneChar() 584 self.__SetCurrentCharValue(T_CHAR_SPACE) 585 self.__GetOneChar() 586 InComment = False 587 # set comments to spaces 588 elif InComment: 589 self.__SetCurrentCharValue(T_CHAR_SPACE) 590 self.__GetOneChar() 591 # check for // comment 592 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_SLASH and not self.__EndOfLine(): 593 InComment = True 594 DoubleSlashComment = True 595 # check for '#' comment 596 elif self.__CurrentChar() == T_CHAR_HASH and not self.__EndOfLine() and not InString: 597 InComment = True 598 HashComment = True 599 # check for /* comment start 600 elif self.__CurrentChar() == T_CHAR_SLASH and self.__NextChar() == T_CHAR_STAR: 601 self.__SetCurrentCharValue( T_CHAR_SPACE) 602 self.__GetOneChar() 603 self.__SetCurrentCharValue( T_CHAR_SPACE) 604 self.__GetOneChar() 605 InComment = True 606 else: 607 self.__GetOneChar() 608 609 # restore from ListOfList to ListOfString 610 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList] 611 self.Rewind() 612 613 ## PreprocessIncludeFile() method 614 # 615 # Preprocess file contents, replace !include statements with file contents. 616 # In the end, rewind the file buffer pointer to the beginning 617 # 618 # @param self The object pointer 619 # 620 def PreprocessIncludeFile(self): 621 # nested include support 622 Processed = False 623 while self.__GetNextToken(): 624 625 if self.__Token == '!include': 626 Processed = True 627 IncludeLine = self.CurrentLineNumber 628 IncludeOffset = self.CurrentOffsetWithinLine - len('!include') 629 if not self.__GetNextToken(): 630 raise Warning("expected include file name", self.FileName, self.CurrentLineNumber) 631 IncFileName = self.__Token 632 __IncludeMacros = {} 633 for Macro in ['WORKSPACE', 'ECP_SOURCE', 'EFI_SOURCE', 'EDK_SOURCE']: 634 MacroVal = self.__GetMacroValue(Macro) 635 if MacroVal: 636 __IncludeMacros[Macro] = MacroVal 637 638 try: 639 IncludedFile = NormPath(ReplaceMacro(IncFileName, __IncludeMacros, RaiseError=True)) 640 except: 641 raise Warning("only these system environment variables are permitted to start the path of the included file: " 642 "$(WORKSPACE), $(ECP_SOURCE), $(EFI_SOURCE), $(EDK_SOURCE)", 643 self.FileName, self.CurrentLineNumber) 644 # 645 # First search the include file under the same directory as FDF file 646 # 647 IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName)) 648 ErrorCode = IncludedFile1.Validate()[0] 649 if ErrorCode != 0: 650 # 651 # Then search the include file under the same directory as DSC file 652 # 653 PlatformDir = '' 654 if GenFdsGlobalVariable.ActivePlatform: 655 PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir 656 elif GlobalData.gActivePlatform: 657 PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir 658 IncludedFile1 = PathClass(IncludedFile, PlatformDir) 659 ErrorCode = IncludedFile1.Validate()[0] 660 if ErrorCode != 0: 661 # 662 # Also search file under the WORKSPACE directory 663 # 664 IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace) 665 ErrorCode = IncludedFile1.Validate()[0] 666 if ErrorCode != 0: 667 raise Warning("The include file does not exist under below directories: \n%s\n%s\n%s\n"%(os.path.dirname(self.FileName), PlatformDir, GlobalData.gWorkspace), 668 self.FileName, self.CurrentLineNumber) 669 670 if not IsValidInclude (IncludedFile1.Path, self.CurrentLineNumber): 671 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1.Path), self.FileName, self.CurrentLineNumber) 672 673 IncFileProfile = IncludeFileProfile(IncludedFile1.Path) 674 675 CurrentLine = self.CurrentLineNumber 676 CurrentOffset = self.CurrentOffsetWithinLine 677 # list index of the insertion, note that line number is 'CurrentLine + 1' 678 InsertAtLine = CurrentLine 679 ParentProfile = GetParentAtLine (CurrentLine) 680 if ParentProfile != None: 681 ParentProfile.IncludeFileList.insert(0, IncFileProfile) 682 IncFileProfile.Level = ParentProfile.Level + 1 683 IncFileProfile.InsertStartLineNumber = InsertAtLine + 1 684 # deal with remaining portions after "!include filename", if exists. 685 if self.__GetNextToken(): 686 if self.CurrentLineNumber == CurrentLine: 687 RemainingLine = self.__CurrentLine()[CurrentOffset:] 688 self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine) 689 IncFileProfile.InsertAdjust += 1 690 self.CurrentLineNumber += 1 691 self.CurrentOffsetWithinLine = 0 692 693 for Line in IncFileProfile.FileLinesList: 694 self.Profile.FileLinesList.insert(InsertAtLine, Line) 695 self.CurrentLineNumber += 1 696 InsertAtLine += 1 697 698 # reversely sorted to better determine error in file 699 AllIncludeFileList.insert(0, IncFileProfile) 700 701 # comment out the processed include file statement 702 TempList = list(self.Profile.FileLinesList[IncludeLine - 1]) 703 TempList.insert(IncludeOffset, '#') 704 self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList) 705 if Processed: # Nested and back-to-back support 706 self.Rewind(DestLine = IncFileProfile.InsertStartLineNumber - 1) 707 Processed = False 708 # Preprocess done. 709 self.Rewind() 710 711 def __GetIfListCurrentItemStat(self, IfList): 712 if len(IfList) == 0: 713 return True 714 715 for Item in IfList: 716 if Item[1] == False: 717 return False 718 719 return True 720 721 ## PreprocessConditionalStatement() method 722 # 723 # Preprocess conditional statement. 724 # In the end, rewind the file buffer pointer to the beginning 725 # 726 # @param self The object pointer 727 # 728 def PreprocessConditionalStatement(self): 729 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined] 730 IfList = [] 731 RegionLayoutLine = 0 732 ReplacedLine = -1 733 while self.__GetNextToken(): 734 # Determine section name and the location dependent macro 735 if self.__GetIfListCurrentItemStat(IfList): 736 if self.__Token.startswith('['): 737 Header = self.__Token 738 if not self.__Token.endswith(']'): 739 self.__SkipToToken(']') 740 Header += self.__SkippedChars 741 if Header.find('$(') != -1: 742 raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber) 743 self.__SectionHeaderParser(Header) 744 continue 745 # Replace macros except in RULE section or out of section 746 elif self.__CurSection and ReplacedLine != self.CurrentLineNumber: 747 ReplacedLine = self.CurrentLineNumber 748 self.__UndoToken() 749 CurLine = self.Profile.FileLinesList[ReplacedLine - 1] 750 PreIndex = 0 751 StartPos = CurLine.find('$(', PreIndex) 752 EndPos = CurLine.find(')', StartPos+2) 753 while StartPos != -1 and EndPos != -1 and self.__Token not in ['!ifdef', '!ifndef', '!if', '!elseif']: 754 MacroName = CurLine[StartPos+2 : EndPos] 755 MacorValue = self.__GetMacroValue(MacroName) 756 if MacorValue != None: 757 CurLine = CurLine.replace('$(' + MacroName + ')', MacorValue, 1) 758 if MacorValue.find('$(') != -1: 759 PreIndex = StartPos 760 else: 761 PreIndex = StartPos + len(MacorValue) 762 else: 763 PreIndex = EndPos + 1 764 StartPos = CurLine.find('$(', PreIndex) 765 EndPos = CurLine.find(')', StartPos+2) 766 self.Profile.FileLinesList[ReplacedLine - 1] = CurLine 767 continue 768 769 if self.__Token == 'DEFINE': 770 if self.__GetIfListCurrentItemStat(IfList): 771 if not self.__CurSection: 772 raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber) 773 DefineLine = self.CurrentLineNumber - 1 774 DefineOffset = self.CurrentOffsetWithinLine - len('DEFINE') 775 if not self.__GetNextToken(): 776 raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber) 777 Macro = self.__Token 778 if not self.__IsToken( "="): 779 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 780 781 Value = self.__GetExpression() 782 self.__SetMacroValue(Macro, Value) 783 self.__WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) 784 elif self.__Token == 'SET': 785 if not self.__GetIfListCurrentItemStat(IfList): 786 continue 787 SetLine = self.CurrentLineNumber - 1 788 SetOffset = self.CurrentOffsetWithinLine - len('SET') 789 PcdPair = self.__GetNextPcdName() 790 PcdName = "%s.%s" % (PcdPair[1], PcdPair[0]) 791 if not self.__IsToken( "="): 792 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 793 794 Value = self.__GetExpression() 795 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True) 796 797 self.__PcdDict[PcdName] = Value 798 799 self.Profile.PcdDict[PcdPair] = Value 800 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 801 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple 802 803 self.__WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) 804 elif self.__Token in ('!ifdef', '!ifndef', '!if'): 805 IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token)) 806 IfList.append([IfStartPos, None, None]) 807 808 CondLabel = self.__Token 809 Expression = self.__GetExpression() 810 811 if CondLabel == '!if': 812 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval') 813 else: 814 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in') 815 if CondLabel == '!ifndef': 816 ConditionSatisfied = not ConditionSatisfied 817 818 BranchDetermined = ConditionSatisfied 819 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined] 820 if ConditionSatisfied: 821 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) 822 elif self.__Token in ('!elseif', '!else'): 823 ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self.__Token)) 824 if len(IfList) <= 0: 825 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber) 826 827 if IfList[-1][1]: 828 IfList[-1] = [ElseStartPos, False, True] 829 self.__WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) 830 else: 831 self.__WipeOffArea.append((IfList[-1][0], ElseStartPos)) 832 IfList[-1] = [ElseStartPos, True, IfList[-1][2]] 833 if self.__Token == '!elseif': 834 Expression = self.__GetExpression() 835 ConditionSatisfied = self.__EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval') 836 IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]] 837 838 if IfList[-1][1]: 839 if IfList[-1][2]: 840 IfList[-1][1] = False 841 else: 842 IfList[-1][2] = True 843 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) 844 elif self.__Token == '!endif': 845 if len(IfList) <= 0: 846 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber) 847 if IfList[-1][1]: 848 self.__WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) 849 else: 850 self.__WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) 851 852 IfList.pop() 853 elif not IfList: # Don't use PCDs inside conditional directive 854 if self.CurrentLineNumber <= RegionLayoutLine: 855 # Don't try the same line twice 856 continue 857 SetPcd = ShortcutPcdPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) 858 if SetPcd: 859 self.__PcdDict[SetPcd.group('name')] = SetPcd.group('value') 860 RegionLayoutLine = self.CurrentLineNumber 861 continue 862 RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) 863 if not RegionSize: 864 RegionLayoutLine = self.CurrentLineNumber 865 continue 866 RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber]) 867 if not RegionSizeGuid: 868 RegionLayoutLine = self.CurrentLineNumber + 1 869 continue 870 self.__PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base') 871 self.__PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size') 872 RegionLayoutLine = self.CurrentLineNumber + 1 873 874 if IfList: 875 raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber) 876 self.Rewind() 877 878 def __CollectMacroPcd(self): 879 MacroDict = {} 880 881 # PCD macro 882 MacroDict.update(GlobalData.gPlatformPcds) 883 MacroDict.update(self.__PcdDict) 884 885 # Lowest priority 886 MacroDict.update(GlobalData.gPlatformDefines) 887 888 if self.__CurSection: 889 # Defines macro 890 ScopeMacro = self.__MacroDict['COMMON', 'COMMON', 'COMMON'] 891 if ScopeMacro: 892 MacroDict.update(ScopeMacro) 893 894 # Section macro 895 ScopeMacro = self.__MacroDict[ 896 self.__CurSection[0], 897 self.__CurSection[1], 898 self.__CurSection[2] 899 ] 900 if ScopeMacro: 901 MacroDict.update(ScopeMacro) 902 903 MacroDict.update(GlobalData.gGlobalDefines) 904 MacroDict.update(GlobalData.gCommandLineDefines) 905 # Highest priority 906 907 return MacroDict 908 909 def __EvaluateConditional(self, Expression, Line, Op = None, Value = None): 910 FileLineTuple = GetRealFileLine(self.FileName, Line) 911 MacroPcdDict = self.__CollectMacroPcd() 912 if Op == 'eval': 913 try: 914 if Value: 915 return ValueExpression(Expression, MacroPcdDict)(True) 916 else: 917 return ValueExpression(Expression, MacroPcdDict)() 918 except WrnExpression, Excpt: 919 # 920 # Catch expression evaluation warning here. We need to report 921 # the precise number of line and return the evaluation result 922 # 923 EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt), 924 File=self.FileName, ExtraData=self.__CurrentLine(), 925 Line=Line) 926 return Excpt.result 927 except Exception, Excpt: 928 if hasattr(Excpt, 'Pcd'): 929 if Excpt.Pcd in GlobalData.gPlatformOtherPcds: 930 Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd] 931 raise Warning("Cannot use this PCD (%s) in an expression as" 932 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section" 933 " of the DSC file (%s), and it is currently defined in this section:" 934 " %s, line #: %d." % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE'], Info[0], Info[1]), 935 *FileLineTuple) 936 else: 937 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE']), 938 *FileLineTuple) 939 else: 940 raise Warning(str(Excpt), *FileLineTuple) 941 else: 942 if Expression.startswith('$(') and Expression[-1] == ')': 943 Expression = Expression[2:-1] 944 return Expression in MacroPcdDict 945 946 ## __IsToken() method 947 # 948 # Check whether input string is found from current char position along 949 # If found, the string value is put into self.__Token 950 # 951 # @param self The object pointer 952 # @param String The string to search 953 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive 954 # @retval True Successfully find string, file buffer pointer moved forward 955 # @retval False Not able to find string, file buffer pointer not changed 956 # 957 def __IsToken(self, String, IgnoreCase = False): 958 self.__SkipWhiteSpace() 959 960 # Only consider the same line, no multi-line token allowed 961 StartPos = self.CurrentOffsetWithinLine 962 index = -1 963 if IgnoreCase: 964 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper()) 965 else: 966 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String) 967 if index == 0: 968 self.CurrentOffsetWithinLine += len(String) 969 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] 970 return True 971 return False 972 973 ## __IsKeyword() method 974 # 975 # Check whether input keyword is found from current char position along, whole word only! 976 # If found, the string value is put into self.__Token 977 # 978 # @param self The object pointer 979 # @param Keyword The string to search 980 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive 981 # @retval True Successfully find string, file buffer pointer moved forward 982 # @retval False Not able to find string, file buffer pointer not changed 983 # 984 def __IsKeyword(self, KeyWord, IgnoreCase = False): 985 self.__SkipWhiteSpace() 986 987 # Only consider the same line, no multi-line token allowed 988 StartPos = self.CurrentOffsetWithinLine 989 index = -1 990 if IgnoreCase: 991 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(KeyWord.upper()) 992 else: 993 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(KeyWord) 994 if index == 0: 995 followingChar = self.__CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)] 996 if not str(followingChar).isspace() and followingChar not in SEPERATOR_TUPLE: 997 return False 998 self.CurrentOffsetWithinLine += len(KeyWord) 999 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] 1000 return True 1001 return False 1002 1003 def __GetExpression(self): 1004 Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1] 1005 Index = len(Line) - 1 1006 while Line[Index] in ['\r', '\n']: 1007 Index -= 1 1008 ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1] 1009 self.CurrentOffsetWithinLine += len(ExpressionString) 1010 ExpressionString = ExpressionString.strip() 1011 return ExpressionString 1012 1013 ## __GetNextWord() method 1014 # 1015 # Get next C name from file lines 1016 # If found, the string value is put into self.__Token 1017 # 1018 # @param self The object pointer 1019 # @retval True Successfully find a C name string, file buffer pointer moved forward 1020 # @retval False Not able to find a C name string, file buffer pointer not changed 1021 # 1022 def __GetNextWord(self): 1023 self.__SkipWhiteSpace() 1024 if self.__EndOfFile(): 1025 return False 1026 1027 TempChar = self.__CurrentChar() 1028 StartPos = self.CurrentOffsetWithinLine 1029 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_': 1030 self.__GetOneChar() 1031 while not self.__EndOfLine(): 1032 TempChar = self.__CurrentChar() 1033 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \ 1034 or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-': 1035 self.__GetOneChar() 1036 1037 else: 1038 break 1039 1040 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] 1041 return True 1042 1043 return False 1044 1045 ## __GetNextToken() method 1046 # 1047 # Get next token unit before a seperator 1048 # If found, the string value is put into self.__Token 1049 # 1050 # @param self The object pointer 1051 # @retval True Successfully find a token unit, file buffer pointer moved forward 1052 # @retval False Not able to find a token unit, file buffer pointer not changed 1053 # 1054 def __GetNextToken(self): 1055 # Skip leading spaces, if exist. 1056 self.__SkipWhiteSpace() 1057 if self.__EndOfFile(): 1058 return False 1059 # Record the token start position, the position of the first non-space char. 1060 StartPos = self.CurrentOffsetWithinLine 1061 StartLine = self.CurrentLineNumber 1062 while StartLine == self.CurrentLineNumber: 1063 TempChar = self.__CurrentChar() 1064 # Try to find the end char that is not a space and not in seperator tuple. 1065 # That is, when we got a space or any char in the tuple, we got the end of token. 1066 if not str(TempChar).isspace() and TempChar not in SEPERATOR_TUPLE: 1067 self.__GetOneChar() 1068 # if we happen to meet a seperator as the first char, we must proceed to get it. 1069 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens. 1070 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE: 1071 self.__GetOneChar() 1072 break 1073 else: 1074 break 1075 # else: 1076 # return False 1077 1078 EndPos = self.CurrentOffsetWithinLine 1079 if self.CurrentLineNumber != StartLine: 1080 EndPos = len(self.Profile.FileLinesList[StartLine-1]) 1081 self.__Token = self.Profile.FileLinesList[StartLine-1][StartPos : EndPos] 1082 if StartPos != self.CurrentOffsetWithinLine: 1083 return True 1084 else: 1085 return False 1086 1087 def __GetNextOp(self): 1088 # Skip leading spaces, if exist. 1089 self.__SkipWhiteSpace() 1090 if self.__EndOfFile(): 1091 return False 1092 # Record the token start position, the position of the first non-space char. 1093 StartPos = self.CurrentOffsetWithinLine 1094 while not self.__EndOfLine(): 1095 TempChar = self.__CurrentChar() 1096 # Try to find the end char that is not a space 1097 if not str(TempChar).isspace(): 1098 self.__GetOneChar() 1099 else: 1100 break 1101 else: 1102 return False 1103 1104 if StartPos != self.CurrentOffsetWithinLine: 1105 self.__Token = self.__CurrentLine()[StartPos : self.CurrentOffsetWithinLine] 1106 return True 1107 else: 1108 return False 1109 ## __GetNextGuid() method 1110 # 1111 # Get next token unit before a seperator 1112 # If found, the GUID string is put into self.__Token 1113 # 1114 # @param self The object pointer 1115 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward 1116 # @retval False Not able to find a registry format GUID, file buffer pointer not changed 1117 # 1118 def __GetNextGuid(self): 1119 1120 if not self.__GetNextToken(): 1121 return False 1122 p = re.compile('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}') 1123 if p.match(self.__Token) != None: 1124 return True 1125 else: 1126 self.__UndoToken() 1127 return False 1128 1129 def __Verify(self, Name, Value, Scope): 1130 if Scope in ['UINT64', 'UINT8']: 1131 ValueNumber = 0 1132 try: 1133 if Value.upper().startswith('0X'): 1134 ValueNumber = int (Value, 16) 1135 else: 1136 ValueNumber = int (Value) 1137 except: 1138 EdkLogger.error("FdfParser", FORMAT_INVALID, "The value is not valid dec or hex number for %s." % Name) 1139 if ValueNumber < 0: 1140 EdkLogger.error("FdfParser", FORMAT_INVALID, "The value can't be set to negative value for %s." % Name) 1141 if Scope == 'UINT64': 1142 if ValueNumber >= 0x10000000000000000: 1143 EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name) 1144 if Scope == 'UINT8': 1145 if ValueNumber >= 0x100: 1146 EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name) 1147 return True 1148 1149 ## __UndoToken() method 1150 # 1151 # Go back one token unit in file buffer 1152 # 1153 # @param self The object pointer 1154 # 1155 def __UndoToken(self): 1156 self.__UndoOneChar() 1157 while self.__CurrentChar().isspace(): 1158 if not self.__UndoOneChar(): 1159 self.__GetOneChar() 1160 return 1161 1162 1163 StartPos = self.CurrentOffsetWithinLine 1164 CurrentLine = self.CurrentLineNumber 1165 while CurrentLine == self.CurrentLineNumber: 1166 1167 TempChar = self.__CurrentChar() 1168 # Try to find the end char that is not a space and not in seperator tuple. 1169 # That is, when we got a space or any char in the tuple, we got the end of token. 1170 if not str(TempChar).isspace() and not TempChar in SEPERATOR_TUPLE: 1171 if not self.__UndoOneChar(): 1172 return 1173 # if we happen to meet a seperator as the first char, we must proceed to get it. 1174 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens. 1175 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPERATOR_TUPLE: 1176 return 1177 else: 1178 break 1179 1180 self.__GetOneChar() 1181 1182 ## __HexDigit() method 1183 # 1184 # Whether char input is a Hex data bit 1185 # 1186 # @param self The object pointer 1187 # @param TempChar The char to test 1188 # @retval True The char is a Hex data bit 1189 # @retval False The char is NOT a Hex data bit 1190 # 1191 def __HexDigit(self, TempChar): 1192 if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \ 1193 or (TempChar >= '0' and TempChar <= '9'): 1194 return True 1195 else: 1196 return False 1197 1198 def __IsHex(self, HexStr): 1199 if not HexStr.upper().startswith("0X"): 1200 return False 1201 if len(self.__Token) <= 2: 1202 return False 1203 charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)] 1204 if len(charList) == 0: 1205 return True 1206 else: 1207 return False 1208 ## __GetNextHexNumber() method 1209 # 1210 # Get next HEX data before a seperator 1211 # If found, the HEX data is put into self.__Token 1212 # 1213 # @param self The object pointer 1214 # @retval True Successfully find a HEX data, file buffer pointer moved forward 1215 # @retval False Not able to find a HEX data, file buffer pointer not changed 1216 # 1217 def __GetNextHexNumber(self): 1218 if not self.__GetNextToken(): 1219 return False 1220 if self.__IsHex(self.__Token): 1221 return True 1222 else: 1223 self.__UndoToken() 1224 return False 1225 1226 ## __GetNextDecimalNumber() method 1227 # 1228 # Get next decimal data before a seperator 1229 # If found, the decimal data is put into self.__Token 1230 # 1231 # @param self The object pointer 1232 # @retval True Successfully find a decimal data, file buffer pointer moved forward 1233 # @retval False Not able to find a decimal data, file buffer pointer not changed 1234 # 1235 def __GetNextDecimalNumber(self): 1236 if not self.__GetNextToken(): 1237 return False 1238 if self.__Token.isdigit(): 1239 return True 1240 else: 1241 self.__UndoToken() 1242 return False 1243 1244 ## __GetNextPcdName() method 1245 # 1246 # Get next PCD token space C name and PCD C name pair before a seperator 1247 # If found, the decimal data is put into self.__Token 1248 # 1249 # @param self The object pointer 1250 # @retval Tuple PCD C name and PCD token space C name pair 1251 # 1252 def __GetNextPcdName(self): 1253 if not self.__GetNextWord(): 1254 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber) 1255 pcdTokenSpaceCName = self.__Token 1256 1257 if not self.__IsToken( "."): 1258 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber) 1259 1260 if not self.__GetNextWord(): 1261 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self.FileName, self.CurrentLineNumber) 1262 pcdCName = self.__Token 1263 1264 return (pcdCName, pcdTokenSpaceCName) 1265 1266 ## __GetStringData() method 1267 # 1268 # Get string contents quoted in "" 1269 # If found, the decimal data is put into self.__Token 1270 # 1271 # @param self The object pointer 1272 # @retval True Successfully find a string data, file buffer pointer moved forward 1273 # @retval False Not able to find a string data, file buffer pointer not changed 1274 # 1275 def __GetStringData(self): 1276 if self.__Token.startswith("\"") or self.__Token.startswith("L\""): 1277 self.__UndoToken() 1278 self.__SkipToToken("\"") 1279 currentLineNumber = self.CurrentLineNumber 1280 1281 if not self.__SkipToToken("\""): 1282 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber) 1283 if currentLineNumber != self.CurrentLineNumber: 1284 raise Warning("Missing Quote \" for String", self.FileName, self.CurrentLineNumber) 1285 self.__Token = self.__SkippedChars.rstrip('\"') 1286 return True 1287 1288 elif self.__Token.startswith("\'") or self.__Token.startswith("L\'"): 1289 self.__UndoToken() 1290 self.__SkipToToken("\'") 1291 currentLineNumber = self.CurrentLineNumber 1292 1293 if not self.__SkipToToken("\'"): 1294 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber) 1295 if currentLineNumber != self.CurrentLineNumber: 1296 raise Warning("Missing Quote \' for String", self.FileName, self.CurrentLineNumber) 1297 self.__Token = self.__SkippedChars.rstrip('\'') 1298 return True 1299 1300 else: 1301 return False 1302 1303 ## __SkipToToken() method 1304 # 1305 # Search forward in file buffer for the string 1306 # The skipped chars are put into self.__SkippedChars 1307 # 1308 # @param self The object pointer 1309 # @param String The string to search 1310 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive 1311 # @retval True Successfully find the string, file buffer pointer moved forward 1312 # @retval False Not able to find the string, file buffer pointer not changed 1313 # 1314 def __SkipToToken(self, String, IgnoreCase = False): 1315 StartPos = self.GetFileBufferPos() 1316 1317 self.__SkippedChars = "" 1318 while not self.__EndOfFile(): 1319 index = -1 1320 if IgnoreCase: 1321 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].upper().find(String.upper()) 1322 else: 1323 index = self.__CurrentLine()[self.CurrentOffsetWithinLine : ].find(String) 1324 if index == 0: 1325 self.CurrentOffsetWithinLine += len(String) 1326 self.__SkippedChars += String 1327 return True 1328 self.__SkippedChars += str(self.__CurrentChar()) 1329 self.__GetOneChar() 1330 1331 self.SetFileBufferPos( StartPos) 1332 self.__SkippedChars = "" 1333 return False 1334 1335 ## GetFileBufferPos() method 1336 # 1337 # Return the tuple of current line and offset within the line 1338 # 1339 # @param self The object pointer 1340 # @retval Tuple Line number and offset pair 1341 # 1342 def GetFileBufferPos(self): 1343 return (self.CurrentLineNumber, self.CurrentOffsetWithinLine) 1344 1345 ## SetFileBufferPos() method 1346 # 1347 # Restore the file buffer position 1348 # 1349 # @param self The object pointer 1350 # @param Pos The new file buffer position 1351 # 1352 def SetFileBufferPos(self, Pos): 1353 (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos 1354 1355 ## Preprocess() method 1356 # 1357 # Preprocess comment, conditional directive, include directive, replace macro. 1358 # Exception will be raised if syntax error found 1359 # 1360 # @param self The object pointer 1361 # 1362 def Preprocess(self): 1363 self.__StringToList() 1364 self.PreprocessFile() 1365 self.PreprocessIncludeFile() 1366 self.__StringToList() 1367 self.PreprocessFile() 1368 self.PreprocessConditionalStatement() 1369 self.__StringToList() 1370 for Pos in self.__WipeOffArea: 1371 self.__ReplaceFragment(Pos[0], Pos[1]) 1372 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList] 1373 1374 while self.__GetDefines(): 1375 pass 1376 1377 ## ParseFile() method 1378 # 1379 # Parse the file profile buffer to extract fd, fv ... information 1380 # Exception will be raised if syntax error found 1381 # 1382 # @param self The object pointer 1383 # 1384 def ParseFile(self): 1385 1386 try: 1387 self.Preprocess() 1388 # 1389 # Keep processing sections of the FDF until no new sections or a syntax error is found 1390 # 1391 while self.__GetFd() or self.__GetFv() or self.__GetFmp() or self.__GetCapsule() or self.__GetVtf() or self.__GetRule() or self.__GetOptionRom(): 1392 pass 1393 1394 except Warning, X: 1395 self.__UndoToken() 1396 #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \ 1397 # At this point, the closest parent would be the included file itself 1398 Profile = GetParentAtLine(X.OriginalLineNumber) 1399 if Profile != None: 1400 X.Message += ' near line %d, column %d: %s' \ 1401 % (X.LineNumber, 0, Profile.FileLinesList[X.LineNumber-1]) 1402 else: 1403 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 1404 X.Message += ' near line %d, column %d: %s' \ 1405 % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :].rstrip('\n').rstrip('\r')) 1406 raise 1407 1408 ## SectionParser() method 1409 # 1410 # Parse the file section info 1411 # Exception will be raised if syntax error found 1412 # 1413 # @param self The object pointer 1414 # @param section The section string 1415 1416 def SectionParser(self, section): 1417 S = section.upper() 1418 if not S.startswith("[DEFINES") and not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \ 1419 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM.") and not S.startswith('[FMPPAYLOAD.'): 1420 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self.FileName, self.CurrentLineNumber) 1421 1422 ## __GetDefines() method 1423 # 1424 # Get Defines section contents and store its data into AllMacrosList 1425 # 1426 # @param self The object pointer 1427 # @retval True Successfully find a Defines 1428 # @retval False Not able to find a Defines 1429 # 1430 def __GetDefines(self): 1431 1432 if not self.__GetNextToken(): 1433 return False 1434 1435 S = self.__Token.upper() 1436 if S.startswith("[") and not S.startswith("[DEFINES"): 1437 self.SectionParser(S) 1438 self.__UndoToken() 1439 return False 1440 1441 self.__UndoToken() 1442 if not self.__IsToken("[DEFINES", True): 1443 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 1444 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ 1445 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) 1446 raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber) 1447 1448 if not self.__IsToken( "]"): 1449 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) 1450 1451 while self.__GetNextWord(): 1452 # handle the SET statement 1453 if self.__Token == 'SET': 1454 self.__UndoToken() 1455 self.__GetSetStatement(None) 1456 continue 1457 1458 Macro = self.__Token 1459 1460 if not self.__IsToken("="): 1461 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1462 if not self.__GetNextToken() or self.__Token.startswith('['): 1463 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber) 1464 Value = self.__Token 1465 1466 return False 1467 1468 ## __GetFd() method 1469 # 1470 # Get FD section contents and store its data into FD dictionary of self.Profile 1471 # 1472 # @param self The object pointer 1473 # @retval True Successfully find a FD 1474 # @retval False Not able to find a FD 1475 # 1476 def __GetFd(self): 1477 1478 if not self.__GetNextToken(): 1479 return False 1480 1481 S = self.__Token.upper() 1482 if S.startswith("[") and not S.startswith("[FD."): 1483 if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \ 1484 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): 1485 raise Warning("Unknown section", self.FileName, self.CurrentLineNumber) 1486 self.__UndoToken() 1487 return False 1488 1489 self.__UndoToken() 1490 if not self.__IsToken("[FD.", True): 1491 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 1492 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ 1493 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) 1494 raise Warning("expected [FD.]", self.FileName, self.CurrentLineNumber) 1495 1496 FdName = self.__GetUiName() 1497 if FdName == "": 1498 if len (self.Profile.FdDict) == 0: 1499 FdName = GenFdsGlobalVariable.PlatformName 1500 if FdName == "" and GlobalData.gActivePlatform: 1501 FdName = GlobalData.gActivePlatform.PlatformName 1502 self.Profile.FdNameNotSet = True 1503 else: 1504 raise Warning("expected FdName in [FD.] section", self.FileName, self.CurrentLineNumber) 1505 self.CurrentFdName = FdName.upper() 1506 1507 if self.CurrentFdName in self.Profile.FdDict: 1508 raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber) 1509 1510 if not self.__IsToken( "]"): 1511 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) 1512 1513 FdObj = Fd.FD() 1514 FdObj.FdUiName = self.CurrentFdName 1515 self.Profile.FdDict[self.CurrentFdName] = FdObj 1516 1517 if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet: 1518 raise Warning("expected all FDs have their name", self.FileName, self.CurrentLineNumber) 1519 1520 Status = self.__GetCreateFile(FdObj) 1521 if not Status: 1522 raise Warning("FD name error", self.FileName, self.CurrentLineNumber) 1523 1524 while self.__GetTokenStatements(FdObj): 1525 pass 1526 for Attr in ("BaseAddress", "Size", "ErasePolarity"): 1527 if getattr(FdObj, Attr) == None: 1528 self.__GetNextToken() 1529 raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber) 1530 1531 if not FdObj.BlockSizeList: 1532 FdObj.BlockSizeList.append((1, FdObj.Size, None)) 1533 1534 self.__GetDefineStatements(FdObj) 1535 1536 self.__GetSetStatements(FdObj) 1537 1538 if not self.__GetRegionLayout(FdObj): 1539 raise Warning("expected region layout", self.FileName, self.CurrentLineNumber) 1540 1541 while self.__GetRegionLayout(FdObj): 1542 pass 1543 return True 1544 1545 ## __GetUiName() method 1546 # 1547 # Return the UI name of a section 1548 # 1549 # @param self The object pointer 1550 # @retval FdName UI name 1551 # 1552 def __GetUiName(self): 1553 Name = "" 1554 if self.__GetNextWord(): 1555 Name = self.__Token 1556 1557 return Name 1558 1559 ## __GetCreateFile() method 1560 # 1561 # Return the output file name of object 1562 # 1563 # @param self The object pointer 1564 # @param Obj object whose data will be stored in file 1565 # @retval FdName UI name 1566 # 1567 def __GetCreateFile(self, Obj): 1568 1569 if self.__IsKeyword( "CREATE_FILE"): 1570 if not self.__IsToken( "="): 1571 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1572 1573 if not self.__GetNextToken(): 1574 raise Warning("expected file name", self.FileName, self.CurrentLineNumber) 1575 1576 FileName = self.__Token 1577 Obj.CreateFileName = FileName 1578 1579 return True 1580 1581 ## __GetTokenStatements() method 1582 # 1583 # Get token statements 1584 # 1585 # @param self The object pointer 1586 # @param Obj for whom token statement is got 1587 # 1588 def __GetTokenStatements(self, Obj): 1589 if self.__IsKeyword( "BaseAddress"): 1590 if not self.__IsToken( "="): 1591 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1592 1593 if not self.__GetNextHexNumber(): 1594 raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber) 1595 1596 Obj.BaseAddress = self.__Token 1597 1598 if self.__IsToken( "|"): 1599 pcdPair = self.__GetNextPcdName() 1600 Obj.BaseAddressPcd = pcdPair 1601 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress 1602 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 1603 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple 1604 return True 1605 1606 if self.__IsKeyword( "Size"): 1607 if not self.__IsToken( "="): 1608 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1609 1610 if not self.__GetNextHexNumber(): 1611 raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber) 1612 1613 Size = self.__Token 1614 if self.__IsToken( "|"): 1615 pcdPair = self.__GetNextPcdName() 1616 Obj.SizePcd = pcdPair 1617 self.Profile.PcdDict[pcdPair] = Size 1618 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 1619 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple 1620 Obj.Size = long(Size, 0) 1621 return True 1622 1623 if self.__IsKeyword( "ErasePolarity"): 1624 if not self.__IsToken( "="): 1625 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1626 1627 if not self.__GetNextToken(): 1628 raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber) 1629 1630 if self.__Token != "1" and self.__Token != "0": 1631 raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber) 1632 1633 Obj.ErasePolarity = self.__Token 1634 return True 1635 1636 return self.__GetBlockStatements(Obj) 1637 1638 ## __GetAddressStatements() method 1639 # 1640 # Get address statements 1641 # 1642 # @param self The object pointer 1643 # @param Obj for whom address statement is got 1644 # @retval True Successfully find 1645 # @retval False Not able to find 1646 # 1647 def __GetAddressStatements(self, Obj): 1648 1649 if self.__IsKeyword("BsBaseAddress"): 1650 if not self.__IsToken( "="): 1651 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1652 1653 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber(): 1654 raise Warning("expected address", self.FileName, self.CurrentLineNumber) 1655 1656 BsAddress = long(self.__Token, 0) 1657 Obj.BsBaseAddress = BsAddress 1658 1659 if self.__IsKeyword("RtBaseAddress"): 1660 if not self.__IsToken( "="): 1661 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1662 1663 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber(): 1664 raise Warning("expected address", self.FileName, self.CurrentLineNumber) 1665 1666 RtAddress = long(self.__Token, 0) 1667 Obj.RtBaseAddress = RtAddress 1668 1669 ## __GetBlockStatements() method 1670 # 1671 # Get block statements 1672 # 1673 # @param self The object pointer 1674 # @param Obj for whom block statement is got 1675 # 1676 def __GetBlockStatements(self, Obj): 1677 IsBlock = False 1678 while self.__GetBlockStatement(Obj): 1679 IsBlock = True 1680 1681 Item = Obj.BlockSizeList[-1] 1682 if Item[0] == None or Item[1] == None: 1683 raise Warning("expected block statement", self.FileName, self.CurrentLineNumber) 1684 return IsBlock 1685 1686 ## __GetBlockStatement() method 1687 # 1688 # Get block statement 1689 # 1690 # @param self The object pointer 1691 # @param Obj for whom block statement is got 1692 # @retval True Successfully find 1693 # @retval False Not able to find 1694 # 1695 def __GetBlockStatement(self, Obj): 1696 if not self.__IsKeyword( "BlockSize"): 1697 return False 1698 1699 if not self.__IsToken( "="): 1700 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1701 1702 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber(): 1703 raise Warning("expected Hex or Integer block size", self.FileName, self.CurrentLineNumber) 1704 1705 BlockSize = self.__Token 1706 BlockSizePcd = None 1707 if self.__IsToken( "|"): 1708 PcdPair = self.__GetNextPcdName() 1709 BlockSizePcd = PcdPair 1710 self.Profile.PcdDict[PcdPair] = BlockSize 1711 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 1712 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple 1713 BlockSize = long(BlockSize, 0) 1714 1715 BlockNumber = None 1716 if self.__IsKeyword( "NumBlocks"): 1717 if not self.__IsToken( "="): 1718 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1719 1720 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber(): 1721 raise Warning("expected block numbers", self.FileName, self.CurrentLineNumber) 1722 1723 BlockNumber = long(self.__Token, 0) 1724 1725 Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd)) 1726 return True 1727 1728 ## __GetDefineStatements() method 1729 # 1730 # Get define statements 1731 # 1732 # @param self The object pointer 1733 # @param Obj for whom define statement is got 1734 # @retval True Successfully find 1735 # @retval False Not able to find 1736 # 1737 def __GetDefineStatements(self, Obj): 1738 while self.__GetDefineStatement( Obj): 1739 pass 1740 1741 ## __GetDefineStatement() method 1742 # 1743 # Get define statement 1744 # 1745 # @param self The object pointer 1746 # @param Obj for whom define statement is got 1747 # @retval True Successfully find 1748 # @retval False Not able to find 1749 # 1750 def __GetDefineStatement(self, Obj): 1751 if self.__IsKeyword("DEFINE"): 1752 self.__GetNextToken() 1753 Macro = self.__Token 1754 if not self.__IsToken( "="): 1755 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1756 1757 if not self.__GetNextToken(): 1758 raise Warning("expected value", self.FileName, self.CurrentLineNumber) 1759 1760 Value = self.__Token 1761 Macro = '$(' + Macro + ')' 1762 Obj.DefineVarDict[Macro] = Value 1763 return True 1764 1765 return False 1766 1767 ## __GetSetStatements() method 1768 # 1769 # Get set statements 1770 # 1771 # @param self The object pointer 1772 # @param Obj for whom set statement is got 1773 # @retval True Successfully find 1774 # @retval False Not able to find 1775 # 1776 def __GetSetStatements(self, Obj): 1777 while self.__GetSetStatement(Obj): 1778 pass 1779 1780 ## __GetSetStatement() method 1781 # 1782 # Get set statement 1783 # 1784 # @param self The object pointer 1785 # @param Obj for whom set statement is got 1786 # @retval True Successfully find 1787 # @retval False Not able to find 1788 # 1789 def __GetSetStatement(self, Obj): 1790 if self.__IsKeyword("SET"): 1791 PcdPair = self.__GetNextPcdName() 1792 1793 if not self.__IsToken( "="): 1794 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1795 1796 Value = self.__GetExpression() 1797 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True) 1798 1799 if Obj: 1800 Obj.SetVarDict[PcdPair] = Value 1801 self.Profile.PcdDict[PcdPair] = Value 1802 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 1803 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple 1804 return True 1805 1806 return False 1807 1808 ## __CalcRegionExpr(self) 1809 # 1810 # Calculate expression for offset or size of a region 1811 # 1812 # @return: None if invalid expression 1813 # Calculated number if successfully 1814 # 1815 def __CalcRegionExpr(self): 1816 StartPos = self.GetFileBufferPos() 1817 Expr = '' 1818 PairCount = 0 1819 while not self.__EndOfFile(): 1820 CurCh = self.__CurrentChar() 1821 if CurCh == '(': 1822 PairCount += 1 1823 elif CurCh == ')': 1824 PairCount -= 1 1825 1826 if CurCh in '|\r\n' and PairCount == 0: 1827 break 1828 Expr += CurCh 1829 self.__GetOneChar() 1830 try: 1831 return long( 1832 ValueExpression(Expr, 1833 self.__CollectMacroPcd() 1834 )(True),0) 1835 except Exception: 1836 self.SetFileBufferPos(StartPos) 1837 return None 1838 1839 ## __GetRegionLayout() method 1840 # 1841 # Get region layout for FD 1842 # 1843 # @param self The object pointer 1844 # @param Fd for whom region is got 1845 # @retval True Successfully find 1846 # @retval False Not able to find 1847 # 1848 def __GetRegionLayout(self, Fd): 1849 Offset = self.__CalcRegionExpr() 1850 if Offset == None: 1851 return False 1852 1853 RegionObj = Region.Region() 1854 RegionObj.Offset = Offset 1855 Fd.RegionList.append(RegionObj) 1856 1857 if not self.__IsToken( "|"): 1858 raise Warning("expected '|'", self.FileName, self.CurrentLineNumber) 1859 1860 Size = self.__CalcRegionExpr() 1861 if Size == None: 1862 raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber) 1863 RegionObj.Size = Size 1864 1865 if not self.__GetNextWord(): 1866 return True 1867 1868 if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"): 1869 # 1870 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]] 1871 # Or it might be next region's offset described by an expression which starts with a PCD. 1872 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size 1873 # 1874 self.__UndoToken() 1875 IsRegionPcd = (RegionSizeGuidPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]) or 1876 RegionOffsetPcdPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:])) 1877 if IsRegionPcd: 1878 RegionObj.PcdOffset = self.__GetNextPcdName() 1879 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0)) 1880 self.__PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset 1881 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 1882 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple 1883 if self.__IsToken( "|"): 1884 RegionObj.PcdSize = self.__GetNextPcdName() 1885 self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size 1886 self.__PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size 1887 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 1888 self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple 1889 1890 if not self.__GetNextWord(): 1891 return True 1892 1893 if self.__Token == "SET": 1894 self.__UndoToken() 1895 self.__GetSetStatements( RegionObj) 1896 if not self.__GetNextWord(): 1897 return True 1898 1899 elif self.__Token == "FV": 1900 self.__UndoToken() 1901 self.__GetRegionFvType( RegionObj) 1902 1903 elif self.__Token == "CAPSULE": 1904 self.__UndoToken() 1905 self.__GetRegionCapType( RegionObj) 1906 1907 elif self.__Token == "FILE": 1908 self.__UndoToken() 1909 self.__GetRegionFileType(RegionObj) 1910 1911 elif self.__Token == "INF": 1912 self.__UndoToken() 1913 RegionObj.RegionType = "INF" 1914 while self.__IsKeyword("INF"): 1915 self.__UndoToken() 1916 ffsInf = self.__ParseInfStatement() 1917 if not ffsInf: 1918 break 1919 RegionObj.RegionDataList.append(ffsInf) 1920 1921 elif self.__Token == "DATA": 1922 self.__UndoToken() 1923 self.__GetRegionDataType(RegionObj) 1924 else: 1925 self.__UndoToken() 1926 if self.__GetRegionLayout(Fd): 1927 return True 1928 raise Warning("A valid region type was not found. " 1929 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred", 1930 self.FileName, self.CurrentLineNumber) 1931 1932 return True 1933 1934 ## __GetRegionFvType() method 1935 # 1936 # Get region fv data for region 1937 # 1938 # @param self The object pointer 1939 # @param RegionObj for whom region data is got 1940 # 1941 def __GetRegionFvType(self, RegionObj): 1942 1943 if not self.__IsKeyword( "FV"): 1944 raise Warning("expected Keyword 'FV'", self.FileName, self.CurrentLineNumber) 1945 1946 if not self.__IsToken( "="): 1947 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1948 1949 if not self.__GetNextToken(): 1950 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) 1951 1952 RegionObj.RegionType = "FV" 1953 RegionObj.RegionDataList.append((self.__Token).upper()) 1954 1955 while self.__IsKeyword( "FV"): 1956 1957 if not self.__IsToken( "="): 1958 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1959 1960 if not self.__GetNextToken(): 1961 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) 1962 1963 RegionObj.RegionDataList.append((self.__Token).upper()) 1964 1965 ## __GetRegionCapType() method 1966 # 1967 # Get region capsule data for region 1968 # 1969 # @param self The object pointer 1970 # @param RegionObj for whom region data is got 1971 # 1972 def __GetRegionCapType(self, RegionObj): 1973 1974 if not self.__IsKeyword("CAPSULE"): 1975 raise Warning("expected Keyword 'CAPSULE'", self.FileName, self.CurrentLineNumber) 1976 1977 if not self.__IsToken("="): 1978 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1979 1980 if not self.__GetNextToken(): 1981 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber) 1982 1983 RegionObj.RegionType = "CAPSULE" 1984 RegionObj.RegionDataList.append(self.__Token) 1985 1986 while self.__IsKeyword("CAPSULE"): 1987 1988 if not self.__IsToken("="): 1989 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 1990 1991 if not self.__GetNextToken(): 1992 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber) 1993 1994 RegionObj.RegionDataList.append(self.__Token) 1995 1996 ## __GetRegionFileType() method 1997 # 1998 # Get region file data for region 1999 # 2000 # @param self The object pointer 2001 # @param RegionObj for whom region data is got 2002 # 2003 def __GetRegionFileType(self, RegionObj): 2004 2005 if not self.__IsKeyword( "FILE"): 2006 raise Warning("expected Keyword 'FILE'", self.FileName, self.CurrentLineNumber) 2007 2008 if not self.__IsToken( "="): 2009 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2010 2011 if not self.__GetNextToken(): 2012 raise Warning("expected File name", self.FileName, self.CurrentLineNumber) 2013 2014 RegionObj.RegionType = "FILE" 2015 RegionObj.RegionDataList.append( self.__Token) 2016 2017 while self.__IsKeyword( "FILE"): 2018 2019 if not self.__IsToken( "="): 2020 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2021 2022 if not self.__GetNextToken(): 2023 raise Warning("expected FILE name", self.FileName, self.CurrentLineNumber) 2024 2025 RegionObj.RegionDataList.append(self.__Token) 2026 2027 ## __GetRegionDataType() method 2028 # 2029 # Get region array data for region 2030 # 2031 # @param self The object pointer 2032 # @param RegionObj for whom region data is got 2033 # 2034 def __GetRegionDataType(self, RegionObj): 2035 2036 if not self.__IsKeyword( "DATA"): 2037 raise Warning("expected Region Data type", self.FileName, self.CurrentLineNumber) 2038 2039 if not self.__IsToken( "="): 2040 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2041 2042 if not self.__IsToken( "{"): 2043 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) 2044 2045 if not self.__GetNextHexNumber(): 2046 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber) 2047 2048 if len(self.__Token) > 18: 2049 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber) 2050 2051 # convert hex string value to byte hex string array 2052 AllString = self.__Token 2053 AllStrLen = len (AllString) 2054 DataString = "" 2055 while AllStrLen > 4: 2056 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + "," 2057 AllStrLen = AllStrLen - 2 2058 DataString = DataString + AllString[:AllStrLen] + "," 2059 2060 # byte value array 2061 if len (self.__Token) <= 4: 2062 while self.__IsToken(","): 2063 if not self.__GetNextHexNumber(): 2064 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber) 2065 if len(self.__Token) > 4: 2066 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) 2067 DataString += self.__Token 2068 DataString += "," 2069 2070 if not self.__IsToken( "}"): 2071 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 2072 2073 DataString = DataString.rstrip(",") 2074 RegionObj.RegionType = "DATA" 2075 RegionObj.RegionDataList.append( DataString) 2076 2077 while self.__IsKeyword( "DATA"): 2078 2079 if not self.__IsToken( "="): 2080 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2081 2082 if not self.__IsToken( "{"): 2083 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) 2084 2085 if not self.__GetNextHexNumber(): 2086 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber) 2087 2088 if len(self.__Token) > 18: 2089 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber) 2090 2091 # convert hex string value to byte hex string array 2092 AllString = self.__Token 2093 AllStrLen = len (AllString) 2094 DataString = "" 2095 while AllStrLen > 4: 2096 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + "," 2097 AllStrLen = AllStrLen - 2 2098 DataString = DataString + AllString[:AllStrLen] + "," 2099 2100 # byte value array 2101 if len (self.__Token) <= 4: 2102 while self.__IsToken(","): 2103 if not self.__GetNextHexNumber(): 2104 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber) 2105 if len(self.__Token) > 4: 2106 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) 2107 DataString += self.__Token 2108 DataString += "," 2109 2110 if not self.__IsToken( "}"): 2111 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 2112 2113 DataString = DataString.rstrip(",") 2114 RegionObj.RegionDataList.append( DataString) 2115 2116 ## __GetFv() method 2117 # 2118 # Get FV section contents and store its data into FV dictionary of self.Profile 2119 # 2120 # @param self The object pointer 2121 # @retval True Successfully find a FV 2122 # @retval False Not able to find a FV 2123 # 2124 def __GetFv(self): 2125 if not self.__GetNextToken(): 2126 return False 2127 2128 S = self.__Token.upper() 2129 if S.startswith("[") and not S.startswith("[FV."): 2130 self.SectionParser(S) 2131 self.__UndoToken() 2132 return False 2133 2134 self.__UndoToken() 2135 if not self.__IsToken("[FV.", True): 2136 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 2137 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ 2138 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) 2139 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 2140 2141 FvName = self.__GetUiName() 2142 self.CurrentFvName = FvName.upper() 2143 2144 if not self.__IsToken( "]"): 2145 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) 2146 2147 FvObj = Fv.FV() 2148 FvObj.UiFvName = self.CurrentFvName 2149 self.Profile.FvDict[self.CurrentFvName] = FvObj 2150 2151 Status = self.__GetCreateFile(FvObj) 2152 if not Status: 2153 raise Warning("FV name error", self.FileName, self.CurrentLineNumber) 2154 2155 self.__GetDefineStatements(FvObj) 2156 2157 self.__GetAddressStatements(FvObj) 2158 2159 FvObj.FvExtEntryTypeValue = [] 2160 FvObj.FvExtEntryType = [] 2161 FvObj.FvExtEntryData = [] 2162 while True: 2163 self.__GetSetStatements(FvObj) 2164 2165 if not (self.__GetBlockStatement(FvObj) or self.__GetFvBaseAddress(FvObj) or 2166 self.__GetFvForceRebase(FvObj) or self.__GetFvAlignment(FvObj) or 2167 self.__GetFvAttributes(FvObj) or self.__GetFvNameGuid(FvObj) or 2168 self.__GetFvExtEntryStatement(FvObj) or self.__GetFvNameString(FvObj)): 2169 break 2170 2171 if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid: 2172 raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber) 2173 2174 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy()) 2175 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy()) 2176 2177 while True: 2178 isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy()) 2179 isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy()) 2180 if not isInf and not isFile: 2181 break 2182 2183 return True 2184 2185 ## __GetFvAlignment() method 2186 # 2187 # Get alignment for FV 2188 # 2189 # @param self The object pointer 2190 # @param Obj for whom alignment is got 2191 # @retval True Successfully find a alignment statement 2192 # @retval False Not able to find a alignment statement 2193 # 2194 def __GetFvAlignment(self, Obj): 2195 2196 if not self.__IsKeyword( "FvAlignment"): 2197 return False 2198 2199 if not self.__IsToken( "="): 2200 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2201 2202 if not self.__GetNextToken(): 2203 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber) 2204 2205 if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \ 2206 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \ 2207 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \ 2208 "1G", "2G"): 2209 raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 2210 Obj.FvAlignment = self.__Token 2211 return True 2212 2213 ## __GetFvBaseAddress() method 2214 # 2215 # Get BaseAddress for FV 2216 # 2217 # @param self The object pointer 2218 # @param Obj for whom FvBaseAddress is got 2219 # @retval True Successfully find a FvBaseAddress statement 2220 # @retval False Not able to find a FvBaseAddress statement 2221 # 2222 def __GetFvBaseAddress(self, Obj): 2223 2224 if not self.__IsKeyword("FvBaseAddress"): 2225 return False 2226 2227 if not self.__IsToken( "="): 2228 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2229 2230 if not self.__GetNextToken(): 2231 raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber) 2232 2233 IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+') 2234 2235 if not IsValidBaseAddrValue.match(self.__Token.upper()): 2236 raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 2237 Obj.FvBaseAddress = self.__Token 2238 return True 2239 2240 ## __GetFvForceRebase() method 2241 # 2242 # Get FvForceRebase for FV 2243 # 2244 # @param self The object pointer 2245 # @param Obj for whom FvForceRebase is got 2246 # @retval True Successfully find a FvForceRebase statement 2247 # @retval False Not able to find a FvForceRebase statement 2248 # 2249 def __GetFvForceRebase(self, Obj): 2250 2251 if not self.__IsKeyword("FvForceRebase"): 2252 return False 2253 2254 if not self.__IsToken( "="): 2255 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2256 2257 if not self.__GetNextToken(): 2258 raise Warning("expected FvForceRebase value", self.FileName, self.CurrentLineNumber) 2259 2260 if self.__Token.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]: 2261 raise Warning("Unknown FvForceRebase value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 2262 2263 if self.__Token.upper() in ["TRUE", "1", "0X1", "0X01"]: 2264 Obj.FvForceRebase = True 2265 elif self.__Token.upper() in ["FALSE", "0", "0X0", "0X00"]: 2266 Obj.FvForceRebase = False 2267 else: 2268 Obj.FvForceRebase = None 2269 2270 return True 2271 2272 2273 ## __GetFvAttributes() method 2274 # 2275 # Get attributes for FV 2276 # 2277 # @param self The object pointer 2278 # @param Obj for whom attribute is got 2279 # @retval None 2280 # 2281 def __GetFvAttributes(self, FvObj): 2282 IsWordToken = False 2283 while self.__GetNextWord(): 2284 IsWordToken = True 2285 name = self.__Token 2286 if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \ 2287 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \ 2288 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \ 2289 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \ 2290 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \ 2291 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT"): 2292 self.__UndoToken() 2293 return False 2294 2295 if not self.__IsToken( "="): 2296 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2297 2298 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"): 2299 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber) 2300 2301 FvObj.FvAttributeDict[name] = self.__Token 2302 2303 return IsWordToken 2304 2305 ## __GetFvNameGuid() method 2306 # 2307 # Get FV GUID for FV 2308 # 2309 # @param self The object pointer 2310 # @param Obj for whom GUID is got 2311 # @retval None 2312 # 2313 def __GetFvNameGuid(self, FvObj): 2314 2315 if not self.__IsKeyword( "FvNameGuid"): 2316 return False 2317 2318 if not self.__IsToken( "="): 2319 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2320 2321 if not self.__GetNextGuid(): 2322 raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber) 2323 2324 FvObj.FvNameGuid = self.__Token 2325 2326 return True 2327 2328 def __GetFvNameString(self, FvObj): 2329 2330 if not self.__IsKeyword( "FvNameString"): 2331 return False 2332 2333 if not self.__IsToken( "="): 2334 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2335 2336 if not self.__GetNextToken() or self.__Token not in ('TRUE', 'FALSE'): 2337 raise Warning("expected TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber) 2338 2339 FvObj.FvNameString = self.__Token 2340 2341 return True 2342 2343 def __GetFvExtEntryStatement(self, FvObj): 2344 2345 if not self.__IsKeyword( "FV_EXT_ENTRY"): 2346 return False 2347 2348 if not self.__IsKeyword ("TYPE"): 2349 raise Warning("expected 'TYPE'", self.FileName, self.CurrentLineNumber) 2350 2351 if not self.__IsToken( "="): 2352 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2353 2354 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber(): 2355 raise Warning("expected Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber) 2356 2357 FvObj.FvExtEntryTypeValue += [self.__Token] 2358 2359 if not self.__IsToken( "{"): 2360 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) 2361 2362 if not self.__IsKeyword ("FILE") and not self.__IsKeyword ("DATA"): 2363 raise Warning("expected 'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber) 2364 2365 FvObj.FvExtEntryType += [self.__Token] 2366 2367 if self.__Token == 'DATA': 2368 2369 if not self.__IsToken( "="): 2370 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2371 2372 if not self.__IsToken( "{"): 2373 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) 2374 2375 if not self.__GetNextHexNumber(): 2376 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber) 2377 2378 if len(self.__Token) > 4: 2379 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) 2380 2381 DataString = self.__Token 2382 DataString += "," 2383 2384 while self.__IsToken(","): 2385 if not self.__GetNextHexNumber(): 2386 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber) 2387 if len(self.__Token) > 4: 2388 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) 2389 DataString += self.__Token 2390 DataString += "," 2391 2392 if not self.__IsToken( "}"): 2393 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 2394 2395 if not self.__IsToken( "}"): 2396 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 2397 2398 DataString = DataString.rstrip(",") 2399 FvObj.FvExtEntryData += [DataString] 2400 2401 if self.__Token == 'FILE': 2402 2403 if not self.__IsToken( "="): 2404 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2405 2406 if not self.__GetNextToken(): 2407 raise Warning("expected FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber) 2408 2409 FvObj.FvExtEntryData += [self.__Token] 2410 2411 if not self.__IsToken( "}"): 2412 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 2413 2414 return True 2415 2416 ## __GetAprioriSection() method 2417 # 2418 # Get token statements 2419 # 2420 # @param self The object pointer 2421 # @param FvObj for whom apriori is got 2422 # @param MacroDict dictionary used to replace macro 2423 # @retval True Successfully find apriori statement 2424 # @retval False Not able to find apriori statement 2425 # 2426 def __GetAprioriSection(self, FvObj, MacroDict = {}): 2427 2428 if not self.__IsKeyword( "APRIORI"): 2429 return False 2430 2431 if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"): 2432 raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber) 2433 AprType = self.__Token 2434 2435 if not self.__IsToken( "{"): 2436 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) 2437 2438 AprSectionObj = AprioriSection.AprioriSection() 2439 AprSectionObj.AprioriType = AprType 2440 2441 self.__GetDefineStatements(AprSectionObj) 2442 MacroDict.update(AprSectionObj.DefineVarDict) 2443 2444 while True: 2445 IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict) 2446 IsFile = self.__GetFileStatement( AprSectionObj) 2447 if not IsInf and not IsFile: 2448 break 2449 2450 if not self.__IsToken( "}"): 2451 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 2452 2453 FvObj.AprioriSectionList.append(AprSectionObj) 2454 return True 2455 2456 def __ParseInfStatement(self): 2457 if not self.__IsKeyword("INF"): 2458 return None 2459 2460 ffsInf = FfsInfStatement.FfsInfStatement() 2461 self.__GetInfOptions(ffsInf) 2462 2463 if not self.__GetNextToken(): 2464 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber) 2465 ffsInf.InfFileName = self.__Token 2466 2467 ffsInf.CurrentLineNum = self.CurrentLineNumber 2468 ffsInf.CurrentLineContent = self.__CurrentLine() 2469 2470 #Replace $(SAPCE) with real space 2471 ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ') 2472 2473 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1: 2474 #do case sensitive check for file path 2475 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate() 2476 if ErrorCode != 0: 2477 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) 2478 2479 if not ffsInf.InfFileName in self.Profile.InfList: 2480 self.Profile.InfList.append(ffsInf.InfFileName) 2481 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 2482 self.Profile.InfFileLineList.append(FileLineTuple) 2483 if ffsInf.UseArch: 2484 if ffsInf.UseArch not in self.Profile.InfDict: 2485 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName] 2486 else: 2487 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName) 2488 else: 2489 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName) 2490 2491 if self.__IsToken('|'): 2492 if self.__IsKeyword('RELOCS_STRIPPED'): 2493 ffsInf.KeepReloc = False 2494 elif self.__IsKeyword('RELOCS_RETAINED'): 2495 ffsInf.KeepReloc = True 2496 else: 2497 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 2498 return ffsInf 2499 2500 ## __GetInfStatement() method 2501 # 2502 # Get INF statements 2503 # 2504 # @param self The object pointer 2505 # @param Obj for whom inf statement is got 2506 # @param MacroDict dictionary used to replace macro 2507 # @retval True Successfully find inf statement 2508 # @retval False Not able to find inf statement 2509 # 2510 def __GetInfStatement(self, Obj, ForCapsule=False, MacroDict={}): 2511 ffsInf = self.__ParseInfStatement() 2512 if not ffsInf: 2513 return False 2514 2515 if ForCapsule: 2516 capsuleFfs = CapsuleData.CapsuleFfs() 2517 capsuleFfs.Ffs = ffsInf 2518 Obj.CapsuleDataList.append(capsuleFfs) 2519 else: 2520 Obj.FfsList.append(ffsInf) 2521 return True 2522 2523 ## __GetInfOptions() method 2524 # 2525 # Get options for INF 2526 # 2527 # @param self The object pointer 2528 # @param FfsInfObj for whom option is got 2529 # 2530 def __GetInfOptions(self, FfsInfObj): 2531 if self.__IsKeyword("FILE_GUID"): 2532 if not self.__IsToken("="): 2533 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2534 if not self.__GetNextGuid(): 2535 raise Warning("expected GUID value", self.FileName, self.CurrentLineNumber) 2536 FfsInfObj.OverrideGuid = self.__Token 2537 2538 if self.__IsKeyword( "RuleOverride"): 2539 if not self.__IsToken( "="): 2540 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2541 if not self.__GetNextToken(): 2542 raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber) 2543 FfsInfObj.Rule = self.__Token 2544 2545 if self.__IsKeyword( "VERSION"): 2546 if not self.__IsToken( "="): 2547 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2548 if not self.__GetNextToken(): 2549 raise Warning("expected Version", self.FileName, self.CurrentLineNumber) 2550 2551 if self.__GetStringData(): 2552 FfsInfObj.Version = self.__Token 2553 2554 if self.__IsKeyword( "UI"): 2555 if not self.__IsToken( "="): 2556 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2557 if not self.__GetNextToken(): 2558 raise Warning("expected UI name", self.FileName, self.CurrentLineNumber) 2559 2560 if self.__GetStringData(): 2561 FfsInfObj.Ui = self.__Token 2562 2563 if self.__IsKeyword( "USE"): 2564 if not self.__IsToken( "="): 2565 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2566 if not self.__GetNextToken(): 2567 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber) 2568 FfsInfObj.UseArch = self.__Token 2569 2570 2571 if self.__GetNextToken(): 2572 p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))') 2573 if p.match(self.__Token) and p.match(self.__Token).span()[1] == len(self.__Token): 2574 FfsInfObj.KeyStringList.append(self.__Token) 2575 if not self.__IsToken(","): 2576 return 2577 else: 2578 self.__UndoToken() 2579 return 2580 2581 while self.__GetNextToken(): 2582 if not p.match(self.__Token): 2583 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) 2584 FfsInfObj.KeyStringList.append(self.__Token) 2585 2586 if not self.__IsToken(","): 2587 break 2588 2589 ## __GetFileStatement() method 2590 # 2591 # Get FILE statements 2592 # 2593 # @param self The object pointer 2594 # @param Obj for whom FILE statement is got 2595 # @param MacroDict dictionary used to replace macro 2596 # @retval True Successfully find FILE statement 2597 # @retval False Not able to find FILE statement 2598 # 2599 def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}): 2600 2601 if not self.__IsKeyword( "FILE"): 2602 return False 2603 2604 if not self.__GetNextWord(): 2605 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber) 2606 2607 if ForCapsule and self.__Token == 'DATA': 2608 self.__UndoToken() 2609 self.__UndoToken() 2610 return False 2611 2612 FfsFileObj = FfsFileStatement.FileStatement() 2613 FfsFileObj.FvFileType = self.__Token 2614 2615 if not self.__IsToken( "="): 2616 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2617 2618 if not self.__GetNextGuid(): 2619 if not self.__GetNextWord(): 2620 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber) 2621 if self.__Token == 'PCD': 2622 if not self.__IsToken( "("): 2623 raise Warning("expected '('", self.FileName, self.CurrentLineNumber) 2624 PcdPair = self.__GetNextPcdName() 2625 if not self.__IsToken( ")"): 2626 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber) 2627 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')' 2628 2629 FfsFileObj.NameGuid = self.__Token 2630 2631 self.__GetFilePart( FfsFileObj, MacroDict.copy()) 2632 2633 if ForCapsule: 2634 capsuleFfs = CapsuleData.CapsuleFfs() 2635 capsuleFfs.Ffs = FfsFileObj 2636 Obj.CapsuleDataList.append(capsuleFfs) 2637 else: 2638 Obj.FfsList.append(FfsFileObj) 2639 2640 return True 2641 2642 ## __FileCouldHaveRelocFlag() method 2643 # 2644 # Check whether reloc strip flag can be set for a file type. 2645 # 2646 # @param self The object pointer 2647 # @param FileType The file type to check with 2648 # @retval True This type could have relocation strip flag 2649 # @retval False No way to have it 2650 # 2651 2652 def __FileCouldHaveRelocFlag (self, FileType): 2653 if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'): 2654 return True 2655 else: 2656 return False 2657 2658 ## __SectionCouldHaveRelocFlag() method 2659 # 2660 # Check whether reloc strip flag can be set for a section type. 2661 # 2662 # @param self The object pointer 2663 # @param SectionType The section type to check with 2664 # @retval True This type could have relocation strip flag 2665 # @retval False No way to have it 2666 # 2667 2668 def __SectionCouldHaveRelocFlag (self, SectionType): 2669 if SectionType in ('TE', 'PE32'): 2670 return True 2671 else: 2672 return False 2673 2674 ## __GetFilePart() method 2675 # 2676 # Get components for FILE statement 2677 # 2678 # @param self The object pointer 2679 # @param FfsFileObj for whom component is got 2680 # @param MacroDict dictionary used to replace macro 2681 # 2682 def __GetFilePart(self, FfsFileObj, MacroDict = {}): 2683 2684 self.__GetFileOpts( FfsFileObj) 2685 2686 if not self.__IsToken("{"): 2687 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): 2688 if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType): 2689 if self.__Token == 'RELOCS_STRIPPED': 2690 FfsFileObj.KeepReloc = False 2691 else: 2692 FfsFileObj.KeepReloc = True 2693 else: 2694 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) 2695 2696 if not self.__IsToken("{"): 2697 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) 2698 2699 if not self.__GetNextToken(): 2700 raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber) 2701 2702 if self.__Token == "FV": 2703 if not self.__IsToken( "="): 2704 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2705 if not self.__GetNextToken(): 2706 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) 2707 FfsFileObj.FvName = self.__Token 2708 2709 elif self.__Token == "FD": 2710 if not self.__IsToken( "="): 2711 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2712 if not self.__GetNextToken(): 2713 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber) 2714 FfsFileObj.FdName = self.__Token 2715 2716 elif self.__Token in ("DEFINE", "APRIORI", "SECTION"): 2717 self.__UndoToken() 2718 self.__GetSectionData( FfsFileObj, MacroDict) 2719 2720 elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW': 2721 self.__UndoToken() 2722 self.__GetRAWData(FfsFileObj, MacroDict) 2723 2724 else: 2725 FfsFileObj.CurrentLineNum = self.CurrentLineNumber 2726 FfsFileObj.CurrentLineContent = self.__CurrentLine() 2727 FfsFileObj.FileName = self.__Token.replace('$(SPACE)', ' ') 2728 self.__VerifyFile(FfsFileObj.FileName) 2729 2730 if not self.__IsToken( "}"): 2731 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 2732 2733 ## __GetRAWData() method 2734 # 2735 # Get RAW data for FILE statement 2736 # 2737 # @param self The object pointer 2738 # @param FfsFileObj for whom section is got 2739 # @param MacroDict dictionary used to replace macro 2740 # 2741 def __GetRAWData(self, FfsFileObj, MacroDict = {}): 2742 FfsFileObj.FileName = [] 2743 FfsFileObj.SubAlignment = [] 2744 while True: 2745 AlignValue = None 2746 if self.__GetAlignment(): 2747 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): 2748 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 2749 #For FFS, Auto is default option same to "" 2750 if not self.__Token == "Auto": 2751 AlignValue = self.__Token 2752 if not self.__GetNextToken(): 2753 raise Warning("expected Filename value", self.FileName, self.CurrentLineNumber) 2754 2755 FileName = self.__Token.replace('$(SPACE)', ' ') 2756 if FileName == '}': 2757 self.__UndoToken() 2758 raise Warning("expected Filename value", self.FileName, self.CurrentLineNumber) 2759 2760 self.__VerifyFile(FileName) 2761 File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir) 2762 FfsFileObj.FileName.append(File.Path) 2763 FfsFileObj.SubAlignment.append(AlignValue) 2764 2765 if self.__IsToken( "}"): 2766 self.__UndoToken() 2767 break 2768 2769 if len(FfsFileObj.SubAlignment) == 1: 2770 FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0] 2771 if len(FfsFileObj.FileName) == 1: 2772 FfsFileObj.FileName = FfsFileObj.FileName[0] 2773 2774 ## __GetFileOpts() method 2775 # 2776 # Get options for FILE statement 2777 # 2778 # @param self The object pointer 2779 # @param FfsFileObj for whom options is got 2780 # 2781 def __GetFileOpts(self, FfsFileObj): 2782 2783 if self.__GetNextToken(): 2784 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') 2785 if Pattern.match(self.__Token): 2786 FfsFileObj.KeyStringList.append(self.__Token) 2787 if self.__IsToken(","): 2788 while self.__GetNextToken(): 2789 if not Pattern.match(self.__Token): 2790 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) 2791 FfsFileObj.KeyStringList.append(self.__Token) 2792 2793 if not self.__IsToken(","): 2794 break 2795 2796 else: 2797 self.__UndoToken() 2798 2799 if self.__IsKeyword( "FIXED", True): 2800 FfsFileObj.Fixed = True 2801 2802 if self.__IsKeyword( "CHECKSUM", True): 2803 FfsFileObj.CheckSum = True 2804 2805 if self.__GetAlignment(): 2806 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): 2807 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 2808 #For FFS, Auto is default option same to "" 2809 if not self.__Token == "Auto": 2810 FfsFileObj.Alignment = self.__Token 2811 2812 ## __GetAlignment() method 2813 # 2814 # Return the alignment value 2815 # 2816 # @param self The object pointer 2817 # @retval True Successfully find alignment 2818 # @retval False Not able to find alignment 2819 # 2820 def __GetAlignment(self): 2821 if self.__IsKeyword( "Align", True): 2822 if not self.__IsToken( "="): 2823 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2824 2825 if not self.__GetNextToken(): 2826 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber) 2827 return True 2828 2829 return False 2830 2831 ## __GetFilePart() method 2832 # 2833 # Get section data for FILE statement 2834 # 2835 # @param self The object pointer 2836 # @param FfsFileObj for whom section is got 2837 # @param MacroDict dictionary used to replace macro 2838 # 2839 def __GetSectionData(self, FfsFileObj, MacroDict = {}): 2840 Dict = {} 2841 Dict.update(MacroDict) 2842 2843 self.__GetDefineStatements(FfsFileObj) 2844 2845 Dict.update(FfsFileObj.DefineVarDict) 2846 self.__GetAprioriSection(FfsFileObj, Dict.copy()) 2847 self.__GetAprioriSection(FfsFileObj, Dict.copy()) 2848 2849 while True: 2850 IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict) 2851 IsEncapSection = self.__GetEncapsulationSec(FfsFileObj) 2852 if not IsLeafSection and not IsEncapSection: 2853 break 2854 2855 ## __GetLeafSection() method 2856 # 2857 # Get leaf section for Obj 2858 # 2859 # @param self The object pointer 2860 # @param Obj for whom leaf section is got 2861 # @param MacroDict dictionary used to replace macro 2862 # @retval True Successfully find section statement 2863 # @retval False Not able to find section statement 2864 # 2865 def __GetLeafSection(self, Obj, MacroDict = {}): 2866 2867 OldPos = self.GetFileBufferPos() 2868 2869 if not self.__IsKeyword( "SECTION"): 2870 if len(Obj.SectionList) == 0: 2871 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber) 2872 else: 2873 return False 2874 2875 AlignValue = None 2876 if self.__GetAlignment(): 2877 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): 2878 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 2879 AlignValue = self.__Token 2880 2881 BuildNum = None 2882 if self.__IsKeyword( "BUILD_NUM"): 2883 if not self.__IsToken( "="): 2884 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2885 2886 if not self.__GetNextToken(): 2887 raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber) 2888 2889 BuildNum = self.__Token 2890 2891 if self.__IsKeyword( "VERSION"): 2892 if AlignValue == 'Auto': 2893 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) 2894 if not self.__IsToken( "="): 2895 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2896 if not self.__GetNextToken(): 2897 raise Warning("expected version", self.FileName, self.CurrentLineNumber) 2898 VerSectionObj = VerSection.VerSection() 2899 VerSectionObj.Alignment = AlignValue 2900 VerSectionObj.BuildNum = BuildNum 2901 if self.__GetStringData(): 2902 VerSectionObj.StringData = self.__Token 2903 else: 2904 VerSectionObj.FileName = self.__Token 2905 Obj.SectionList.append(VerSectionObj) 2906 2907 elif self.__IsKeyword( "UI"): 2908 if AlignValue == 'Auto': 2909 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) 2910 if not self.__IsToken( "="): 2911 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2912 if not self.__GetNextToken(): 2913 raise Warning("expected UI", self.FileName, self.CurrentLineNumber) 2914 UiSectionObj = UiSection.UiSection() 2915 UiSectionObj.Alignment = AlignValue 2916 if self.__GetStringData(): 2917 UiSectionObj.StringData = self.__Token 2918 else: 2919 UiSectionObj.FileName = self.__Token 2920 Obj.SectionList.append(UiSectionObj) 2921 2922 elif self.__IsKeyword( "FV_IMAGE"): 2923 if AlignValue == 'Auto': 2924 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) 2925 if not self.__IsToken( "="): 2926 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2927 if not self.__GetNextToken(): 2928 raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber) 2929 2930 FvName = self.__Token 2931 FvObj = None 2932 2933 if self.__IsToken( "{"): 2934 FvObj = Fv.FV() 2935 FvObj.UiFvName = FvName.upper() 2936 self.__GetDefineStatements(FvObj) 2937 MacroDict.update(FvObj.DefineVarDict) 2938 self.__GetBlockStatement(FvObj) 2939 self.__GetSetStatements(FvObj) 2940 self.__GetFvAlignment(FvObj) 2941 self.__GetFvAttributes(FvObj) 2942 self.__GetAprioriSection(FvObj, MacroDict.copy()) 2943 self.__GetAprioriSection(FvObj, MacroDict.copy()) 2944 2945 while True: 2946 IsInf = self.__GetInfStatement(FvObj, MacroDict.copy()) 2947 IsFile = self.__GetFileStatement(FvObj, MacroDict.copy()) 2948 if not IsInf and not IsFile: 2949 break 2950 2951 if not self.__IsToken( "}"): 2952 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 2953 2954 FvImageSectionObj = FvImageSection.FvImageSection() 2955 FvImageSectionObj.Alignment = AlignValue 2956 if FvObj != None: 2957 FvImageSectionObj.Fv = FvObj 2958 FvImageSectionObj.FvName = None 2959 else: 2960 FvImageSectionObj.FvName = FvName.upper() 2961 FvImageSectionObj.FvFileName = FvName 2962 2963 Obj.SectionList.append(FvImageSectionObj) 2964 2965 elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"): 2966 if AlignValue == 'Auto': 2967 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) 2968 DepexSectionObj = DepexSection.DepexSection() 2969 DepexSectionObj.Alignment = AlignValue 2970 DepexSectionObj.DepexType = self.__Token 2971 2972 if not self.__IsToken( "="): 2973 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 2974 if not self.__IsToken( "{"): 2975 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) 2976 if not self.__SkipToToken( "}"): 2977 raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber) 2978 2979 DepexSectionObj.Expression = self.__SkippedChars.rstrip('}') 2980 Obj.SectionList.append(DepexSectionObj) 2981 2982 else: 2983 if not self.__GetNextWord(): 2984 raise Warning("expected section type", self.FileName, self.CurrentLineNumber) 2985 2986 # Encapsulation section appear, UndoToken and return 2987 if self.__Token == "COMPRESS" or self.__Token == "GUIDED": 2988 self.SetFileBufferPos(OldPos) 2989 return False 2990 2991 if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ 2992 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"): 2993 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 2994 if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'): 2995 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) 2996 2997 # DataSection 2998 DataSectionObj = DataSection.DataSection() 2999 DataSectionObj.Alignment = AlignValue 3000 DataSectionObj.SecType = self.__Token 3001 3002 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): 3003 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType): 3004 if self.__Token == 'RELOCS_STRIPPED': 3005 DataSectionObj.KeepReloc = False 3006 else: 3007 DataSectionObj.KeepReloc = True 3008 else: 3009 raise Warning("File type %s, section type %s, could not have reloc strip flag%d" % (Obj.FvFileType, DataSectionObj.SecType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) 3010 3011 if self.__IsToken("="): 3012 if not self.__GetNextToken(): 3013 raise Warning("expected section file path", self.FileName, self.CurrentLineNumber) 3014 DataSectionObj.SectFileName = self.__Token 3015 self.__VerifyFile(DataSectionObj.SectFileName) 3016 else: 3017 if not self.__GetCglSection(DataSectionObj): 3018 return False 3019 3020 Obj.SectionList.append(DataSectionObj) 3021 3022 return True 3023 3024 ## __VerifyFile 3025 # 3026 # Check if file exists or not: 3027 # If current phase if GenFds, the file must exist; 3028 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist 3029 # @param FileName: File path to be verified. 3030 # 3031 def __VerifyFile(self, FileName): 3032 if FileName.replace('$(WORKSPACE)', '').find('$') != -1: 3033 return 3034 if not GlobalData.gAutoGenPhase or not self.__GetMacroValue("OUTPUT_DIRECTORY") in FileName: 3035 ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate() 3036 if ErrorCode != 0: 3037 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) 3038 3039 ## __GetCglSection() method 3040 # 3041 # Get compressed or GUIDed section for Obj 3042 # 3043 # @param self The object pointer 3044 # @param Obj for whom leaf section is got 3045 # @param AlignValue alignment value for complex section 3046 # @retval True Successfully find section statement 3047 # @retval False Not able to find section statement 3048 # 3049 def __GetCglSection(self, Obj, AlignValue = None): 3050 3051 if self.__IsKeyword( "COMPRESS"): 3052 type = "PI_STD" 3053 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"): 3054 type = self.__Token 3055 3056 if not self.__IsToken("{"): 3057 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) 3058 3059 CompressSectionObj = CompressSection.CompressSection() 3060 CompressSectionObj.Alignment = AlignValue 3061 CompressSectionObj.CompType = type 3062 # Recursive sections... 3063 while True: 3064 IsLeafSection = self.__GetLeafSection(CompressSectionObj) 3065 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj) 3066 if not IsLeafSection and not IsEncapSection: 3067 break 3068 3069 3070 if not self.__IsToken( "}"): 3071 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 3072 Obj.SectionList.append(CompressSectionObj) 3073 3074 # else: 3075 # raise Warning("Compress type not known") 3076 3077 return True 3078 3079 elif self.__IsKeyword( "GUIDED"): 3080 GuidValue = None 3081 if self.__GetNextGuid(): 3082 GuidValue = self.__Token 3083 3084 AttribDict = self.__GetGuidAttrib() 3085 if not self.__IsToken("{"): 3086 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) 3087 GuidSectionObj = GuidSection.GuidSection() 3088 GuidSectionObj.Alignment = AlignValue 3089 GuidSectionObj.NameGuid = GuidValue 3090 GuidSectionObj.SectionType = "GUIDED" 3091 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"] 3092 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"] 3093 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"] 3094 # Recursive sections... 3095 while True: 3096 IsLeafSection = self.__GetLeafSection(GuidSectionObj) 3097 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj) 3098 if not IsLeafSection and not IsEncapSection: 3099 break 3100 3101 if not self.__IsToken( "}"): 3102 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 3103 Obj.SectionList.append(GuidSectionObj) 3104 3105 return True 3106 3107 return False 3108 3109 ## __GetGuidAttri() method 3110 # 3111 # Get attributes for GUID section 3112 # 3113 # @param self The object pointer 3114 # @retval AttribDict Dictionary of key-value pair of section attributes 3115 # 3116 def __GetGuidAttrib(self): 3117 3118 AttribDict = {} 3119 AttribDict["PROCESSING_REQUIRED"] = "NONE" 3120 AttribDict["AUTH_STATUS_VALID"] = "NONE" 3121 AttribDict["EXTRA_HEADER_SIZE"] = -1 3122 while self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID") \ 3123 or self.__IsKeyword("EXTRA_HEADER_SIZE"): 3124 AttribKey = self.__Token 3125 3126 if not self.__IsToken("="): 3127 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3128 3129 if not self.__GetNextToken(): 3130 raise Warning("expected TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber) 3131 elif AttribKey == "EXTRA_HEADER_SIZE": 3132 Base = 10 3133 if self.__Token[0:2].upper() == "0X": 3134 Base = 16 3135 try: 3136 AttribDict[AttribKey] = int(self.__Token, Base) 3137 continue 3138 except ValueError: 3139 raise Warning("expected Number", self.FileName, self.CurrentLineNumber) 3140 elif self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"): 3141 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber) 3142 AttribDict[AttribKey] = self.__Token 3143 3144 return AttribDict 3145 3146 ## __GetEncapsulationSec() method 3147 # 3148 # Get encapsulation section for FILE 3149 # 3150 # @param self The object pointer 3151 # @param FfsFile for whom section is got 3152 # @retval True Successfully find section statement 3153 # @retval False Not able to find section statement 3154 # 3155 def __GetEncapsulationSec(self, FfsFileObj): 3156 3157 OldPos = self.GetFileBufferPos() 3158 if not self.__IsKeyword( "SECTION"): 3159 if len(FfsFileObj.SectionList) == 0: 3160 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber) 3161 else: 3162 return False 3163 3164 AlignValue = None 3165 if self.__GetAlignment(): 3166 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): 3167 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 3168 AlignValue = self.__Token 3169 3170 if not self.__GetCglSection(FfsFileObj, AlignValue): 3171 self.SetFileBufferPos(OldPos) 3172 return False 3173 else: 3174 return True 3175 3176 def __GetFmp(self): 3177 if not self.__GetNextToken(): 3178 return False 3179 S = self.__Token.upper() 3180 if S.startswith("[") and not S.startswith("[FMPPAYLOAD."): 3181 self.SectionParser(S) 3182 self.__UndoToken() 3183 return False 3184 3185 self.__UndoToken() 3186 self.__SkipToToken("[FMPPAYLOAD.", True) 3187 FmpUiName = self.__GetUiName().upper() 3188 if FmpUiName in self.Profile.FmpPayloadDict: 3189 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber) 3190 3191 FmpData = CapsuleData.CapsulePayload() 3192 FmpData.UiName = FmpUiName 3193 3194 if not self.__IsToken( "]"): 3195 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) 3196 3197 if not self.__GetNextToken(): 3198 raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber) 3199 FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT'] 3200 while self.__Token in FmpKeyList: 3201 Name = self.__Token 3202 FmpKeyList.remove(Name) 3203 if not self.__IsToken("="): 3204 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3205 if Name == 'IMAGE_TYPE_ID': 3206 if not self.__GetNextGuid(): 3207 raise Warning("expected GUID value for IMAGE_TYPE_ID.", self.FileName, self.CurrentLineNumber) 3208 FmpData.ImageTypeId = self.__Token 3209 elif Name == 'CERTIFICATE_GUID': 3210 if not self.__GetNextGuid(): 3211 raise Warning("expected GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber) 3212 FmpData.Certificate_Guid = self.__Token 3213 if uuid.UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and uuid.UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID: 3214 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber) 3215 else: 3216 if not self.__GetNextToken(): 3217 raise Warning("expected value of %s" % Name, self.FileName, self.CurrentLineNumber) 3218 Value = self.__Token 3219 if Name == 'IMAGE_HEADER_INIT_VERSION': 3220 if self.__Verify(Name, Value, 'UINT8'): 3221 FmpData.Version = Value 3222 elif Name == 'IMAGE_INDEX': 3223 if self.__Verify(Name, Value, 'UINT8'): 3224 FmpData.ImageIndex = Value 3225 elif Name == 'HARDWARE_INSTANCE': 3226 if self.__Verify(Name, Value, 'UINT8'): 3227 FmpData.HardwareInstance = Value 3228 elif Name == 'MONOTONIC_COUNT': 3229 if self.__Verify(Name, Value, 'UINT64'): 3230 FmpData.MonotonicCount = Value 3231 if FmpData.MonotonicCount.upper().startswith('0X'): 3232 FmpData.MonotonicCount = (long)(FmpData.MonotonicCount, 16) 3233 else: 3234 FmpData.MonotonicCount = (long)(FmpData.MonotonicCount) 3235 if not self.__GetNextToken(): 3236 break 3237 else: 3238 self.__UndoToken() 3239 3240 if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid): 3241 EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.") 3242 # remove CERTIFICATE_GUID and MONOTONIC_COUNT from FmpKeyList, since these keys are optional 3243 if 'CERTIFICATE_GUID' in FmpKeyList: 3244 FmpKeyList.remove('CERTIFICATE_GUID') 3245 if 'MONOTONIC_COUNT' in FmpKeyList: 3246 FmpKeyList.remove('MONOTONIC_COUNT') 3247 if FmpKeyList: 3248 raise Warning("Missing keywords %s in FMP payload section." % ', '.join(FmpKeyList), self.FileName, self.CurrentLineNumber) 3249 # get the Image file and Vendor code file 3250 self.__GetFMPCapsuleData(FmpData) 3251 if not FmpData.ImageFile: 3252 raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber) 3253 # check whether more than one Vendor code file 3254 if len(FmpData.VendorCodeFile) > 1: 3255 raise Warning("At most one Image file and one Vendor code file are allowed in FMP payload section.", self.FileName, self.CurrentLineNumber) 3256 self.Profile.FmpPayloadDict[FmpUiName] = FmpData 3257 return True 3258 3259 ## __GetCapsule() method 3260 # 3261 # Get capsule section contents and store its data into capsule list of self.Profile 3262 # 3263 # @param self The object pointer 3264 # @retval True Successfully find a capsule 3265 # @retval False Not able to find a capsule 3266 # 3267 def __GetCapsule(self): 3268 3269 if not self.__GetNextToken(): 3270 return False 3271 3272 S = self.__Token.upper() 3273 if S.startswith("[") and not S.startswith("[CAPSULE."): 3274 self.SectionParser(S) 3275 self.__UndoToken() 3276 return False 3277 3278 self.__UndoToken() 3279 if not self.__IsToken("[CAPSULE.", True): 3280 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 3281 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ 3282 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) 3283 raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber) 3284 3285 CapsuleObj = Capsule.Capsule() 3286 3287 CapsuleName = self.__GetUiName() 3288 if not CapsuleName: 3289 raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber) 3290 3291 CapsuleObj.UiCapsuleName = CapsuleName.upper() 3292 3293 if not self.__IsToken( "]"): 3294 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) 3295 3296 if self.__IsKeyword("CREATE_FILE"): 3297 if not self.__IsToken( "="): 3298 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3299 3300 if not self.__GetNextToken(): 3301 raise Warning("expected file name", self.FileName, self.CurrentLineNumber) 3302 3303 CapsuleObj.CreateFile = self.__Token 3304 3305 self.__GetCapsuleStatements(CapsuleObj) 3306 self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj 3307 return True 3308 3309 ## __GetCapsuleStatements() method 3310 # 3311 # Get statements for capsule 3312 # 3313 # @param self The object pointer 3314 # @param Obj for whom statements are got 3315 # 3316 def __GetCapsuleStatements(self, Obj): 3317 self.__GetCapsuleTokens(Obj) 3318 self.__GetDefineStatements(Obj) 3319 self.__GetSetStatements(Obj) 3320 self.__GetCapsuleData(Obj) 3321 3322 ## __GetCapsuleTokens() method 3323 # 3324 # Get token statements for capsule 3325 # 3326 # @param self The object pointer 3327 # @param Obj for whom token statements are got 3328 # 3329 def __GetCapsuleTokens(self, Obj): 3330 if not self.__GetNextToken(): 3331 return False 3332 while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"): 3333 Name = self.__Token.strip() 3334 if not self.__IsToken("="): 3335 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3336 if not self.__GetNextToken(): 3337 raise Warning("expected value", self.FileName, self.CurrentLineNumber) 3338 if Name == 'CAPSULE_FLAGS': 3339 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"): 3340 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber) 3341 Value = self.__Token.strip() 3342 while self.__IsToken(","): 3343 Value += ',' 3344 if not self.__GetNextToken(): 3345 raise Warning("expected value", self.FileName, self.CurrentLineNumber) 3346 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"): 3347 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber) 3348 Value += self.__Token.strip() 3349 elif Name == 'OEM_CAPSULE_FLAGS': 3350 Value = self.__Token.strip() 3351 if not Value.upper().startswith('0X'): 3352 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber) 3353 try: 3354 Value = int(Value, 0) 3355 except ValueError: 3356 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber) 3357 if not 0x0000 <= Value <= 0xFFFF: 3358 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber) 3359 Value = self.__Token.strip() 3360 else: 3361 Value = self.__Token.strip() 3362 Obj.TokensDict[Name] = Value 3363 if not self.__GetNextToken(): 3364 return False 3365 self.__UndoToken() 3366 3367 ## __GetCapsuleData() method 3368 # 3369 # Get capsule data for capsule 3370 # 3371 # @param self The object pointer 3372 # @param Obj for whom capsule data are got 3373 # 3374 def __GetCapsuleData(self, Obj): 3375 3376 while True: 3377 IsInf = self.__GetInfStatement(Obj, True) 3378 IsFile = self.__GetFileStatement(Obj, True) 3379 IsFv = self.__GetFvStatement(Obj) 3380 IsFd = self.__GetFdStatement(Obj) 3381 IsAnyFile = self.__GetAnyFileStatement(Obj) 3382 IsAfile = self.__GetAfileStatement(Obj) 3383 IsFmp = self.__GetFmpStatement(Obj) 3384 if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp): 3385 break 3386 3387 ## __GetFMPCapsuleData() method 3388 # 3389 # Get capsule data for FMP capsule 3390 # 3391 # @param self The object pointer 3392 # @param Obj for whom capsule data are got 3393 # 3394 def __GetFMPCapsuleData(self, Obj): 3395 3396 while True: 3397 IsFv = self.__GetFvStatement(Obj, True) 3398 IsFd = self.__GetFdStatement(Obj, True) 3399 IsAnyFile = self.__GetAnyFileStatement(Obj, True) 3400 if not (IsFv or IsFd or IsAnyFile): 3401 break 3402 3403 ## __GetFvStatement() method 3404 # 3405 # Get FV for capsule 3406 # 3407 # @param self The object pointer 3408 # @param CapsuleObj for whom FV is got 3409 # @retval True Successfully find a FV statement 3410 # @retval False Not able to find a FV statement 3411 # 3412 def __GetFvStatement(self, CapsuleObj, FMPCapsule = False): 3413 3414 if not self.__IsKeyword("FV"): 3415 return False 3416 3417 if not self.__IsToken("="): 3418 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3419 3420 if not self.__GetNextToken(): 3421 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) 3422 3423 if self.__Token.upper() not in self.Profile.FvDict.keys(): 3424 raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber) 3425 3426 CapsuleFv = CapsuleData.CapsuleFv() 3427 CapsuleFv.FvName = self.__Token 3428 if FMPCapsule: 3429 if not CapsuleObj.ImageFile: 3430 CapsuleObj.ImageFile.append(CapsuleFv) 3431 else: 3432 CapsuleObj.VendorCodeFile.append(CapsuleFv) 3433 else: 3434 CapsuleObj.CapsuleDataList.append(CapsuleFv) 3435 return True 3436 3437 ## __GetFdStatement() method 3438 # 3439 # Get FD for capsule 3440 # 3441 # @param self The object pointer 3442 # @param CapsuleObj for whom FD is got 3443 # @retval True Successfully find a FD statement 3444 # @retval False Not able to find a FD statement 3445 # 3446 def __GetFdStatement(self, CapsuleObj, FMPCapsule = False): 3447 3448 if not self.__IsKeyword("FD"): 3449 return False 3450 3451 if not self.__IsToken("="): 3452 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3453 3454 if not self.__GetNextToken(): 3455 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber) 3456 3457 if self.__Token.upper() not in self.Profile.FdDict.keys(): 3458 raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber) 3459 3460 CapsuleFd = CapsuleData.CapsuleFd() 3461 CapsuleFd.FdName = self.__Token 3462 if FMPCapsule: 3463 if not CapsuleObj.ImageFile: 3464 CapsuleObj.ImageFile.append(CapsuleFd) 3465 else: 3466 CapsuleObj.VendorCodeFile.append(CapsuleFd) 3467 else: 3468 CapsuleObj.CapsuleDataList.append(CapsuleFd) 3469 return True 3470 3471 def __GetFmpStatement(self, CapsuleObj): 3472 if not self.__IsKeyword("FMP_PAYLOAD"): 3473 if not self.__IsKeyword("FMP"): 3474 return False 3475 3476 if not self.__IsKeyword("PAYLOAD"): 3477 self.__UndoToken() 3478 return False 3479 3480 if not self.__IsToken("="): 3481 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3482 3483 if not self.__GetNextToken(): 3484 raise Warning("expected payload name after FMP_PAYLOAD =", self.FileName, self.CurrentLineNumber) 3485 Payload = self.__Token.upper() 3486 if Payload not in self.Profile.FmpPayloadDict: 3487 raise Warning("This FMP Payload does not exist: %s" % self.__Token, self.FileName, self.CurrentLineNumber) 3488 CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload]) 3489 return True 3490 3491 def __ParseRawFileStatement(self): 3492 if not self.__IsKeyword("FILE"): 3493 return None 3494 3495 if not self.__IsKeyword("DATA"): 3496 self.__UndoToken() 3497 return None 3498 3499 if not self.__IsToken("="): 3500 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3501 3502 if not self.__GetNextToken(): 3503 raise Warning("expected File name", self.FileName, self.CurrentLineNumber) 3504 3505 AnyFileName = self.__Token 3506 self.__VerifyFile(AnyFileName) 3507 3508 if not os.path.isabs(AnyFileName): 3509 AnyFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, AnyFileName) 3510 3511 return AnyFileName 3512 3513 ## __GetAnyFileStatement() method 3514 # 3515 # Get AnyFile for capsule 3516 # 3517 # @param self The object pointer 3518 # @param CapsuleObj for whom AnyFile is got 3519 # @retval True Successfully find a Anyfile statement 3520 # @retval False Not able to find a AnyFile statement 3521 # 3522 def __GetAnyFileStatement(self, CapsuleObj, FMPCapsule = False): 3523 AnyFileName = self.__ParseRawFileStatement() 3524 if not AnyFileName: 3525 return False 3526 3527 CapsuleAnyFile = CapsuleData.CapsuleAnyFile() 3528 CapsuleAnyFile.FileName = AnyFileName 3529 if FMPCapsule: 3530 if not CapsuleObj.ImageFile: 3531 CapsuleObj.ImageFile.append(CapsuleAnyFile) 3532 else: 3533 CapsuleObj.VendorCodeFile.append(CapsuleAnyFile) 3534 else: 3535 CapsuleObj.CapsuleDataList.append(CapsuleAnyFile) 3536 return True 3537 3538 ## __GetAfileStatement() method 3539 # 3540 # Get Afile for capsule 3541 # 3542 # @param self The object pointer 3543 # @param CapsuleObj for whom Afile is got 3544 # @retval True Successfully find a Afile statement 3545 # @retval False Not able to find a Afile statement 3546 # 3547 def __GetAfileStatement(self, CapsuleObj): 3548 3549 if not self.__IsKeyword("APPEND"): 3550 return False 3551 3552 if not self.__IsToken("="): 3553 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3554 3555 if not self.__GetNextToken(): 3556 raise Warning("expected Afile name", self.FileName, self.CurrentLineNumber) 3557 3558 AfileName = self.__Token 3559 AfileBaseName = os.path.basename(AfileName) 3560 3561 if os.path.splitext(AfileBaseName)[1] not in [".bin",".BIN",".Bin",".dat",".DAT",".Dat",".data",".DATA",".Data"]: 3562 raise Warning('invalid binary file type, should be one of "bin","BIN","Bin","dat","DAT","Dat","data","DATA","Data"', \ 3563 self.FileName, self.CurrentLineNumber) 3564 3565 if not os.path.isabs(AfileName): 3566 AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName) 3567 self.__VerifyFile(AfileName) 3568 else: 3569 if not os.path.exists(AfileName): 3570 raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber) 3571 else: 3572 pass 3573 3574 CapsuleAfile = CapsuleData.CapsuleAfile() 3575 CapsuleAfile.FileName = AfileName 3576 CapsuleObj.CapsuleDataList.append(CapsuleAfile) 3577 return True 3578 3579 ## __GetRule() method 3580 # 3581 # Get Rule section contents and store its data into rule list of self.Profile 3582 # 3583 # @param self The object pointer 3584 # @retval True Successfully find a Rule 3585 # @retval False Not able to find a Rule 3586 # 3587 def __GetRule(self): 3588 3589 if not self.__GetNextToken(): 3590 return False 3591 3592 S = self.__Token.upper() 3593 if S.startswith("[") and not S.startswith("[RULE."): 3594 self.SectionParser(S) 3595 self.__UndoToken() 3596 return False 3597 self.__UndoToken() 3598 if not self.__IsToken("[Rule.", True): 3599 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 3600 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ 3601 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) 3602 raise Warning("expected [Rule.]", self.FileName, self.CurrentLineNumber) 3603 3604 if not self.__SkipToToken("."): 3605 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber) 3606 3607 Arch = self.__SkippedChars.rstrip(".") 3608 if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"): 3609 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber) 3610 3611 ModuleType = self.__GetModuleType() 3612 3613 TemplateName = "" 3614 if self.__IsToken("."): 3615 if not self.__GetNextWord(): 3616 raise Warning("expected template name", self.FileName, self.CurrentLineNumber) 3617 TemplateName = self.__Token 3618 3619 if not self.__IsToken( "]"): 3620 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) 3621 3622 RuleObj = self.__GetRuleFileStatements() 3623 RuleObj.Arch = Arch.upper() 3624 RuleObj.ModuleType = ModuleType 3625 RuleObj.TemplateName = TemplateName 3626 if TemplateName == '' : 3627 self.Profile.RuleDict['RULE' + \ 3628 '.' + \ 3629 Arch.upper() + \ 3630 '.' + \ 3631 ModuleType.upper() ] = RuleObj 3632 else : 3633 self.Profile.RuleDict['RULE' + \ 3634 '.' + \ 3635 Arch.upper() + \ 3636 '.' + \ 3637 ModuleType.upper() + \ 3638 '.' + \ 3639 TemplateName.upper() ] = RuleObj 3640 # self.Profile.RuleList.append(rule) 3641 return True 3642 3643 ## __GetModuleType() method 3644 # 3645 # Return the module type 3646 # 3647 # @param self The object pointer 3648 # @retval string module type 3649 # 3650 def __GetModuleType(self): 3651 3652 if not self.__GetNextWord(): 3653 raise Warning("expected Module type", self.FileName, self.CurrentLineNumber) 3654 if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \ 3655 "DXE_DRIVER", "DXE_SAL_DRIVER", \ 3656 "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \ 3657 "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \ 3658 "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \ 3659 "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE"): 3660 raise Warning("Unknown Module type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 3661 return self.__Token 3662 3663 ## __GetFileExtension() method 3664 # 3665 # Return the file extension 3666 # 3667 # @param self The object pointer 3668 # @retval string file name extension 3669 # 3670 def __GetFileExtension(self): 3671 if not self.__IsToken("."): 3672 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber) 3673 3674 Ext = "" 3675 if self.__GetNextToken(): 3676 Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)') 3677 if Pattern.match(self.__Token): 3678 Ext = self.__Token 3679 return '.' + Ext 3680 else: 3681 raise Warning("Unknown file extension '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 3682 3683 else: 3684 raise Warning("expected file extension", self.FileName, self.CurrentLineNumber) 3685 3686 ## __GetRuleFileStatement() method 3687 # 3688 # Get rule contents 3689 # 3690 # @param self The object pointer 3691 # @retval Rule Rule object 3692 # 3693 def __GetRuleFileStatements(self): 3694 3695 if not self.__IsKeyword("FILE"): 3696 raise Warning("expected FILE", self.FileName, self.CurrentLineNumber) 3697 3698 if not self.__GetNextWord(): 3699 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber) 3700 3701 Type = self.__Token.strip().upper() 3702 if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\ 3703 "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE"): 3704 raise Warning("Unknown FV type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 3705 3706 if not self.__IsToken("="): 3707 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3708 3709 if not self.__IsKeyword("$(NAMED_GUID)"): 3710 if not self.__GetNextWord(): 3711 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber) 3712 if self.__Token == 'PCD': 3713 if not self.__IsToken( "("): 3714 raise Warning("expected '('", self.FileName, self.CurrentLineNumber) 3715 PcdPair = self.__GetNextPcdName() 3716 if not self.__IsToken( ")"): 3717 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber) 3718 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')' 3719 3720 NameGuid = self.__Token 3721 3722 KeepReloc = None 3723 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): 3724 if self.__FileCouldHaveRelocFlag(Type): 3725 if self.__Token == 'RELOCS_STRIPPED': 3726 KeepReloc = False 3727 else: 3728 KeepReloc = True 3729 else: 3730 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) 3731 3732 KeyStringList = [] 3733 if self.__GetNextToken(): 3734 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') 3735 if Pattern.match(self.__Token): 3736 KeyStringList.append(self.__Token) 3737 if self.__IsToken(","): 3738 while self.__GetNextToken(): 3739 if not Pattern.match(self.__Token): 3740 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) 3741 KeyStringList.append(self.__Token) 3742 3743 if not self.__IsToken(","): 3744 break 3745 3746 else: 3747 self.__UndoToken() 3748 3749 3750 Fixed = False 3751 if self.__IsKeyword("Fixed", True): 3752 Fixed = True 3753 3754 CheckSum = False 3755 if self.__IsKeyword("CheckSum", True): 3756 CheckSum = True 3757 3758 AlignValue = "" 3759 if self.__GetAlignment(): 3760 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): 3761 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 3762 #For FFS, Auto is default option same to "" 3763 if not self.__Token == "Auto": 3764 AlignValue = self.__Token 3765 3766 if self.__IsToken("{"): 3767 # Complex file rule expected 3768 Rule = RuleComplexFile.RuleComplexFile() 3769 Rule.FvFileType = Type 3770 Rule.NameGuid = NameGuid 3771 Rule.Alignment = AlignValue 3772 Rule.CheckSum = CheckSum 3773 Rule.Fixed = Fixed 3774 Rule.KeyStringList = KeyStringList 3775 if KeepReloc != None: 3776 Rule.KeepReloc = KeepReloc 3777 3778 while True: 3779 IsEncapsulate = self.__GetRuleEncapsulationSection(Rule) 3780 IsLeaf = self.__GetEfiSection(Rule) 3781 if not IsEncapsulate and not IsLeaf: 3782 break 3783 3784 if not self.__IsToken("}"): 3785 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 3786 3787 return Rule 3788 3789 else: 3790 # Simple file rule expected 3791 if not self.__GetNextWord(): 3792 raise Warning("expected leaf section type", self.FileName, self.CurrentLineNumber) 3793 3794 SectionName = self.__Token 3795 3796 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ 3797 "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"): 3798 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber) 3799 3800 3801 if self.__IsKeyword("Fixed", True): 3802 Fixed = True 3803 3804 if self.__IsKeyword("CheckSum", True): 3805 CheckSum = True 3806 3807 SectAlignment = "" 3808 if self.__GetAlignment(): 3809 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): 3810 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 3811 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'): 3812 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) 3813 SectAlignment = self.__Token 3814 3815 Ext = None 3816 if self.__IsToken('|'): 3817 Ext = self.__GetFileExtension() 3818 elif not self.__GetNextToken(): 3819 raise Warning("expected File name", self.FileName, self.CurrentLineNumber) 3820 3821 Rule = RuleSimpleFile.RuleSimpleFile() 3822 Rule.SectionType = SectionName 3823 Rule.FvFileType = Type 3824 Rule.NameGuid = NameGuid 3825 Rule.Alignment = AlignValue 3826 Rule.SectAlignment = SectAlignment 3827 Rule.CheckSum = CheckSum 3828 Rule.Fixed = Fixed 3829 Rule.KeyStringList = KeyStringList 3830 if KeepReloc != None: 3831 Rule.KeepReloc = KeepReloc 3832 Rule.FileExtension = Ext 3833 Rule.FileName = self.__Token 3834 return Rule 3835 3836 ## __GetEfiSection() method 3837 # 3838 # Get section list for Rule 3839 # 3840 # @param self The object pointer 3841 # @param Obj for whom section is got 3842 # @retval True Successfully find section statement 3843 # @retval False Not able to find section statement 3844 # 3845 def __GetEfiSection(self, Obj): 3846 3847 OldPos = self.GetFileBufferPos() 3848 if not self.__GetNextWord(): 3849 return False 3850 SectionName = self.__Token 3851 3852 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ 3853 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"): 3854 self.__UndoToken() 3855 return False 3856 3857 if SectionName == "FV_IMAGE": 3858 FvImageSectionObj = FvImageSection.FvImageSection() 3859 if self.__IsKeyword("FV_IMAGE"): 3860 pass 3861 if self.__IsToken( "{"): 3862 FvObj = Fv.FV() 3863 self.__GetDefineStatements(FvObj) 3864 self.__GetBlockStatement(FvObj) 3865 self.__GetSetStatements(FvObj) 3866 self.__GetFvAlignment(FvObj) 3867 self.__GetFvAttributes(FvObj) 3868 self.__GetAprioriSection(FvObj) 3869 self.__GetAprioriSection(FvObj) 3870 3871 while True: 3872 IsInf = self.__GetInfStatement(FvObj) 3873 IsFile = self.__GetFileStatement(FvObj) 3874 if not IsInf and not IsFile: 3875 break 3876 3877 if not self.__IsToken( "}"): 3878 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 3879 FvImageSectionObj.Fv = FvObj 3880 FvImageSectionObj.FvName = None 3881 3882 else: 3883 if not self.__IsKeyword("FV"): 3884 raise Warning("expected 'FV'", self.FileName, self.CurrentLineNumber) 3885 FvImageSectionObj.FvFileType = self.__Token 3886 3887 if self.__GetAlignment(): 3888 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): 3889 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 3890 FvImageSectionObj.Alignment = self.__Token 3891 3892 if self.__IsToken('|'): 3893 FvImageSectionObj.FvFileExtension = self.__GetFileExtension() 3894 elif self.__GetNextToken(): 3895 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ 3896 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"): 3897 FvImageSectionObj.FvFileName = self.__Token 3898 else: 3899 self.__UndoToken() 3900 else: 3901 raise Warning("expected FV file name", self.FileName, self.CurrentLineNumber) 3902 3903 Obj.SectionList.append(FvImageSectionObj) 3904 return True 3905 3906 EfiSectionObj = EfiSection.EfiSection() 3907 EfiSectionObj.SectionType = SectionName 3908 3909 if not self.__GetNextToken(): 3910 raise Warning("expected file type", self.FileName, self.CurrentLineNumber) 3911 3912 if self.__Token == "STRING": 3913 if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType): 3914 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) 3915 3916 if not self.__IsToken('='): 3917 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3918 3919 if not self.__GetNextToken(): 3920 raise Warning("expected Quoted String", self.FileName, self.CurrentLineNumber) 3921 3922 if self.__GetStringData(): 3923 EfiSectionObj.StringData = self.__Token 3924 3925 if self.__IsKeyword("BUILD_NUM"): 3926 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType): 3927 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) 3928 3929 if not self.__IsToken("="): 3930 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3931 if not self.__GetNextToken(): 3932 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber) 3933 EfiSectionObj.BuildNum = self.__Token 3934 3935 else: 3936 EfiSectionObj.FileType = self.__Token 3937 self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType) 3938 3939 if self.__IsKeyword("Optional"): 3940 if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType): 3941 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) 3942 EfiSectionObj.Optional = True 3943 3944 if self.__IsKeyword("BUILD_NUM"): 3945 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType): 3946 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) 3947 3948 if not self.__IsToken("="): 3949 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 3950 if not self.__GetNextToken(): 3951 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber) 3952 EfiSectionObj.BuildNum = self.__Token 3953 3954 if self.__GetAlignment(): 3955 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): 3956 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 3957 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'): 3958 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) 3959 EfiSectionObj.Alignment = self.__Token 3960 3961 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'): 3962 if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType): 3963 if self.__Token == 'RELOCS_STRIPPED': 3964 EfiSectionObj.KeepReloc = False 3965 else: 3966 EfiSectionObj.KeepReloc = True 3967 if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc: 3968 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber) 3969 else: 3970 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber) 3971 3972 3973 if self.__IsToken('|'): 3974 EfiSectionObj.FileExtension = self.__GetFileExtension() 3975 elif self.__GetNextToken(): 3976 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\ 3977 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"): 3978 3979 if self.__Token.startswith('PCD'): 3980 self.__UndoToken() 3981 self.__GetNextWord() 3982 3983 if self.__Token == 'PCD': 3984 if not self.__IsToken( "("): 3985 raise Warning("expected '('", self.FileName, self.CurrentLineNumber) 3986 PcdPair = self.__GetNextPcdName() 3987 if not self.__IsToken( ")"): 3988 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber) 3989 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')' 3990 3991 EfiSectionObj.FileName = self.__Token 3992 3993 else: 3994 self.__UndoToken() 3995 else: 3996 raise Warning("expected section file name", self.FileName, self.CurrentLineNumber) 3997 3998 Obj.SectionList.append(EfiSectionObj) 3999 return True 4000 4001 ## __RuleSectionCouldBeOptional() method 4002 # 4003 # Get whether a section could be optional 4004 # 4005 # @param self The object pointer 4006 # @param SectionType The section type to check 4007 # @retval True section could be optional 4008 # @retval False section never optional 4009 # 4010 def __RuleSectionCouldBeOptional(self, SectionType): 4011 if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"): 4012 return True 4013 else: 4014 return False 4015 4016 ## __RuleSectionCouldHaveBuildNum() method 4017 # 4018 # Get whether a section could have build number information 4019 # 4020 # @param self The object pointer 4021 # @param SectionType The section type to check 4022 # @retval True section could have build number information 4023 # @retval False section never have build number information 4024 # 4025 def __RuleSectionCouldHaveBuildNum(self, SectionType): 4026 if SectionType in ("VERSION"): 4027 return True 4028 else: 4029 return False 4030 4031 ## __RuleSectionCouldHaveString() method 4032 # 4033 # Get whether a section could have string 4034 # 4035 # @param self The object pointer 4036 # @param SectionType The section type to check 4037 # @retval True section could have string 4038 # @retval False section never have string 4039 # 4040 def __RuleSectionCouldHaveString(self, SectionType): 4041 if SectionType in ("UI", "VERSION"): 4042 return True 4043 else: 4044 return False 4045 4046 ## __CheckRuleSectionFileType() method 4047 # 4048 # Get whether a section matches a file type 4049 # 4050 # @param self The object pointer 4051 # @param SectionType The section type to check 4052 # @param FileType The file type to check 4053 # 4054 def __CheckRuleSectionFileType(self, SectionType, FileType): 4055 if SectionType == "COMPAT16": 4056 if FileType not in ("COMPAT16", "SEC_COMPAT16"): 4057 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) 4058 elif SectionType == "PE32": 4059 if FileType not in ("PE32", "SEC_PE32"): 4060 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) 4061 elif SectionType == "PIC": 4062 if FileType not in ("PIC", "PIC"): 4063 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) 4064 elif SectionType == "TE": 4065 if FileType not in ("TE", "SEC_TE"): 4066 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) 4067 elif SectionType == "RAW": 4068 if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"): 4069 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) 4070 elif SectionType == "DXE_DEPEX" or SectionType == "SMM_DEPEX": 4071 if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"): 4072 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) 4073 elif SectionType == "UI": 4074 if FileType not in ("UI", "SEC_UI"): 4075 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) 4076 elif SectionType == "VERSION": 4077 if FileType not in ("VERSION", "SEC_VERSION"): 4078 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) 4079 elif SectionType == "PEI_DEPEX": 4080 if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"): 4081 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) 4082 elif SectionType == "GUID": 4083 if FileType not in ("PE32", "SEC_GUID"): 4084 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber) 4085 4086 ## __GetRuleEncapsulationSection() method 4087 # 4088 # Get encapsulation section for Rule 4089 # 4090 # @param self The object pointer 4091 # @param Rule for whom section is got 4092 # @retval True Successfully find section statement 4093 # @retval False Not able to find section statement 4094 # 4095 def __GetRuleEncapsulationSection(self, Rule): 4096 4097 if self.__IsKeyword( "COMPRESS"): 4098 Type = "PI_STD" 4099 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"): 4100 Type = self.__Token 4101 4102 if not self.__IsToken("{"): 4103 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) 4104 4105 CompressSectionObj = CompressSection.CompressSection() 4106 4107 CompressSectionObj.CompType = Type 4108 # Recursive sections... 4109 while True: 4110 IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj) 4111 IsLeaf = self.__GetEfiSection(CompressSectionObj) 4112 if not IsEncapsulate and not IsLeaf: 4113 break 4114 4115 if not self.__IsToken( "}"): 4116 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 4117 Rule.SectionList.append(CompressSectionObj) 4118 4119 return True 4120 4121 elif self.__IsKeyword( "GUIDED"): 4122 GuidValue = None 4123 if self.__GetNextGuid(): 4124 GuidValue = self.__Token 4125 4126 if self.__IsKeyword( "$(NAMED_GUID)"): 4127 GuidValue = self.__Token 4128 4129 AttribDict = self.__GetGuidAttrib() 4130 4131 if not self.__IsToken("{"): 4132 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber) 4133 GuidSectionObj = GuidSection.GuidSection() 4134 GuidSectionObj.NameGuid = GuidValue 4135 GuidSectionObj.SectionType = "GUIDED" 4136 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"] 4137 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"] 4138 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"] 4139 4140 # Efi sections... 4141 while True: 4142 IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj) 4143 IsLeaf = self.__GetEfiSection(GuidSectionObj) 4144 if not IsEncapsulate and not IsLeaf: 4145 break 4146 4147 if not self.__IsToken( "}"): 4148 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) 4149 Rule.SectionList.append(GuidSectionObj) 4150 4151 return True 4152 4153 return False 4154 4155 ## __GetVtf() method 4156 # 4157 # Get VTF section contents and store its data into VTF list of self.Profile 4158 # 4159 # @param self The object pointer 4160 # @retval True Successfully find a VTF 4161 # @retval False Not able to find a VTF 4162 # 4163 def __GetVtf(self): 4164 4165 if not self.__GetNextToken(): 4166 return False 4167 4168 S = self.__Token.upper() 4169 if S.startswith("[") and not S.startswith("[VTF."): 4170 self.SectionParser(S) 4171 self.__UndoToken() 4172 return False 4173 4174 self.__UndoToken() 4175 if not self.__IsToken("[VTF.", True): 4176 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 4177 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ 4178 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) 4179 raise Warning("expected [VTF.]", self.FileName, self.CurrentLineNumber) 4180 4181 if not self.__SkipToToken("."): 4182 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber) 4183 4184 Arch = self.__SkippedChars.rstrip(".").upper() 4185 if Arch not in ("IA32", "X64", "IPF", "ARM", "AARCH64"): 4186 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber) 4187 4188 if not self.__GetNextWord(): 4189 raise Warning("expected VTF name", self.FileName, self.CurrentLineNumber) 4190 Name = self.__Token.upper() 4191 4192 VtfObj = Vtf.Vtf() 4193 VtfObj.UiName = Name 4194 VtfObj.KeyArch = Arch 4195 4196 if self.__IsToken(","): 4197 if not self.__GetNextWord(): 4198 raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber) 4199 if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"): 4200 raise Warning("Unknown Arch '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 4201 VtfObj.ArchList = self.__Token.upper() 4202 4203 if not self.__IsToken( "]"): 4204 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) 4205 4206 if self.__IsKeyword("IA32_RST_BIN"): 4207 if not self.__IsToken("="): 4208 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4209 4210 if not self.__GetNextToken(): 4211 raise Warning("expected Reset file", self.FileName, self.CurrentLineNumber) 4212 4213 VtfObj.ResetBin = self.__Token 4214 if VtfObj.ResetBin.replace('$(WORKSPACE)', '').find('$') == -1: 4215 #check for file path 4216 ErrorCode, ErrorInfo = PathClass(NormPath(VtfObj.ResetBin), GenFdsGlobalVariable.WorkSpaceDir).Validate() 4217 if ErrorCode != 0: 4218 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) 4219 4220 while self.__GetComponentStatement(VtfObj): 4221 pass 4222 4223 self.Profile.VtfList.append(VtfObj) 4224 return True 4225 4226 ## __GetComponentStatement() method 4227 # 4228 # Get components in VTF 4229 # 4230 # @param self The object pointer 4231 # @param VtfObj for whom component is got 4232 # @retval True Successfully find a component 4233 # @retval False Not able to find a component 4234 # 4235 def __GetComponentStatement(self, VtfObj): 4236 4237 if not self.__IsKeyword("COMP_NAME"): 4238 return False 4239 4240 if not self.__IsToken("="): 4241 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4242 4243 if not self.__GetNextWord(): 4244 raise Warning("expected Component Name", self.FileName, self.CurrentLineNumber) 4245 4246 CompStatementObj = ComponentStatement.ComponentStatement() 4247 CompStatementObj.CompName = self.__Token 4248 4249 if not self.__IsKeyword("COMP_LOC"): 4250 raise Warning("expected COMP_LOC", self.FileName, self.CurrentLineNumber) 4251 4252 if not self.__IsToken("="): 4253 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4254 4255 CompStatementObj.CompLoc = "" 4256 if self.__GetNextWord(): 4257 CompStatementObj.CompLoc = self.__Token 4258 if self.__IsToken('|'): 4259 if not self.__GetNextWord(): 4260 raise Warning("Expected Region Name", self.FileName, self.CurrentLineNumber) 4261 4262 if self.__Token not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support 4263 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 4264 4265 CompStatementObj.FilePos = self.__Token 4266 else: 4267 self.CurrentLineNumber += 1 4268 self.CurrentOffsetWithinLine = 0 4269 4270 if not self.__IsKeyword("COMP_TYPE"): 4271 raise Warning("expected COMP_TYPE", self.FileName, self.CurrentLineNumber) 4272 4273 if not self.__IsToken("="): 4274 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4275 4276 if not self.__GetNextToken(): 4277 raise Warning("expected Component type", self.FileName, self.CurrentLineNumber) 4278 if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"): 4279 if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \ 4280 not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]): 4281 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 4282 CompStatementObj.CompType = self.__Token 4283 4284 if not self.__IsKeyword("COMP_VER"): 4285 raise Warning("expected COMP_VER", self.FileName, self.CurrentLineNumber) 4286 4287 if not self.__IsToken("="): 4288 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4289 4290 if not self.__GetNextToken(): 4291 raise Warning("expected Component version", self.FileName, self.CurrentLineNumber) 4292 4293 Pattern = re.compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', re.DOTALL) 4294 if Pattern.match(self.__Token) == None: 4295 raise Warning("Unknown version format '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 4296 CompStatementObj.CompVer = self.__Token 4297 4298 if not self.__IsKeyword("COMP_CS"): 4299 raise Warning("expected COMP_CS", self.FileName, self.CurrentLineNumber) 4300 4301 if not self.__IsToken("="): 4302 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4303 4304 if not self.__GetNextToken(): 4305 raise Warning("expected Component CS", self.FileName, self.CurrentLineNumber) 4306 if self.__Token not in ("1", "0"): 4307 raise Warning("Unknown Component CS '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 4308 CompStatementObj.CompCs = self.__Token 4309 4310 4311 if not self.__IsKeyword("COMP_BIN"): 4312 raise Warning("expected COMP_BIN", self.FileName, self.CurrentLineNumber) 4313 4314 if not self.__IsToken("="): 4315 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4316 4317 if not self.__GetNextToken(): 4318 raise Warning("expected Component file", self.FileName, self.CurrentLineNumber) 4319 4320 CompStatementObj.CompBin = self.__Token 4321 if CompStatementObj.CompBin != '-' and CompStatementObj.CompBin.replace('$(WORKSPACE)', '').find('$') == -1: 4322 #check for file path 4323 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompBin), GenFdsGlobalVariable.WorkSpaceDir).Validate() 4324 if ErrorCode != 0: 4325 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) 4326 4327 if not self.__IsKeyword("COMP_SYM"): 4328 raise Warning("expected COMP_SYM", self.FileName, self.CurrentLineNumber) 4329 4330 if not self.__IsToken("="): 4331 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4332 4333 if not self.__GetNextToken(): 4334 raise Warning("expected Component symbol file", self.FileName, self.CurrentLineNumber) 4335 4336 CompStatementObj.CompSym = self.__Token 4337 if CompStatementObj.CompSym != '-' and CompStatementObj.CompSym.replace('$(WORKSPACE)', '').find('$') == -1: 4338 #check for file path 4339 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompSym), GenFdsGlobalVariable.WorkSpaceDir).Validate() 4340 if ErrorCode != 0: 4341 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) 4342 4343 if not self.__IsKeyword("COMP_SIZE"): 4344 raise Warning("expected COMP_SIZE", self.FileName, self.CurrentLineNumber) 4345 4346 if not self.__IsToken("="): 4347 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4348 4349 if self.__IsToken("-"): 4350 CompStatementObj.CompSize = self.__Token 4351 elif self.__GetNextDecimalNumber(): 4352 CompStatementObj.CompSize = self.__Token 4353 elif self.__GetNextHexNumber(): 4354 CompStatementObj.CompSize = self.__Token 4355 else: 4356 raise Warning("Unknown size '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 4357 4358 VtfObj.ComponentStatementList.append(CompStatementObj) 4359 return True 4360 4361 ## __GetOptionRom() method 4362 # 4363 # Get OptionROM section contents and store its data into OptionROM list of self.Profile 4364 # 4365 # @param self The object pointer 4366 # @retval True Successfully find a OptionROM 4367 # @retval False Not able to find a OptionROM 4368 # 4369 def __GetOptionRom(self): 4370 4371 if not self.__GetNextToken(): 4372 return False 4373 4374 S = self.__Token.upper() 4375 if S.startswith("[") and not S.startswith("[OPTIONROM."): 4376 self.SectionParser(S) 4377 self.__UndoToken() 4378 return False 4379 4380 self.__UndoToken() 4381 if not self.__IsToken("[OptionRom.", True): 4382 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) 4383 4384 OptRomName = self.__GetUiName() 4385 4386 if not self.__IsToken( "]"): 4387 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber) 4388 4389 OptRomObj = OptionRom.OPTIONROM() 4390 OptRomObj.DriverName = OptRomName 4391 self.Profile.OptRomDict[OptRomName] = OptRomObj 4392 4393 while True: 4394 isInf = self.__GetOptRomInfStatement(OptRomObj) 4395 isFile = self.__GetOptRomFileStatement(OptRomObj) 4396 if not isInf and not isFile: 4397 break 4398 4399 return True 4400 4401 ## __GetOptRomInfStatement() method 4402 # 4403 # Get INF statements 4404 # 4405 # @param self The object pointer 4406 # @param Obj for whom inf statement is got 4407 # @retval True Successfully find inf statement 4408 # @retval False Not able to find inf statement 4409 # 4410 def __GetOptRomInfStatement(self, Obj): 4411 4412 if not self.__IsKeyword( "INF"): 4413 return False 4414 4415 ffsInf = OptRomInfStatement.OptRomInfStatement() 4416 self.__GetInfOptions( ffsInf) 4417 4418 if not self.__GetNextToken(): 4419 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber) 4420 ffsInf.InfFileName = self.__Token 4421 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1: 4422 #check for file path 4423 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate() 4424 if ErrorCode != 0: 4425 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) 4426 4427 if not ffsInf.InfFileName in self.Profile.InfList: 4428 self.Profile.InfList.append(ffsInf.InfFileName) 4429 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) 4430 self.Profile.InfFileLineList.append(FileLineTuple) 4431 if ffsInf.UseArch: 4432 if ffsInf.UseArch not in self.Profile.InfDict: 4433 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName] 4434 else: 4435 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName) 4436 else: 4437 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName) 4438 4439 4440 self.__GetOptRomOverrides (ffsInf) 4441 4442 Obj.FfsList.append(ffsInf) 4443 return True 4444 4445 ## __GetOptRomOverrides() method 4446 # 4447 # Get overrides for OptROM INF & FILE 4448 # 4449 # @param self The object pointer 4450 # @param FfsInfObj for whom overrides is got 4451 # 4452 def __GetOptRomOverrides(self, Obj): 4453 if self.__IsToken('{'): 4454 Overrides = OptionRom.OverrideAttribs() 4455 while True: 4456 if self.__IsKeyword( "PCI_VENDOR_ID"): 4457 if not self.__IsToken( "="): 4458 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4459 if not self.__GetNextHexNumber(): 4460 raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber) 4461 Overrides.PciVendorId = self.__Token 4462 continue 4463 4464 if self.__IsKeyword( "PCI_CLASS_CODE"): 4465 if not self.__IsToken( "="): 4466 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4467 if not self.__GetNextHexNumber(): 4468 raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber) 4469 Overrides.PciClassCode = self.__Token 4470 continue 4471 4472 if self.__IsKeyword( "PCI_DEVICE_ID"): 4473 if not self.__IsToken( "="): 4474 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4475 if not self.__GetNextHexNumber(): 4476 raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber) 4477 4478 Overrides.PciDeviceId = self.__Token 4479 continue 4480 4481 if self.__IsKeyword( "PCI_REVISION"): 4482 if not self.__IsToken( "="): 4483 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4484 if not self.__GetNextHexNumber(): 4485 raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber) 4486 Overrides.PciRevision = self.__Token 4487 continue 4488 4489 if self.__IsKeyword( "PCI_COMPRESS"): 4490 if not self.__IsToken( "="): 4491 raise Warning("expected '='", self.FileName, self.CurrentLineNumber) 4492 if not self.__GetNextToken(): 4493 raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber) 4494 Overrides.NeedCompress = self.__Token.upper() == 'TRUE' 4495 continue 4496 4497 if self.__IsToken( "}"): 4498 break 4499 else: 4500 EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber) 4501 4502 Obj.OverrideAttribs = Overrides 4503 4504 ## __GetOptRomFileStatement() method 4505 # 4506 # Get FILE statements 4507 # 4508 # @param self The object pointer 4509 # @param Obj for whom FILE statement is got 4510 # @retval True Successfully find FILE statement 4511 # @retval False Not able to find FILE statement 4512 # 4513 def __GetOptRomFileStatement(self, Obj): 4514 4515 if not self.__IsKeyword( "FILE"): 4516 return False 4517 4518 FfsFileObj = OptRomFileStatement.OptRomFileStatement() 4519 4520 if not self.__IsKeyword("EFI") and not self.__IsKeyword("BIN"): 4521 raise Warning("expected Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber) 4522 FfsFileObj.FileType = self.__Token 4523 4524 if not self.__GetNextToken(): 4525 raise Warning("expected File path", self.FileName, self.CurrentLineNumber) 4526 FfsFileObj.FileName = self.__Token 4527 if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1: 4528 #check for file path 4529 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate() 4530 if ErrorCode != 0: 4531 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) 4532 4533 if FfsFileObj.FileType == 'EFI': 4534 self.__GetOptRomOverrides(FfsFileObj) 4535 4536 Obj.FfsList.append(FfsFileObj) 4537 4538 return True 4539 4540 ## __GetCapInFd() method 4541 # 4542 # Get Cap list contained in FD 4543 # 4544 # @param self The object pointer 4545 # @param FdName FD name 4546 # @retval CapList List of Capsule in FD 4547 # 4548 def __GetCapInFd (self, FdName): 4549 4550 CapList = [] 4551 if FdName.upper() in self.Profile.FdDict.keys(): 4552 FdObj = self.Profile.FdDict[FdName.upper()] 4553 for elementRegion in FdObj.RegionList: 4554 if elementRegion.RegionType == 'CAPSULE': 4555 for elementRegionData in elementRegion.RegionDataList: 4556 if elementRegionData.endswith(".cap"): 4557 continue 4558 if elementRegionData != None and elementRegionData.upper() not in CapList: 4559 CapList.append(elementRegionData.upper()) 4560 return CapList 4561 4562 ## __GetReferencedFdCapTuple() method 4563 # 4564 # Get FV and FD list referenced by a capsule image 4565 # 4566 # @param self The object pointer 4567 # @param CapObj Capsule section to be searched 4568 # @param RefFdList referenced FD by section 4569 # @param RefFvList referenced FV by section 4570 # 4571 def __GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []): 4572 4573 for CapsuleDataObj in CapObj.CapsuleDataList : 4574 if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName != None and CapsuleDataObj.FvName.upper() not in RefFvList: 4575 RefFvList.append (CapsuleDataObj.FvName.upper()) 4576 elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName != None and CapsuleDataObj.FdName.upper() not in RefFdList: 4577 RefFdList.append (CapsuleDataObj.FdName.upper()) 4578 elif CapsuleDataObj.Ffs != None: 4579 if isinstance(CapsuleDataObj.Ffs, FfsFileStatement.FileStatement): 4580 if CapsuleDataObj.Ffs.FvName != None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList: 4581 RefFvList.append(CapsuleDataObj.Ffs.FvName.upper()) 4582 elif CapsuleDataObj.Ffs.FdName != None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList: 4583 RefFdList.append(CapsuleDataObj.Ffs.FdName.upper()) 4584 else: 4585 self.__GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList) 4586 4587 ## __GetFvInFd() method 4588 # 4589 # Get FV list contained in FD 4590 # 4591 # @param self The object pointer 4592 # @param FdName FD name 4593 # @retval FvList list of FV in FD 4594 # 4595 def __GetFvInFd (self, FdName): 4596 4597 FvList = [] 4598 if FdName.upper() in self.Profile.FdDict.keys(): 4599 FdObj = self.Profile.FdDict[FdName.upper()] 4600 for elementRegion in FdObj.RegionList: 4601 if elementRegion.RegionType == 'FV': 4602 for elementRegionData in elementRegion.RegionDataList: 4603 if elementRegionData.endswith(".fv"): 4604 continue 4605 if elementRegionData != None and elementRegionData.upper() not in FvList: 4606 FvList.append(elementRegionData.upper()) 4607 return FvList 4608 4609 ## __GetReferencedFdFvTuple() method 4610 # 4611 # Get FD and FV list referenced by a FFS file 4612 # 4613 # @param self The object pointer 4614 # @param FfsFile contains sections to be searched 4615 # @param RefFdList referenced FD by section 4616 # @param RefFvList referenced FV by section 4617 # 4618 def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []): 4619 4620 for FfsObj in FvObj.FfsList: 4621 if isinstance(FfsObj, FfsFileStatement.FileStatement): 4622 if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList: 4623 RefFvList.append(FfsObj.FvName.upper()) 4624 elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList: 4625 RefFdList.append(FfsObj.FdName.upper()) 4626 else: 4627 self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList) 4628 4629 ## __GetReferencedFdFvTupleFromSection() method 4630 # 4631 # Get FD and FV list referenced by a FFS section 4632 # 4633 # @param self The object pointer 4634 # @param FfsFile contains sections to be searched 4635 # @param FdList referenced FD by section 4636 # @param FvList referenced FV by section 4637 # 4638 def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []): 4639 4640 SectionStack = [] 4641 SectionStack.extend(FfsFile.SectionList) 4642 while SectionStack != []: 4643 SectionObj = SectionStack.pop() 4644 if isinstance(SectionObj, FvImageSection.FvImageSection): 4645 if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList: 4646 FvList.append(SectionObj.FvName.upper()) 4647 if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList: 4648 FvList.append(SectionObj.Fv.UiFvName.upper()) 4649 self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList) 4650 4651 if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection): 4652 SectionStack.extend(SectionObj.SectionList) 4653 4654 ## CycleReferenceCheck() method 4655 # 4656 # Check whether cycle reference exists in FDF 4657 # 4658 # @param self The object pointer 4659 # @retval True cycle reference exists 4660 # @retval False Not exists cycle reference 4661 # 4662 def CycleReferenceCheck(self): 4663 # 4664 # Check the cycle between FV and FD image 4665 # 4666 MaxLength = len (self.Profile.FvDict) 4667 for FvName in self.Profile.FvDict.keys(): 4668 LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName 4669 RefFvStack = [] 4670 RefFvStack.append(FvName) 4671 FdAnalyzedList = [] 4672 4673 Index = 0 4674 while RefFvStack != [] and Index < MaxLength: 4675 Index = Index + 1 4676 FvNameFromStack = RefFvStack.pop() 4677 if FvNameFromStack.upper() in self.Profile.FvDict.keys(): 4678 FvObj = self.Profile.FvDict[FvNameFromStack.upper()] 4679 else: 4680 continue 4681 4682 RefFdList = [] 4683 RefFvList = [] 4684 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList) 4685 4686 for RefFdName in RefFdList: 4687 if RefFdName in FdAnalyzedList: 4688 continue 4689 4690 LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName) 4691 FvInFdList = self.__GetFvInFd(RefFdName) 4692 if FvInFdList != []: 4693 for FvNameInFd in FvInFdList: 4694 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd) 4695 if FvNameInFd not in RefFvStack: 4696 RefFvStack.append(FvNameInFd) 4697 4698 if FvName in RefFvStack or FvNameFromStack in RefFvStack: 4699 EdkLogger.info(LogStr) 4700 return True 4701 FdAnalyzedList.append(RefFdName) 4702 4703 for RefFvName in RefFvList: 4704 LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName) 4705 if RefFvName not in RefFvStack: 4706 RefFvStack.append(RefFvName) 4707 4708 if FvName in RefFvStack or FvNameFromStack in RefFvStack: 4709 EdkLogger.info(LogStr) 4710 return True 4711 4712 # 4713 # Check the cycle between Capsule and FD image 4714 # 4715 MaxLength = len (self.Profile.CapsuleDict) 4716 for CapName in self.Profile.CapsuleDict.keys(): 4717 # 4718 # Capsule image to be checked. 4719 # 4720 LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName 4721 RefCapStack = [] 4722 RefCapStack.append(CapName) 4723 FdAnalyzedList = [] 4724 FvAnalyzedList = [] 4725 4726 Index = 0 4727 while RefCapStack != [] and Index < MaxLength: 4728 Index = Index + 1 4729 CapNameFromStack = RefCapStack.pop() 4730 if CapNameFromStack.upper() in self.Profile.CapsuleDict.keys(): 4731 CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()] 4732 else: 4733 continue 4734 4735 RefFvList = [] 4736 RefFdList = [] 4737 self.__GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList) 4738 4739 FvListLength = 0 4740 FdListLength = 0 4741 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList): 4742 for RefFdName in RefFdList: 4743 if RefFdName in FdAnalyzedList: 4744 continue 4745 4746 LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName) 4747 CapInFdList = self.__GetCapInFd(RefFdName) 4748 if CapInFdList != []: 4749 for CapNameInFd in CapInFdList: 4750 LogStr += "FD %s contains Capsule %s\n" % (RefFdName,CapNameInFd) 4751 if CapNameInFd not in RefCapStack: 4752 RefCapStack.append(CapNameInFd) 4753 4754 if CapName in RefCapStack or CapNameFromStack in RefCapStack: 4755 EdkLogger.info(LogStr) 4756 return True 4757 4758 FvInFdList = self.__GetFvInFd(RefFdName) 4759 if FvInFdList != []: 4760 for FvNameInFd in FvInFdList: 4761 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd) 4762 if FvNameInFd not in RefFvList: 4763 RefFvList.append(FvNameInFd) 4764 4765 FdAnalyzedList.append(RefFdName) 4766 # 4767 # the number of the parsed FV and FD image 4768 # 4769 FvListLength = len (RefFvList) 4770 FdListLength = len (RefFdList) 4771 for RefFvName in RefFvList: 4772 if RefFvName in FvAnalyzedList: 4773 continue 4774 LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName) 4775 if RefFvName.upper() in self.Profile.FvDict.keys(): 4776 FvObj = self.Profile.FvDict[RefFvName.upper()] 4777 else: 4778 continue 4779 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList) 4780 FvAnalyzedList.append(RefFvName) 4781 4782 return False 4783 4784 if __name__ == "__main__": 4785 import sys 4786 try: 4787 test_file = sys.argv[1] 4788 except IndexError, v: 4789 print "Usage: %s filename" % sys.argv[0] 4790 sys.exit(1) 4791 4792 parser = FdfParser(test_file) 4793 try: 4794 parser.ParseFile() 4795 parser.CycleReferenceCheck() 4796 except Warning, X: 4797 print str(X) 4798 else: 4799 print "Success!" 4800 4801