]> git.proxmox.com Git - mirror_edk2.git/blob - EmulatorPkg/Unix/lldbefi.py
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / EmulatorPkg / Unix / lldbefi.py
1 #!/usr/bin/python
2
3 #
4 # Copyright 2014 Apple Inc. All rights reserved.
5 #
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
7 #
8
9 import lldb
10 import os
11 import uuid
12 import string
13 import optparse
14 import shlex
15
16 guid_dict = {}
17
18
19 def EFI_GUID_TypeSummary (valobj,internal_dict):
20 """ Type summary for EFI GUID, print C Name if known
21 """
22 # typedef struct {
23 # UINT32 Data1;
24 # UINT16 Data2;
25 # UINT16 Data3;
26 # UINT8 Data4[8];
27 # } EFI_GUID;
28 SBError = lldb.SBError()
29
30 data1_val = valobj.GetChildMemberWithName('Data1')
31 data1 = data1_val.GetValueAsUnsigned(0)
32 data2_val = valobj.GetChildMemberWithName('Data2')
33 data2 = data2_val.GetValueAsUnsigned(0)
34 data3_val = valobj.GetChildMemberWithName('Data3')
35 data3 = data3_val.GetValueAsUnsigned(0)
36 str = "%x-%x-%x-" % (data1, data2, data3)
37
38 data4_val = valobj.GetChildMemberWithName('Data4')
39 for i in range (data4_val.num_children):
40 if i == 2:
41 str +='-'
42 str += "%02x" % data4_val.GetChildAtIndex(i).data.GetUnsignedInt8(SBError, 0)
43
44 return guid_dict.get (str.upper(), '')
45
46
47
48 EFI_STATUS_Dict = {
49 (0x8000000000000000 | 1): "Load Error",
50 (0x8000000000000000 | 2): "Invalid Parameter",
51 (0x8000000000000000 | 3): "Unsupported",
52 (0x8000000000000000 | 4): "Bad Buffer Size",
53 (0x8000000000000000 | 5): "Buffer Too Small",
54 (0x8000000000000000 | 6): "Not Ready",
55 (0x8000000000000000 | 7): "Device Error",
56 (0x8000000000000000 | 8): "Write Protected",
57 (0x8000000000000000 | 9): "Out of Resources",
58 (0x8000000000000000 | 10): "Volume Corrupt",
59 (0x8000000000000000 | 11): "Volume Full",
60 (0x8000000000000000 | 12): "No Media",
61 (0x8000000000000000 | 13): "Media changed",
62 (0x8000000000000000 | 14): "Not Found",
63 (0x8000000000000000 | 15): "Access Denied",
64 (0x8000000000000000 | 16): "No Response",
65 (0x8000000000000000 | 17): "No mapping",
66 (0x8000000000000000 | 18): "Time out",
67 (0x8000000000000000 | 19): "Not started",
68 (0x8000000000000000 | 20): "Already started",
69 (0x8000000000000000 | 21): "Aborted",
70 (0x8000000000000000 | 22): "ICMP Error",
71 (0x8000000000000000 | 23): "TFTP Error",
72 (0x8000000000000000 | 24): "Protocol Error",
73
74 0 : "Success",
75 1 : "Warning Unknown Glyph",
76 2 : "Warning Delete Failure",
77 3 : "Warning Write Failure",
78 4 : "Warning Buffer Too Small",
79
80 (0x80000000 | 1): "Load Error",
81 (0x80000000 | 2): "Invalid Parameter",
82 (0x80000000 | 3): "Unsupported",
83 (0x80000000 | 4): "Bad Buffer Size",
84 (0x80000000 | 5): "Buffer Too Small",
85 (0x80000000 | 6): "Not Ready",
86 (0x80000000 | 7): "Device Error",
87 (0x80000000 | 8): "Write Protected",
88 (0x80000000 | 9): "Out of Resources",
89 (0x80000000 | 10): "Volume Corrupt",
90 (0x80000000 | 11): "Volume Full",
91 (0x80000000 | 12): "No Media",
92 (0x80000000 | 13): "Media changed",
93 (0x80000000 | 14): "Not Found",
94 (0x80000000 | 15): "Access Denied",
95 (0x80000000 | 16): "No Response",
96 (0x80000000 | 17): "No mapping",
97 (0x80000000 | 18): "Time out",
98 (0x80000000 | 19): "Not started",
99 (0x80000000 | 20): "Already started",
100 (0x80000000 | 21): "Aborted",
101 (0x80000000 | 22): "ICMP Error",
102 (0x80000000 | 23): "TFTP Error",
103 (0x80000000 | 24): "Protocol Error",
104 }
105
106 def EFI_STATUS_TypeSummary (valobj,internal_dict):
107 #
108 # Return summary string for EFI_STATUS from dictionary
109 #
110 Status = valobj.GetValueAsUnsigned(0)
111 return EFI_STATUS_Dict.get (Status, '')
112
113
114 def EFI_TPL_TypeSummary (valobj,internal_dict):
115 #
116 # Return TPL values
117 #
118
119 if valobj.TypeIsPointerType():
120 return ""
121
122 Tpl = valobj.GetValueAsUnsigned(0)
123 if Tpl < 4:
124 Str = "%d" % Tpl
125 elif Tpl == 6:
126 Str = "TPL_DRIVER (Obsolete Concept in edk2)"
127 elif Tpl < 8:
128 Str = "TPL_APPLICATION"
129 if Tpl - 4 > 0:
130 Str += " + " + "%d" % (Tpl - 4)
131 elif Tpl < 16:
132 Str = "TPL_CALLBACK"
133 if Tpl - 8 > 0:
134 Str += " + " + "%d" % (Tpl - 4)
135 elif Tpl < 31:
136 Str = "TPL_NOTIFY"
137 if Tpl - 16 > 0:
138 Str += " + " + "%d" % (Tpl - 4)
139 elif Tpl == 31:
140 Str = "TPL_HIGH_LEVEL"
141 else:
142 Str = "Invalid TPL"
143
144 return Str
145
146
147 def CHAR16_TypeSummary (valobj,internal_dict):
148 #
149 # Display EFI CHAR16 'unsigned short' as string
150 #
151 SBError = lldb.SBError()
152 Str = ''
153 if valobj.TypeIsPointerType():
154 if valobj.GetValueAsUnsigned () == 0:
155 return "NULL"
156
157 # CHAR16 * max string size 1024
158 for i in range (1024):
159 Char = valobj.GetPointeeData(i,1).GetUnsignedInt16(SBError, 0)
160 if SBError.fail or Char == 0:
161 break
162 Str += unichr (Char)
163 Str = 'L"' + Str + '"'
164 return Str.encode ('utf-8', 'replace')
165
166 if valobj.num_children == 0:
167 # CHAR16
168 if chr (valobj.unsigned) in string.printable:
169 Str = "L'" + unichr (valobj.unsigned) + "'"
170 return Str.encode ('utf-8', 'replace')
171 else:
172 # CHAR16 []
173 for i in range (valobj.num_children):
174 Char = valobj.GetChildAtIndex(i).data.GetUnsignedInt16(SBError, 0)
175 if Char == 0:
176 break
177 Str += unichr (Char)
178 Str = 'L"' + Str + '"'
179 return Str.encode ('utf-8', 'replace')
180
181 return Str
182
183 def CHAR8_TypeSummary (valobj,internal_dict):
184 #
185 # Display EFI CHAR8 'signed char' as string
186 # unichr() is used as a junk string can produce an error message like this:
187 # UnicodeEncodeError: 'ascii' codec can't encode character u'\x90' in position 1: ordinal not in range(128)
188 #
189 SBError = lldb.SBError()
190 Str = ''
191 if valobj.TypeIsPointerType():
192 if valobj.GetValueAsUnsigned () == 0:
193 return "NULL"
194
195 # CHAR8 * max string size 1024
196 for i in range (1024):
197 Char = valobj.GetPointeeData(i,1).GetUnsignedInt8(SBError, 0)
198 if SBError.fail or Char == 0:
199 break
200 Str += unichr (Char)
201 Str = '"' + Str + '"'
202 return Str.encode ('utf-8', 'replace')
203
204 if valobj.num_children == 0:
205 # CHAR8
206 if chr (valobj.unsigned) in string.printable:
207 Str = '"' + unichr (valobj.unsigned) + '"'
208 return Str.encode ('utf-8', 'replace')
209 else:
210 # CHAR8 []
211 for i in range (valobj.num_children):
212 Char = valobj.GetChildAtIndex(i).data.GetUnsignedInt8(SBError, 0)
213 if Char == 0:
214 break
215 Str += unichr (Char)
216 Str = '"' + Str + '"'
217 return Str.encode ('utf-8', 'replace')
218
219 return Str
220
221 device_path_dict = {
222 (0x01, 0x01): "PCI_DEVICE_PATH",
223 (0x01, 0x02): "PCCARD_DEVICE_PATH",
224 (0x01, 0x03): "MEMMAP_DEVICE_PATH",
225 (0x01, 0x04): "VENDOR_DEVICE_PATH",
226 (0x01, 0x05): "CONTROLLER_DEVICE_PATH",
227 (0x02, 0x01): "ACPI_HID_DEVICE_PATH",
228 (0x02, 0x02): "ACPI_EXTENDED_HID_DEVICE_PATH",
229 (0x02, 0x03): "ACPI_ADR_DEVICE_PATH",
230 (0x03, 0x01): "ATAPI_DEVICE_PATH",
231 (0x03, 0x12): "SATA_DEVICE_PATH",
232 (0x03, 0x02): "SCSI_DEVICE_PATH",
233 (0x03, 0x03): "FIBRECHANNEL_DEVICE_PATH",
234 (0x03, 0x04): "F1394_DEVICE_PATH",
235 (0x03, 0x05): "USB_DEVICE_PATH",
236 (0x03, 0x0f): "USB_CLASS_DEVICE_PATH",
237 (0x03, 0x10): "FW_SBP2_UNIT_LUN_DEVICE_PATH",
238 (0x03, 0x11): "DEVICE_LOGICAL_UNIT_DEVICE_PATH",
239 (0x03, 0x06): "I2O_DEVICE_PATH",
240 (0x03, 0x0b): "MAC_ADDR_DEVICE_PATH",
241 (0x03, 0x0c): "IPv4_DEVICE_PATH",
242 (0x03, 0x09): "INFINIBAND_DEVICE_PATH",
243 (0x03, 0x0e): "UART_DEVICE_PATH",
244 (0x03, 0x0a): "VENDOR_DEVICE_PATH",
245 (0x03, 0x13): "ISCSI_DEVICE_PATH",
246 (0x04, 0x01): "HARDDRIVE_DEVICE_PATH",
247 (0x04, 0x02): "CDROM_DEVICE_PATH",
248 (0x04, 0x03): "VENDOR_DEVICE_PATH",
249 (0x04, 0x04): "FILEPATH_DEVICE_PATH",
250 (0x04, 0x05): "MEDIA_PROTOCOL_DEVICE_PATH",
251 (0x05, 0x01): "BBS_BBS_DEVICE_PATH",
252 (0x7F, 0xFF): "EFI_DEVICE_PATH_PROTOCOL",
253 (0xFF, 0xFF): "EFI_DEVICE_PATH_PROTOCOL",
254 }
255
256 def EFI_DEVICE_PATH_PROTOCOL_TypeSummary (valobj,internal_dict):
257 #
258 #
259 #
260 if valobj.TypeIsPointerType():
261 # EFI_DEVICE_PATH_PROTOCOL *
262 return ""
263
264 Str = ""
265 if valobj.num_children == 3:
266 # EFI_DEVICE_PATH_PROTOCOL
267 Type = valobj.GetChildMemberWithName('Type').unsigned
268 SubType = valobj.GetChildMemberWithName('SubType').unsigned
269 if (Type, SubType) in device_path_dict:
270 TypeStr = device_path_dict[Type, SubType]
271 else:
272 TypeStr = ""
273
274 LenLow = valobj.GetChildMemberWithName('Length').GetChildAtIndex(0).unsigned
275 LenHigh = valobj.GetChildMemberWithName('Length').GetChildAtIndex(1).unsigned
276 Len = LenLow + (LenHigh >> 8)
277
278 Address = long ("%d" % valobj.addr)
279 if (Address == lldb.LLDB_INVALID_ADDRESS):
280 # Need to research this, it seems to be the nested struct case
281 ExprStr = ""
282 elif (Type & 0x7f == 0x7f):
283 ExprStr = "End Device Path" if SubType == 0xff else "End This Instance"
284 else:
285 ExprStr = "expr *(%s *)0x%08x" % (TypeStr, Address)
286
287 Str = " {\n"
288 Str += " (UINT8) Type = 0x%02x // %s\n" % (Type, "END" if (Type & 0x7f == 0x7f) else "")
289 Str += " (UINT8) SubType = 0x%02x // %s\n" % (SubType, ExprStr)
290 Str += " (UINT8 [2]) Length = { // 0x%04x (%d) bytes\n" % (Len, Len)
291 Str += " (UINT8) [0] = 0x%02x\n" % LenLow
292 Str += " (UINT8) [1] = 0x%02x\n" % LenHigh
293 Str += " }\n"
294 if (Type & 0x7f == 0x7f) and (SubType == 0xff):
295 pass
296 elif ExprStr != "":
297 NextNode = Address + Len
298 Str += "// Next node 'expr *(EFI_DEVICE_PATH_PROTOCOL *)0x%08x'\n" % NextNode
299
300 return Str
301
302
303
304 def TypePrintFormating(debugger):
305 #
306 # Set the default print formatting for EFI types in lldb.
307 # seems lldb defaults to decimal.
308 #
309 category = debugger.GetDefaultCategory()
310 FormatBool = lldb.SBTypeFormat(lldb.eFormatBoolean)
311 category.AddTypeFormat(lldb.SBTypeNameSpecifier("BOOLEAN"), FormatBool)
312
313 FormatHex = lldb.SBTypeFormat(lldb.eFormatHex)
314 category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT64"), FormatHex)
315 category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT64"), FormatHex)
316 category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT32"), FormatHex)
317 category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT32"), FormatHex)
318 category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT16"), FormatHex)
319 category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT16"), FormatHex)
320 category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT8"), FormatHex)
321 category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT8"), FormatHex)
322 category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINTN"), FormatHex)
323 category.AddTypeFormat(lldb.SBTypeNameSpecifier("INTN"), FormatHex)
324 category.AddTypeFormat(lldb.SBTypeNameSpecifier("CHAR8"), FormatHex)
325 category.AddTypeFormat(lldb.SBTypeNameSpecifier("CHAR16"), FormatHex)
326
327 category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_PHYSICAL_ADDRESS"), FormatHex)
328 category.AddTypeFormat(lldb.SBTypeNameSpecifier("PHYSICAL_ADDRESS"), FormatHex)
329 category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_STATUS"), FormatHex)
330 category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_TPL"), FormatHex)
331 category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_LBA"), FormatHex)
332 category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_BOOT_MODE"), FormatHex)
333 category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_FV_FILETYPE"), FormatHex)
334
335 #
336 # Smart type printing for EFI
337 #
338 debugger.HandleCommand("type summary add EFI_GUID --python-function lldbefi.EFI_GUID_TypeSummary")
339 debugger.HandleCommand("type summary add EFI_STATUS --python-function lldbefi.EFI_STATUS_TypeSummary")
340 debugger.HandleCommand("type summary add EFI_TPL --python-function lldbefi.EFI_TPL_TypeSummary")
341 debugger.HandleCommand("type summary add EFI_DEVICE_PATH_PROTOCOL --python-function lldbefi.EFI_DEVICE_PATH_PROTOCOL_TypeSummary")
342
343 debugger.HandleCommand("type summary add CHAR16 --python-function lldbefi.CHAR16_TypeSummary")
344 debugger.HandleCommand('type summary add --regex "CHAR16 \[[0-9]+\]" --python-function lldbefi.CHAR16_TypeSummary')
345 debugger.HandleCommand("type summary add CHAR8 --python-function lldbefi.CHAR8_TypeSummary")
346 debugger.HandleCommand('type summary add --regex "CHAR8 \[[0-9]+\]" --python-function lldbefi.CHAR8_TypeSummary')
347
348 debugger.HandleCommand(
349 'setting set frame-format "frame #${frame.index}: ${frame.pc}'
350 '{ ${module.file.basename}{:${function.name}()${function.pc-offset}}}'
351 '{ at ${line.file.fullpath}:${line.number}}\n"'
352 )
353
354 gEmulatorBreakWorkaroundNeeded = True
355
356 def LoadEmulatorEfiSymbols(frame, bp_loc , internal_dict):
357 #
358 # This is an lldb breakpoint script, and assumes the breakpoint is on a
359 # function with the same prototype as SecGdbScriptBreak(). The
360 # argument names are important as lldb looks them up.
361 #
362 # VOID
363 # SecGdbScriptBreak (
364 # char *FileName,
365 # int FileNameLength,
366 # long unsigned int LoadAddress,
367 # int AddSymbolFlag
368 # )
369 # {
370 # return;
371 # }
372 #
373 # When the emulator loads a PE/COFF image, it calls the stub function with
374 # the filename of the symbol file, the length of the FileName, the
375 # load address and a flag to indicate if this is a load or unload operation
376 #
377 global gEmulatorBreakWorkaroundNeeded
378
379 if gEmulatorBreakWorkaroundNeeded:
380 # turn off lldb debug prints on SIGALRM (EFI timer tick)
381 frame.thread.process.target.debugger.HandleCommand("process handle SIGALRM -n false")
382 gEmulatorBreakWorkaroundNeeded = False
383
384 # Convert C string to Python string
385 Error = lldb.SBError()
386 FileNamePtr = frame.FindVariable ("FileName").GetValueAsUnsigned()
387 FileNameLen = frame.FindVariable ("FileNameLength").GetValueAsUnsigned()
388
389 FileName = frame.thread.process.ReadCStringFromMemory (FileNamePtr, FileNameLen, Error)
390 if not Error.Success():
391 print("!ReadCStringFromMemory() did not find a %d byte C string at %x" % (FileNameLen, FileNamePtr))
392 # make breakpoint command continue
393 return False
394
395 debugger = frame.thread.process.target.debugger
396 if frame.FindVariable ("AddSymbolFlag").GetValueAsUnsigned() == 1:
397 LoadAddress = frame.FindVariable ("LoadAddress").GetValueAsUnsigned() - 0x240
398
399 debugger.HandleCommand ("target modules add %s" % FileName)
400 print("target modules load --slid 0x%x %s" % (LoadAddress, FileName))
401 debugger.HandleCommand ("target modules load --slide 0x%x --file %s" % (LoadAddress, FileName))
402 else:
403 target = debugger.GetSelectedTarget()
404 for SBModule in target.module_iter():
405 ModuleName = SBModule.GetFileSpec().GetDirectory() + '/'
406 ModuleName += SBModule.GetFileSpec().GetFilename()
407 if FileName == ModuleName or FileName == SBModule.GetFileSpec().GetFilename():
408 target.ClearModuleLoadAddress (SBModule)
409 if not target.RemoveModule (SBModule):
410 print("!lldb.target.RemoveModule (%s) FAILED" % SBModule)
411
412 # make breakpoint command continue
413 return False
414
415 def GuidToCStructStr (guid, Name=False):
416 #
417 # Convert a 16-byte bytesarray (or bytearray compat object) to C guid string
418 # { 0xB402621F, 0xA940, 0x1E4A, { 0x86, 0x6B, 0x4D, 0xC9, 0x16, 0x2B, 0x34, 0x7C } }
419 #
420 # Name=True means lookup name in GuidNameDict and us it if you find it
421 #
422
423 if not isinstance (guid, bytearray):
424 # convert guid object to UUID, and UUID to bytearray
425 Uuid = uuid.UUID(guid)
426 guid = bytearray (Uuid.bytes_le)
427
428 return "{ 0x%02.2X%02.2X%02.2X%02.2X, 0x%02.2X%02.2X, 0x%02.2X%02.2X, { 0x%02.2X, 0x%02.2X, 0x%02.2X, 0x%02.2X, 0x%02.2X, 0x%02.2X, 0x%02.2X, 0x%02.2X } }" % \
429 (guid[3], guid[2], guid[1], guid[0], guid[5], guid[4], guid[7], guid[6], guid[8], guid[9], guid[10], guid[11], guid[12], guid[13], guid[14], guid[15])
430
431 def ParseGuidString(GuidStr):
432 #
433 # Error check and convert C Guid init to string
434 # ParseGuidString("49152E77-1ADA-4764-B7A2-7AFEFED95E8B")
435 # ParseGuidString("{ 0xBA24B391, 0x73FD, 0xC54C, { 0x9E, 0xAF, 0x0C, 0xA7, 0x8A, 0x35, 0x46, 0xD1 } }")
436 #
437
438 if "{" in GuidStr :
439 # convert C form "{ 0xBA24B391, 0x73FD, 0xC54C, { 0x9E, 0xAF, 0x0C, 0xA7, 0x8A, 0x35, 0x46, 0xD1 } }"
440 # to string form BA24B391-73FD-C54C-9EAF-0CA78A3546D1
441 # make a list of Hex numbers like: ['0xBA24B391', '0x73FD', '0xC54C', '0x9E', '0xAF', '0x0C', '0xA7', '0x8A', '0x35', '0x46', '0xD1']
442 Hex = ''.join(x for x in GuidStr if x not in '{,}').split()
443 Str = "%08X-%04X-%04X-%02.2X%02.2X-%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X" % \
444 (int(Hex[0], 0), int(Hex[1], 0), int(Hex[2], 0), int(Hex[3], 0), int(Hex[4], 0), \
445 int(Hex[5], 0), int(Hex[6], 0), int(Hex[7], 0), int(Hex[8], 0), int(Hex[9], 0), int(Hex[10], 0))
446 elif GuidStr.count('-') == 4:
447 # validate "49152E77-1ADA-4764-B7A2-7AFEFED95E8B" form
448 Check = "%s" % str(uuid.UUID(GuidStr)).upper()
449 if GuidStr.upper() == Check:
450 Str = GuidStr.upper()
451 else:
452 Ste = ""
453 else:
454 Str = ""
455
456 return Str
457
458
459 def create_guid_options():
460 usage = "usage: %prog [data]"
461 description='''lookup EFI_GUID by CName, C struct, or GUID string and print out all three.
462 '''
463 parser = optparse.OptionParser(description=description, prog='guid',usage=usage)
464 return parser
465
466 def efi_guid_command(debugger, command, result, dict):
467 # Use the Shell Lexer to properly parse up command options just like a
468 # shell would
469 command_args = shlex.split(command)
470 parser = create_guid_options()
471 try:
472 (options, args) = parser.parse_args(command_args)
473 if len(args) >= 1:
474 if args[0] == "{":
475 # caller forgot to quote the string"
476 # mark arg[0] a string containing all args[n]
477 args[0] = ' '.join(args)
478 GuidStr = ParseGuidString (args[0])
479 if GuidStr == "":
480 # return Key of GuidNameDict for value args[0]
481 GuidStr = [Key for Key, Value in guid_dict.iteritems() if Value == args[0]][0]
482 GuidStr = GuidStr.upper()
483 except:
484 # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
485 # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
486 result.SetError ("option parsing failed")
487 return
488
489
490 if len(args) >= 1:
491 if GuidStr in guid_dict:
492 print("%s = %s" % (guid_dict[GuidStr], GuidStr))
493 print("%s = %s" % (guid_dict[GuidStr], GuidToCStructStr (GuidStr)))
494 else:
495 print(GuidStr)
496 else:
497 # dump entire dictionary
498 width = max(len(v) for k,v in guid_dict.iteritems())
499 for value in sorted(guid_dict, key=guid_dict.get):
500 print('%-*s %s %s' % (width, guid_dict[value], value, GuidToCStructStr(value)))
501
502 return
503
504
505 #
506 ########## Code that runs when this script is imported into LLDB ###########
507 #
508 def __lldb_init_module (debugger, internal_dict):
509 # This initializer is being run from LLDB in the embedded command interpreter
510 # Make the options so we can generate the help text for the new LLDB
511 # command line command prior to registering it with LLDB below
512
513 global guid_dict
514
515 # Source Guid.xref file if we can find it
516 inputfile = os.getcwd()
517 inputfile += os.sep + os.pardir + os.sep + 'FV' + os.sep + 'Guid.xref'
518 with open(inputfile) as f:
519 for line in f:
520 data = line.split(' ')
521 if len(data) >= 2:
522 guid_dict[data[0].upper()] = data[1].strip('\n')
523
524 # init EFI specific type formatters
525 TypePrintFormating (debugger)
526
527
528 # add guid command
529 parser = create_guid_options()
530 efi_guid_command.__doc__ = parser.format_help()
531 debugger.HandleCommand('command script add -f lldbefi.efi_guid_command guid')
532
533
534 Target = debugger.GetTargetAtIndex(0)
535 if Target:
536 Breakpoint = Target.BreakpointCreateByName('SecGdbScriptBreak')
537 if Breakpoint.GetNumLocations() == 1:
538 # Set the emulator breakpoints, if we are in the emulator
539 debugger.HandleCommand("breakpoint command add -s python -F lldbefi.LoadEmulatorEfiSymbols {id}".format(id=Breakpoint.GetID()))
540 print('Type r to run emulator. SecLldbScriptBreak armed. EFI modules should now get source level debugging in the emulator.')