Fix various typos in comments and documentation. Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Andrew Fish <afish@apple.com> Cc: Ray Ni <ray.ni@intel.com> Signed-off-by: Antoine Coeur <coeur@gmx.fr> Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Signed-off-by: Philippe Mathieu-Daude <philmd@redhat.com> Message-Id: <20200207010831.9046-6-philmd@redhat.com>
		
			
				
	
	
		
			542 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			542 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/usr/bin/python
 | |
| 
 | |
| #
 | |
| #  Copyright 2014 Apple Inc. All rights reserved.
 | |
| #
 | |
| #  SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| #
 | |
| 
 | |
| import lldb
 | |
| import os
 | |
| import uuid
 | |
| import string
 | |
| import commands
 | |
| import optparse
 | |
| import shlex
 | |
| 
 | |
| guid_dict = {}
 | |
| 
 | |
| 
 | |
| def EFI_GUID_TypeSummary (valobj,internal_dict):
 | |
|     """ Type summary for EFI GUID, print C Name if known
 | |
|     """
 | |
|     # typedef struct {
 | |
|     #   UINT32  Data1;
 | |
|     #   UINT16  Data2;
 | |
|     #   UINT16  Data3;
 | |
|     #   UINT8   Data4[8];
 | |
|     # } EFI_GUID;
 | |
|     SBError = lldb.SBError()
 | |
| 
 | |
|     data1_val = valobj.GetChildMemberWithName('Data1')
 | |
|     data1 = data1_val.GetValueAsUnsigned(0)
 | |
|     data2_val = valobj.GetChildMemberWithName('Data2')
 | |
|     data2 = data2_val.GetValueAsUnsigned(0)
 | |
|     data3_val = valobj.GetChildMemberWithName('Data3')
 | |
|     data3 = data3_val.GetValueAsUnsigned(0)
 | |
|     str = "%x-%x-%x-" % (data1, data2, data3)
 | |
| 
 | |
|     data4_val = valobj.GetChildMemberWithName('Data4')
 | |
|     for i in range (data4_val.num_children):
 | |
|         if i == 2:
 | |
|             str +='-'
 | |
|         str += "%02x" % data4_val.GetChildAtIndex(i).data.GetUnsignedInt8(SBError, 0)
 | |
| 
 | |
|     return guid_dict.get (str.upper(), '')
 | |
| 
 | |
| 
 | |
| 
 | |
| EFI_STATUS_Dict = {
 | |
|     (0x8000000000000000 |  1): "Load Error",
 | |
|     (0x8000000000000000 |  2): "Invalid Parameter",
 | |
|     (0x8000000000000000 |  3): "Unsupported",
 | |
|     (0x8000000000000000 |  4): "Bad Buffer Size",
 | |
|     (0x8000000000000000 |  5): "Buffer Too Small",
 | |
|     (0x8000000000000000 |  6): "Not Ready",
 | |
|     (0x8000000000000000 |  7): "Device Error",
 | |
|     (0x8000000000000000 |  8): "Write Protected",
 | |
|     (0x8000000000000000 |  9): "Out of Resources",
 | |
|     (0x8000000000000000 | 10): "Volume Corrupt",
 | |
|     (0x8000000000000000 | 11): "Volume Full",
 | |
|     (0x8000000000000000 | 12): "No Media",
 | |
|     (0x8000000000000000 | 13): "Media changed",
 | |
|     (0x8000000000000000 | 14): "Not Found",
 | |
|     (0x8000000000000000 | 15): "Access Denied",
 | |
|     (0x8000000000000000 | 16): "No Response",
 | |
|     (0x8000000000000000 | 17): "No mapping",
 | |
|     (0x8000000000000000 | 18): "Time out",
 | |
|     (0x8000000000000000 | 19): "Not started",
 | |
|     (0x8000000000000000 | 20): "Already started",
 | |
|     (0x8000000000000000 | 21): "Aborted",
 | |
|     (0x8000000000000000 | 22): "ICMP Error",
 | |
|     (0x8000000000000000 | 23): "TFTP Error",
 | |
|     (0x8000000000000000 | 24): "Protocol Error",
 | |
| 
 | |
|                           0 : "Success",
 | |
|                           1 : "Warning Unknown Glyph",
 | |
|                           2 : "Warning Delete Failure",
 | |
|                           3 : "Warning Write Failure",
 | |
|                           4 : "Warning Buffer Too Small",
 | |
| 
 | |
|     (0x80000000         |  1): "Load Error",
 | |
|     (0x80000000         |  2): "Invalid Parameter",
 | |
|     (0x80000000         |  3): "Unsupported",
 | |
|     (0x80000000         |  4): "Bad Buffer Size",
 | |
|     (0x80000000         |  5): "Buffer Too Small",
 | |
|     (0x80000000         |  6): "Not Ready",
 | |
|     (0x80000000         |  7): "Device Error",
 | |
|     (0x80000000         |  8): "Write Protected",
 | |
|     (0x80000000         |  9): "Out of Resources",
 | |
|     (0x80000000         | 10): "Volume Corrupt",
 | |
|     (0x80000000         | 11): "Volume Full",
 | |
|     (0x80000000         | 12): "No Media",
 | |
|     (0x80000000         | 13): "Media changed",
 | |
|     (0x80000000         | 14): "Not Found",
 | |
|     (0x80000000         | 15): "Access Denied",
 | |
|     (0x80000000         | 16): "No Response",
 | |
|     (0x80000000         | 17): "No mapping",
 | |
|     (0x80000000         | 18): "Time out",
 | |
|     (0x80000000         | 19): "Not started",
 | |
|     (0x80000000         | 20): "Already started",
 | |
|     (0x80000000         | 21): "Aborted",
 | |
|     (0x80000000         | 22): "ICMP Error",
 | |
|     (0x80000000         | 23): "TFTP Error",
 | |
|     (0x80000000         | 24): "Protocol Error",
 | |
| }
 | |
