Ejemplo n.º 1
0
static SCM
gdbscm_memory_port_range (SCM port)
{
  ioscm_memory_port *iomem;

  SCM_ASSERT_TYPE (gdbscm_is_memory_port (port), port, SCM_ARG1, FUNC_NAME,
		   memory_port_desc_name);

  iomem = (ioscm_memory_port *) SCM_STREAM (port);
  return scm_list_2 (gdbscm_scm_from_ulongest (iomem->start),
		     gdbscm_scm_from_ulongest (iomem->end));
}
Ejemplo n.º 2
0
static SCM
gdbscm_open_memory (SCM rest)
{
  const SCM keywords[] = {
    mode_keyword, start_keyword, size_keyword, SCM_BOOL_F
  };
  char *mode = NULL;
  CORE_ADDR start = 0;
  CORE_ADDR end;
  int mode_arg_pos = -1, start_arg_pos = -1, size_arg_pos = -1;
  ULONGEST size;
  SCM port;
  long mode_bits;

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG1, keywords, "#sUU", rest,
			      &mode_arg_pos, &mode,
			      &start_arg_pos, &start,
			      &size_arg_pos, &size);

  scm_dynwind_begin ((scm_t_dynwind_flags) 0);

  if (mode == NULL)
    mode = xstrdup ("r");
  scm_dynwind_free (mode);

  if (size_arg_pos > 0)
    {
      /* For now be strict about start+size overflowing.  If it becomes
	 a nuisance we can relax things later.  */
      if (start + size < start)
	{
	  gdbscm_out_of_range_error (FUNC_NAME, 0,
				scm_list_2 (gdbscm_scm_from_ulongest (start),
					    gdbscm_scm_from_ulongest (size)),
				     _("start+size overflows"));
	}
      end = start + size;
    }
  else
    end = ~(CORE_ADDR) 0;

  mode_bits = ioscm_parse_mode_bits (FUNC_NAME, mode);

  port = ioscm_open_port (memory_port_desc, mode_bits);

  ioscm_init_memory_port (port, start, end);

  scm_dynwind_end ();

  /* TODO: Set the file name as "memory-start-end"?  */
  return port;
}
Ejemplo n.º 3
0
static void
gdbscm_memory_port_flush (SCM port)
{
  scm_t_port *pt = SCM_PTAB_ENTRY (port);
  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
  size_t to_write = pt->write_pos - pt->write_buf;

  if (to_write == 0)
    return;

  /* There's no way to indicate a short write, so if the request goes past
     the end of the port's memory range, flag an error.  */
  if (to_write > iomem->size - iomem->current)
    {
      gdbscm_out_of_range_error (FUNC_NAME, 0,
				 gdbscm_scm_from_ulongest (to_write),
				 _("writing beyond end of memory range"));
    }

  if (target_write_memory (iomem->start + iomem->current, pt->write_buf,
			   to_write) != 0)
    gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL);

  iomem->current += to_write;
  pt->write_pos = pt->write_buf;
  pt->rw_active = SCM_PORT_NEITHER;
}
static SCM
gdbscm_lazy_string_address (SCM self)
{
    SCM ls_scm = lsscm_get_lazy_string_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
    lazy_string_smob *ls_smob = (lazy_string_smob *) SCM_SMOB_DATA (ls_scm);

    return gdbscm_scm_from_ulongest (ls_smob->address);
}
Ejemplo n.º 5
0
static SCM
gdbscm_sal_pc (SCM self)
{
  sal_smob *s_smob = stscm_get_valid_sal_smob_arg (self, SCM_ARG1, FUNC_NAME);
  const struct symtab_and_line *sal = &s_smob->sal;

  return gdbscm_scm_from_ulongest (sal->pc);
}
Ejemplo n.º 6
0
static SCM
gdbscm_sal_last (SCM self)
{
  sal_smob *s_smob = stscm_get_valid_sal_smob_arg (self, SCM_ARG1, FUNC_NAME);
  const struct symtab_and_line *sal = &s_smob->sal;

  if (sal->end > 0)
    return gdbscm_scm_from_ulongest (sal->end - 1);
  return SCM_BOOL_F;
}
Ejemplo n.º 7
0
static SCM
dascm_make_insn (CORE_ADDR pc, const char *assembly, int insn_len)
{
  return scm_list_3 (scm_cons (address_symbol,
			       gdbscm_scm_from_ulongest (pc)),
		     scm_cons (asm_symbol,
			       gdbscm_scm_from_c_string (assembly)),
		     scm_cons (length_symbol,
			       scm_from_int (insn_len)));
}
Ejemplo n.º 8
0
static const char *
gdbscm_disasm_read_memory_worker (void *datap)
{
  struct gdbscm_disasm_read_data *data
    = (struct gdbscm_disasm_read_data *) datap;
  struct disassemble_info *dinfo = data->dinfo;
  struct gdbscm_disasm_data *disasm_data
    = (struct gdbscm_disasm_data *) dinfo->application_data;
  SCM seekto, newpos, port = disasm_data->port;
  size_t bytes_read;

  seekto = gdbscm_scm_from_ulongest (data->memaddr - disasm_data->offset);
  newpos = scm_seek (port, seekto, scm_from_int (SEEK_SET));
  if (!scm_is_eq (seekto, newpos))
    return "seek error";

  bytes_read = scm_c_read (port, data->myaddr, data->length);

  if (bytes_read != data->length)
    return "short read";

  /* If we get here the read succeeded.  */
  return NULL;
}
Ejemplo n.º 9
0
static SCM
gdbscm_arch_disassemble (SCM self, SCM start_scm, SCM rest)
{
  arch_smob *a_smob
    = arscm_get_arch_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME);
  struct gdbarch *gdbarch = arscm_get_gdbarch (a_smob);
  const SCM keywords[] = {
    port_keyword, offset_keyword, size_keyword, count_keyword, SCM_BOOL_F
  };
  int port_arg_pos = -1, offset_arg_pos = -1;
  int size_arg_pos = -1, count_arg_pos = -1;
  SCM port = SCM_BOOL_F;
  ULONGEST offset = 0;
  unsigned int count = 1;
  unsigned int size;
  ULONGEST start_arg;
  CORE_ADDR start, end;
  CORE_ADDR pc;
  unsigned int i;
  int using_port;
  SCM result;

  gdbscm_parse_function_args (FUNC_NAME, SCM_ARG2, keywords, "U#OUuu",
			      start_scm, &start_arg, rest,
			      &port_arg_pos, &port,
			      &offset_arg_pos, &offset,
			      &size_arg_pos, &size,
			      &count_arg_pos, &count);
  /* START is first stored in a ULONGEST because we don't have a format char
     for CORE_ADDR, and it's not really worth it to have one yet.  */
  start = start_arg;

  if (port_arg_pos > 0)
    {
      SCM_ASSERT_TYPE (gdbscm_is_false (port)
		       || gdbscm_is_true (scm_input_port_p (port)),
		       port, port_arg_pos, FUNC_NAME, _("input port"));
    }
  using_port = gdbscm_is_true (port);

  if (offset_arg_pos > 0
      && (port_arg_pos < 0
	  || gdbscm_is_false (port)))
    {
      gdbscm_out_of_range_error (FUNC_NAME, offset_arg_pos,
				 gdbscm_scm_from_ulongest (offset),
				 _("offset provided but port is missing"));
    }

  if (size_arg_pos > 0)
    {
      if (size == 0)
	return SCM_EOL;
      /* For now be strict about start+size overflowing.  If it becomes
	 a nuisance we can relax things later.  */
      if (start + size < start)
	{
	  gdbscm_out_of_range_error (FUNC_NAME, 0,
				scm_list_2 (gdbscm_scm_from_ulongest (start),
					    gdbscm_scm_from_ulongest (size)),
				     _("start+size overflows"));
	}
      end = start + size - 1;
    }
  else
    end = ~(CORE_ADDR) 0;

  if (count == 0)
    return SCM_EOL;

  result = SCM_EOL;

  for (pc = start, i = 0; pc <= end && i < count; )
    {
      int insn_len = 0;
      struct ui_file *memfile = mem_fileopen ();
      struct cleanup *cleanups = make_cleanup_ui_file_delete (memfile);

      TRY
	{
	  if (using_port)
	    {
	      insn_len = gdbscm_print_insn_from_port (gdbarch, port, offset,
						      pc, memfile, NULL);
	    }
	  else
	    insn_len = gdb_print_insn (gdbarch, pc, memfile, NULL);
	}
      CATCH (except, RETURN_MASK_ALL)
	{
	  GDBSCM_HANDLE_GDB_EXCEPTION_WITH_CLEANUPS (except, cleanups);
	}
      END_CATCH

      std::string as = ui_file_as_string (memfile);

      result = scm_cons (dascm_make_insn (pc, as.c_str (), insn_len),
			 result);

      pc += insn_len;
      i++;
      do_cleanups (cleanups);
    }
