예제 #1
0
enum mi_cmd_result
mi_cmd_symbol_list_lines (char *command, char **argv, int argc)
{
  char *filename;
  struct symtab *s;
  int i;
  struct cleanup *cleanup_stack, *cleanup_tuple;

  if (argc != 1)
    error (_("mi_cmd_symbol_list_lines: Usage: SOURCE_FILENAME"));

  filename = argv[0];
  s = lookup_symtab (filename);

  if (s == NULL)
    error (_("mi_cmd_symbol_list_lines: Unknown source file name."));

  /* Now, dump the associated line table.  The pc addresses are already
     sorted by increasing values in the symbol table, so no need to
     perform any other sorting. */

  cleanup_stack = make_cleanup_ui_out_list_begin_end (uiout, "lines");

  if (LINETABLE (s) != NULL && LINETABLE (s)->nitems > 0)
    for (i = 0; i < LINETABLE (s)->nitems; i++)
    {
      cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
      ui_out_field_core_addr (uiout, "pc", LINETABLE (s)->item[i].pc);
      ui_out_field_int (uiout, "line", LINETABLE (s)->item[i].line);
      do_cleanups (cleanup_tuple);
    }

  do_cleanups (cleanup_stack);

  return MI_CMD_DONE;
}
예제 #2
0
파일: disasm.c 프로젝트: GunioRobot/macgdb
static int
dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
	    struct disassemble_info * di,
	    CORE_ADDR low, CORE_ADDR high,
	    int how_many, int flags, struct ui_stream *stb)
{
  int num_displayed = 0;
  CORE_ADDR pc;

  /* parts of the symbolic representation of the address */
  int unmapped;
  int offset;
  int line;
  struct cleanup *ui_out_chain;

  for (pc = low; pc < high;)
    {
      char *filename = NULL;
      char *name = NULL;

      QUIT;
      if (how_many >= 0)
	{
	  if (num_displayed >= how_many)
	    break;
	  else
	    num_displayed++;
	}
      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
      ui_out_field_core_addr (uiout, "address", gdbarch, pc);

      if (!build_address_symbolic (pc, 0, &name, &offset, &filename,
				   &line, &unmapped))
	{
	  /* We don't care now about line, filename and
	     unmapped. But we might in the future. */
	  ui_out_text (uiout, " <");
	  ui_out_field_string (uiout, "func-name", name);
	  ui_out_text (uiout, "+");
	  ui_out_field_int (uiout, "offset", offset);
	  ui_out_text (uiout, ">:\t");
	}
      else
	ui_out_text (uiout, ":\t");

      if (filename != NULL)
	xfree (filename);
      if (name != NULL)
	xfree (name);

      ui_file_rewind (stb->stream);
      if (flags & DISASSEMBLY_RAW_INSN)
        {
          CORE_ADDR old_pc = pc;
          bfd_byte data;
          int status;
          pc += gdbarch_print_insn (gdbarch, pc, di);
          for (;old_pc < pc; old_pc++)
            {
              status = (*di->read_memory_func) (old_pc, &data, 1, di);
              if (status != 0)
                (*di->memory_error_func) (status, old_pc, di);
              ui_out_message (uiout, 0, " %02x", (unsigned)data);
            }
          ui_out_text (uiout, "\t");
        }
      else
        pc += gdbarch_print_insn (gdbarch, pc, di);
      ui_out_field_stream (uiout, "inst", stb);
      ui_file_rewind (stb->stream);
      do_cleanups (ui_out_chain);
      ui_out_text (uiout, "\n");
    }
  return num_displayed;
}
예제 #3
0
static int
dump_insns (struct gdbarch *gdbarch, struct ui_out *uiout,
	    struct disassemble_info * di,
	    CORE_ADDR low, CORE_ADDR high,
	    int how_many, int flags, struct ui_stream *stb)
{
  int num_displayed = 0;
  CORE_ADDR pc;

  /* parts of the symbolic representation of the address */
  int unmapped;
  int offset;
  int line;
  struct cleanup *ui_out_chain;

  for (pc = low; pc < high;)
    {
      char *filename = NULL;
      char *name = NULL;

      QUIT;
      if (how_many >= 0)
	{
	  if (num_displayed >= how_many)
	    break;
	  else
	    num_displayed++;
	}
      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
      ui_out_text (uiout, pc_prefix (pc));
      ui_out_field_core_addr (uiout, "address", gdbarch, pc);

      if (!build_address_symbolic (gdbarch, pc, 0, &name, &offset, &filename,
				   &line, &unmapped))
	{
	  /* We don't care now about line, filename and
	     unmapped. But we might in the future.  */
	  ui_out_text (uiout, " <");
	  if ((flags & DISASSEMBLY_OMIT_FNAME) == 0)
	    ui_out_field_string (uiout, "func-name", name);
	  ui_out_text (uiout, "+");
	  ui_out_field_int (uiout, "offset", offset);
	  ui_out_text (uiout, ">:\t");
	}
      else
	ui_out_text (uiout, ":\t");

      if (filename != NULL)
	xfree (filename);
      if (name != NULL)
	xfree (name);

      ui_file_rewind (stb->stream);
      if (flags & DISASSEMBLY_RAW_INSN)
        {
          CORE_ADDR old_pc = pc;
          bfd_byte data;
          int status;
          const char *spacer = "";

          /* Build the opcodes using a temporary stream so we can
             write them out in a single go for the MI.  */
          struct ui_stream *opcode_stream = ui_out_stream_new (uiout);
          struct cleanup *cleanups =
            make_cleanup_ui_out_stream_delete (opcode_stream);

          pc += gdbarch_print_insn (gdbarch, pc, di);
          for (;old_pc < pc; old_pc++)
            {
              status = (*di->read_memory_func) (old_pc, &data, 1, di);
              if (status != 0)
                (*di->memory_error_func) (status, old_pc, di);
              fprintf_filtered (opcode_stream->stream, "%s%02x",
                                spacer, (unsigned) data);
              spacer = " ";
            }
          ui_out_field_stream (uiout, "opcodes", opcode_stream);
          ui_out_text (uiout, "\t");

          do_cleanups (cleanups);
        }
      else
        pc += gdbarch_print_insn (gdbarch, pc, di);
      ui_out_field_stream (uiout, "inst", stb);
      ui_file_rewind (stb->stream);
      do_cleanups (ui_out_chain);
      ui_out_text (uiout, "\n");
    }
  return num_displayed;
}
예제 #4
0
/*
 * First, disassemble all instructions of the function and store them in buffer
 * Second, follow and calculate register values at each instruction
 * Finally, display all disassembled instruction with annotation of object context
 */