| 
 | |
| def EFI_STATUS_TypeSummary (valobj,internal_dict):
 | |
|   #
 | |
|   # Return summary string for EFI_STATUS from dictionary
 | |
|   #
 | |
|   Status = valobj.GetValueAsUnsigned(0)
 | |
|   return EFI_STATUS_Dict.get (Status, '')
 | |
| 
 | |
| 
 | |
| def EFI_TPL_TypeSummary (valobj,internal_dict):
 | |
|   #
 | |
|   # Return TPL values
 | |
|   #
 | |
| 
 | |
|   if valobj.TypeIsPointerType():
 | |
|     return ""
 | |
| 
 | |
|   Tpl = valobj.GetValueAsUnsigned(0)
 | |
|   if   Tpl < 4:
 | |
|     Str = "%d" % Tpl
 | |
|   elif Tpl == 6:
 | |
|     Str = "TPL_DRIVER (Obsolete Concept in edk2)"
 | |
|   elif Tpl < 8:
 | |
|     Str = "TPL_APPLICATION"
 | |
|     if Tpl - 4 > 0:
 | |
|       Str += " + " + "%d" % (Tpl - 4)
 | |
|   elif Tpl < 16:
 | |
|     Str = "TPL_CALLBACK"
 | |
|     if Tpl - 8 > 0:
 | |
|       Str += " + " + "%d" % (Tpl - 4)
 | |
|   elif Tpl < 31:
 | |
|     Str = "TPL_NOTIFY"
 | |
|     if Tpl - 16 > 0:
 | |
|       Str += " + " + "%d" % (Tpl - 4)
 | |
|   elif Tpl == 31:
 | |
|     Str = "TPL_HIGH_LEVEL"
 | |
|   else:
 | |
|     Str = "Invalid TPL"
 | |
| 
 | |
|   return Str
 | |
| 
 | |
| 
 | |
| def CHAR16_TypeSummary (valobj,internal_dict):
 | |
|   #
 | |
|   # Display EFI CHAR16 'unsigned short' as string
 | |
|   #
 | |
|   SBError = lldb.SBError()
 | |
|   Str = ''
 | |
|   if valobj.TypeIsPointerType():
 | |
|     if valobj.GetValueAsUnsigned () == 0:
 | |
|       return "NULL"
 | |
| 
 | |
|     # CHAR16 *   max string size 1024
 | |
|     for i in range (1024):
 | |
|       Char = valobj.GetPointeeData(i,1).GetUnsignedInt16(SBError, 0)
 | |
|       if SBError.fail or Char == 0:
 | |
|         break
 | |
|       Str += unichr (Char)
 | |
|     Str = 'L"' + Str + '"'
 | |
|     return Str.encode ('utf-8', 'replace')
 | |
| 
 | |
|   if valobj.num_children == 0:
 | |
|     # CHAR16
 | |
