X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/39236c6e673c41db228275375ab7fdb0f837b292..a991bd8d3e7fe02dbca0644054bab73c5b75324a:/tools/lldbmacros/utils.py?ds=inline diff --git a/tools/lldbmacros/utils.py b/tools/lldbmacros/utils.py old mode 100644 new mode 100755 index 104a528cc..6039f2048 --- a/tools/lldbmacros/utils.py +++ b/tools/lldbmacros/utils.py @@ -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 #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