int decode_insns(struct decode_control_block* decode_cb)
{
	unsigned int insn_index, i;
	int num_insns = 0;
	struct gdbarch *gdbarch = decode_cb->gdbarch;
	struct ui_out *uiout = decode_cb->uiout;

	// Disassemble the whole function even if user chooses
	// only a subset of it
	num_insns += dump_insns(decode_cb);

	// copy known function parameters
	init_reg_table(decode_cb->param_regs);
	init_stack_vars();

	g_reg_table.cur_regs[RIP]->has_value = 1;
	// Annotate the context of each instruction
	for (insn_index = 0; insn_index < g_num_insns; insn_index++)
	{
		int cur_insn = 0;
		struct ca_dis_insn* insn = &g_insns_buffer[insn_index];

		// update program counter for RIP-relative instruction
		// RIP points to the address of the next instruction before executing current one
		if (insn_index + 1 < g_num_insns)
			set_reg_value_at_pc(RIP, (insn+1)->pc, insn->pc);

		// user may set some register values deliberately
		if (decode_cb->user_regs)
		{
			if (insn->pc == decode_cb->low
				|| (insn_index + 1 < g_num_insns && g_insns_buffer[insn_index + 1].pc > decode_cb->low) )
			{
				if (insn->pc == decode_cb->func_start)
					set_reg_table_at_pc(decode_cb->user_regs, 0);
				else
					set_reg_table_at_pc(decode_cb->user_regs, insn->pc);
			}
		}

		// analyze and update register context affected by this instruction
		if (decode_cb->innermost_frame)
		{
			if (insn->pc == decode_cb->current)
				cur_insn = 1;
		}
		else if (insn_index + 1 < g_num_insns && g_insns_buffer[insn_index + 1].pc == decode_cb->current)
			cur_insn = 1;

		process_one_insn(insn, cur_insn);

		if (cur_insn)
		{
			// return the register context back to caller
			for (i = 0; i < TOTAL_REGS; i++)
			{
				struct ca_reg_value* reg = g_reg_table.cur_regs[i];
				if (reg->has_value)
				{
					// only pass on values, symbol may be out of context in another function
					struct ca_reg_value* dst = &decode_cb->param_regs[i];
					memcpy(dst, reg, sizeof(struct ca_reg_value));
					dst->sym_name = NULL;
				}
			}
		}
	}
	if (decode_cb->verbose)
		validate_reg_table();

	// display disassembled insns
	for (insn_index = 0; insn_index < g_num_insns; insn_index++)
	{
		struct ca_dis_insn* insn = &g_insns_buffer[insn_index];
		// parts of the symbolic representation of the address
		int unmapped;
		int offset;
		int line;
		char *filename = NULL;
		char *name = NULL;

		if (insn->pc >= decode_cb->high)
			break;
		else if (insn->pc >= decode_cb->low)
		{
			// instruction address + offset
			ui_out_text(uiout, pc_prefix(insn->pc));
			ui_out_field_core_addr(uiout, "address", gdbarch, insn->pc);

			if (!build_address_symbolic(gdbarch, insn->pc, 0, &name, &offset, &filename,
					&line, &unmapped))
			{
				ui_out_text(uiout, " <");
				//if (decode_cb->verbose)
				//	ui_out_field_string(uiout, "func-name", name);
				ui_out_text(uiout, "+");
				ui_out_field_int(uiout, "offset", offset);
				ui_out_text(uiout, ">:\t");
			} else
				ui_out_message(uiout, 0, "<+%ld>:\t", insn->pc - decode_cb->func_start);

			// disassembled instruction with annotation
			print_one_insn(insn, uiout);

			if (filename != NULL)
				free(filename);
			if (name != NULL)
				free(name);
		}
	}

	reset_reg_table();
	reset_stack_vars();

	return num_insns;
}
예제 #5
0
파일: mi-main.c 프로젝트: debrouxl/tiemu
enum mi_cmd_result
mi_cmd_data_read_memory (char *command, char **argv, int argc)
{
  struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
  CORE_ADDR addr;
  long total_bytes;
  long nr_cols;
  long nr_rows;
  char word_format;
  struct type *word_type;
  long word_size;
  char word_asize;
  char aschar;
  gdb_byte *mbuf;
  int nr_bytes;
  long offset = 0;
  int optind = 0;
  char *optarg;
  enum opt
    {
      OFFSET_OPT
    };
  static struct mi_opt opts[] =
  {
    {"o", OFFSET_OPT, 1},
    0
  };

  while (1)
    {
      int opt = mi_getopt ("mi_cmd_data_read_memory", argc, argv, opts,
			   &optind, &optarg);
      if (opt < 0)
	break;
      switch ((enum opt) opt)
	{
	case OFFSET_OPT:
	  offset = atol (optarg);
	  break;
	}
    }
  argv += optind;
  argc -= optind;

  if (argc < 5 || argc > 6)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_read_memory: Usage: ADDR WORD-FORMAT WORD-SIZE NR-ROWS NR-COLS [ASCHAR].");
      return MI_CMD_ERROR;
    }

  /* Extract all the arguments. */

  /* Start address of the memory dump. */
  addr = parse_and_eval_address (argv[0]) + offset;
  /* The format character to use when displaying a memory word. See
     the ``x'' command. */
  word_format = argv[1][0];
  /* The size of the memory word. */
  word_size = atol (argv[2]);
  switch (word_size)
    {
    case 1:
      word_type = builtin_type_int8;
      word_asize = 'b';
      break;
    case 2:
      word_type = builtin_type_int16;
      word_asize = 'h';
      break;
    case 4:
      word_type = builtin_type_int32;
      word_asize = 'w';
      break;
    case 8:
      word_type = builtin_type_int64;
      word_asize = 'g';
      break;
    default:
      word_type = builtin_type_int8;
      word_asize = 'b';
    }
  /* The number of rows */
  nr_rows = atol (argv[3]);
  if (nr_rows <= 0)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_read_memory: invalid number of rows.");
      return MI_CMD_ERROR;
    }
  /* number of bytes per row. */
  nr_cols = atol (argv[4]);
  if (nr_cols <= 0)
    {
      mi_error_message = xstrprintf ("mi_cmd_data_read_memory: invalid number of columns.");
      return MI_CMD_ERROR;
    }
  /* The un-printable character when printing ascii. */
  if (argc == 6)
    aschar = *argv[5];
  else
    aschar = 0;

  /* create a buffer and read it in. */
  total_bytes = word_size * nr_rows * nr_cols;
  mbuf = xcalloc (total_bytes, 1);
  make_cleanup (xfree, mbuf);

  nr_bytes = target_read (&current_target, TARGET_OBJECT_MEMORY, NULL,
			  mbuf, addr, total_bytes);
  if (nr_bytes <= 0)
    {
      do_cleanups (cleanups);
      mi_error_message = xstrdup ("Unable to read memory.");
      return MI_CMD_ERROR;
    }

  /* output the header information. */
  ui_out_field_core_addr (uiout, "addr", addr);
  ui_out_field_int (uiout, "nr-bytes", nr_bytes);
  ui_out_field_int (uiout, "total-bytes", total_bytes);
  ui_out_field_core_addr (uiout, "next-row", addr + word_size * nr_cols);
  ui_out_field_core_addr (uiout, "prev-row", addr - word_size * nr_cols);
  ui_out_field_core_addr (uiout, "next-page", addr + total_bytes);
  ui_out_field_core_addr (uiout, "prev-page", addr - total_bytes);

  /* Build the result as a two dimentional table. */
  {
    struct ui_stream *stream = ui_out_stream_new (uiout);
    struct cleanup *cleanup_list_memory;
    int row;
    int row_byte;
    cleanup_list_memory = make_cleanup_ui_out_list_begin_end (uiout, "memory");
    for (row = 0, row_byte = 0;
	 row < nr_rows;
	 row++, row_byte += nr_cols * word_size)
      {
	int col;
	int col_byte;
	struct cleanup *cleanup_tuple;
	struct cleanup *cleanup_list_data;
	cleanup_tuple = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
	ui_out_field_core_addr (uiout, "addr", addr + row_byte);
	/* ui_out_field_core_addr_symbolic (uiout, "saddr", addr + row_byte); */
	cleanup_list_data = make_cleanup_ui_out_list_begin_end (uiout, "data");
	for (col = 0, col_byte = row_byte;
	     col < nr_cols;
	     col++, col_byte += word_size)
	  {
	    if (col_byte + word_size > nr_bytes)
	      {
		ui_out_field_string (uiout, NULL, "N/A");
	      }
	    else
	      {
		ui_file_rewind (stream->stream);
		print_scalar_formatted (mbuf + col_byte, word_type, word_format,
					word_asize, stream->stream);
		ui_out_field_stream (uiout, NULL, stream);
	      }
	  }
	do_cleanups (cleanup_list_data);
	if (aschar)
	  {
	    int byte;
	    ui_file_rewind (stream->stream);
	    for (byte = row_byte; byte < row_byte + word_size * nr_cols; byte++)
	      {
		if (byte >= nr_bytes)
		  {
		    fputc_unfiltered ('X', stream->stream);
		  }
		else if (mbuf[byte] < 32 || mbuf[byte] > 126)
		  {
		    fputc_unfiltered (aschar, stream->stream);
		  }
		else
		  fputc_unfiltered (mbuf[byte], stream->stream);
	      }
	    ui_out_field_stream (uiout, "ascii", stream);
	  }
	do_cleanups (cleanup_tuple);
      }
    ui_out_stream_delete (stream);
    do_cleanups (cleanup_list_memory);
  }
  do_cleanups (cleanups);
  return MI_CMD_DONE;
}
예제 #6
0
static void
darwin_debug_regions_recurse (task_t task)
{
  mach_vm_address_t r_addr;
  mach_vm_address_t r_start;
  mach_vm_size_t r_size;
  natural_t r_depth;
  mach_msg_type_number_t r_info_size;
  vm_region_submap_short_info_data_64_t r_info;
  kern_return_t kret;
  int ret;
  struct cleanup *table_chain;
  struct ui_out *uiout = current_uiout;

  table_chain = make_cleanup_ui_out_table_begin_end (uiout, 9, -1, "regions");

  if (gdbarch_addr_bit (target_gdbarch ()) <= 32)
    {
      ui_out_table_header (uiout, 10, ui_left, "start", "Start");
      ui_out_table_header (uiout, 10, ui_left, "end", "End");
    }
  else
    {
      ui_out_table_header (uiout, 18, ui_left, "start", "Start");
      ui_out_table_header (uiout, 18, ui_left, "end", "End");
    }
  ui_out_table_header (uiout, 3, ui_left, "min-prot", "Min");
  ui_out_table_header (uiout, 3, ui_left, "max-prot", "Max");
  ui_out_table_header (uiout, 5, ui_left, "inheritence", "Inh");
  ui_out_table_header (uiout, 9, ui_left, "share-mode", "Shr");
  ui_out_table_header (uiout, 1, ui_left, "depth", "D");
  ui_out_table_header (uiout, 3, ui_left, "submap", "Sm");
  ui_out_table_header (uiout, 0, ui_noalign, "tag", "Tag");

  ui_out_table_body (uiout);

  r_start = 0;
  r_depth = 0;
  while (1)
    {
      const char *tag;
      struct cleanup *row_chain;

      r_info_size = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64;
      r_size = -1;
      kret = mach_vm_region_recurse (task, &r_start, &r_size, &r_depth,
				     (vm_region_recurse_info_t) &r_info,
				     &r_info_size);
      if (kret != KERN_SUCCESS)
	break;
      row_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "regions-row");

      ui_out_field_core_addr (uiout, "start", target_gdbarch (), r_start);
      ui_out_field_core_addr (uiout, "end", target_gdbarch (), r_start + r_size);
      ui_out_field_string (uiout, "min-prot", 
			   unparse_protection (r_info.protection));
      ui_out_field_string (uiout, "max-prot", 
			   unparse_protection (r_info.max_protection));
      ui_out_field_string (uiout, "inheritence",
			   unparse_inheritance (r_info.inheritance));
      ui_out_field_string (uiout, "share-mode",
			   unparse_share_mode (r_info.share_mode));
      ui_out_field_int (uiout, "depth", r_depth);
      ui_out_field_string (uiout, "submap",
			   r_info.is_submap ? _("sm ") : _("obj"));
      tag = unparse_user_tag (r_info.user_tag);
      if (tag)
	ui_out_field_string (uiout, "tag", tag);
      else
	ui_out_field_int (uiout, "tag", r_info.user_tag);

      do_cleanups (row_chain);

      if (!ui_out_is_mi_like_p (uiout))
	ui_out_text (uiout, "\n");

      if (r_info.is_submap)
	r_depth++;
      else
	r_start += r_size;
    }
  do_cleanups (table_chain);

}
예제 #7
0
파일: disasm.c 프로젝트: HoMeCracKeR/gdb-ng
static int
dump_insns (struct ui_out *uiout, struct disassemble_info * di,
	    CORE_ADDR low, CORE_ADDR high,
	    int how_many, struct ui_stream *stb)
{
  int num_displayed = 0;
  CORE_ADDR pc;

  /* parts of the symbolic representation of the address */
  int unmapped;
  int offset;
  int line;

  struct cleanup *ui_out_chain;

  struct cleanup *table_chain;
  struct cleanup *tuple_chain;
		  
  for (pc = low; pc < high;)
    {
      char *filename = NULL;
      char *name = NULL;

      QUIT;
      if (how_many >= 0)
	{
	  if (num_displayed >= how_many)
	    break;
	  else
	    num_displayed++;
	}
      ui_out_chain = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
      ui_out_field_core_addr (uiout, "address", pc);

      if (!build_address_symbolic (pc, 0, &name, &offset, &filename,
				   &line, &unmapped))
	{
	  /* We don't care now about line, filename and
	     unmapped. But we might in the future. */
	  ui_out_text (uiout, " <");
	  ui_out_field_string (uiout, "func-name", name);
	  ui_out_text (uiout, "+");
	  ui_out_field_int (uiout, "offset", offset);
	  ui_out_text (uiout, ">: ");
	}
      else
		  ui_out_text (uiout, ": ");
		
      if (filename != NULL)
	xfree (filename);
      if (name != NULL)
	xfree (name);
		
      ui_file_rewind (stb->stream);
	  // dump the disassembly raw bytes - ripped from gnu gdb latest cvs version
	  // fG! - 12/08/2009
	  // save the initial disassembly address
      CORE_ADDR old_pc = pc;
      bfd_byte data;
      int status;
      int i;
		
	  // this will return the disassembled instructions, but it will be buffered into the stream
	  // pc will hold the final address after the disassembly, so we can compute the length of the instruction
	  // the macro returns the number of bytes disassembled
      pc += TARGET_PRINT_INSN (pc, di);
      i = pc - old_pc;
	  // read the bytes from the initial address to the final address
      for (; old_pc < pc; old_pc++)
      {
		status = (*di->read_memory_func) (old_pc, &data, 1, di);
		if (status != 0) (*di->memory_error_func) (status, old_pc, di);
		// print the raw bytes
        ui_out_message (uiout, 0, " %02x", (unsigned)data);
       }
      // to align the output... gdb tables don't work correctly :(
      for (; i < 10 ; i++) ui_out_text(uiout, "   ");
      ui_out_text(uiout, " ");
	  // now we can finally print the buffered stream
      ui_out_field_stream (uiout, "inst", stb);		
      ui_file_rewind (stb->stream);

	  do_cleanups (ui_out_chain);
	  ui_out_text (uiout, "\n");
    }
  return num_displayed;
}