]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/Xml/XmlParser.py
BaseTools: Clear build versions to sync with buildtools/BaseTools
[mirror_edk2.git] / BaseTools / Source / Python / UPT / Xml / XmlParser.py
1 ## @file
2 # This file is used to parse a xml file of .PKG file
3 #
4 # Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
5 #
6 # This program and the accompanying materials are licensed and made available
7 # under the terms and conditions of the BSD License which accompanies this
8 # distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 #
14
15 '''
16 XmlParser
17 '''
18
19 ##
20 # Import Modules
21 #
22 import re
23
24 from Library.Xml.XmlRoutines import XmlNode
25 from Library.Xml.XmlRoutines import CreateXmlElement
26 from Library.Xml.XmlRoutines import XmlList
27 from Library.Xml.XmlRoutines import XmlParseFile
28 from Core.DistributionPackageClass import DistributionPackageClass
29 from Object.POM.ModuleObject import DepexObject
30 from Library.ParserValidate import IsValidInfMoudleType
31 from Library.ParserValidate import IsValidInstallPath
32 from Library.Misc import IsEqualList
33 from Library.Misc import Sdict
34
35 from Logger.StringTable import ERR_XML_INVALID_VARIABLENAME
36 from Logger.StringTable import ERR_XML_INVALID_LIB_SUPMODLIST
37 from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPARCHLIST
38 from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPMODLIST
39 from Logger.StringTable import ERR_XML_INVALID_EXTERN_SUPMODLIST_NOT_LIB
40 from Logger.StringTable import ERR_FILE_NAME_INVALIDE
41 from Logger.StringTable import ERR_XML_INVALID_BINARY_FILE_TYPE
42 from Logger.ToolError import PARSER_ERROR
43 from Logger.ToolError import FORMAT_INVALID
44
45 from Xml.CommonXml import DistributionPackageHeaderXml
46 from Xml.CommonXml import MiscellaneousFileXml
47 from Xml.CommonXml import UserExtensionsXml
48 from Xml.XmlParserMisc import ConvertVariableName
49 from Xml.XmlParserMisc import IsRequiredItemListNull
50 from Xml.ModuleSurfaceAreaXml import ModuleSurfaceAreaXml
51 from Xml.PackageSurfaceAreaXml import PackageSurfaceAreaXml
52
53 import Logger.Log as Logger
54
55 ##
56 # DistributionPackageXml
57 #
58 class DistributionPackageXml(object):
59 def __init__(self):
60 self.DistP = DistributionPackageClass()
61 self.Pkg = ''
62
63 ## ValidateDistributionPackage
64 #
65 # Check if any required item is missing in DistributionPackage
66 #
67 def ValidateDistributionPackage(self):
68 XmlTreeLevel = ['DistributionPackage']
69 if self.DistP:
70 #
71 # Check DistributionPackage -> DistributionHeader
72 #
73 XmlTreeLevel = ['DistributionPackage', '']
74 CheckDict = {'DistributionHeader':self.DistP.Header }
75 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
76
77 if self.DistP.Header:
78 DpHeader = self.DistP.Header
79 XmlTreeLevel = ['DistributionPackage', 'DistributionHeader']
80 CheckDict = Sdict()
81 CheckDict['Name'] = DpHeader.GetName()
82 CheckDict['GUID'] = DpHeader.GetGuid()
83 CheckDict['Version'] = DpHeader.GetVersion()
84 CheckDict['Copyright'] = DpHeader.GetCopyright()
85 CheckDict['License'] = DpHeader.GetLicense()
86 CheckDict['Abstract'] = DpHeader.GetAbstract()
87 CheckDict['Vendor'] = DpHeader.GetVendor()
88 CheckDict['Date'] = DpHeader.GetDate()
89 CheckDict['XmlSpecification'] = DpHeader.GetXmlSpecification()
90
91 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
92 else:
93 XmlTreeLevel = ['DistributionPackage', 'DistributionHeader']
94 CheckDict = CheckDict = {'DistributionHeader':'', }
95 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
96
97 #
98 # Check Each Package
99 #
100 for Key in self.DistP.PackageSurfaceArea:
101 ValidatePackageSurfaceArea(self.DistP.PackageSurfaceArea[Key])
102
103 #
104 # Check Each Module
105 #
106 for Key in self.DistP.ModuleSurfaceArea:
107 ValidateMS(self.DistP.ModuleSurfaceArea[Key], ['DistributionPackage', 'ModuleSurfaceArea'])
108
109 #
110 # Check Each Tool
111 #
112 if self.DistP.Tools:
113 XmlTreeLevel = ['DistributionPackage', 'Tools', 'Header']
114 CheckDict = {'Name':self.DistP.Tools.GetName(), }
115 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
116
117 if not self.DistP.Tools.GetFileList():
118 XmlTreeLevel = ['DistributionPackage', 'Tools']
119 CheckDict = {'FileName':None, }
120 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
121 for Item in self.DistP.Tools.GetFileList():
122 XmlTreeLevel = ['DistributionPackage', 'Tools']
123 CheckDict = {'FileName':Item.GetURI(), }
124 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
125
126 #
127 # Check Each Misc File
128 #
129 if self.DistP.MiscellaneousFiles:
130 XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles', 'Header']
131 CheckDict = {'Name':self.DistP.MiscellaneousFiles.GetName(), }
132 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
133
134 if not self.DistP.MiscellaneousFiles.GetFileList():
135 XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles']
136 CheckDict = {'FileName':None, }
137 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
138 for Item in self.DistP.MiscellaneousFiles.GetFileList():
139 XmlTreeLevel = ['DistributionPackage', 'MiscellaneousFiles']
140 CheckDict = {'FileName':Item.GetURI(), }
141 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
142
143 #
144 # Check Each Distribution Level User Extension
145 #
146 for Item in self.DistP.UserExtensions:
147 XmlTreeLevel = ['DistributionPackage', 'UserExtensions']
148 CheckDict = {'UserId':Item.GetUserID(), }
149 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
150
151
152 def FromXml(self, Filename=None):
153 if Filename != None:
154 self.DistP = DistributionPackageClass()
155 #
156 # Load to XML
157 #
158 self.Pkg = XmlParseFile(Filename)
159
160 #
161 # Parse Header information
162 #
163 Tmp = DistributionPackageHeaderXml()
164 DistributionPackageHeader = \
165 Tmp.FromXml(XmlNode(self.Pkg, '/DistributionPackage/DistributionHeader'), 'DistributionHeader')
166 self.DistP.Header = DistributionPackageHeader
167 #
168 # Parse each PackageSurfaceArea
169 #
170 for Item in XmlList(self.Pkg, '/DistributionPackage/PackageSurfaceArea'):
171 Psa = PackageSurfaceAreaXml()
172 Package = Psa.FromXml(Item, 'PackageSurfaceArea')
173 self.DistP.PackageSurfaceArea[(Package.GetGuid(), \
174 Package.GetVersion(), \
175 Package.GetPackagePath())] = \
176 Package
177 #
178 # Parse each ModuleSurfaceArea
179 #
180 for Item in XmlList(self.Pkg, '/DistributionPackage/ModuleSurfaceArea'):
181 Msa = ModuleSurfaceAreaXml()
182 Module = Msa.FromXml(Item, 'ModuleSurfaceArea', True)
183 ModuleKey = (Module.GetGuid(), Module.GetVersion(), Module.GetName(), Module.GetModulePath())
184 self.DistP.ModuleSurfaceArea[ModuleKey] = Module
185
186 #
187 # Parse Tools
188 #
189 Tmp = MiscellaneousFileXml()
190 self.DistP.Tools = Tmp.FromXml2(XmlNode(self.Pkg, '/DistributionPackage/Tools'), 'Tools')
191
192 #
193 # Parse MiscFiles
194 #
195 Tmp = MiscellaneousFileXml()
196 self.DistP.MiscellaneousFiles = \
197 Tmp.FromXml2(XmlNode(self.Pkg, \
198 '/DistributionPackage/MiscellaneousFiles'), \
199 'MiscellaneousFiles')
200
201 #
202 # Parse UserExtensions
203 #
204 for Item in XmlList(self.Pkg, '/DistributionPackage/UserExtensions'):
205 Tmp = UserExtensionsXml()
206 self.DistP.UserExtensions.append(Tmp.FromXml2(Item, 'UserExtensions'))
207
208 #
209 # Check Required Items for XML
210 #
211 self.ValidateDistributionPackage()
212
213 return self.DistP
214
215 def ToXml(self, DistP):
216 if self.DistP:
217 pass
218 if DistP != None:
219 #
220 # Parse DistributionPackageHeader
221 #
222 Attrs = [['xmlns', 'http://www.uefi.org/2011/1.1'],
223 ['xmlns:xsi', 'http:/www.w3.org/2001/XMLSchema-instance'],
224 ]
225 Root = CreateXmlElement('DistributionPackage', '', [], Attrs)
226
227 Tmp = DistributionPackageHeaderXml()
228 Root.appendChild(Tmp.ToXml(DistP.Header, 'DistributionHeader'))
229 #
230 # Parse each PackageSurfaceArea
231 #
232 for Package in DistP.PackageSurfaceArea.values():
233 Psa = PackageSurfaceAreaXml()
234 DomPackage = Psa.ToXml(Package)
235 Root.appendChild(DomPackage)
236 #
237 # Parse each ModuleSurfaceArea
238 #
239 for Module in DistP.ModuleSurfaceArea.values():
240 Msa = ModuleSurfaceAreaXml()
241 DomModule = Msa.ToXml(Module)
242 Root.appendChild(DomModule)
243 #
244 # Parse Tools
245 #
246 Tmp = MiscellaneousFileXml()
247 ToolNode = Tmp.ToXml2(DistP.Tools, 'Tools')
248 if ToolNode is not None:
249 Root.appendChild(ToolNode)
250 #
251 # Parse MiscFiles
252 #
253 Tmp = MiscellaneousFileXml()
254 MiscFileNode = Tmp.ToXml2(DistP.MiscellaneousFiles,
255 'MiscellaneousFiles')
256 if MiscFileNode is not None:
257 Root.appendChild(MiscFileNode)
258
259 XmlContent = Root.toprettyxml(indent=' ')
260
261
262 #
263 # Remove empty element
264 #
265 XmlContent = re.sub(r'[\s\r\n]*<[^<>=]*/>', '', XmlContent)
266
267 #
268 # Remove empty help text element
269 #
270 XmlContent = re.sub(r'[\s\r\n]*<HelpText Lang="en-US"/>', '',
271 XmlContent)
272
273 #
274 # Remove SupArchList="COMMON" or "common"
275 #
276 XmlContent = \
277 re.sub(r'[\s\r\n]*SupArchList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*COMMON'
278 '[\s\r\n]*"', '', XmlContent)
279 XmlContent = \
280 re.sub(r'[\s\r\n]*SupArchList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*common'
281 '[\s\r\n]*"', '', XmlContent)
282 #
283 # Remove <SupArchList> COMMON </SupArchList>
284 #
285 XmlContent = \
286 re.sub(r'[\s\r\n]*<SupArchList>[\s\r\n]*COMMON[\s\r\n]*'
287 '</SupArchList>[\s\r\n]*', '', XmlContent)
288
289 #
290 # Remove <SupArchList> common </SupArchList>
291 #
292 XmlContent = \
293 re.sub(r'[\s\r\n]*<SupArchList>[\s\r\n]*'
294 'common[\s\r\n]*</SupArchList>[\s\r\n]*', '', XmlContent)
295
296 #
297 # Remove SupModList="COMMON" or "common"
298 #
299 XmlContent = \
300 re.sub(r'[\s\r\n]*SupModList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*COMMON'
301 '[\s\r\n]*"', '', XmlContent)
302 XmlContent = \
303 re.sub(r'[\s\r\n]*SupModList[\s\r\n]*=[\s\r\n]*"[\s\r\n]*common'
304 '[\s\r\n]*"', '', XmlContent)
305
306 return XmlContent
307
308 return ''
309
310 ## ValidateMS
311 #
312 # Check if any required item is missing in ModuleSurfaceArea
313 #
314 # @param Module: The ModuleSurfaceArea to be checked
315 # @param XmlTreeLevel: The top level of Module
316 #
317 def ValidateMS(Module, TopXmlTreeLevel):
318 ValidateMS1(Module, TopXmlTreeLevel)
319 ValidateMS2(Module, TopXmlTreeLevel)
320 ValidateMS3(Module, TopXmlTreeLevel)
321
322 ## ValidateMS1
323 #
324 # Check if any required item is missing in ModuleSurfaceArea
325 #
326 # @param Module: The ModuleSurfaceArea to be checked
327 # @param XmlTreeLevel: The top level of Module
328 #
329 def ValidateMS1(Module, TopXmlTreeLevel):
330 #
331 # Check Guids -> GuidCName
332 #
333 XmlTreeLevel = TopXmlTreeLevel + ['Guids']
334 for Item in Module.GetGuidList():
335 if Item == None:
336 CheckDict = {'GuidCName':''}
337 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
338
339 XmlTreeLevel = TopXmlTreeLevel + ['Guids', 'GuidCName']
340 for Item in Module.GetGuidList():
341 CheckDict = {'CName':Item.GetCName(),
342 'GuidType':Item.GetGuidTypeList(),
343 'Usage':Item.GetUsage()}
344 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
345
346 if Item.GetVariableName():
347 Result = ConvertVariableName(Item.GetVariableName())
348 if Result is None:
349 Msg = "->".join(Node for Node in XmlTreeLevel)
350 ErrorMsg = ERR_XML_INVALID_VARIABLENAME % (Item.GetVariableName(), Item.GetCName(), Msg)
351 Logger.Error('\nUPT', PARSER_ERROR, ErrorMsg, RaiseError=True)
352 else:
353 Item.SetVariableName(Result)
354
355 #
356 # Check Protocols -> Protocol
357 #
358 XmlTreeLevel = TopXmlTreeLevel + ['Protocols']
359 for Item in Module.GetProtocolList():
360 if Item == None:
361 CheckDict = {'Protocol':''}
362 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
363
364 XmlTreeLevel = TopXmlTreeLevel + ['Protocols', 'Protocol']
365 for Item in Module.GetProtocolList():
366 CheckDict = {'CName':Item.GetCName(),
367 'Usage':Item.GetUsage()}
368 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
369
370 #
371 # Check PPIs -> Ppi
372 #
373 XmlTreeLevel = TopXmlTreeLevel + ['PPIs']
374 for Item in Module.GetPpiList():
375 if Item == None:
376 CheckDict = {'Ppi':''}
377 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
378
379 XmlTreeLevel = TopXmlTreeLevel + ['PPIs', 'Ppi']
380 for Item in Module.GetPpiList():
381 CheckDict = {'CName':Item.GetCName(),
382 'Usage':Item.GetUsage()}
383 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
384
385 #
386 # Check PcdCoded -> Entry
387 #
388 XmlTreeLevel = TopXmlTreeLevel + ['PcdCoded']
389 for Item in Module.GetPcdList():
390 if Item == None:
391 CheckDict = {'PcdEntry':''}
392 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
393
394 XmlTreeLevel = TopXmlTreeLevel + ['PcdCoded', 'PcdEntry']
395 for Item in Module.GetPcdList():
396 CheckDict = {'TokenSpaceGuidCname':Item.GetTokenSpaceGuidCName(),
397 'CName':Item.GetCName(),
398 'PcdUsage':Item.GetValidUsage(),
399 'PcdItemType':Item.GetItemType()}
400 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
401
402 #
403 # Check Externs -> Extern
404 #
405 XmlTreeLevel = TopXmlTreeLevel + ['Externs']
406 for Item in Module.GetExternList():
407 if Item == None:
408 CheckDict = {'Extern':''}
409 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
410
411 #
412 # If SupArchList is used to identify different EntryPoint, UnloadImage, Constructor/Destructor elements and
413 # that SupArchList does not match ModuleSurfaceArea.ModuleProperties:SupArchList, the tool must exit gracefully,
414 # informing the user that the EDK II Build system does not support different EntryPoint, UnloadImage,
415 # Constructor or Destructor elements based on Architecture type. Two SupArchList attributes are considered
416 # identical if it lists the same CPU architectures in any order.
417 #
418 for Item in Module.GetExternList():
419 if len(Item.SupArchList) > 0:
420 if not IsEqualList(Item.SupArchList, Module.SupArchList):
421 Logger.Error('\nUPT',
422 PARSER_ERROR,
423 ERR_XML_INVALID_EXTERN_SUPARCHLIST % (str(Item.SupArchList), str(Module.SupArchList)),
424 RaiseError=True)
425
426 #
427 # Check DistributionPackage -> ModuleSurfaceArea -> UserExtensions
428 #
429 XmlTreeLevel = TopXmlTreeLevel + ['UserExtensions']
430 for Item in Module.GetUserExtensionList():
431 CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
432 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
433
434 #
435 # Check DistributionPackage -> PackageSurfaceArea -> MiscellaneousFiles -> Filename
436 #
437 XmlTreeLevel = TopXmlTreeLevel + ['MiscellaneousFiles']
438 for Item in Module.GetMiscFileList():
439 if not Item.GetFileList():
440 CheckDict = {'Filename':'', }
441 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
442 for File in Item.GetFileList():
443 CheckDict = {'Filename':File.GetURI(), }
444
445 ## ValidateMS2
446 #
447 # Check if any required item is missing in ModuleSurfaceArea
448 #
449 # @param Module: The ModuleSurfaceArea to be checked
450 # @param XmlTreeLevel: The top level of Module
451 #
452 def ValidateMS2(Module, TopXmlTreeLevel):
453 #
454 # Check Header
455 #
456 XmlTreeLevel = TopXmlTreeLevel + ['Header']
457 CheckDict = Sdict()
458 CheckDict['Name'] = Module.GetName()
459 CheckDict['BaseName'] = Module.GetBaseName()
460 CheckDict['GUID'] = Module.GetGuid()
461 CheckDict['Version'] = Module.GetVersion()
462 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
463
464 #
465 # Check ModuleProperties
466 #
467 XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties']
468 CheckDict = {'ModuleType':Module.GetModuleType(),
469 'Path':Module.GetModulePath()}
470 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
471
472 if not IsValidInstallPath(Module.GetModulePath()):
473 Logger.Error("UPT", FORMAT_INVALID, ERR_FILE_NAME_INVALIDE % Module.GetModulePath())
474
475 #
476 # Check ModuleProperties->BootMode
477 #
478 XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['BootMode']
479 for Item in Module.GetBootModeList():
480 CheckDict = {'Usage':Item.GetUsage(),
481 'SupportedBootModes':Item.GetSupportedBootModes()}
482 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
483
484 #
485 # Check ModuleProperties->Event
486 #
487 XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['Event']
488 for Item in Module.GetEventList():
489 CheckDict = {'Usage':Item.GetUsage(),
490 'EventType':Item.GetEventType()}
491 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
492
493 #
494 # Check ModuleProperties->Hob
495 #
496 XmlTreeLevel = TopXmlTreeLevel + ['ModuleProperties'] + ['HOB']
497 for Item in Module.GetHobList():
498 CheckDict = {'Usage':Item.GetUsage(),
499 'HobType':Item.GetHobType()}
500 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
501
502 #
503 # The UDP Specification supports the module type of UEFI_RUNTIME_DRIVER, which is not present in the EDK II INF
504 # File Specification v. 1.23, so UPT must perform the following translation that include the generation of a
505 # [Depex] section.
506 #
507 if Module.ModuleType == "UEFI_RUNTIME_DRIVER":
508 Module.ModuleType = "DXE_RUNTIME_DRIVER"
509 DxeObj = DepexObject()
510 DxeObj.SetDepex("gEfiBdsArchProtocolGuid AND \ngEfiCpuArchProtocolGuid AND\n" + \
511 "gEfiMetronomeArchProtocolGuid AND \ngEfiMonotonicCounterArchProtocolGuid AND\n" + \
512 "gEfiRealTimeClockArchProtocolGuid AND \ngEfiResetArchProtocolGuid AND\n" + \
513 "gEfiRuntimeArchProtocolGuid AND \ngEfiSecurityArchProtocolGuid AND\n" + \
514 "gEfiTimerArchProtocolGuid AND \ngEfiVariableWriteArchProtocolGuid AND\n" + \
515 "gEfiVariableArchProtocolGuid AND \ngEfiWatchdogTimerArchProtocolGuid")
516 DxeObj.SetModuleType(['DXE_RUNTIME_DRIVER'])
517 Module.PeiDepex = []
518 Module.DxeDepex = []
519 Module.SmmDepex = []
520 Module.DxeDepex.append(DxeObj)
521
522 #
523 # Check LibraryClassDefinitions -> LibraryClass
524 #
525 XmlTreeLevel = TopXmlTreeLevel + ['LibraryClassDefinitions']
526 for Item in Module.GetLibraryClassList():
527 if Item == None:
528 CheckDict = {'LibraryClass':''}
529 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
530
531 XmlTreeLevel = TopXmlTreeLevel + ['LibraryClassDefinitions', 'LibraryClass']
532
533 IsLibraryModule = False
534 LibrarySupModList = []
535 for Item in Module.GetLibraryClassList():
536 CheckDict = {'Keyword':Item.GetLibraryClass(),
537 'Usage':Item.GetUsage()}
538 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
539 #
540 # If the LibraryClass:SupModList is not "UNDEFINED" the LIBRARY_CLASS entry must have the list
541 # appended using the format:
542 # LIBRARY_CLASS = <ClassName> ["|" <Edk2ModuleTypeList>]
543 #
544 # Edk2ModuleTypeList ::= <ModuleType> [" " <ModuleType>]{0,}
545 # <ModuleTypes> ::= {"BASE"} {"SEC"} {"PEI_CORE"} {"PEIM"}
546 # {"DXE_CORE"} {"DXE_DRIVER"} {"SMM_CORE"}
547 # {"DXE_SMM_DRIVER"} {"DXE_RUNTIME_DRIVER"}
548 # {"DXE_SAL_DRIVER"} {"UEFI_DRIVER"}
549 # {"UEFI_APPLICATION"} {"USER_DEFINED"}
550 #
551 if len(Item.SupModuleList) > 0:
552 for SupModule in Item.SupModuleList:
553 if not IsValidInfMoudleType(SupModule):
554 Logger.Error('\nUPT',
555 PARSER_ERROR,
556 ERR_XML_INVALID_LIB_SUPMODLIST % (Item.LibraryClass, str(SupModule)),
557 RaiseError=True)
558
559 if Item.Usage == 'PRODUCES' or Item.Usage == 'SOMETIMES_PRODUCES':
560 IsLibraryModule = True
561 LibrarySupModList = Item.SupModuleList
562
563
564 #
565 # For Library modules (indicated by a LIBRARY_CLASS statement in the [Defines] section)
566 # If the SupModList attribute of the CONSTRUCTOR or DESTRUCTOR element does not match the Supported Module
567 # Types listed after "LIBRARY_CLASS = <Keyword> |", the tool should gracefully exit with an error message
568 # stating that there is a conflict in the module types the CONSTRUCTOR/DESTRUCTOR is to be used with and
569 # the Module types this Library supports.
570 #
571 if IsLibraryModule:
572 for Item in Module.GetExternList():
573 if Item.Constructor or Item.Destructor:
574 if hasattr(Item, 'SupModList') and len(Item.SupModList) > 0 and \
575 not IsEqualList(Item.SupModList, LibrarySupModList):
576 Logger.Error('\nUPT',
577 PARSER_ERROR,
578 ERR_XML_INVALID_EXTERN_SUPMODLIST % (str(Item.SupModList), str(LibrarySupModList)),
579 RaiseError=True)
580
581 #
582 # If the module is not a library module, the MODULE_TYPE listed in the ModuleSurfaceArea.Header must match the
583 # SupModList attribute. If these conditions cannot be met, the tool must exit gracefully, informing the user
584 # that the EDK II Build system does not currently support the features required by this Module.
585 #
586 if not IsLibraryModule:
587 for Item in Module.GetExternList():
588 if hasattr(Item, 'SupModList') and len(Item.SupModList) > 0 and \
589 not IsEqualList(Item.SupModList, [Module.ModuleType]):
590 Logger.Error('\nUPT',
591 PARSER_ERROR,
592 ERR_XML_INVALID_EXTERN_SUPMODLIST_NOT_LIB % (str(Module.ModuleType), str(Item.SupModList)),
593 RaiseError=True)
594 #
595 # Check SourceFiles
596 #
597 XmlTreeLevel = TopXmlTreeLevel + ['SourceFiles']
598 for Item in Module.GetSourceFileList():
599 if Item == None:
600 CheckDict = {'Filename':''}
601 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
602
603 XmlTreeLevel = TopXmlTreeLevel + ['SourceFiles']
604 for Item in Module.GetSourceFileList():
605 CheckDict = {'Filename':Item.GetSourceFile()}
606 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
607
608 for ItemCount in range(len(Module.GetBinaryFileList())):
609 Item = Module.GetBinaryFileList()[ItemCount]
610 if Item and len(Item.FileNamList) > 0 and Item.FileNamList[0].FileType == 'FREEFORM':
611 Item.FileNamList[0].FileType = 'SUBTYPE_GUID'
612 Module.GetBinaryFileList()[ItemCount] = Item
613 if Item and len(Item.FileNamList) > 0 and Item.FileNamList[0].FileType == 'DISPOSABLE':
614 Logger.Error('\nUPT',
615 PARSER_ERROR,
616 ERR_XML_INVALID_BINARY_FILE_TYPE % ('DISPOSABLE'),
617 RaiseError=True)
618
619 ## ValidateMS3
620 #
621 # Check if any required item is missing in ModuleSurfaceArea
622 #
623 # @param Module: The ModuleSurfaceArea to be checked
624 # @param XmlTreeLevel: The top level of Module
625 #
626 def ValidateMS3(Module, TopXmlTreeLevel):
627 #
628 # Check PackageDependencies -> Package
629 #
630 XmlTreeLevel = TopXmlTreeLevel + ['PackageDependencies']
631 for Item in Module.GetPackageDependencyList():
632 if Item == None:
633 CheckDict = {'Package':''}
634 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
635
636 XmlTreeLevel = TopXmlTreeLevel + ['PackageDependencies', 'Package']
637 for Item in Module.GetPackageDependencyList():
638 CheckDict = {'GUID':Item.GetGuid()}
639 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
640
641 #
642 # Check BinaryFiles -> BinaryFile
643 #
644 for Item in Module.GetBinaryFileList():
645 if Item == None:
646 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles']
647 CheckDict = {'BinaryFile':''}
648 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
649 if not Item.GetFileNameList():
650 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile']
651 CheckDict = {'Filename':''}
652 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
653
654 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile']
655 for File in Item.GetFileNameList():
656 CheckDict = {'Filename':File.GetFilename(),
657 'FileType':File.GetFileType()}
658 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
659 for AsBuilt in Item.GetAsBuiltList():
660 #
661 # Check LibInstance
662 #
663 if len(AsBuilt.LibraryInstancesList) == 1 and not AsBuilt.LibraryInstancesList[0]:
664 CheckDict = {'GUID':''}
665 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'LibraryInstances']
666 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
667
668 for LibItem in AsBuilt.LibraryInstancesList:
669 CheckDict = {'Guid':LibItem.Guid,
670 'Version':LibItem.Version}
671 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'LibraryInstances']
672 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
673
674 #
675 # Check PatchPcd
676 #
677 for PatchPcdItem in AsBuilt.PatchPcdList:
678 CheckDict = {'TokenSpaceGuidValue':PatchPcdItem.TokenSpaceGuidValue,
679 'PcdCName':PatchPcdItem.PcdCName,
680 'Token':PatchPcdItem.Token,
681 'DatumType':PatchPcdItem.DatumType,
682 'Value':PatchPcdItem.DefaultValue,
683 'Offset':PatchPcdItem.Offset}
684 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'PatchPcdValue']
685 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
686 #
687 # Check PcdError
688 #
689 for PcdErrorItem in PatchPcdItem.PcdErrorsList:
690 CheckDict = {'ErrorNumber':PcdErrorItem.ErrorNumber}
691 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt',
692 'PatchPcdValue', 'PcdError']
693 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
694 #
695 # Check PcdEx
696 #
697 for PcdExItem in AsBuilt.PcdExValueList:
698 CheckDict = {'TokenSpaceGuidValue':PcdExItem.TokenSpaceGuidValue,
699 'Token':PcdExItem.Token,
700 'DatumType':PcdExItem.DatumType,
701 'Value':PcdExItem.DefaultValue}
702 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt', 'PcdExValue']
703 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
704 #
705 # Check PcdError
706 #
707 for PcdErrorItem in PcdExItem.PcdErrorsList:
708 CheckDict = {'ErrorNumber':PcdErrorItem.ErrorNumber}
709 XmlTreeLevel = TopXmlTreeLevel + ['BinaryFiles', 'BinaryFile', 'AsBuilt',
710 'PcdExValue', 'PcdError']
711 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
712 #
713 # Check SmmDepex
714 #
715 XmlTreeLevel = TopXmlTreeLevel + ['SmmDepex']
716 for Item in Module.GetSmmDepex():
717 CheckDict = {'Expression':Item.GetDepex()}
718 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
719
720 #
721 # Check PeiDepex
722 #
723 XmlTreeLevel = TopXmlTreeLevel + ['PeiDepex']
724 for Item in Module.GetPeiDepex():
725 CheckDict = {'Expression':Item.GetDepex()}
726 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
727
728 #
729 # Check DxeDepex
730 #
731 XmlTreeLevel = TopXmlTreeLevel + ['DxeDepex']
732 for Item in Module.GetDxeDepex():
733 CheckDict = {'Expression':Item.GetDepex()}
734 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
735
736 #
737 # Check <UserExtensions>
738 #
739 XmlTreeLevel = TopXmlTreeLevel + ['UserExtensions']
740 for Item in Module.GetUserExtensionList():
741 CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
742 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
743
744 ## ValidatePS1
745 #
746 # ValidatePS1
747 #
748 def ValidatePS1(Package):
749 #
750 # Check DistributionPackage -> PackageSurfaceArea -> Header
751 #
752 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'Header']
753 CheckDict = Sdict()
754 CheckDict['Name'] = Package.GetName()
755 CheckDict['BaseName'] = Package.GetBaseName()
756 CheckDict['GUID'] = Package.GetGuid()
757 CheckDict['Version'] = Package.GetVersion()
758 CheckDict['PackagePath'] = Package.GetPackagePath()
759
760 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
761 if not IsValidInstallPath(Package.GetPackagePath()):
762 Logger.Error("UPT", FORMAT_INVALID, ERR_FILE_NAME_INVALIDE % Package.GetPackagePath())
763
764 #
765 # Check DistributionPackage -> PackageSurfaceArea -> ClonedFrom
766 #
767 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ClonedFrom']
768 for Item in Package.GetClonedFromList():
769 if Item == None:
770 CheckDict = Sdict()
771 CheckDict['GUID'] = ''
772 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
773 CheckDict = Sdict()
774 CheckDict['GUID'] = Item.GetPackageGuid()
775 CheckDict['Version'] = Item.GetPackageVersion()
776
777 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
778
779 #
780 # Check DistributionPackage -> PackageSurfaceArea -> LibraryClassDeclarations -> LibraryClass
781 #
782 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'LibraryClassDeclarations']
783 for Item in Package.GetLibraryClassList():
784 if Item == None:
785 CheckDict = {'LibraryClass':''}
786 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
787
788 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'LibraryClassDeclarations', 'LibraryClass']
789 for Item in Package.GetLibraryClassList():
790 CheckDict = {'Keyword':Item.GetLibraryClass(),
791 'HeaderFile':Item.GetIncludeHeader()}
792 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
793
794 #
795 # Check DistributionPackage -> PackageSurfaceArea -> IndustryStandardIncludes -> IndustryStandardHeader
796 #
797 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'IndustryStandardIncludes']
798 for Item in Package.GetStandardIncludeFileList():
799 if Item == None:
800 CheckDict = {'IndustryStandardHeader':''}
801 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
802
803 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'IndustryStandardIncludes', 'IndustryStandardHeader']
804 for Item in Package.GetStandardIncludeFileList():
805 CheckDict = {'HeaderFile':Item.GetFilePath()}
806 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
807
808 #
809 # Check DistributionPackage -> PackageSurfaceArea -> PackageIncludes -> PackageHeader
810 #
811 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PackageIncludes']
812 for Item in Package.GetPackageIncludeFileList():
813 if Item == None:
814 CheckDict = {'PackageHeader':''}
815 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
816
817 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PackageIncludes', 'PackageHeader']
818 for Item in Package.GetPackageIncludeFileList():
819 CheckDict = {'HeaderFile':Item.GetFilePath()}
820 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
821
822 ## ValidatePS2
823 #
824 # ValidatePS2
825 #
826 def ValidatePS2(Package):
827 #
828 # Check DistributionPackage -> PackageSurfaceArea -> Modules -> ModuleSurfaceArea
829 #
830 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'Modules', 'ModuleSurfaceArea']
831 for Item in Package.GetModuleDict().values():
832 ValidateMS(Item, XmlTreeLevel)
833
834 #
835 # Check DistributionPackage -> PackageSurfaceArea -> GuidDeclarations Entry
836 #
837 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'GuidDeclarations']
838 for Item in Package.GetGuidList():
839 if Item == None:
840 CheckDict = {'Entry':''}
841 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
842
843 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'GuidDeclarations', 'Entry']
844 for Item in Package.GetGuidList():
845 CheckDict = {'CName':Item.GetCName(),
846 'GuidValue':Item.GetGuid()}
847 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
848
849 #
850 # Check DistributionPackage -> PackageSurfaceArea -> ProtocolDeclarations -> Entry
851 #
852 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ProtocolDeclarations']
853 for Item in Package.GetProtocolList():
854 if Item == None:
855 CheckDict = {'Entry':''}
856 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
857
858 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'ProtocolDeclarations', 'Entry']
859 for Item in Package.GetProtocolList():
860 CheckDict = {'CName':Item.GetCName(),
861 'GuidValue':Item.GetGuid()}
862 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
863
864 #
865 # Check DistributionPackage -> PackageSurfaceArea -> PpiDeclarations -> Entry
866 #
867 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PpiDeclarations']
868 for Item in Package.GetPpiList():
869 if Item == None:
870 CheckDict = {'Entry':''}
871 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
872
873 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PpiDeclarations', 'Entry']
874 for Item in Package.GetPpiList():
875 CheckDict = {'CName':Item.GetCName(),
876 'GuidValue':Item.GetGuid()}
877 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
878
879 #
880 # Check DistributionPackage -> PackageSurfaceArea -> PcdDeclarations -> Entry
881 #
882 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PcdDeclarations']
883 for Item in Package.GetPcdList():
884 if Item == None:
885 CheckDict = {'PcdEntry':''}
886 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
887
888 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'PcdDeclarations', 'PcdEntry']
889 for Item in Package.GetPcdList():
890 CheckDict = {'TokenSpaceGuidCname':Item.GetTokenSpaceGuidCName(),
891 'Token':Item.GetToken(),
892 'CName':Item.GetCName(),
893 'DatumType':Item.GetDatumType(),
894 'ValidUsage':Item.GetValidUsage(),
895 'DefaultValue':Item.GetDefaultValue()}
896 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
897
898 #
899 # Check DistributionPackage -> PackageSurfaceArea -> UserExtensions
900 #
901 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'UserExtensions']
902 for Item in Package.GetUserExtensionList():
903 CheckDict = {'UserId':Item.GetUserID(), 'Identifier':Item.GetIdentifier()}
904 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
905
906 #
907 # Check DistributionPackage -> PackageSurfaceArea -> MiscellaneousFiles -> Filename
908 #
909 XmlTreeLevel = ['DistributionPackage', 'PackageSurfaceArea', 'MiscellaneousFiles']
910 for Item in Package.GetMiscFileList():
911 if not Item.GetFileList():
912 CheckDict = {'Filename':'', }
913 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
914 for File in Item.GetFileList():
915 CheckDict = {'Filename':File.GetURI(), }
916 IsRequiredItemListNull(CheckDict, XmlTreeLevel)
917
918 ## ValidatePackageSurfaceArea
919 #
920 # Check if any required item is missing in PackageSurfaceArea
921 #
922 # @param Package: The PackageSurfaceArea to be checked
923 #
924 def ValidatePackageSurfaceArea(Package):
925 ValidatePS1(Package)
926 ValidatePS2(Package)