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