1#!/usr/bin/python 2 3# 4# Copyright 2014 Apple Inc. All righes reserved. 5# 6# This program and the accompanying materials 7# are licensed and made available under the terms and conditions of the BSD License 8# which accompanies this distribution. The full text of the license may be found at 9# http://opensource.org/licenses/bsd-license.php. 10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12# 13 14import lldb 15import os 16import uuid 17import string 18import commands 19import optparse 20import shlex 21 22guid_dict = {} 23 24 25def EFI_GUID_TypeSummary (valobj,internal_dict): 26 """ Type summary for EFI GUID, print C Name if known 27 """ 28 # typedef struct { 29 # UINT32 Data1; 30 # UINT16 Data2; 31 # UINT16 Data3; 32 # UINT8 Data4[8]; 33 # } EFI_GUID; 34 SBError = lldb.SBError() 35 36 data1_val = valobj.GetChildMemberWithName('Data1') 37 data1 = data1_val.GetValueAsUnsigned(0) 38 data2_val = valobj.GetChildMemberWithName('Data2') 39 data2 = data2_val.GetValueAsUnsigned(0) 40 data3_val = valobj.GetChildMemberWithName('Data3') 41 data3 = data3_val.GetValueAsUnsigned(0) 42 str = "%x-%x-%x-" % (data1, data2, data3) 43 44 data4_val = valobj.GetChildMemberWithName('Data4') 45 for i in range (data4_val.num_children): 46 if i == 2: 47 str +='-' 48 str += "%02x" % data4_val.GetChildAtIndex(i).data.GetUnsignedInt8(SBError, 0) 49 50 return guid_dict.get (str.upper(), '') 51 52 53 54EFI_STATUS_Dict = { 55 (0x8000000000000000 | 1): "Load Error", 56 (0x8000000000000000 | 2): "Invalid Parameter", 57 (0x8000000000000000 | 3): "Unsupported", 58 (0x8000000000000000 | 4): "Bad Buffer Size", 59 (0x8000000000000000 | 5): "Buffer Too Small", 60 (0x8000000000000000 | 6): "Not Ready", 61 (0x8000000000000000 | 7): "Device Error", 62 (0x8000000000000000 | 8): "Write Protected", 63 (0x8000000000000000 | 9): "Out of Resources", 64 (0x8000000000000000 | 10): "Volume Corrupt", 65 (0x8000000000000000 | 11): "Volume Full", 66 (0x8000000000000000 | 12): "No Media", 67 (0x8000000000000000 | 13): "Media changed", 68 (0x8000000000000000 | 14): "Not Found", 69 (0x8000000000000000 | 15): "Access Denied", 70 (0x8000000000000000 | 16): "No Response", 71 (0x8000000000000000 | 17): "No mapping", 72 (0x8000000000000000 | 18): "Time out", 73 (0x8000000000000000 | 19): "Not started", 74 (0x8000000000000000 | 20): "Already started", 75 (0x8000000000000000 | 21): "Aborted", 76 (0x8000000000000000 | 22): "ICMP Error", 77 (0x8000000000000000 | 23): "TFTP Error", 78 (0x8000000000000000 | 24): "Protocol Error", 79 80 0 : "Success", 81 1 : "Warning Unknown Glyph", 82 2 : "Warning Delete Failure", 83 3 : "Warning Write Failure", 84 4 : "Warning Buffer Too Small", 85 86 (0x80000000 | 1): "Load Error", 87 (0x80000000 | 2): "Invalid Parameter", 88 (0x80000000 | 3): "Unsupported", 89 (0x80000000 | 4): "Bad Buffer Size", 90 (0x80000000 | 5): "Buffer Too Small", 91 (0x80000000 | 6): "Not Ready", 92 (0x80000000 | 7): "Device Error", 93 (0x80000000 | 8): "Write Protected", 94 (0x80000000 | 9): "Out of Resources", 95 (0x80000000 | 10): "Volume Corrupt", 96 (0x80000000 | 11): "Volume Full", 97 (0x80000000 | 12): "No Media", 98 (0x80000000 | 13): "Media changed", 99 (0x80000000 | 14): "Not Found", 100 (0x80000000 | 15): "Access Denied", 101 (0x80000000 | 16): "No Response", 102 (0x80000000 | 17): "No mapping", 103 (0x80000000 | 18): "Time out", 104 (0x80000000 | 19): "Not started", 105 (0x80000000 | 20): "Already started", 106 (0x80000000 | 21): "Aborted", 107 (0x80000000 | 22): "ICMP Error", 108 (0x80000000 | 23): "TFTP Error", 109 (0x80000000 | 24): "Protocol Error", 110} 111 112def EFI_STATUS_TypeSummary (valobj,internal_dict): 113 # 114 # Return summary string for EFI_STATUS from dictionary 115 # 116 Status = valobj.GetValueAsUnsigned(0) 117 return EFI_STATUS_Dict.get (Status, '') 118 119 120def EFI_TPL_TypeSummary (valobj,internal_dict): 121 # 122 # Return TPL values 123 # 124 125 if valobj.TypeIsPointerType(): 126 return "" 127 128 Tpl = valobj.GetValueAsUnsigned(0) 129 if Tpl < 4: 130 Str = "%d" % Tpl 131 elif Tpl == 6: 132 Str = "TPL_DRIVER (Obsolete Concept in edk2)" 133 elif Tpl < 8: 134 Str = "TPL_APPLICATION" 135 if Tpl - 4 > 0: 136 Str += " + " + "%d" % (Tpl - 4) 137 elif Tpl < 16: 138 Str = "TPL_CALLBACK" 139 if Tpl - 8 > 0: 140 Str += " + " + "%d" % (Tpl - 4) 141 elif Tpl < 31: 142 Str = "TPL_NOTIFY" 143 if Tpl - 16 > 0: 144 Str += " + " + "%d" % (Tpl - 4) 145 elif Tpl == 31: 146 Str = "TPL_HIGH_LEVEL" 147 else: 148 Str = "Invalid TPL" 149 150 return Str 151 152 153def CHAR16_TypeSummary (valobj,internal_dict): 154 # 155 # Display EFI CHAR16 'unsigned short' as string 156 # 157 SBError = lldb.SBError() 158 Str = '' 159 if valobj.TypeIsPointerType(): 160 if valobj.GetValueAsUnsigned () == 0: 161 return "NULL" 162 163 # CHAR16 * max string size 1024 164 for i in range (1024): 165 Char = valobj.GetPointeeData(i,1).GetUnsignedInt16(SBError, 0) 166 if SBError.fail or Char == 0: 167 break 168 Str += unichr (Char) 169 Str = 'L"' + Str + '"' 170 return Str.encode ('utf-8', 'replace') 171 172 if valobj.num_children == 0: 173 # CHAR16 174 if chr (valobj.unsigned) in string.printable: 175 Str = "L'" + unichr (valobj.unsigned) + "'" 176 return Str.encode ('utf-8', 'replace') 177 else: 178 # CHAR16 [] 179 for i in range (valobj.num_children): 180 Char = valobj.GetChildAtIndex(i).data.GetUnsignedInt16(SBError, 0) 181 if Char == 0: 182 break 183 Str += unichr (Char) 184 Str = 'L"' + Str + '"' 185 return Str.encode ('utf-8', 'replace') 186 187 return Str 188 189def CHAR8_TypeSummary (valobj,internal_dict): 190 # 191 # Display EFI CHAR8 'signed char' as string 192 # unichr() is used as a junk string can produce an error message like this: 193 # UnicodeEncodeError: 'ascii' codec can't encode character u'\x90' in position 1: ordinal not in range(128) 194 # 195 SBError = lldb.SBError() 196 Str = '' 197 if valobj.TypeIsPointerType(): 198 if valobj.GetValueAsUnsigned () == 0: 199 return "NULL" 200 201 # CHAR8 * max string size 1024 202 for i in range (1024): 203 Char = valobj.GetPointeeData(i,1).GetUnsignedInt8(SBError, 0) 204 if SBError.fail or Char == 0: 205 break 206 Str += unichr (Char) 207 Str = '"' + Str + '"' 208 return Str.encode ('utf-8', 'replace') 209 210 if valobj.num_children == 0: 211 # CHAR8 212 if chr (valobj.unsigned) in string.printable: 213 Str = '"' + unichr (valobj.unsigned) + '"' 214 return Str.encode ('utf-8', 'replace') 215 else: 216 # CHAR8 [] 217 for i in range (valobj.num_children): 218 Char = valobj.GetChildAtIndex(i).data.GetUnsignedInt8(SBError, 0) 219 if Char == 0: 220 break 221 Str += unichr (Char) 222 Str = '"' + Str + '"' 223 return Str.encode ('utf-8', 'replace') 224 225 return Str 226 227device_path_dict = { 228 (0x01, 0x01): "PCI_DEVICE_PATH", 229 (0x01, 0x02): "PCCARD_DEVICE_PATH", 230 (0x01, 0x03): "MEMMAP_DEVICE_PATH", 231 (0x01, 0x04): "VENDOR_DEVICE_PATH", 232 (0x01, 0x05): "CONTROLLER_DEVICE_PATH", 233 (0x02, 0x01): "ACPI_HID_DEVICE_PATH", 234 (0x02, 0x02): "ACPI_EXTENDED_HID_DEVICE_PATH", 235 (0x02, 0x03): "ACPI_ADR_DEVICE_PATH", 236 (0x03, 0x01): "ATAPI_DEVICE_PATH", 237 (0x03, 0x12): "SATA_DEVICE_PATH", 238 (0x03, 0x02): "SCSI_DEVICE_PATH", 239 (0x03, 0x03): "FIBRECHANNEL_DEVICE_PATH", 240 (0x03, 0x04): "F1394_DEVICE_PATH", 241 (0x03, 0x05): "USB_DEVICE_PATH", 242 (0x03, 0x0f): "USB_CLASS_DEVICE_PATH", 243 (0x03, 0x10): "FW_SBP2_UNIT_LUN_DEVICE_PATH", 244 (0x03, 0x11): "DEVICE_LOGICAL_UNIT_DEVICE_PATH", 245 (0x03, 0x06): "I2O_DEVICE_PATH", 246 (0x03, 0x0b): "MAC_ADDR_DEVICE_PATH", 247 (0x03, 0x0c): "IPv4_DEVICE_PATH", 248 (0x03, 0x09): "INFINIBAND_DEVICE_PATH", 249 (0x03, 0x0e): "UART_DEVICE_PATH", 250 (0x03, 0x0a): "VENDOR_DEVICE_PATH", 251 (0x03, 0x13): "ISCSI_DEVICE_PATH", 252 (0x04, 0x01): "HARDDRIVE_DEVICE_PATH", 253 (0x04, 0x02): "CDROM_DEVICE_PATH", 254 (0x04, 0x03): "VENDOR_DEVICE_PATH", 255 (0x04, 0x04): "FILEPATH_DEVICE_PATH", 256 (0x04, 0x05): "MEDIA_PROTOCOL_DEVICE_PATH", 257 (0x05, 0x01): "BBS_BBS_DEVICE_PATH", 258 (0x7F, 0xFF): "EFI_DEVICE_PATH_PROTOCOL", 259 (0xFF, 0xFF): "EFI_DEVICE_PATH_PROTOCOL", 260} 261 262def EFI_DEVICE_PATH_PROTOCOL_TypeSummary (valobj,internal_dict): 263 # 264 # 265 # 266 if valobj.TypeIsPointerType(): 267 # EFI_DEVICE_PATH_PROTOCOL * 268 return "" 269 270 Str = "" 271 if valobj.num_children == 3: 272 # EFI_DEVICE_PATH_PROTOCOL 273 Type = valobj.GetChildMemberWithName('Type').unsigned 274 SubType = valobj.GetChildMemberWithName('SubType').unsigned 275 if (Type, SubType) in device_path_dict: 276 TypeStr = device_path_dict[Type, SubType] 277 else: 278 TypeStr = "" 279 280 LenLow = valobj.GetChildMemberWithName('Length').GetChildAtIndex(0).unsigned 281 LenHigh = valobj.GetChildMemberWithName('Length').GetChildAtIndex(1).unsigned 282 Len = LenLow + (LenHigh >> 8) 283 284 Address = long ("%d" % valobj.addr) 285 if (Address == lldb.LLDB_INVALID_ADDRESS): 286 # Need to reserach this, it seems to be the nested struct case 287 ExprStr = "" 288 elif (Type & 0x7f == 0x7f): 289 ExprStr = "End Device Path" if SubType == 0xff else "End This Instance" 290 else: 291 ExprStr = "expr *(%s *)0x%08x" % (TypeStr, Address) 292 293 Str = " {\n" 294 Str += " (UINT8) Type = 0x%02x // %s\n" % (Type, "END" if (Type & 0x7f == 0x7f) else "") 295 Str += " (UINT8) SubType = 0x%02x // %s\n" % (SubType, ExprStr) 296 Str += " (UINT8 [2]) Length = { // 0x%04x (%d) bytes\n" % (Len, Len) 297 Str += " (UINT8) [0] = 0x%02x\n" % LenLow 298 Str += " (UINT8) [1] = 0x%02x\n" % LenHigh 299 Str += " }\n" 300 if (Type & 0x7f == 0x7f) and (SubType == 0xff): 301 pass 302 elif ExprStr != "": 303 NextNode = Address + Len 304 Str += "// Next node 'expr *(EFI_DEVICE_PATH_PROTOCOL *)0x%08x'\n" % NextNode 305 306 return Str 307 308 309 310def TypePrintFormating(debugger): 311 # 312 # Set the default print formating for EFI types in lldb. 313 # seems lldb defaults to decimal. 314 # 315 category = debugger.GetDefaultCategory() 316 FormatBool = lldb.SBTypeFormat(lldb.eFormatBoolean) 317 category.AddTypeFormat(lldb.SBTypeNameSpecifier("BOOLEAN"), FormatBool) 318 319 FormatHex = lldb.SBTypeFormat(lldb.eFormatHex) 320 category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT64"), FormatHex) 321 category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT64"), FormatHex) 322 category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT32"), FormatHex) 323 category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT32"), FormatHex) 324 category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT16"), FormatHex) 325 category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT16"), FormatHex) 326 category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT8"), FormatHex) 327 category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT8"), FormatHex) 328 category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINTN"), FormatHex) 329 category.AddTypeFormat(lldb.SBTypeNameSpecifier("INTN"), FormatHex) 330 category.AddTypeFormat(lldb.SBTypeNameSpecifier("CHAR8"), FormatHex) 331 category.AddTypeFormat(lldb.SBTypeNameSpecifier("CHAR16"), FormatHex) 332 333 category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_PHYSICAL_ADDRESS"), FormatHex) 334 category.AddTypeFormat(lldb.SBTypeNameSpecifier("PHYSICAL_ADDRESS"), FormatHex) 335 category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_STATUS"), FormatHex) 336 category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_TPL"), FormatHex) 337 category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_LBA"), FormatHex) 338 category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_BOOT_MODE"), FormatHex) 339 category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_FV_FILETYPE"), FormatHex) 340 341 # 342 # Smart type printing for EFI 343 # 344 debugger.HandleCommand("type summary add EFI_GUID --python-function lldbefi.EFI_GUID_TypeSummary") 345 debugger.HandleCommand("type summary add EFI_STATUS --python-function lldbefi.EFI_STATUS_TypeSummary") 346 debugger.HandleCommand("type summary add EFI_TPL --python-function lldbefi.EFI_TPL_TypeSummary") 347 debugger.HandleCommand("type summary add EFI_DEVICE_PATH_PROTOCOL --python-function lldbefi.EFI_DEVICE_PATH_PROTOCOL_TypeSummary") 348 349 debugger.HandleCommand("type summary add CHAR16 --python-function lldbefi.CHAR16_TypeSummary") 350 debugger.HandleCommand('type summary add --regex "CHAR16 \[[0-9]+\]" --python-function lldbefi.CHAR16_TypeSummary') 351 debugger.HandleCommand("type summary add CHAR8 --python-function lldbefi.CHAR8_TypeSummary") 352 debugger.HandleCommand('type summary add --regex "CHAR8 \[[0-9]+\]" --python-function lldbefi.CHAR8_TypeSummary') 353 354 355gEmulatorBreakWorkaroundNeeded = True 356 357def LoadEmulatorEfiSymbols(frame, bp_loc , internal_dict): 358 # 359 # This is an lldb breakpoint script, and assumes the breakpoint is on a 360 # function with the same prototype as SecGdbScriptBreak(). The 361 # argument names are important as lldb looks them up. 362 # 363 # VOID 364 # SecGdbScriptBreak ( 365 # char *FileName, 366 # int FileNameLength, 367 # long unsigned int LoadAddress, 368 # int AddSymbolFlag 369 # ) 370 # { 371 # return; 372 # } 373 # 374 # When the emulator loads a PE/COFF image, it calls the stub function with 375 # the filename of the symbol file, the length of the FileName, the 376 # load address and a flag to indicate if this is a load or unload operation 377 # 378 global gEmulatorBreakWorkaroundNeeded 379 380 if gEmulatorBreakWorkaroundNeeded: 381 # turn off lldb debug prints on SIGALRM (EFI timer tick) 382 frame.thread.process.target.debugger.HandleCommand("process handle SIGALRM -n false") 383 gEmulatorBreakWorkaroundNeeded = False 384 385 # Convert C string to Python string 386 Error = lldb.SBError() 387 FileNamePtr = frame.FindVariable ("FileName").GetValueAsUnsigned() 388 FileNameLen = frame.FindVariable ("FileNameLength").GetValueAsUnsigned() 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 contiue 393 frame.GetThread().GetProcess().Continue() 394 395 debugger = frame.thread.process.target.debugger 396 if frame.FindVariable ("AddSymbolFlag").GetValueAsUnsigned() == 1: 397 LoadAddress = frame.FindVariable ("LoadAddress").GetValueAsUnsigned() 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 contiue 413 frame.thread.process.Continue() 414 415def GuidToCStructStr (guid, Name=False): 416 # 417 # Convert a 16-byte bytesarry (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 431def 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 459def 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 466def 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# 508def __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 formaters 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.' 541