]> git.saurik.com Git - apple/xnu.git/blobdiff - tools/lldbmacros/utils.py
xnu-7195.81.3.tar.gz
[apple/xnu.git] / tools / lldbmacros / utils.py
old mode 100644 (file)
new mode 100755 (executable)
index 104a528..6039f20
@@ -27,6 +27,8 @@ def lldb_run_command(cmdstring):
     lldb_run_command_state['active'] = False
     if res.Succeeded():
         retval = res.GetOutput()
+    else:
+        retval = "ERROR:" + res.GetError()
     return retval
 
 def EnableLLDBAPILogging():
@@ -44,9 +46,9 @@ def EnableLLDBAPILogging():
     cmd_str = enable_log_base_cmd + ' kdp-remote packets'
     print cmd_str
     print lldb_run_command(cmd_str)
-    print lldb_run_command("verison")
+    print lldb_run_command("version")
     print "Please collect the logs from %s for filing a radar. If you had encountered an exception in a lldbmacro command please re-run it." % logfile_name
-    print "Please make sure to provide the output of 'verison', 'image list' and output of command that failed."
+    print "Please make sure to provide the output of 'version', 'image list' and output of command that failed."
     return
 
 def GetConnectionProtocol():
@@ -111,6 +113,8 @@ def GetLongestMatchOption(searchstr, options=[], ignore_case=True):
         so = o
         if ignore_case:
             so = o.lower()
+        if so == searchstr:
+            return [o]
         if so.find(searchstr) >=0 :
             found_options.append(o)
     return found_options
@@ -136,7 +140,16 @@ def Cast(obj, target_type):
     """
     return cast(obj, target_type)
 
-    
+def ContainerOf(obj, target_type, field_name):
+    """ Type cast an object to another C type from a pointer to a field.
+        params:
+            obj - core.value  object representing some C construct in lldb
+            target_type - str : ex 'struct thread'
+                        - lldb.SBType :
+            field_name - the field name within the target_type obj is a pointer to
+    """
+    return containerof(obj, target_type, field_name)
+
 def loadLLDB():
     """ Util function to load lldb python framework in case not available in common include paths.
     """
@@ -344,7 +357,7 @@ def addDSYM(uuid, info):
         # modify the list to show we loaded this
         _dsymlist[uuid] = True
 
-def loadDSYM(uuid, load_address):
+def loadDSYM(uuid, load_address, sections=[]):
     """ Load an already added symbols to a particular load address
         params: uuid - str - uuid string
                 load_address - int - address where to load the symbols
@@ -354,9 +367,36 @@ def loadDSYM(uuid, load_address):
     """
     if uuid not in _dsymlist:
         return False
-    cmd_str = "target modules load --uuid %s --slide %d" % ( uuid, load_address)
-    debuglog(cmd_str)
+    if not sections:
+        cmd_str = "target modules load --uuid %s --slide %d" % ( uuid, load_address)
+        debuglog(cmd_str)
+    else:
+        cmd_str = "target modules load --uuid {}   ".format(uuid)
+        sections_str = ""
+        for s in sections:
+            sections_str += " {} {:#0x} ".format(s.name, s.vmaddr)
+        cmd_str += sections_str
+        debuglog(cmd_str)
+
     lldb.debugger.HandleCommand(cmd_str)
+    return True
+
+
+def RunShellCommand(command):
+    """ Run a shell command in subprocess.
+        params: command with arguments to run
+        returns: (exit_code, stdout, stderr)
+    """
+    import shlex, subprocess
+    cmd_args = shlex.split(command)
+    output_str = ""
+    exit_code = 0
+    try:
+        output_str = subprocess.check_output(cmd_args, stderr=subprocess.STDOUT)
+    except subprocess.CalledProcessError, e:
+        exit_code = e.returncode
+    finally:
+        return (exit_code, output_str, '')
 
 def dsymForUUID(uuid):
     """ Get dsym informaiton by calling dsymForUUID 
@@ -367,7 +407,7 @@ def dsymForUUID(uuid):
     """
     import subprocess
     import plistlib
-    output = subprocess.check_output(["/usr/local/bin/dsymForUUID", uuid])
+    output = subprocess.check_output(["/usr/local/bin/dsymForUUID", "--copyExecutable", uuid])
     if output:
         # because of <rdar://12713712>
         #plist = plistlib.readPlistFromString(output)
@@ -389,3 +429,57 @@ def debuglog(s):
     if config['debug']:
       print "DEBUG:",s
     return None
+
+def IsAppleInternal():
+    """ check if apple_internal modules are available
+        returns: True if apple_internal module is present
+    """
+    import imp
+    try:
+        imp.find_module("apple_internal")
+        retval = True
+    except ImportError:
+        retval = False
+    return retval
+
+def print_hex_data(data, begin_offset=0, desc=""):
+    """ print on stdout "hexdump -C < data" like output
+        params:
+            data - bytearray or array of int where each int < 255
+            begin_offset - int offset that should be printed in left column
+            desc - str optional description to print on the first line to describe data
+    """
+    if desc:
+        print "{}:".format(desc)
+    index = 0
+    total_len = len(data)
+    hex_buf = ""
+    char_buf = ""
+    while index < total_len:
+        hex_buf += " {:02x}".format(data[index])
+        if data[index] < 0x20 or data[index] > 0x7e:
+            char_buf += "."
+        else:
+            char_buf += "{:c}".format(data[index])
+        index += 1
+        if index and index < total_len and index % 8 == 0:
+            hex_buf += " "
+        if index > 1 and index < total_len and (index % 16) == 0:
+            print "{:08x} {: <50s} |{: <16s}|".format(begin_offset + index - 16, hex_buf, char_buf)
+            hex_buf = ""
+            char_buf = ""
+    print "{:08x} {: <50s} |{: <16s}|".format(begin_offset + index - 16, hex_buf, char_buf)
+    return
+
+def Ones(x):
+    return (1 << x)-1
+
+def StripPAC(x, TySz):
+    sign_mask = 1 << 55
+    ptr_mask = Ones(64-TySz)
+    pac_mask = ~ptr_mask
+    sign = x & sign_mask
+    if sign:
+        return (x | pac_mask) + 2**64
+    else:
+        return x & ptr_mask