|     if chr (valobj.unsigned) in string.printable:
 | |
|       Str = "L'" + unichr (valobj.unsigned) + "'"
 | |
|       return Str.encode ('utf-8', 'replace')
 | |
|   else:
 | |
|     # CHAR16 []
 | |
|     for i in range (valobj.num_children):
 | |
|       Char = valobj.GetChildAtIndex(i).data.GetUnsignedInt16(SBError, 0)
 | |
|       if Char == 0:
 | |
|         break
 | |
|       Str += unichr (Char)
 | |
|     Str = 'L"' + Str + '"'
 | |
|     return Str.encode ('utf-8', 'replace')
 | |
| 
 | |
|   return Str
 | |
| 
 | |
| def CHAR8_TypeSummary (valobj,internal_dict):
 | |
|   #
 | |
|   # Display EFI CHAR8 'signed char' as string
 | |
|   # unichr() is used as a junk string can produce an error message like this:
 | |
|   # UnicodeEncodeError: 'ascii' codec can't encode character u'\x90' in position 1: ordinal not in range(128)
 | |
|   #
 | |
|   SBError = lldb.SBError()
 | |
|   Str = ''
 | |
|   if valobj.TypeIsPointerType():
 | |
|     if valobj.GetValueAsUnsigned () == 0:
 | |
|       return "NULL"
 | |
| 
 | |
|     # CHAR8 *   max string size 1024
 | |
|     for i in range (1024):
 | |
|       Char = valobj.GetPointeeData(i,1).GetUnsignedInt8(SBError, 0)
 | |
|       if SBError.fail or Char == 0:
 | |
|         break
 | |
|       Str += unichr (Char)
 | |
|     Str = '"' + Str + '"'
 | |
|     return Str.encode ('utf-8', 'replace')
 | |
| 
 | |
|   if valobj.num_children == 0:
 | |
|     # CHAR8
 | |
|     if chr (valobj.unsigned) in string.printable:
 | |
|       Str = '"' + unichr (valobj.unsigned)  + '"'
 | |
|       return Str.encode ('utf-8', 'replace')
 | |
|   else:
 | |
|     # CHAR8 []
 | |
|     for i in range (valobj.num_children):
 | |
|       Char = valobj.GetChildAtIndex(i).data.GetUnsignedInt8(SBError, 0)
 | |
|       if Char == 0:
 | |
|         break
 | |
|       Str += unichr (Char)
 | |
|     Str = '"' + Str + '"'
 | |
|     return Str.encode ('utf-8', 'replace')
 | |
| 
 | |
|   return Str
 | |
| 
 | |
| device_path_dict = {
 | |
|   (0x01, 0x01): "PCI_DEVICE_PATH",
 | |
|   (0x01, 0x02): "PCCARD_DEVICE_PATH",
 | |
|   (0x01, 0x03): "MEMMAP_DEVICE_PATH",
 | |
|   (0x01, 0x04): "VENDOR_DEVICE_PATH",
 | |
|   (0x01, 0x05): "CONTROLLER_DEVICE_PATH",
 | |
|   (0x02, 0x01): "ACPI_HID_DEVICE_PATH",
 | |
|   (0x02, 0x02): "ACPI_EXTENDED_HID_DEVICE_PATH",
 | |
|   (0x02, 0x03): "ACPI_ADR_DEVICE_PATH",
 | |
|   (0x03, 0x01): "ATAPI_DEVICE_PATH",
 | |
|   (0x03, 0x12): "SATA_DEVICE_PATH",
 | |
|   (0x03, 0x02): "SCSI_DEVICE_PATH",
 | |
|   (0x03, 0x03): "FIBRECHANNEL_DEVICE_PATH",
 | |
|   (0x03, 0x04): "F1394_DEVICE_PATH",
 | |
|   (0x03, 0x05): "USB_DEVICE_PATH",
 | |
|   (0x03, 0x0f): "USB_CLASS_DEVICE_PATH",
 | |
|   (0x03, 0x10): "FW_SBP2_UNIT_LUN_DEVICE_PATH",
 | |
|   (0x03, 0x11): "DEVICE_LOGICAL_UNIT_DEVICE_PATH",
 | |
|   (0x03, 0x06): "I2O_DEVICE_PATH",
 | |
|   (0x03, 0x0b): "MAC_ADDR_DEVICE_PATH",
 | |
|   (0x03, 0x0c): "IPv4_DEVICE_PATH",
 | |
|   (0x03, 0x09): "INFINIBAND_DEVICE_PATH",
 | |
|   (0x03, 0x0e): "UART_DEVICE_PATH",
 | |
|   (0x03, 0x0a): "VENDOR_DEVICE_PATH",
 | |
|   (0x03, 0x13): "ISCSI_DEVICE_PATH",
 | |
|   (0x04, 0x01): "HARDDRIVE_DEVICE_PATH",
 | |
|   (0x04, 0x02): "CDROM_DEVICE_PATH",
 | |
|   (0x04, 0x03): "VENDOR_DEVICE_PATH",
 | |
|   (0x04, 0x04): "FILEPATH_DEVICE_PATH",
 | |
|   (0x04, 0x05): "MEDIA_PROTOCOL_DEVICE_PATH",
 | |
|   (0x05, 0x01): "BBS_BBS_DEVICE_PATH",
 | |
|   (0x7F, 0xFF): "EFI_DEVICE_PATH_PROTOCOL",
 | |
|   (0xFF, 0xFF): "EFI_DEVICE_PATH_PROTOCOL",
 | |
| }
 | |
