def is_command_exist(name): result_str = crashhelper.run_gdb_command("!which %s" % (name)) if result_str.startswith("which"): return False return True
def disasm(ins_addr, o, args, cmd_path_list): global asm_color_dict global funcname global stackaddr_list global stack_op_dict path_list = cmd_path_list.split(':') disasm_path = "" for path in path_list: if os.path.exists(path + "/disasm.py"): disasm_path = path + "/disasm.py" break if disasm_path == "": print("Can't find disasm.py in path") return options = "" if (o.noaction == False): options = "-l" if (o.reverse): options = options + " -r" cmd_options = "" if (o.sourceonly): cmd_options = cmd_options + " -s" if (o.fullsource): cmd_options = cmd_options + " -f" if (not o.reverse): options = options + " -r" if ins_addr.startswith("/"): ins_addr = ins_addr[1:] # get rid of the first slash if ":" in ins_addr or \ (not ins_addr.startswith(".") and "." in ins_addr): # It's for ppc if ":" not in ins_addr: # Let's make fake line number ins_addr = ins_addr + ": 0" else: words = ins_addr.split(":") ins_addr = "" for column in words: if ins_addr == "": ins_addr = column + ":" else: ins_addr = ins_addr + " " + column for line_number in args[1:]: ins_addr = ins_addr + " " + line_number kernel_ver, release_ver = get_kernel_version() disasm_str = "/usr/src/debug/kernel-%s/linux-%s/%s" % \ (kernel_ver, release_ver, ins_addr) else: command_str = "dis %s %s" % (options, ins_addr) disasm_str = exec_crash_command(command_str) if (disasm_str.startswith("symbol not found")): print(disasm_str) return result_str = "" if (o.noaction or not disasm_str.startswith("/")): result_str = disasm_str else: python_list = {"python", "python3", "python2"} for python_cmd in python_list: if (is_command_exist(python_cmd)): kerver, relver = get_kernel_version() ver_line = "" if kerver.find(".rt") >= 0: # rt kernel relver = relver[:relver.find("-")] ver_line = "/usr/src/debug/kernel-%s/linux-%s/" % \ (relver, kerver) else: ver_line = disasm_str.splitlines()[0] disasm_str = ver_line + "\n" + disasm_str result_str = crashhelper.run_gdb_command("!echo '%s' | %s %s %s" % \ (disasm_str, python_cmd, \ disasm_path, cmd_options)) break if (o.graph): result_str = draw_branches(result_str, o.jump_op_list) set_stack_data(disasm_str, ins_addr) # To retreive stack data if o.stackaddr != "": stackaddr_list = [int(o.stackaddr, 16)] set_asm_colors() crashcolor.set_color(crashcolor.RESET) for one_line in result_str.splitlines(): idx = one_line.find("0x") if idx >= 0: line = one_line[idx:] graph = one_line[:idx] is_disasm_line = True else: # source line prog = re.compile(r"(?P<line_number>[0-9]+)") m = prog.search(one_line) line = None if m is not None: line = m.group("line_number") if line == None: prog = re.compile(r"/[a-zA-Z]") line = prog.match(one_line) if line == None: line = one_line idx = one_line.find(line) line = one_line[idx:] graph = one_line[:idx] is_disasm_line = False idx = 2 default_color = crashcolor.RESET for char in graph: color = default_color idx = idx + 1 if char == '+': default_color = idx color = default_color elif char == '|': color = idx elif char == '-' or char == '=': color = default_color elif char == '>' or char == '*': color = crashcolor.RED else: color = crashcolor.RESET crashcolor.set_color(color) print(char, end='') if idx == crashcolor.MAX_COLOR: idx = 2 if idx == 7: # For black background situation idx = idx + 1 if is_disasm_line == True: line = interpret_one_line(line) # Retreive stack data if possible words = line.split() if len(words) > 2: if (o.symbol and is_address(words[-1]) == True): # Translate address into symbol line = ("%s%s" % (words[-1], find_symbol(words[-1]))).join( line.rsplit(words[-1], 1)) color_str = get_colored_asm(words[2].strip()) idx = line.find(words[2], len(words[0]) + len(words[1]) + 1) print(line[:idx], end='') if color_str != None: crashcolor.set_color(color_str) print(line[idx:idx + len(words[2])], end='') if color_str != None: crashcolor.set_color(operand_color) if len(words) >= 4: # Not handling callq or jmp. line = line[idx:] print("%s" % line[len(words[2]):line.find(words[3])], end='') idx = line.find(words[3]) op_list = words[3].split(",") line = line[idx:] for i in range(0, len(op_list)): opval = op_list[i] color_str = get_colored_arg(opval) if color_str == None: crashcolor.set_color(crashcolor.RESET) else: crashcolor.set_color(color_str) if i < len(op_list) - 1: next_idx = line.find(op_list[i + 1], len(opval)) else: next_idx = len(opval) print(line[:next_idx], end='') if color_str == None: crashcolor.set_color(crashcolor.RESET) else: crashcolor.set_color(operand_color) line = line[next_idx:] crashcolor.set_color(crashcolor.RESET) if (is_disasm_line): comment_idx = line.find(";") if comment_idx > -1: print(line[:comment_idx], end='') crashcolor.set_color(crashcolor.LIGHTYELLOW) print(line[comment_idx:]) else: comment_idx = line.find("<") if comment_idx > -1: print(line[:comment_idx], end='') crashcolor.set_color(crashcolor.LIGHTMAGENTA) print(line[comment_idx:]) else: print("%s" % line) else: print(line) crashcolor.set_color(crashcolor.RESET) else: print(line[idx + len(words[2]):]) crashcolor.set_color(crashcolor.RESET) else: print(line) crashcolor.set_color(crashcolor.RESET)
def disasm(ins_addr, o, args, cmd_path_list): global asm_color_dict path_list = cmd_path_list.split(':') disasm_path = "" for path in path_list: if os.path.exists(path + "/disasm.py"): disasm_path = path + "/disasm.py" break if disasm_path == "": print("Can't find disasm.py in path") return options = "-l" if (o.reverse): options = options + " -r" cmd_options = "" if (o.graph): cmd_options = cmd_options + " -g" if (o.fullsource): cmd_options = cmd_options + " -f" if (not o.reverse): options = options + " -r" if (o.jump_op_list != ""): cmd_options = cmd_options + " -j '" + o.jump_op_list + "'" if ":" in ins_addr or \ (not ins_addr.startswith(".") and "." in ins_addr): # It's for ppc if ":" not in ins_addr: # Let's make fake line number ins_addr = ins_addr + ": 0" else: words = ins_addr.split(":") ins_addr = "" for column in words: if ins_addr == "": ins_addr = column + ":" else: ins_addr = ins_addr + " " + column for line_number in args[1:]: ins_addr = ins_addr + " " + line_number kernel_ver, release_ver = get_kernel_version() disasm_str = "/usr/src/debug/kernel-%s/linux-%s/%s" % \ (kernel_ver, release_ver, ins_addr) else: command_str = "dis %s %s" % (options, ins_addr) disasm_str = exec_crash_command(command_str) if (disasm_str.startswith("symbol not found")): print (disasm_str) return result_str = crashhelper.run_gdb_command("!echo '%s' | python %s %s" % \ (disasm_str, disasm_path, cmd_options)) set_asm_colors() crashcolor.set_color(crashcolor.RESET) for one_line in result_str.splitlines(): idx = one_line.find("0x") if idx >= 0: line = one_line[idx:] graph = one_line[:idx] else: # source line prog = re.compile(r"(?P<line_number>[0-9]+)") m = prog.search(one_line) line = None if m is not None: line = m.group("line_number") if line == None: prog = re.compile(r"/[a-zA-Z]") line = prog.match(one_line) if line == None: line = one_line idx = one_line.find(line) line = one_line[idx:] graph = one_line[:idx] idx = 2 default_color = crashcolor.RESET for char in graph: color = default_color idx = idx + 1 if char == '+': default_color = idx color = default_color elif char == '|': color = idx elif char == '-' or char == '=': color = default_color elif char == '>' or char == '*': color = crashcolor.RED else: color = crashcolor.RESET crashcolor.set_color(color) print(char, end='') if idx == crashcolor.MAX_COLOR: idx = 2 words = line.split() if len(words) > 2: color_str = get_colored_asm(words[2].strip()) idx = line.find(words[2], len(words[0]) + len(words[1]) + 1) print(line[:idx], end='') if color_str != None: crashcolor.set_color(color_str) print(line[idx:idx+len(words[2])], end='') if color_str != None: crashcolor.set_color(operand_color) if len(words) >= 4: # Not handling callq or jmp. print(line[idx+len(words[2]):line.find(words[3])], end='') idx = line.find(words[3]) op_list = words[3].split(",") line = line[idx:] for i in range(0, len(op_list)): opval = op_list[i] color_str = get_colored_arg(opval) if color_str == None: crashcolor.set_color(crashcolor.RESET) else: crashcolor.set_color(color_str) if i < len(op_list) - 1: next_idx = line.find(op_list[i + 1], len(opval)) else: next_idx = len(opval) print(line[:next_idx], end='') if color_str == None: crashcolor.set_color(crashcolor.RESET) else: crashcolor.set_color(operand_color) line = line[next_idx:] crashcolor.set_color(crashcolor.RESET) print(line) else: print(line[idx+len(words[2]):]) crashcolor.set_color(crashcolor.RESET) else: print(line) crashcolor.set_color(crashcolor.RESET)