def __init__(self, args, first, _): cmd_parts = self.parse_args(args, [2, 3] if first else [1, 2], ';') self.arch = gdb.current_arch() if first: self.start_address = eval_int(cmd_parts.pop(0)) end = cmd_parts.pop(0) self.end_address = None if end == 'NULL' else eval_int(end) self.count = eval_int(cmd_parts.pop(0)) if cmd_parts else None
def invoke(self, arg, _): self.dont_repeat() args = gdb.string_to_argv(arg) if len(args) > 2: raise ValueError( 'Usage: gohere [default | e | vnew | new] [address]') address = '$pc' if len(args) < 2 else args[1] open_method = 'default' if not args else args[0] pos = gdb.find_pc_line(eval_int(address)) if not pos.symtab: raise ValueError("Can't find address {}".format(address)) nvim = get_nvim_instance() if open_method == 'default': win = find_marked_window(nvim) if win: nvim.command('{} wincmd w'.format(win.number)) open_method = 'e' nvim.command('{} +{} {}'.format(open_method, pos.line, os.path.abspath(pos.symtab.filename))) nvim.command('silent! {}foldopen!'.format(pos.line))
def eval_user_expressions(cls, string): '''Take argument `string` and replace all occurances of $#<expression># with the value of the enclosed expression as evaluated by gdb.parse_and_eval() before being cast to an integer. These valus are then put back into the input string as hexadecimal constants. e.g. "hello there $#1 + 10#" => "hello there 0xb" ''' return_parts = [] # TODO Make this a 'proper' parser -- for now I just hope no-one's # using '#' characters in their gdb expressions. pattern = r'\$#([^#]*)#' prev_end = 0 for match in re.finditer(pattern, string): return_parts.append(string[prev_end:match.start()]) return_parts.append(hex(eval_int(match.group(1)))) prev_end = match.end() return_parts.append(string[prev_end:]) return ''.join(return_parts)
def __init__(self, args, first, _): self.cmd_parts = self.parse_args(args, [3,3] if first else [2,2], ';') self.maxdepth = eval_int(self.cmd_parts[-1]) self.file_regex = self.cmd_parts[-2].strip() # User asked for specific files, wo only know the filename if there is # debugging information, hence ignore all functions that don't have # debugging info. self.dont_fallback = re.match(self.file_regex, '') is not None self.func_stack = [] # hypothetical_stack checks for recursion, but also allows the # hypothetical-call-stack walker to see what the current stack is. type(self).hypothetical_stack = [] if first: self.__add_addr(eval_int(self.cmd_parts[0]), 0) self.arch = gdb.current_arch()
def __init__(self, args, first, _): if first: typename, start_addr, count = self.parse_args(args, [3, 3], ';') self.start_addr = eval_int(start_addr) self.__iter_helper = self.__iter_first else: typename, count = self.parse_args(args, [2, 2], ';') self.start_addr = None self.__iter_helper = self.__iter_pipe # TODO This is hacky, and we don't handle char[], &char that users # might like to use. if typename.find('*') != -1: self.element_size = helpers.uintptr_t.sizeof else: self.element_size = gdb.lookup_type(typename).sizeof self.count = eval_int(count)
def __init__(self, args, first, _): if first: start, test_expr, follow_expr = self.parse_args(args, [3, 3], ';') self.start = eval_int(start) else: test_expr, follow_expr = self.parse_args(args, [2, 2], ';') self.start = None # Here we split the arguments into something that will form the # arguments next. self.test_cmd = self.parse_args(test_expr, None, '{}', False) self.follow_cmd = self.parse_args(follow_expr, None, '{}', False)
def invoke(self, arg, _): args = gdb.string_to_argv(arg) func_addr = eval_int(''.join(args[:-1])) # Let possible error raise -- user needs to know something went wrong. func_dis, func_name, func_file = function_disassembly(func_addr) glob_name = args[-1] glob_uses = [ self.make_info(val) for val in func_dis if val['asm'].split()[-1] == '<{}>'.format(glob_name) ] if glob_uses: print('"{}" uses "{}" in the following places'.format( func_name, glob_name)) print('\n'.join(glob_uses))
def invoke(self, *_): pos = eval_int('$pc') line = gdb.find_pc_line(pos) if not line.symtab: return try: block = gdb.block_for_pc(pos) except RuntimeError as e: if e.args == ('Cannot locate object file for block.', ): return raise if block.function is None: print('First found block no function', pos) return while block.function.name is None: if block.superblock: block = block.superblock else: print('No superblock at', pos) return if block.function is None: print('Function iterated to None in', pos) return offset = pos - block.start offset_str = '+{}'.format(offset) if offset else '' entering = self.update_fp_stack() if entering: curindent = self.indent self.indent += 4 direction_string = '-->' else: self.indent -= 4 curindent = self.indent direction_string = '<--' print_str = '{}{}{}{} {}:{}'.format(' ' * curindent, direction_string, block.function.name, offset_str, line.symtab.filename, line.line) print(print_str)
def update_fp_stack(self): '''Update fp stack according to if $fp was seen before. Return False if $fp was seen before (and hence if we think we are leaving a function), True otherwise. ''' curfp = eval_int('$rbp') if not self.fp_stack or curfp < self.fp_stack[-1]: self.fp_stack.append(curfp) return True # The frame pointer decreases upon entering a new function, and # increases otherwise. # Because strange things can happen with the indirected @plt functions, # we take all frame pointers that are below the current one off our # stack. self.fp_stack.pop() return False
def follow_to_termination(self, start): while eval_int(self.form_command(self.test_cmd, start)) == 0: yield start start = eval_int(self.form_command(self.follow_cmd, start))
def iter_def(self, inpipe): for element in inpipe: if eval_int(self.form_command(self.command_parts, element)): break for element in inpipe: yield element
def __init__(self, args, *_): self.limit = eval_int(self.parse_args(args, [1, 1])[0])
def __init__(self, args, *_): # Use eval_int() so user can use variables from the inferior without # having to wrap them in $##. self.limit = eval_int(self.parse_args(args, [1, 1])[0])
def iter_def(self, inpipe): for element in inpipe: command = self.form_command(self.command_parts, element) if eval_int(command): yield element
def __iter_with_input(self, inpipe): for element in inpipe: yield eval_int(self.form_command(self.command_parts, element))
def __iter_without_input(self, _): yield eval_int(self.command_parts[0])