| 
 | |
| def EFI_DEVICE_PATH_PROTOCOL_TypeSummary (valobj,internal_dict):
 | |
|   #
 | |
|   #
 | |
|   #
 | |
|   if valobj.TypeIsPointerType():
 | |
|     # EFI_DEVICE_PATH_PROTOCOL *
 | |
|     return ""
 | |
| 
 | |
|   Str = ""
 | |
|   if valobj.num_children == 3:
 | |
|     # EFI_DEVICE_PATH_PROTOCOL
 | |
|     Type    = valobj.GetChildMemberWithName('Type').unsigned
 | |
|     SubType = valobj.GetChildMemberWithName('SubType').unsigned
 | |
|     if (Type, SubType) in device_path_dict:
 | |
|       TypeStr = device_path_dict[Type, SubType]
 | |
|     else:
 | |
|       TypeStr = ""
 | |
| 
 | |
|     LenLow  = valobj.GetChildMemberWithName('Length').GetChildAtIndex(0).unsigned
 | |
|     LenHigh = valobj.GetChildMemberWithName('Length').GetChildAtIndex(1).unsigned
 | |
|     Len = LenLow + (LenHigh >> 8)
 | |
| 
 | |
|     Address = long ("%d" % valobj.addr)
 | |
|     if (Address == lldb.LLDB_INVALID_ADDRESS):
 | |
|       # Need to research this, it seems to be the nested struct case
 | |
|       ExprStr = ""
 | |
|     elif (Type & 0x7f == 0x7f):
 | |
|       ExprStr = "End Device Path" if SubType == 0xff else "End This Instance"
 | |
|     else:
 | |
|       ExprStr = "expr *(%s *)0x%08x" % (TypeStr, Address)
 | |
| 
 | |
|     Str =  " {\n"
 | |
|     Str += "   (UINT8) Type    = 0x%02x // %s\n" % (Type, "END" if (Type & 0x7f == 0x7f) else "")
 | |
|     Str += "   (UINT8) SubType = 0x%02x // %s\n" % (SubType, ExprStr)
 | |
|     Str += "   (UINT8 [2]) Length = { // 0x%04x (%d) bytes\n" % (Len, Len)
 | |
|     Str += "     (UINT8) [0] = 0x%02x\n" % LenLow
 | |
|     Str += "     (UINT8) [1] = 0x%02x\n" % LenHigh
 | |
|     Str +=  "   }\n"
 | |
|     if (Type & 0x7f == 0x7f) and (SubType == 0xff):
 | |
|       pass
 | |
|     elif ExprStr != "":
 | |
|       NextNode = Address + Len
 | |
|       Str += "// Next node 'expr *(EFI_DEVICE_PATH_PROTOCOL *)0x%08x'\n" % NextNode
 | |
| 
 | |
|   return Str
 | |
| 
 | |
| 
 | |
| 
 | |
| def TypePrintFormating(debugger):
 | |
|     #
 | |
|     # Set the default print formatting for EFI types in lldb.
 | |
|     # seems lldb defaults to decimal.
 | |
|     #
 | |
|     category = debugger.GetDefaultCategory()
 | |
|     FormatBool = lldb.SBTypeFormat(lldb.eFormatBoolean)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("BOOLEAN"), FormatBool)
 | |
| 
 | |
