Beispiel #1
0
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;

  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, ">:\t");
	}
      else
	ui_out_text (uiout, ":\t");

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

      ui_file_rewind (stb->stream);
      pc += TARGET_PRINT_INSN (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;
}
Beispiel #2
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_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;
}
Beispiel #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;
}
Beispiel #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;
}
Beispiel #5
0
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;
}