]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/Eot/Parser.py
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / BaseTools / Source / Python / Eot / Parser.py
1 ## @file
2 # This file is used to define common parsing related functions used in parsing
3 # Inf/Dsc/Makefile process
4 #
5 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
7 #
8
9 ##
10 # Import Modules
11 #
12 from __future__ import absolute_import
13 import Common.LongFilePathOs as os, re
14 import Common.EdkLogger as EdkLogger
15 from Common.DataType import *
16 from CommonDataClass.DataClass import *
17 from Common.StringUtils import CleanString, GetSplitValueList, ReplaceMacro
18 from . import EotGlobalData
19 from Common.StringUtils import GetSplitList
20 from Common.LongFilePathSupport import OpenLongFilePath as open
21
22 import subprocess
23
24 ## DeCompress
25 #
26 # Call external decompress tool to decompress the fv section
27 #
28 def DeCompress(Method, Input):
29 # Write the input to a temp file
30 open('_Temp.bin', 'wb').write(Input)
31 cmd = ''
32 if Method == 'Lzma':
33 cmd = r'LzmaCompress -o _New.bin -d _Temp.bin'
34 if Method == 'Efi':
35 cmd = r'TianoCompress -d --uefi -o _New.bin _Temp.bin'
36 if Method == 'Framework':
37 cmd = r'TianoCompress -d -o _New.bin _Temp.bin'
38
39 # Call tool to create the decompressed output file
40 Process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
41 Process.communicate()[0]
42
43 # Return the beffer of New.bin
44 if os.path.exists('_New.bin'):
45 return open('_New.bin', 'rb').read()
46
47
48 ## PreProcess() method
49 #
50 # Pre process a file
51 #
52 # 1. Remove all comments
53 # 2. Merge multiple lines code to one line
54 #
55 # @param Filename: Name of the file to be parsed
56 # @param MergeMultipleLines: Switch for if merge multiple lines
57 # @param LineNo: Default line no
58 #
59 # @return Lines: The file contents after removing comments
60 #
61 def PreProcess(Filename, MergeMultipleLines = True, LineNo = -1):
62 Lines = []
63 Filename = os.path.normpath(Filename)
64 if not os.path.isfile(Filename):
65 EdkLogger.error("Eot", EdkLogger.FILE_NOT_FOUND, ExtraData=Filename)
66
67 IsFindBlockComment = False
68 IsFindBlockCode = False
69 ReservedLine = ''
70 ReservedLineLength = 0
71 for Line in open(Filename, 'r'):
72 Line = Line.strip()
73 # Remove comment block
74 if Line.find(TAB_COMMENT_EDK_START) > -1:
75 ReservedLine = GetSplitList(Line, TAB_COMMENT_EDK_START, 1)[0]
76 IsFindBlockComment = True
77 if Line.find(TAB_COMMENT_EDK_END) > -1:
78 Line = ReservedLine + GetSplitList(Line, TAB_COMMENT_EDK_END, 1)[1]
79 ReservedLine = ''
80 IsFindBlockComment = False
81 if IsFindBlockComment:
82 Lines.append('')
83 continue
84
85 # Remove comments at tail and remove spaces again
86 Line = CleanString(Line)
87 if Line == '':
88 Lines.append('')
89 continue
90
91 if MergeMultipleLines:
92 # Add multiple lines to one line
93 if IsFindBlockCode and Line[-1] != TAB_SLASH:
94 ReservedLine = (ReservedLine + TAB_SPACE_SPLIT + Line).strip()
95 Lines.append(ReservedLine)
96 for Index in (0, ReservedLineLength):
97 Lines.append('')
98 ReservedLine = ''
99 ReservedLineLength = 0
100 IsFindBlockCode = False
101 continue
102 if Line[-1] == TAB_SLASH:
103 ReservedLine = ReservedLine + TAB_SPACE_SPLIT + Line[0:-1].strip()
104 ReservedLineLength = ReservedLineLength + 1
105 IsFindBlockCode = True
106 continue
107
108 Lines.append(Line)
109
110 return Lines
111
112 ## AddToGlobalMacro() method
113 #
114 # Add a macro to EotGlobalData.gMACRO
115 #
116 # @param Name: Name of the macro
117 # @param Value: Value of the macro
118 #
119 def AddToGlobalMacro(Name, Value):
120 Value = ReplaceMacro(Value, EotGlobalData.gMACRO, True)
121 EotGlobalData.gMACRO[Name] = Value
122
123 ## AddToSelfMacro() method
124 #
125 # Parse a line of macro definition and add it to a macro set
126 #
127 # @param SelfMacro: The self macro set
128 # @param Line: The line of a macro definition
129 #
130 # @return Name: Name of macro
131 # @return Value: Value of macro
132 #
133 def AddToSelfMacro(SelfMacro, Line):
134 Name, Value = '', ''
135 List = GetSplitValueList(Line, TAB_EQUAL_SPLIT, 1)
136 if len(List) == 2:
137 Name = List[0]
138 Value = List[1]
139 Value = ReplaceMacro(Value, EotGlobalData.gMACRO, True)
140 Value = ReplaceMacro(Value, SelfMacro, True)
141 SelfMacro[Name] = Value
142
143 return (Name, Value)
144
145 ## GetIncludeListOfFile() method
146 #
147 # Get the include path list for a source file
148 #
149 # 1. Find the source file belongs to which INF file
150 # 2. Find the inf's package
151 # 3. Return the include path list of the package
152 #
153 # @param WorkSpace: WORKSPACE path
154 # @param Filepath: File path
155 # @param Db: Eot database
156 #
157 # @return IncludeList: A list of include directories
158 #
159 def GetIncludeListOfFile(WorkSpace, Filepath, Db):
160 IncludeList = []
161 Filepath = os.path.normpath(Filepath)
162 SqlCommand = """
163 select Value1 from Inf where Model = %s and BelongsToFile in(
164 select distinct B.BelongsToFile from File as A left join Inf as B
165 where A.ID = B.BelongsToFile and B.Model = %s and (A.Path || '%s' || B.Value1) = '%s')""" \
166 % (MODEL_META_DATA_PACKAGE, MODEL_EFI_SOURCE_FILE, '\\', Filepath)
167 RecordSet = Db.TblFile.Exec(SqlCommand)
168 for Record in RecordSet:
169 DecFullPath = os.path.normpath(os.path.join(WorkSpace, Record[0]))
170 (DecPath, DecName) = os.path.split(DecFullPath)
171 SqlCommand = """select Value1 from Dec where BelongsToFile =
172 (select ID from File where FullPath = '%s') and Model = %s""" \
173 % (DecFullPath, MODEL_EFI_INCLUDE)
174 NewRecordSet = Db.TblDec.Exec(SqlCommand)
175 for NewRecord in NewRecordSet:
176 IncludePath = os.path.normpath(os.path.join(DecPath, NewRecord[0]))
177 if IncludePath not in IncludeList:
178 IncludeList.append(IncludePath)
179
180 return IncludeList
181
182 ## GetTableList() method
183 #
184 # Search table file and find all small tables
185 #
186 # @param FileModelList: Model code for the file list
187 # @param Table: Table to insert records
188 # @param Db: Eot database
189 #
190 # @return TableList: A list of tables
191 #
192 def GetTableList(FileModelList, Table, Db):
193 TableList = []
194 SqlCommand = """select ID, FullPath from File where Model in %s""" % str(FileModelList)
195 RecordSet = Db.TblFile.Exec(SqlCommand)
196 for Record in RecordSet:
197 TableName = Table + str(Record[0])
198 TableList.append([TableName, Record[1]])
199
200 return TableList
201
202 ## GetAllIncludeDir() method
203 #
204 # Find all Include directories
205 #
206 # @param Db: Eot database
207 #
208 # @return IncludeList: A list of include directories
209 #
210 def GetAllIncludeDirs(Db):
211 IncludeList = []
212 SqlCommand = """select distinct Value1 from Inf where Model = %s order by Value1""" % MODEL_EFI_INCLUDE
213 RecordSet = Db.TblInf.Exec(SqlCommand)
214
215 for Record in RecordSet:
216 IncludeList.append(Record[0])
217
218 return IncludeList
219
220 ## GetAllIncludeFiles() method
221 #
222 # Find all Include files
223 #
224 # @param Db: Eot database
225 #
226 # @return IncludeFileList: A list of include files
227 #
228 def GetAllIncludeFiles(Db):
229 IncludeList = GetAllIncludeDirs(Db)
230 IncludeFileList = []
231
232 for Dir in IncludeList:
233 if os.path.isdir(Dir):
234 SubDir = os.listdir(Dir)
235 for Item in SubDir:
236 if os.path.isfile(Item):
237 IncludeFileList.append(Item)
238
239 return IncludeFileList
240
241 ## GetAllSourceFiles() method
242 #
243 # Find all source files
244 #
245 # @param Db: Eot database
246 #
247 # @return SourceFileList: A list of source files
248 #
249 def GetAllSourceFiles(Db):
250 SourceFileList = []
251 SqlCommand = """select distinct Value1 from Inf where Model = %s order by Value1""" % MODEL_EFI_SOURCE_FILE
252 RecordSet = Db.TblInf.Exec(SqlCommand)
253
254 for Record in RecordSet:
255 SourceFileList.append(Record[0])
256
257 return SourceFileList
258
259 ## GetAllFiles() method
260 #
261 # Find all files, both source files and include files
262 #
263 # @param Db: Eot database
264 #
265 # @return FileList: A list of files
266 #
267 def GetAllFiles(Db):
268 FileList = []
269 IncludeFileList = GetAllIncludeFiles(Db)
270 SourceFileList = GetAllSourceFiles(Db)
271 for Item in IncludeFileList:
272 if os.path.isfile(Item) and Item not in FileList:
273 FileList.append(Item)
274 for Item in SourceFileList:
275 if os.path.isfile(Item) and Item not in FileList:
276 FileList.append(Item)
277
278 return FileList
279
280 ## ParseConditionalStatement() method
281 #
282 # Parse conditional statement
283 #
284 # @param Line: One line to be parsed
285 # @param Macros: A set of all macro
286 # @param StatusSet: A set of all status
287 #
288 # @retval True: Find keyword of conditional statement
289 # @retval False: Not find keyword of conditional statement
290 #
291 def ParseConditionalStatement(Line, Macros, StatusSet):
292 NewLine = Line.upper()
293 if NewLine.find(TAB_IF_EXIST.upper()) > -1:
294 IfLine = Line[NewLine.find(TAB_IF_EXIST) + len(TAB_IF_EXIST) + 1:].strip()
295 IfLine = ReplaceMacro(IfLine, EotGlobalData.gMACRO, True)
296 IfLine = ReplaceMacro(IfLine, Macros, True)
297 IfLine = IfLine.replace("\"", '')
298 IfLine = IfLine.replace("(", '')
299 IfLine = IfLine.replace(")", '')
300 Status = os.path.exists(os.path.normpath(IfLine))
301 StatusSet.append([Status])
302 return True
303 if NewLine.find(TAB_IF_DEF.upper()) > -1:
304 IfLine = Line[NewLine.find(TAB_IF_DEF) + len(TAB_IF_DEF) + 1:].strip()
305 Status = False
306 if IfLine in Macros or IfLine in EotGlobalData.gMACRO:
307 Status = True
308 StatusSet.append([Status])
309 return True
310 if NewLine.find(TAB_IF_N_DEF.upper()) > -1:
311 IfLine = Line[NewLine.find(TAB_IF_N_DEF) + len(TAB_IF_N_DEF) + 1:].strip()
312 Status = False
313 if IfLine not in Macros and IfLine not in EotGlobalData.gMACRO:
314 Status = True
315 StatusSet.append([Status])
316 return True
317 if NewLine.find(TAB_IF.upper()) > -1:
318 IfLine = Line[NewLine.find(TAB_IF) + len(TAB_IF) + 1:].strip()
319 Status = ParseConditionalStatementMacros(IfLine, Macros)
320 StatusSet.append([Status])
321 return True
322 if NewLine.find(TAB_ELSE_IF.upper()) > -1:
323 IfLine = Line[NewLine.find(TAB_ELSE_IF) + len(TAB_ELSE_IF) + 1:].strip()
324 Status = ParseConditionalStatementMacros(IfLine, Macros)
325 StatusSet[-1].append(Status)
326 return True
327 if NewLine.find(TAB_ELSE.upper()) > -1:
328 Status = False
329 for Item in StatusSet[-1]:
330 Status = Status or Item
331 StatusSet[-1].append(not Status)
332 return True
333 if NewLine.find(TAB_END_IF.upper()) > -1:
334 StatusSet.pop()
335 return True
336
337 return False
338
339 ## ParseConditionalStatement() method
340 #
341 # Parse conditional statement with Macros
342 #
343 # @param Line: One line to be parsed
344 # @param Macros: A set of macros
345 #
346 # @return Line: New line after replacing macros
347 #
348 def ParseConditionalStatementMacros(Line, Macros):
349 if Line.upper().find('DEFINED(') > -1 or Line.upper().find('EXIST') > -1:
350 return False
351 Line = ReplaceMacro(Line, EotGlobalData.gMACRO, True)
352 Line = ReplaceMacro(Line, Macros, True)
353 Line = Line.replace("&&", "and")
354 Line = Line.replace("||", "or")
355 return eval(Line)
356
357 ## GetConditionalStatementStatus() method
358 #
359 # 1. Assume the latest status as True
360 # 2. Pop the top status of status set, previous status
361 # 3. Compare the latest one and the previous one and get new status
362 #
363 # @param StatusSet: A set of all status
364 #
365 # @return Status: The final status
366 #
367 def GetConditionalStatementStatus(StatusSet):
368 Status = True
369 for Item in StatusSet:
370 Status = Status and Item[-1]
371
372 return Status
373
374 ## SearchBelongsToFunction() method
375 #
376 # Search all functions belong to the file
377 #
378 # @param BelongsToFile: File id
379 # @param StartLine: Start line of search scope
380 # @param EndLine: End line of search scope
381 #
382 # @return: The found function
383 #
384 def SearchBelongsToFunction(BelongsToFile, StartLine, EndLine):
385 SqlCommand = """select ID, Name from Function where BelongsToFile = %s and StartLine <= %s and EndLine >= %s""" %(BelongsToFile, StartLine, EndLine)
386 RecordSet = EotGlobalData.gDb.TblFunction.Exec(SqlCommand)
387 if RecordSet != []:
388 return RecordSet[0][0], RecordSet[0][1]
389 else:
390 return -1, ''
391
392 ## SearchPpiCallFunction() method
393 #
394 # Search all used PPI calling function 'PeiServicesReInstallPpi' and 'PeiServicesInstallPpi'
395 # Store the result to database
396 #
397 # @param Identifier: Table id
398 # @param SourceFileID: Source file id
399 # @param SourceFileFullPath: Source file full path
400 # @param ItemMode: Mode of the item
401 #
402 def SearchPpiCallFunction(Identifier, SourceFileID, SourceFileFullPath, ItemMode):
403 ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''
404 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
405 where (Name like '%%%s%%' and Model = %s)""" \
406 % (Identifier, 'PeiServicesReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)
407 BelongsToFunctionID, BelongsToFunction = -1, ''
408 Db = EotGlobalData.gDb.TblReport
409 RecordSet = Db.Exec(SqlCommand)
410 for Record in RecordSet:
411 Index = 0
412 BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]
413 BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)
414 VariableList = Record[0].split(',')
415 for Variable in VariableList:
416 Variable = Variable.strip()
417 # Get index of the variable
418 if Variable.find('[') > -1:
419 Index = int(Variable[Variable.find('[') + 1 : Variable.find(']')])
420 Variable = Variable[:Variable.find('[')]
421 # Get variable name
422 if Variable.startswith('&'):
423 Variable = Variable[1:]
424 # Get variable value
425 SqlCommand = """select Value from %s where (Name like '%%%s%%') and Model = %s""" \
426 % (Identifier, Variable, MODEL_IDENTIFIER_VARIABLE)
427 NewRecordSet = Db.Exec(SqlCommand)
428 if NewRecordSet:
429 NewRecord = NewRecordSet[0][0]
430 VariableValueList = NewRecord.split('},')
431 if len(VariableValueList) > Index:
432 VariableValue = VariableValueList[Index]
433 NewVariableValueList = VariableValue.split(',')
434 if len(NewVariableValueList) > 1:
435 NewVariableValue = NewVariableValueList[1].strip()
436 if NewVariableValue.startswith('&'):
437 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, NewVariableValue[1:], GuidMacro, GuidValue, BelongsToFunction, 0)
438 continue
439 else:
440 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, NewParameter))
441
442 ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''
443 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
444 where (Value like '%%%s%%' and Model = %s)""" \
445 % (Identifier, 'PeiServicesInstallPpi', MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)
446 BelongsToFunctionID, BelongsToFunction = -1, ''
447 Db = EotGlobalData.gDb.TblReport
448 RecordSet = Db.Exec(SqlCommand)
449
450 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s
451 where (Name like '%%%s%%' and Model = %s)""" \
452 % (Identifier, 'PeiServicesInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)
453 Db = EotGlobalData.gDb.TblReport
454 RecordSet2 = Db.Exec(SqlCommand)
455
456 for Record in RecordSet + RecordSet2:
457 if Record == []:
458 continue
459 Index = 0
460 BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]
461 BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)
462 Variable = Record[0].replace('PeiServicesInstallPpi', '').replace('(', '').replace(')', '').replace('&', '').strip()
463 Variable = Variable[Variable.find(',') + 1:].strip()
464 # Get index of the variable
465 if Variable.find('[') > -1:
466 Index = int(Variable[Variable.find('[') + 1 : Variable.find(']')])
467 Variable = Variable[:Variable.find('[')]
468 # Get variable name
469 if Variable.startswith('&'):
470 Variable = Variable[1:]
471 # Get variable value
472 SqlCommand = """select Value from %s where (Name like '%%%s%%') and Model = %s""" \
473 % (Identifier, Variable, MODEL_IDENTIFIER_VARIABLE)
474 NewRecordSet = Db.Exec(SqlCommand)
475 if NewRecordSet:
476 NewRecord = NewRecordSet[0][0]
477 VariableValueList = NewRecord.split('},')
478 for VariableValue in VariableValueList[Index:]:
479 NewVariableValueList = VariableValue.split(',')
480 if len(NewVariableValueList) > 1:
481 NewVariableValue = NewVariableValueList[1].strip()
482 if NewVariableValue.startswith('&'):
483 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, NewVariableValue[1:], GuidMacro, GuidValue, BelongsToFunction, 0)
484 continue
485 else:
486 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, NewParameter))
487
488 ## SearchPpis() method
489 #
490 # Search all used PPI calling function
491 # Store the result to database
492 #
493 # @param SqlCommand: SQL command statement
494 # @param Table: Table id
495 # @param SourceFileID: Source file id
496 # @param SourceFileFullPath: Source file full path
497 # @param ItemMode: Mode of the item
498 # @param PpiMode: Mode of PPI
499 #
500 def SearchPpi(SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemMode, PpiMode = 1):
501 ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Ppi', '', '', ''
502 BelongsToFunctionID, BelongsToFunction = -1, ''
503 Db = EotGlobalData.gDb.TblReport
504 RecordSet = Db.Exec(SqlCommand)
505 for Record in RecordSet:
506 Parameter = GetPpiParameter(Record[0], PpiMode)
507 BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]
508 # Get BelongsToFunction
509 BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)
510
511 # Default is Not Found
512 IsFound = False
513
514 # For Consumed Ppi
515 if ItemMode == 'Consumed':
516 if Parameter.startswith('g'):
517 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, Parameter, GuidMacro, GuidValue, BelongsToFunction, 0)
518 else:
519 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))
520 continue
521
522 # Direct Parameter.Guid
523 SqlCommand = """select Value from %s where (Name like '%%%s.Guid%%' or Name like '%%%s->Guid%%') and Model = %s""" % (Table, Parameter, Parameter, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)
524 NewRecordSet = Db.Exec(SqlCommand)
525 for NewRecord in NewRecordSet:
526 GuidName = GetParameterName(NewRecord[0])
527 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
528 IsFound = True
529
530 # Defined Parameter
531 if not IsFound:
532 Key = Parameter
533 if Key.rfind(' ') > -1:
534 Key = Key[Key.rfind(' ') : ].strip().replace('&', '')
535 Value = FindKeyValue(EotGlobalData.gDb.TblFile, Table, Key)
536 List = GetSplitValueList(Value.replace('\n', ''), TAB_COMMA_SPLIT)
537 if len(List) > 1:
538 GuidName = GetParameterName(List[1])
539 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
540 IsFound = True
541
542 # A list Parameter
543 if not IsFound:
544 Start = Parameter.find('[')
545 End = Parameter.find(']')
546 if Start > -1 and End > -1 and Start < End:
547 try:
548 Index = int(Parameter[Start + 1 : End])
549 Parameter = Parameter[0 : Start]
550 SqlCommand = """select Value from %s where Name = '%s' and Model = %s""" % (Table, Parameter, MODEL_IDENTIFIER_VARIABLE)
551 NewRecordSet = Db.Exec(SqlCommand)
552 for NewRecord in NewRecordSet:
553 NewParameter = GetSplitValueList(NewRecord[0], '}')[Index]
554 GuidName = GetPpiParameter(NewParameter[NewParameter.find('{') : ])
555 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
556 IsFound = True
557 except Exception:
558 pass
559
560 # A External Parameter
561 if not IsFound:
562 SqlCommand = """select File.ID from Inf, File
563 where BelongsToFile = (select BelongsToFile from Inf where Value1 = '%s')
564 and Inf.Model = %s and Inf.Value1 = File.FullPath and File.Model = %s""" % (SourceFileFullPath, MODEL_EFI_SOURCE_FILE, MODEL_FILE_C)
565 NewRecordSet = Db.Exec(SqlCommand)
566 for NewRecord in NewRecordSet:
567 Table = 'Identifier' + str(NewRecord[0])
568 SqlCommand = """select Value from %s where Name = '%s' and Modifier = 'EFI_PEI_PPI_DESCRIPTOR' and Model = %s""" % (Table, Parameter, MODEL_IDENTIFIER_VARIABLE)
569 PpiSet = Db.Exec(SqlCommand)
570 if PpiSet != []:
571 GuidName = GetPpiParameter(PpiSet[0][0])
572 if GuidName != '':
573 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
574 IsFound = True
575 break
576
577 if not IsFound:
578 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))
579
580 ## SearchProtocols() method
581 #
582 # Search all used PROTOCOL calling function
583 # Store the result to database
584 #
585 # @param SqlCommand: SQL command statement
586 # @param Table: Table id
587 # @param SourceFileID: Source file id
588 # @param SourceFileFullPath: Source file full path
589 # @param ItemMode: Mode of the item
590 # @param ProtocolMode: Mode of PROTOCOL
591 #
592 def SearchProtocols(SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemMode, ProtocolMode):
593 ItemName, ItemType, GuidName, GuidMacro, GuidValue = '', 'Protocol', '', '', ''
594 BelongsToFunctionID, BelongsToFunction = -1, ''
595 Db = EotGlobalData.gDb.TblReport
596 RecordSet = Db.Exec(SqlCommand)
597 for Record in RecordSet:
598 Parameter = ''
599 BelongsToFile, StartLine, EndLine = Record[2], Record[3], Record[4]
600 # Get BelongsToFunction
601 BelongsToFunctionID, BelongsToFunction = SearchBelongsToFunction(BelongsToFile, StartLine, EndLine)
602
603 # Default is Not Found
604 IsFound = False
605
606 if ProtocolMode == 0 or ProtocolMode == 1:
607 Parameter = GetProtocolParameter(Record[0], ProtocolMode)
608 if Parameter.startswith('g') or Parameter.endswith('Guid') or Parameter == 'ShellEnvProtocol' or Parameter == 'ShellInterfaceProtocol':
609 GuidName = GetParameterName(Parameter)
610 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
611 IsFound = True
612
613 if ProtocolMode == 2:
614 Protocols = GetSplitValueList(Record[0], TAB_COMMA_SPLIT)
615 for Protocol in Protocols:
616 if Protocol.startswith('&') and Protocol.endswith('Guid'):
617 GuidName = GetParameterName(Protocol)
618 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
619 IsFound = True
620 else:
621 NewValue = FindKeyValue(EotGlobalData.gDb.TblFile, Table, Protocol)
622 if Protocol != NewValue and NewValue.endswith('Guid'):
623 GuidName = GetParameterName(NewValue)
624 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
625 IsFound = True
626
627 if not IsFound:
628 if BelongsToFunction in EotGlobalData.gProducedProtocolLibrary or BelongsToFunction in EotGlobalData.gConsumedProtocolLibrary:
629 EotGlobalData.gOP_UN_MATCHED_IN_LIBRARY_CALLING.write('%s, %s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter, BelongsToFunction))
630 else:
631 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))
632
633 ## SearchFunctionCalling() method
634 #
635 # Search all used PPI/PROTOCOL calling function by library
636 # Store the result to database
637 #
638 # @param SqlCommand: SQL command statement
639 # @param Table: Table id
640 # @param SourceFileID: Source file id
641 # @param SourceFileFullPath: Source file full path
642 # @param ItemType: Type of the item, PPI or PROTOCOL
643 # @param ItemMode: Mode of item
644 #
645 def SearchFunctionCalling(Table, SourceFileID, SourceFileFullPath, ItemType, ItemMode):
646 LibraryList = {}
647 Db = EotGlobalData.gDb.TblReport
648 Parameters, ItemName, GuidName, GuidMacro, GuidValue, BelongsToFunction = [], '', '', '', '', ''
649 if ItemType == 'Protocol' and ItemMode == 'Produced':
650 LibraryList = EotGlobalData.gProducedProtocolLibrary
651 elif ItemType == 'Protocol' and ItemMode == 'Consumed':
652 LibraryList = EotGlobalData.gConsumedProtocolLibrary
653 elif ItemType == 'Protocol' and ItemMode == 'Callback':
654 LibraryList = EotGlobalData.gCallbackProtocolLibrary
655 elif ItemType == 'Ppi' and ItemMode == 'Produced':
656 LibraryList = EotGlobalData.gProducedPpiLibrary
657 elif ItemType == 'Ppi' and ItemMode == 'Consumed':
658 LibraryList = EotGlobalData.gConsumedPpiLibrary
659
660 for Library in LibraryList:
661 Index = LibraryList[Library]
662 SqlCommand = """select Value, StartLine from %s
663 where Name like '%%%s%%' and Model = %s""" \
664 % (Table, Library, MODEL_IDENTIFIER_FUNCTION_CALLING)
665 RecordSet = Db.Exec(SqlCommand)
666 for Record in RecordSet:
667 IsFound = False
668 if Index == -1:
669 ParameterList = GetSplitValueList(Record[0], TAB_COMMA_SPLIT)
670 for Parameter in ParameterList:
671 Parameters.append(GetParameterName(Parameter))
672 else:
673 Parameters = [GetProtocolParameter(Record[0], Index)]
674 StartLine = Record[1]
675 for Parameter in Parameters:
676 if Parameter.startswith('g') or Parameter.endswith('Guid') or Parameter == 'ShellEnvProtocol' or Parameter == 'ShellInterfaceProtocol':
677 GuidName = GetParameterName(Parameter)
678 Db.Insert(-1, '', '', SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, 0)
679 IsFound = True
680
681 if not IsFound:
682 EotGlobalData.gOP_UN_MATCHED.write('%s, %s, %s, %s, %s, %s\n' % (ItemType, ItemMode, SourceFileID, SourceFileFullPath, StartLine, Parameter))
683
684 ## FindProtocols() method
685 #
686 # Find defined protocols
687 #
688 # @param SqlCommand: SQL command statement
689 # @param Table: Table id
690 # @param SourceFileID: Source file id
691 # @param SourceFileFullPath: Source file full path
692 # @param ItemName: String of protocol definition
693 # @param ItemType: Type of the item, PPI or PROTOCOL
694 # @param ItemMode: Mode of item
695 #
696 #def FindProtocols(Db, SqlCommand, Table, SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue):
697 # BelongsToFunction = ''
698 # RecordSet = Db.Exec(SqlCommand)
699 # for Record in RecordSet:
700 # IsFound = True
701 # Parameter = GetProtocolParameter(Record[0])
702
703 ## GetProtocolParameter() method
704 #
705 # Parse string of protocol and find parameters
706 #
707 # @param Parameter: Parameter to be parsed
708 # @param Index: The index of the parameter
709 #
710 # @return: call common GetParameter
711 #
712 def GetProtocolParameter(Parameter, Index = 1):
713 return GetParameter(Parameter, Index)
714
715 ## GetPpiParameter() method
716 #
717 # Parse string of ppi and find parameters
718 #
719 # @param Parameter: Parameter to be parsed
720 # @param Index: The index of the parameter
721 #
722 # @return: call common GetParameter
723 #
724 def GetPpiParameter(Parameter, Index = 1):
725 return GetParameter(Parameter, Index)
726
727 ## GetParameter() method
728 #
729 # Get a parameter by index
730 #
731 # @param Parameter: Parameter to be parsed
732 # @param Index: The index of the parameter
733 #
734 # @return Parameter: The found parameter
735 #
736 def GetParameter(Parameter, Index = 1):
737 ParameterList = GetSplitValueList(Parameter, TAB_COMMA_SPLIT)
738 if len(ParameterList) > Index:
739 Parameter = GetParameterName(ParameterList[Index])
740
741 return Parameter
742
743 return ''
744
745 ## GetParameterName() method
746 #
747 # Get a parameter name
748 #
749 # @param Parameter: Parameter to be parsed
750 #
751 # @return: The name of parameter
752 #
753 def GetParameterName(Parameter):
754 if isinstance(Parameter, type('')) and Parameter.startswith('&'):
755 return Parameter[1:].replace('{', '').replace('}', '').replace('\r', '').replace('\n', '').strip()
756 else:
757 return Parameter.strip()
758
759 ## FindKeyValue() method
760 #
761 # Find key value of a variable
762 #
763 # @param Db: Database to be searched
764 # @param Table: Table to be searched
765 # @param Key: The keyword
766 #
767 # @return Value: The value of the keyword
768 #
769 def FindKeyValue(Db, Table, Key):
770 SqlCommand = """select Value from %s where Name = '%s' and (Model = %s or Model = %s)""" % (Table, Key, MODEL_IDENTIFIER_VARIABLE, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)
771 RecordSet = Db.Exec(SqlCommand)
772 Value = ''
773 for Record in RecordSet:
774 if Record[0] != 'NULL':
775 Value = FindKeyValue(Db, Table, GetParameterName(Record[0]))
776
777 if Value != '':
778 return Value
779 else:
780 return Key
781
782 ## ParseMapFile() method
783 #
784 # Parse map files to get a dict of 'ModuleName' : {FunName : FunAddress}
785 #
786 # @param Files: A list of map files
787 #
788 # @return AllMaps: An object of all map files
789 #
790 def ParseMapFile(Files):
791 AllMaps = {}
792 CurrentModule = ''
793 CurrentMaps = {}
794 for File in Files:
795 Content = open(File, 'r').readlines()
796 for Line in Content:
797 Line = CleanString(Line)
798 # skip empty line
799 if Line == '':
800 continue
801
802 if Line.find('(') > -1 and Line.find(')') > -1:
803 if CurrentModule != '' and CurrentMaps != {}:
804 AllMaps[CurrentModule] = CurrentMaps
805 CurrentModule = Line[:Line.find('(')]
806 CurrentMaps = {}
807 continue
808 else:
809 Name = ''
810 Address = ''
811 List = Line.split()
812 Address = List[0]
813 if List[1] == 'F' or List[1] == 'FS':
814 Name = List[2]
815 else:
816 Name = List[1]
817 CurrentMaps[Name] = Address
818 continue
819
820 return AllMaps
821
822 ## ConvertGuid
823 #
824 # Convert a GUID to a GUID with all upper letters
825 #
826 # @param guid: The GUID to be converted
827 #
828 # @param newGuid: The GUID with all upper letters.
829 #
830 def ConvertGuid(guid):
831 numList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
832 newGuid = ''
833 if guid.startswith('g'):
834 guid = guid[1:]
835 for i in guid:
836 if i.upper() == i and i not in numList:
837 newGuid = newGuid + ('_' + i)
838 else:
839 newGuid = newGuid + i.upper()
840 if newGuid.startswith('_'):
841 newGuid = newGuid[1:]
842 if newGuid.endswith('_'):
843 newGuid = newGuid[:-1]
844
845 return newGuid
846
847 ## ConvertGuid2() method
848 #
849 # Convert a GUID to a GUID with new string instead of old string
850 #
851 # @param guid: The GUID to be converted
852 # @param old: Old string to be replaced
853 # @param new: New string to replace the old one
854 #
855 # @param newGuid: The GUID after replacement
856 #
857 def ConvertGuid2(guid, old, new):
858 newGuid = ConvertGuid(guid)
859 newGuid = newGuid.replace(old, new)
860
861 return newGuid
862
863 ##
864 #
865 # This acts like the main() function for the script, unless it is 'import'ed into another
866 # script.
867 #
868 if __name__ == '__main__':
869 pass