|     FormatHex  = lldb.SBTypeFormat(lldb.eFormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT64"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT64"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT32"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT32"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT16"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT16"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINT8"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("INT8"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("UINTN"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("INTN"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("CHAR8"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("CHAR16"), FormatHex)
 | |
| 
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_PHYSICAL_ADDRESS"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("PHYSICAL_ADDRESS"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_STATUS"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_TPL"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_LBA"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_BOOT_MODE"), FormatHex)
 | |
|     category.AddTypeFormat(lldb.SBTypeNameSpecifier("EFI_FV_FILETYPE"), FormatHex)
 | |
| 
 | |
|     #
 | |
|     # Smart type printing for EFI
 | |
|     #
 | |
|     debugger.HandleCommand("type summary add EFI_GUID --python-function lldbefi.EFI_GUID_TypeSummary")
 | |
|     debugger.HandleCommand("type summary add EFI_STATUS --python-function lldbefi.EFI_STATUS_TypeSummary")
 | |
|     debugger.HandleCommand("type summary add EFI_TPL --python-function lldbefi.EFI_TPL_TypeSummary")
 | |
|     debugger.HandleCommand("type summary add EFI_DEVICE_PATH_PROTOCOL --python-function lldbefi.EFI_DEVICE_PATH_PROTOCOL_TypeSummary")
 | |
| 
 | |
|     debugger.HandleCommand("type summary add CHAR16 --python-function lldbefi.CHAR16_TypeSummary")
 | |
|     debugger.HandleCommand('type summary add --regex "CHAR16 \[[0-9]+\]" --python-function lldbefi.CHAR16_TypeSummary')
 | |
|     debugger.HandleCommand("type summary add CHAR8 --python-function lldbefi.CHAR8_TypeSummary")
 | |
|     debugger.HandleCommand('type summary add --regex "CHAR8 \[[0-9]+\]" --python-function lldbefi.CHAR8_TypeSummary')
 | |
| 
 | |
|     debugger.HandleCommand(
 | |
|       'setting set frame-format "frame #${frame.index}: ${frame.pc}'
 | |
|       '{ ${module.file.basename}{:${function.name}()${function.pc-offset}}}'
 | |
|       '{ at ${line.file.fullpath}:${line.number}}\n"'
 | |
|       )
 | |
| 
 | |
| gEmulatorBreakWorkaroundNeeded = True
 | |
| 
 | |
| def LoadEmulatorEfiSymbols(frame, bp_loc , internal_dict):
 | |
|     #
 | |
|     # This is an lldb breakpoint script, and assumes the breakpoint is on a
 | |
|     # function with the same prototype as SecGdbScriptBreak(). The
 | |
|     # argument names are important as lldb looks them up.
 | |
|     #
 | |
|     # VOID
 | |
|     # SecGdbScriptBreak (
 | |
|     #   char                *FileName,
 | |
|     #   int                 FileNameLength,
 | |
|     #   long unsigned int   LoadAddress,
 | |
|     #   int                 AddSymbolFlag
 | |
|     #   )
 | |
|     # {
 | |
|     #   return;
 | |
|     # }
 | |
|     #
 | |
|     # When the emulator loads a PE/COFF image, it calls the stub function with
 | |
|     # the filename of the symbol file, the length of the FileName, the
 | |
|     # load address and a flag to indicate if this is a load or unload operation
 | |
|     #
 | |
|     global gEmulatorBreakWorkaroundNeeded
 | |
| 
 | |
|     if gEmulatorBreakWorkaroundNeeded:
 | |
|         # turn off lldb debug prints on SIGALRM (EFI timer tick)
 | |
|         frame.thread.process.target.debugger.HandleCommand("process handle SIGALRM -n false")
 | |
|         gEmulatorBreakWorkaroundNeeded = False
 | |
| 
 | |
|     # Convert C string to Python string
 | |
|     Error = lldb.SBError()
 | |
|     FileNamePtr = frame.FindVariable ("FileName").GetValueAsUnsigned()
 | |
|     FileNameLen = frame.FindVariable ("FileNameLength").GetValueAsUnsigned()
 | |
| 
 | |
|     FileName = frame.thread.process.ReadCStringFromMemory (FileNamePtr, FileNameLen, Error)
 | |
|     if not Error.Success():
 | |
|         print "!ReadCStringFromMemory() did not find a %d byte C string at %x" % (FileNameLen, FileNamePtr)
 | |
|         # make breakpoint command continue
 | |
|         return False
 | |
| 
 | |
|     debugger = frame.thread.process.target.debugger
 | |
|     if frame.FindVariable ("AddSymbolFlag").GetValueAsUnsigned() == 1:
 | |
|         LoadAddress = frame.FindVariable ("LoadAddress").GetValueAsUnsigned() - 0x240
 | |
| 
 | |
|         debugger.HandleCommand ("target modules add  %s" % FileName)
 | |
|         print "target modules load --slid 0x%x %s" % (LoadAddress, FileName)
 | |
|         debugger.HandleCommand ("target modules load --slide 0x%x --file %s" % (LoadAddress, FileName))
 | |
|     else:
 | |
|         target = debugger.GetSelectedTarget()
 | |
|         for SBModule in target.module_iter():
 | |
|             ModuleName  = SBModule.GetFileSpec().GetDirectory() + '/'
 | |
|             ModuleName += SBModule.GetFileSpec().GetFilename()
 | |
|             if FileName == ModuleName or FileName == SBModule.GetFileSpec().GetFilename():
 | |
|                 target.ClearModuleLoadAddress (SBModule)
 | |
|                 if not target.RemoveModule (SBModule):
 | |
|                     print "!lldb.target.RemoveModule (%s) FAILED" % SBModule
 | |
| 
 | |
|     # make breakpoint command continue
 | |
|     return False
 | |
| 
 | |
| def GuidToCStructStr (guid, Name=False):
 | |
|   #
 | |
|   # Convert a 16-byte bytesarray (or bytearray compat object) to C guid string
 | |
|   # { 0xB402621F, 0xA940, 0x1E4A, { 0x86, 0x6B, 0x4D, 0xC9, 0x16, 0x2B, 0x34, 0x7C } }
 | |
|   #
 | |
|   # Name=True means lookup name in GuidNameDict and us it if you find it
 | |
|   #
 | |
| 
 | |
|   if not isinstance (guid, bytearray):
 | |
|     # convert guid object to UUID, and UUID to bytearray
 | |
|     Uuid = uuid.UUID(guid)
 | |
|     guid = bytearray (Uuid.bytes_le)
 | |
| 
 | |
|   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 } }" % \
 | |