Ejemplo n.º 10
0
static void
gdbscm_memory_port_write (SCM port, const void *void_data, size_t size)
{
  scm_t_port *pt = SCM_PTAB_ENTRY (port);
  ioscm_memory_port *iomem = (ioscm_memory_port *) SCM_STREAM (port);
  const gdb_byte *data = (const gdb_byte *) void_data;

  /* There's no way to indicate a short write, so if the request goes past
     the end of the port's memory range, flag an error.  */
  if (size > iomem->size - iomem->current)
    {
      gdbscm_out_of_range_error (FUNC_NAME, 0, gdbscm_scm_from_ulongest (size),
				 _("writing beyond end of memory range"));
    }

  if (pt->write_buf == &pt->shortbuf)
    {
      /* Unbuffered port.  */
      if (target_write_memory (iomem->start + iomem->current, data, size) != 0)
	gdbscm_memory_error (FUNC_NAME, _("error writing memory"), SCM_EOL);
      iomem->current += size;
      return;
    }

  /* Note: The edge case of what to do when the buffer exactly fills is
     debatable.  Guile flushes when the buffer exactly fills up, so we
     do too.  It's counter-intuitive to my mind, but in case there's a
     subtlety somewhere that depends on this, we do the same.  */

  {
    size_t space = pt->write_end - pt->write_pos;

    if (size < space)
      {
	/* Data fits in buffer, and does not fill it.  */
	memcpy (pt->write_pos, data, size);
	pt->write_pos += size;
      }
    else
      {
	memcpy (pt->write_pos, data, space);
	pt->write_pos = pt->write_end;
	gdbscm_memory_port_flush (port);
	{
	  const gdb_byte *ptr = data + space;
	  size_t remaining = size - space;

	  if (remaining >= pt->write_buf_size)
	    {
	      if (target_write_memory (iomem->start + iomem->current, ptr,
				       remaining) != 0)
		gdbscm_memory_error (FUNC_NAME, _("error writing memory"),
				     SCM_EOL);
	      iomem->current += remaining;
	    }
	  else
	    {
	      memcpy (pt->write_pos, ptr, remaining);
	      pt->write_pos += remaining;
	    }
	}
      }
  }
}