|          (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])
 | |
| 
 | |
| def ParseGuidString(GuidStr):
 | |
|   #
 | |
|   # Error check and convert C Guid init to string
 | |
|   # ParseGuidString("49152E77-1ADA-4764-B7A2-7AFEFED95E8B")
 | |
|   # ParseGuidString("{ 0xBA24B391, 0x73FD, 0xC54C, { 0x9E, 0xAF, 0x0C, 0xA7, 0x8A, 0x35, 0x46, 0xD1 } }")
 | |
|   #
 | |
| 
 | |
|   if "{" in GuidStr                                                                                         :
 | |
|     # convert C form "{ 0xBA24B391, 0x73FD, 0xC54C, { 0x9E, 0xAF, 0x0C, 0xA7, 0x8A, 0x35, 0x46, 0xD1 } }"
 | |
|     # to string form BA24B391-73FD-C54C-9EAF-0CA78A3546D1
 | |
|     # make a list of Hex numbers like: ['0xBA24B391', '0x73FD', '0xC54C', '0x9E', '0xAF', '0x0C', '0xA7', '0x8A', '0x35', '0x46', '0xD1']
 | |
|     Hex = ''.join(x for x in GuidStr if x not in '{,}').split()
 | |
|     Str = "%08X-%04X-%04X-%02.2X%02.2X-%02.2X%02.2X%02.2X%02.2X%02.2X%02.2X" % \
 | |
|           (int(Hex[0], 0), int(Hex[1], 0), int(Hex[2], 0), int(Hex[3], 0), int(Hex[4], 0), \
 | |
|            int(Hex[5], 0), int(Hex[6], 0), int(Hex[7], 0), int(Hex[8], 0), int(Hex[9], 0), int(Hex[10], 0))
 | |
|   elif GuidStr.count('-') == 4:
 | |
|     # validate "49152E77-1ADA-4764-B7A2-7AFEFED95E8B" form
 | |
|     Check = "%s" % str(uuid.UUID(GuidStr)).upper()
 | |
|     if GuidStr.upper() == Check:
 | |
|       Str = GuidStr.upper()
 | |
|     else:
 | |
|       Ste = ""
 | |
|   else:
 | |
|     Str = ""
 | |
| 
 | |
|   return Str
 | |
| 
 | |
| 
 | |
| def create_guid_options():
 | |
|     usage = "usage: %prog [data]"
 | |
|     description='''lookup EFI_GUID by CName, C struct, or GUID string and print out all three.
 | |
|     '''
 | |
|     parser = optparse.OptionParser(description=description, prog='guid',usage=usage)
 | |
|     return parser
 | |
| 
 | |
| def efi_guid_command(debugger, command, result, dict):
 | |
|     # Use the Shell Lexer to properly parse up command options just like a
 | |
|     # shell would
 | |
|     command_args = shlex.split(command)
 | |
|     parser = create_guid_options()
 | |
|     try:
 | |
|         (options, args) = parser.parse_args(command_args)
 | |
|         if len(args) >= 1:
 | |
|           if args[0] == "{":
 | |
|               # caller forgot to quote the string"
 | |
|               # mark arg[0] a string containing all args[n]
 | |
|               args[0] = ' '.join(args)
 | |
|           GuidStr = ParseGuidString (args[0])
 | |
|           if GuidStr == "":
 | |
|               # return Key of GuidNameDict for value args[0]
 | |
|               GuidStr = [Key for Key, Value in guid_dict.iteritems() if Value == args[0]][0]
 | |
|           GuidStr = GuidStr.upper()
 | |
|     except:
 | |
|         # if you don't handle exceptions, passing an incorrect argument to the OptionParser will cause LLDB to exit
 | |
|         # (courtesy of OptParse dealing with argument errors by throwing SystemExit)
 | |
|         result.SetError ("option parsing failed")
 | |
|         return
 | |
| 
 | |
| 
 | |
|     if len(args) >= 1:
 | |
|         if GuidStr in guid_dict:
 | |
|             print "%s = %s" % (guid_dict[GuidStr], GuidStr)
 | |
|             print "%s = %s" % (guid_dict[GuidStr], GuidToCStructStr (GuidStr))
 | |
|         else:
 | |
|             print GuidStr
 | |
|     else:
 | |
|         # dump entire dictionary
 | |
|         width = max(len(v) for k,v in guid_dict.iteritems())
 | |
|         for value in sorted(guid_dict, key=guid_dict.get):
 | |
|             print '%-*s %s %s' % (width, guid_dict[value], value, GuidToCStructStr(value))
 | |
| 
 | |
|     return
 | |
| 
 | |
| 
 | |
| #
 | |
| ########## Code that runs when this script is imported into LLDB ###########
 | |
| #
 | |
| def __lldb_init_module (debugger, internal_dict):
 | |
|     # This initializer is being run from LLDB in the embedded command interpreter
 | |
|     # Make the options so we can generate the help text for the new LLDB
 | |
|     # command line command prior to registering it with LLDB below
 | |
| 
 | |
|     global guid_dict
 | |
| 
 | |
|     # Source Guid.xref file if we can find it
 | |
|     inputfile = os.getcwd()
 | |
|     inputfile += os.sep + os.pardir + os.sep + 'FV' + os.sep + 'Guid.xref'
 | |
|     with open(inputfile) as f:
 | |
|         for line in f:
 | |
|             data = line.split(' ')
 | |
|             if len(data) >= 2:
 | |
|                 guid_dict[data[0].upper()] = data[1].strip('\n')
 | |
| 
 | |
|     # init EFI specific type formatters
 | |
|     TypePrintFormating (debugger)
 | |
| 
 | |
| 
 | |
|     # add guid command
 | |
|     parser = create_guid_options()
 | |
|     efi_guid_command.__doc__ = parser.format_help()
 | |
|     debugger.HandleCommand('command script add -f lldbefi.efi_guid_command guid')
 | |
| 
 | |
| 
 | |
|     Target = debugger.GetTargetAtIndex(0)
 | |
|     if Target:
 | |
|         Breakpoint = Target.BreakpointCreateByName('SecGdbScriptBreak')
 | |
|         if Breakpoint.GetNumLocations() == 1:
 | |
|             # Set the emulator breakpoints, if we are in the emulator
 | |
|             debugger.HandleCommand("breakpoint command add -s python -F lldbefi.LoadEmulatorEfiSymbols {id}".format(id=Breakpoint.GetID()))
 | |
|             print 'Type r to run emulator. SecLldbScriptBreak armed. EFI modules should now get source level debugging in the emulator.'
 |