Esempio n. 1
0
static void
inf_ptrace_attach (struct target_ops *ops, char *args, int from_tty)
{
  char *exec_file;
  pid_t pid;
  struct inferior *inf;

  /* Do not change either targets above or the same target if already present.
     The reason is the target stack is shared across multiple inferiors.  */
  int ops_already_pushed = target_is_pushed (ops);
  struct cleanup *back_to = NULL;

  pid = parse_pid_to_attach (args);

  if (pid == getpid ())		/* Trying to m********e?  */
    error (_("I refuse to debug myself!"));

  if (! ops_already_pushed)
    {
      /* target_pid_to_str already uses the target.  Also clear possible core
	 file with its process_stratum.  */
      push_target (ops);
      back_to = make_cleanup_unpush_target (ops);
    }

  if (from_tty)
    {
      exec_file = get_exec_file (0);

      if (exec_file)
	printf_unfiltered (_("Attaching to program: %s, %s\n"), exec_file,
			   target_pid_to_str (pid_to_ptid (pid)));
      else
	printf_unfiltered (_("Attaching to %s\n"),
			   target_pid_to_str (pid_to_ptid (pid)));

      gdb_flush (gdb_stdout);
    }

#ifdef PT_ATTACH
  errno = 0;
  ptrace (PT_ATTACH, pid, (PTRACE_TYPE_ARG3)0, 0);
  if (errno != 0)
    perror_with_name (("ptrace"));
#else
  error (_("This system does not support attaching to a process"));
#endif

  inf = current_inferior ();
  inferior_appeared (inf, pid);
  inf->attach_flag = 1;
  inferior_ptid = pid_to_ptid (pid);

  /* Always add a main thread.  If some target extends the ptrace
     target, it should decorate the ptid later with more info.  */
  add_thread_silent (inferior_ptid);

  if (! ops_already_pushed)
    discard_cleanups (back_to);
}
Esempio n. 2
0
static LdInfo *
rs6000_core_ldinfo (bfd *abfd)
{
  struct bfd_section *ldinfo_sec;
  int ldinfo_size;
  gdb_byte *ldinfo_buf;
  struct cleanup *cleanup;

  ldinfo_sec = bfd_get_section_by_name (abfd, ".ldinfo");
  if (ldinfo_sec == NULL)
    error (_("cannot find .ldinfo section from core file: %s\n"),
	   bfd_errmsg (bfd_get_error ()));
  ldinfo_size = bfd_get_section_size (ldinfo_sec);

  ldinfo_buf = xmalloc (ldinfo_size);
  cleanup = make_cleanup (xfree, ldinfo_buf);

  if (! bfd_get_section_contents (abfd, ldinfo_sec,
				  ldinfo_buf, 0, ldinfo_size))
    error (_("unable to read .ldinfo section from core file: %s\n"),
	   bfd_errmsg (bfd_get_error ()));

  discard_cleanups (cleanup);
  return (LdInfo *) ldinfo_buf;
}
Esempio n. 3
0
static void
inf_ptrace_create_inferior (struct target_ops *ops,
			    char *exec_file, char *allargs, char **env,
			    int from_tty)
{
  int pid;

  /* Do not change either targets above or the same target if already present.
     The reason is the target stack is shared across multiple inferiors.  */
  int ops_already_pushed = target_is_pushed (ops);
  struct cleanup *back_to = NULL;

  if (! ops_already_pushed)
    {
      /* Clear possible core file with its process_stratum.  */
      push_target (ops);
      back_to = make_cleanup_unpush_target (ops);
    }

  pid = fork_inferior (exec_file, allargs, env, inf_ptrace_me, NULL,
		       NULL, NULL, NULL);

  if (! ops_already_pushed)
    discard_cleanups (back_to);

  startup_inferior (START_INFERIOR_TRAPS_EXPECTED);

  /* On some targets, there must be some explicit actions taken after
     the inferior has been started up.  */
  target_post_startup_inferior (pid_to_ptid (pid));
}
Esempio n. 4
0
static struct so_list *
aix5_current_sos (void)
{
  struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
  struct so_list *sos;

  /* Fetch the list of mappings, excluding the main executable. */
  sos = build_so_list_from_mapfile (PIDGET (inferior_ptid), MA_MAINEXEC, 0);

  /* Reverse the list; it looks nicer when we print it if the mappings
     are in the same order as in the map file.  */
  if (sos)
    {
      struct so_list *next = sos->next;

      sos->next = 0;
      while (next)
	{
	  struct so_list *prev = sos;

	  sos = next;
	  next = next->next;
	  sos->next = prev;
	}
    }
  discard_cleanups (old_chain);
  return sos;
}
Esempio n. 5
0
static PyObject *
create_inferior_call_event_object (inferior_call_kind flag, ptid_t ptid,
				   CORE_ADDR addr)
{
  int pid;
  long tid, lwp;
  PyObject *event;
  PyObject *ptid_obj = NULL;
  PyObject *addr_obj = NULL;
  int failed;
  struct cleanup *cleanups;
  struct cleanup *member_cleanups;

  switch (flag)
    {
    case INFERIOR_CALL_PRE:
      event = create_event_object (&inferior_call_pre_event_object_type);
      break;
    case INFERIOR_CALL_POST:
      event = create_event_object (&inferior_call_post_event_object_type);
      break;
    default:
      return NULL;
    }

  cleanups = make_cleanup_py_decref (event);

  ptid_obj = gdbpy_create_ptid_object (ptid);
  if (ptid_obj == NULL)
    goto fail;
  member_cleanups = make_cleanup_py_decref (ptid_obj);

  failed = evpy_add_attribute (event, "ptid", ptid_obj) < 0;
  if (failed)
    goto fail;

  addr_obj = PyLong_FromLongLong (addr);
  if (addr_obj == NULL)
    goto fail;
  make_cleanup_py_decref (addr_obj);

  failed = evpy_add_attribute (event, "address", addr_obj) < 0;
  if (failed)
    goto fail;

  do_cleanups (member_cleanups);
  discard_cleanups (cleanups);
  return event;

 fail:
  do_cleanups (cleanups);
  return NULL;
}
Esempio n. 6
0
struct notif_event *
remote_notif_parse (struct notif_client *nc, char *buf)
{
  struct notif_event *event = nc->alloc_event ();
  struct cleanup *old_chain
    = make_cleanup (do_notif_event_xfree, event);

  if (notif_debug)
    fprintf_unfiltered (gdb_stdlog, "notif: parse '%s'\n", nc->name);

  nc->parse (nc, buf, event);

  discard_cleanups (old_chain);
  return event;
}
Esempio n. 7
0
void
remote_notif_ack (struct notif_client *nc, char *buf)
{
  struct notif_event *event = nc->alloc_event ();
  struct cleanup *old_chain
    = make_cleanup (do_notif_event_xfree, event);

  if (notif_debug)
    fprintf_unfiltered (gdb_stdlog, "notif: ack '%s'\n",
			nc->ack_command);

  nc->parse (nc, buf, event);
  nc->ack (nc, buf, event);

  discard_cleanups (old_chain);
}
Esempio n. 8
0
static PyObject *
create_register_changed_event_object (struct frame_info *frame, 
				      int regnum)
{
  PyObject *event;
  PyObject *frame_obj = NULL;
  PyObject *regnum_obj = NULL;
  int failed;
  struct cleanup *cleanups;
  struct cleanup *member_cleanups;

  event = create_event_object (&register_changed_event_object_type);
  if (event == NULL)
    return NULL;

  cleanups = make_cleanup_py_decref (event);

  frame_obj = frame_info_to_frame_object (frame);
  if (frame_obj == NULL)
    goto fail;
  member_cleanups = make_cleanup_py_decref (frame_obj);

  failed = evpy_add_attribute (event, "frame", frame_obj) < 0;
  if (failed)
    goto fail;

  regnum_obj = PyLong_FromLongLong (regnum);
  if (regnum_obj == NULL)
    goto fail;
  make_cleanup_py_decref (regnum_obj);

  failed = evpy_add_attribute (event, "regnum", regnum_obj) < 0;
  if (failed)
    goto fail;

  do_cleanups (member_cleanups);
  discard_cleanups (cleanups);
  return event;

 fail:
  do_cleanups (cleanups);
  return NULL;
}
Esempio n. 9
0
static PyObject *
create_memory_changed_event_object (CORE_ADDR addr, ssize_t len)
{
  PyObject *event;
  PyObject *addr_obj = NULL;
  PyObject *len_obj = NULL;
  int failed;
  struct cleanup *cleanups;
  struct cleanup *member_cleanups;

  event = create_event_object (&memory_changed_event_object_type);

  if (event == NULL)
    return NULL;
  cleanups = make_cleanup_py_decref (event);

  addr_obj = PyLong_FromLongLong (addr);
  if (addr_obj == NULL)
    goto fail;
  member_cleanups = make_cleanup_py_decref (addr_obj);

  failed = evpy_add_attribute (event, "address", addr_obj) < 0;
  if (failed)
    goto fail;

  len_obj = PyLong_FromLong (len);
  if (len_obj == NULL)
    goto fail;
  make_cleanup_py_decref (len_obj);

  failed = evpy_add_attribute (event, "length", len_obj) < 0;
  if (failed)
    goto fail;

  do_cleanups (member_cleanups);
  discard_cleanups (cleanups);
  return event;

 fail:
  do_cleanups (cleanups);
  return NULL;
}
Esempio n. 10
0
static void
gcore_command (char *args, int from_tty)
{
  struct cleanup *filename_chain;
  struct cleanup *bfd_chain;
  char *corefilename;
  bfd *obfd;

  /* No use generating a corefile without a target process.  */
  if (!target_has_execution)
    noprocess ();

  if (args && *args)
    corefilename = tilde_expand (args);
  else
    {
      /* Default corefile name is "core.PID".  */
      corefilename = xstrprintf ("core.%d", ptid_get_pid (inferior_ptid));
    }
  filename_chain = make_cleanup (xfree, corefilename);

  if (info_verbose)
    fprintf_filtered (gdb_stdout,
		      "Opening corefile '%s' for output.\n", corefilename);

  /* Open the output file.  */
  obfd = create_gcore_bfd (corefilename);

  /* Need a cleanup that will close and delete the file.  */
  bfd_chain = make_cleanup (do_bfd_delete_cleanup, obfd);

  /* Call worker function.  */
  write_gcore_file (obfd);

  /* Succeeded.  */
  discard_cleanups (bfd_chain);
  gdb_bfd_unref (obfd);

  fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename);
  do_cleanups (filename_chain);
}
Esempio n. 11
0
File: macroexp.c Progetto: 5kg/gdb
char *
macro_expand_next (char **lexptr,
                   macro_lookup_ftype *lookup_func,
                   void *lookup_baton)
{
  struct macro_buffer src, dest, tok;
  struct cleanup *back_to;

  /* Set up SRC to refer to the input text, pointed to by *lexptr.  */
  init_shared_buffer (&src, *lexptr, strlen (*lexptr));

  /* Set up DEST to receive the expansion, if there is one.  */
  init_buffer (&dest, 0);
  dest.last_token = 0;
  back_to = make_cleanup (cleanup_macro_buffer, &dest);

  /* Get the text's first preprocessing token.  */
  if (! get_token (&tok, &src))
    {
      do_cleanups (back_to);
      return 0;
    }

  /* If it's a macro invocation, expand it.  */
  if (maybe_expand (&dest, &tok, &src, 0, lookup_func, lookup_baton))
    {
      /* It was a macro invocation!  Package up the expansion as a
         null-terminated string and return it.  Set *lexptr to the
         start of the next token in the input.  */
      appendc (&dest, '\0');
      discard_cleanups (back_to);
      *lexptr = src.text;
      return dest.text;
    }
  else
    {
      /* It wasn't a macro invocation.  */
      do_cleanups (back_to);
      return 0;
    }
}
Esempio n. 12
0
File: macroexp.c Progetto: 5kg/gdb
char *
macro_expand (const char *source,
              macro_lookup_ftype *lookup_func,
              void *lookup_func_baton)
{
  struct macro_buffer src, dest;
  struct cleanup *back_to;

  init_shared_buffer (&src, (char *) source, strlen (source));

  init_buffer (&dest, 0);
  dest.last_token = 0;
  back_to = make_cleanup (cleanup_macro_buffer, &dest);

  scan (&dest, &src, 0, lookup_func, lookup_func_baton);

  appendc (&dest, '\0');

  discard_cleanups (back_to);
  return dest.text;
}
Esempio n. 13
0
static void
gcore_command (char *args, int from_tty)
{
  struct cleanup *old_chain;
  char *corefilename, corefilename_buffer[40];
  bfd *obfd;

  /* No use generating a corefile without a target process.  */
  if (!target_has_execution)
    noprocess ();

  if (args && *args)
    corefilename = args;
  else
    {
      /* Default corefile name is "core.PID".  */
      xsnprintf (corefilename_buffer, sizeof (corefilename_buffer),
		 "core.%d", PIDGET (inferior_ptid));
      corefilename = corefilename_buffer;
    }

  if (info_verbose)
    fprintf_filtered (gdb_stdout,
		      "Opening corefile '%s' for output.\n", corefilename);

  /* Open the output file.  */
  obfd = create_gcore_bfd (corefilename);

  /* Need a cleanup that will close and delete the file.  */
  old_chain = make_cleanup (do_bfd_delete_cleanup, obfd);

  /* Call worker function.  */
  write_gcore_file (obfd);

  /* Succeeded.  */
  fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename);

  discard_cleanups (old_chain);
  gdb_bfd_unref (obfd);
}
Esempio n. 14
0
static void
record_btrace_open (char *args, int from_tty)
{
  struct cleanup *disable_chain;
  struct thread_info *tp;

  DEBUG ("open");

  record_preopen ();

  if (!target_has_execution)
    error (_("The program is not being run."));

  if (!target_supports_btrace ())
    error (_("Target does not support branch tracing."));

  if (non_stop)
    error (_("Record btrace can't debug inferior in non-stop mode."));

  gdb_assert (record_btrace_thread_observer == NULL);

  disable_chain = make_cleanup (null_cleanup, NULL);
  ALL_THREADS (tp)
    if (args == NULL || *args == 0 || number_is_in_list (args, tp->num))
      {
	btrace_enable (tp);

	make_cleanup (record_btrace_disable_callback, tp);
      }

  record_btrace_auto_enable ();

  push_target (&record_btrace_ops);

  observer_notify_record_changed (current_inferior (),  1);

  discard_cleanups (disable_chain);
}
Esempio n. 15
0
struct command_line *
get_command_line (enum command_control_type type, char *arg)
{
  struct command_line *cmd;
  struct cleanup *old_chain = NULL;

  /* Allocate and build a new command line structure.  */
  cmd = build_command_line (type, arg);

  old_chain = make_cleanup_free_command_lines (&cmd);

  /* Read in the body of this command.  */
  if (recurse_read_control_structure (read_next_line, cmd, 0, 0)
      == invalid_control)
    {
      warning (_("Error reading in canned sequence of commands."));
      do_cleanups (old_chain);
      return NULL;
    }

  discard_cleanups (old_chain);
  return cmd;
}
Esempio n. 16
0
static struct so_list *
darwin_current_sos (void)
{
  struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
  int ptr_len = TYPE_LENGTH (ptr_type);
  unsigned int image_info_size;
  struct so_list *head = NULL;
  struct so_list *tail = NULL;
  int i;
  struct darwin_info *info = get_darwin_info ();

  /* Be sure image infos are loaded.  */
  darwin_load_image_infos (info);

  if (!darwin_dyld_version_ok (info))
    return NULL;

  image_info_size = ptr_len * 3;

  /* Read infos for each solib.
     The first entry was rumored to be the executable itself, but this is not
     true when a large number of shared libraries are used (table expanded ?).
     We now check all entries, but discard executable images.  */
  for (i = 0; i < info->all_image.count; i++)
    {
      CORE_ADDR iinfo = info->all_image.info + i * image_info_size;
      gdb_byte buf[image_info_size];
      CORE_ADDR load_addr;
      CORE_ADDR path_addr;
      struct mach_o_header_external hdr;
      unsigned long hdr_val;
      char *file_path;
      int errcode;
      struct darwin_so_list *dnew;
      struct so_list *newobj;
      struct cleanup *old_chain;

      /* Read image info from inferior.  */
      if (target_read_memory (iinfo, buf, image_info_size))
	break;

      load_addr = extract_typed_address (buf, ptr_type);
      path_addr = extract_typed_address (buf + ptr_len, ptr_type);

      /* Read Mach-O header from memory.  */
      if (target_read_memory (load_addr, (gdb_byte *) &hdr, sizeof (hdr) - 4))
	break;
      /* Discard wrong magic numbers.  Shouldn't happen.  */
      hdr_val = extract_unsigned_integer
        (hdr.magic, sizeof (hdr.magic), byte_order);
      if (hdr_val != BFD_MACH_O_MH_MAGIC && hdr_val != BFD_MACH_O_MH_MAGIC_64)
        continue;
      /* Discard executable.  Should happen only once.  */
      hdr_val = extract_unsigned_integer
        (hdr.filetype, sizeof (hdr.filetype), byte_order);
      if (hdr_val == BFD_MACH_O_MH_EXECUTE)
        continue;

      target_read_string (path_addr, &file_path,
			  SO_NAME_MAX_PATH_SIZE - 1, &errcode);
      if (errcode)
	break;

      /* Create and fill the new so_list element.  */
      dnew = XCNEW (struct darwin_so_list);
      newobj = &dnew->sl;
      old_chain = make_cleanup (xfree, dnew);

      newobj->lm_info = &dnew->li;

      strncpy (newobj->so_name, file_path, SO_NAME_MAX_PATH_SIZE - 1);
      newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
      strcpy (newobj->so_original_name, newobj->so_name);
      xfree (file_path);
      newobj->lm_info->lm_addr = load_addr;

      if (head == NULL)
	head = newobj;
      else
	tail->next = newobj;
      tail = newobj;

      discard_cleanups (old_chain);
    }

  return head;
}
Esempio n. 17
0
static void
core_open (const char *arg, int from_tty)
{
  const char *p;
  int siggy;
  struct cleanup *old_chain;
  char *temp;
  int scratch_chan;
  int flags;
  char *filename;

  target_preopen (from_tty);
  if (!arg)
    {
      if (core_bfd)
	error (_("No core file specified.  (Use `detach' "
		 "to stop debugging a core file.)"));
      else
	error (_("No core file specified."));
    }

  filename = tilde_expand (arg);
  if (!IS_ABSOLUTE_PATH (filename))
    {
      temp = concat (current_directory, "/",
		     filename, (char *) NULL);
      xfree (filename);
      filename = temp;
    }

  old_chain = make_cleanup (xfree, filename);

  flags = O_BINARY | O_LARGEFILE;
  if (write_files)
    flags |= O_RDWR;
  else
    flags |= O_RDONLY;
  scratch_chan = gdb_open_cloexec (filename, flags, 0);
  if (scratch_chan < 0)
    perror_with_name (filename);

  gdb_bfd_ref_ptr temp_bfd (gdb_bfd_fopen (filename, gnutarget,
					   write_files ? FOPEN_RUB : FOPEN_RB,
					   scratch_chan));
  if (temp_bfd == NULL)
    perror_with_name (filename);

  if (!bfd_check_format (temp_bfd.get (), bfd_core)
      && !gdb_check_format (temp_bfd.get ()))
    {
      /* Do it after the err msg */
      /* FIXME: should be checking for errors from bfd_close (for one
         thing, on error it does not free all the storage associated
         with the bfd).  */
      error (_("\"%s\" is not a core dump: %s"),
	     filename, bfd_errmsg (bfd_get_error ()));
    }

  /* Looks semi-reasonable.  Toss the old core file and work on the
     new.  */

  do_cleanups (old_chain);
  unpush_target (&core_ops);
  core_bfd = temp_bfd.release ();
  old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/);

  core_gdbarch = gdbarch_from_bfd (core_bfd);

  /* Find a suitable core file handler to munch on core_bfd */
  core_vec = sniff_core_bfd (core_bfd);

  validate_files ();

  core_data = XCNEW (struct target_section_table);

  /* Find the data section */
  if (build_section_table (core_bfd,
			   &core_data->sections,
			   &core_data->sections_end))
    error (_("\"%s\": Can't find sections: %s"),
	   bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));

  /* If we have no exec file, try to set the architecture from the
     core file.  We don't do this unconditionally since an exec file
     typically contains more information that helps us determine the
     architecture than a core file.  */
  if (!exec_bfd)
    set_gdbarch_from_file (core_bfd);

  push_target (&core_ops);
  discard_cleanups (old_chain);

  /* Do this before acknowledging the inferior, so if
     post_create_inferior throws (can happen easilly if you're loading
     a core file with the wrong exec), we aren't left with threads
     from the previous inferior.  */
  init_thread_list ();

  inferior_ptid = null_ptid;

  /* Need to flush the register cache (and the frame cache) from a
     previous debug session.  If inferior_ptid ends up the same as the
     last debug session --- e.g., b foo; run; gcore core1; step; gcore
     core2; core core1; core core2 --- then there's potential for
     get_current_regcache to return the cached regcache of the
     previous session, and the frame cache being stale.  */
  registers_changed ();

  /* Build up thread list from BFD sections, and possibly set the
     current thread to the .reg/NN section matching the .reg
     section.  */
  bfd_map_over_sections (core_bfd, add_to_thread_list,
			 bfd_get_section_by_name (core_bfd, ".reg"));

  if (ptid_equal (inferior_ptid, null_ptid))
    {
      /* Either we found no .reg/NN section, and hence we have a
	 non-threaded core (single-threaded, from gdb's perspective),
	 or for some reason add_to_thread_list couldn't determine
	 which was the "main" thread.  The latter case shouldn't
	 usually happen, but we're dealing with input here, which can
	 always be broken in different ways.  */
      struct thread_info *thread = first_thread_of_process (-1);

      if (thread == NULL)
	{
	  inferior_appeared (current_inferior (), CORELOW_PID);
	  inferior_ptid = pid_to_ptid (CORELOW_PID);
	  add_thread_silent (inferior_ptid);
	}
      else
	switch_to_thread (thread->ptid);
    }

  post_create_inferior (&core_ops, from_tty);

  /* Now go through the target stack looking for threads since there
     may be a thread_stratum target loaded on top of target core by
     now.  The layer above should claim threads found in the BFD
     sections.  */
  TRY
    {
      target_update_thread_list ();
    }

  CATCH (except, RETURN_MASK_ERROR)
    {
      exception_print (gdb_stderr, except);
    }
Esempio n. 18
0
/* Implementation of gdb.read_memory (address, length).
   Returns a Python buffer object with LENGTH bytes of the inferior's
   memory at ADDRESS.  Both arguments are integers.  */
static PyObject *
infpy_read_memory (PyObject *self, PyObject *args, PyObject *kw)
{
    int error = 0;
    CORE_ADDR addr, length;
    void *buffer = NULL;
    membuf_object *membuf_obj;
    PyObject *addr_obj, *length_obj;
    struct cleanup *cleanups;
    volatile struct gdb_exception except;
    static char *keywords[] = { "address", "length", NULL };

    if (! PyArg_ParseTupleAndKeywords (args, kw, "OO", keywords,
                                       &addr_obj, &length_obj))
        return NULL;

    cleanups = make_cleanup (null_cleanup, NULL);

    TRY_CATCH (except, RETURN_MASK_ALL)
    {
        if (!get_addr_from_python (addr_obj, &addr)
                || !get_addr_from_python (length_obj, &length))
        {
            error = 1;
            break;
        }

        buffer = xmalloc (length);
        make_cleanup (xfree, buffer);

        read_memory (addr, buffer, length);
    }
    if (except.reason < 0)
    {
        do_cleanups (cleanups);
        GDB_PY_HANDLE_EXCEPTION (except);
    }

    if (error)
    {
        do_cleanups (cleanups);
        return NULL;
    }

    membuf_obj = PyObject_New (membuf_object, &membuf_object_type);
    if (membuf_obj == NULL)
    {
        PyErr_SetString (PyExc_MemoryError,
                         _("Could not allocate memory buffer object."));
        do_cleanups (cleanups);
        return NULL;
    }

    discard_cleanups (cleanups);

    membuf_obj->buffer = buffer;
    membuf_obj->addr = addr;
    membuf_obj->length = length;

    return PyBuffer_FromReadWriteObject ((PyObject *) membuf_obj, 0,
                                         Py_END_OF_BUFFER);
}
Esempio n. 19
0
static void
parse_find_args (char *args, ULONGEST *max_countp,
		 char **pattern_bufp, ULONGEST *pattern_lenp,
		 CORE_ADDR *start_addrp, ULONGEST *search_space_lenp,
		 bfd_boolean big_p)
{
  /* Default to using the specified type.  */
  char size = '\0';
  ULONGEST max_count = ~(ULONGEST) 0;
  /* Buffer to hold the search pattern.  */
  char *pattern_buf;
  /* Current size of search pattern buffer.
     We realloc space as needed.  */
#define INITIAL_PATTERN_BUF_SIZE 100
  ULONGEST pattern_buf_size = INITIAL_PATTERN_BUF_SIZE;
  /* Pointer to one past the last in-use part of pattern_buf.  */
  char *pattern_buf_end;
  ULONGEST pattern_len;
  CORE_ADDR start_addr;
  ULONGEST search_space_len;
  char *s = args;
  struct cleanup *old_cleanups;
  struct value *v;

  if (args == NULL)
    error (_("Missing search parameters."));

  pattern_buf = xmalloc (pattern_buf_size);
  pattern_buf_end = pattern_buf;
  old_cleanups = make_cleanup (free_current_contents, &pattern_buf);

  /* Get search granularity and/or max count if specified.
     They may be specified in either order, together or separately.  */

  while (*s == '/')
    {
      ++s;

      while (*s != '\0' && *s != '/' && !isspace (*s))
	{
	  if (isdigit (*s))
	    {
	      max_count = atoi (s);
	      while (isdigit (*s))
		++s;
	      continue;
	    }

	  switch (*s)
	    {
	    case 'b':
	    case 'h':
	    case 'w':
	    case 'g':
	      size = *s++;
	      break;
	    default:
	      error (_("Invalid size granularity."));
	    }
	}

      while (isspace (*s))
	++s;
    }

  /* Get the search range.  */

  v = parse_to_comma_and_eval (&s);
  start_addr = value_as_address (v);

  if (*s == ',')
    ++s;
  while (isspace (*s))
    ++s;

  if (*s == '+')
    {
      LONGEST len;
      ++s;
      v = parse_to_comma_and_eval (&s);
      len = value_as_long (v);
      if (len == 0)
	{
	  printf_filtered (_("Empty search range.\n"));
	  return;
	}
      if (len < 0)
	error (_("Invalid length."));
      /* Watch for overflows.  */
      if (len > CORE_ADDR_MAX
	  || (start_addr + len - 1) < start_addr)
	error (_("Search space too large."));
      search_space_len = len;
    }
  else
    {
      CORE_ADDR end_addr;
      v = parse_to_comma_and_eval (&s);
      end_addr = value_as_address (v);
      if (start_addr > end_addr)
	error (_("Invalid search space, end preceeds start."));
      search_space_len = end_addr - start_addr + 1;
      /* We don't support searching all of memory
	 (i.e. start=0, end = 0xff..ff).
	 Bail to avoid overflows later on.  */
      if (search_space_len == 0)
	error (_("Overflow in address range computation, choose smaller range."));
    }

  if (*s == ',')
    ++s;

  /* Fetch the search string.  */

  while (*s != '\0')
    {
      LONGEST x;
      int val_bytes;

      while (isspace (*s))
	++s;

      v = parse_to_comma_and_eval (&s);
      val_bytes = TYPE_LENGTH (value_type (v));

      /* Keep it simple and assume size == 'g' when watching for when we
	 need to grow the pattern buf.  */
      if ((pattern_buf_end - pattern_buf + max (val_bytes, sizeof (int64_t)))
	  > pattern_buf_size)
	{
	  size_t current_offset = pattern_buf_end - pattern_buf;
	  pattern_buf_size *= 2;
	  pattern_buf = xrealloc (pattern_buf, pattern_buf_size);
	  pattern_buf_end = pattern_buf + current_offset;
	}

      if (size != '\0')
	{
	  x = value_as_long (v);
	  switch (size)
	    {
	    case 'b':
	      *pattern_buf_end++ = x;
	      break;
	    case 'h':
	      put_bits (x, pattern_buf_end, 16, big_p);
	      pattern_buf_end += sizeof (int16_t);
	      break;
	    case 'w':
	      put_bits (x, pattern_buf_end, 32, big_p);
	      pattern_buf_end += sizeof (int32_t);
	      break;
	    case 'g':
	      put_bits (x, pattern_buf_end, 64, big_p);
	      pattern_buf_end += sizeof (int64_t);
	      break;
	    }
	}
      else
	{
	  memcpy (pattern_buf_end, value_contents_raw (v), val_bytes);
	  pattern_buf_end += val_bytes;
	}

      if (*s == ',')
	++s;
      while (isspace (*s))
	++s;
    }

  if (pattern_buf_end == pattern_buf)
    error (_("Missing search pattern."));

  pattern_len = pattern_buf_end - pattern_buf;

  if (search_space_len < pattern_len)
    error (_("Search space too small to contain pattern."));

  *max_countp = max_count;
  *pattern_bufp = pattern_buf;
  *pattern_lenp = pattern_len;
  *start_addrp = start_addr;
  *search_space_lenp = search_space_len;

  /* We successfully parsed the arguments, leave the freeing of PATTERN_BUF
     to the caller now.  */
  discard_cleanups (old_cleanups);
}
Esempio n. 20
0
static struct block_symbol
cp_lookup_symbol_via_imports (const char *scope,
			      const char *name,
			      const struct block *block,
			      const domain_enum domain,
			      const int search_scope_first,
			      const int declaration_only,
			      const int search_parents)
{
  struct using_direct *current;
  struct block_symbol sym;
  int len;
  int directive_match;
  struct cleanup *searched_cleanup;

  sym.symbol = NULL;
  sym.block = NULL;

  /* First, try to find the symbol in the given namespace if requested.  */
  if (search_scope_first)
    sym = cp_lookup_symbol_in_namespace (scope, name,
					 block, domain, 1);

  if (sym.symbol != NULL)
    return sym;

  /* Go through the using directives.  If any of them add new names to
     the namespace we're searching in, see if we can find a match by
     applying them.  */

  for (current = block_using (block);
       current != NULL;
       current = current->next)
    {
      const char **excludep;

      len = strlen (current->import_dest);
      directive_match = (search_parents
                         ? (startswith (scope, current->import_dest)
                            && (len == 0
                                || scope[len] == ':'
				|| scope[len] == '\0'))
                         : strcmp (scope, current->import_dest) == 0);

      /* If the import destination is the current scope or one of its
         ancestors then it is applicable.  */
      if (directive_match && !current->searched)
	{
	  /* Mark this import as searched so that the recursive call
	     does not search it again.  */
	  current->searched = 1;
	  searched_cleanup = make_cleanup (reset_directive_searched,
					   current);

	  /* If there is an import of a single declaration, compare the
	     imported declaration (after optional renaming by its alias)
	     with the sought out name.  If there is a match pass
	     current->import_src as NAMESPACE to direct the search
	     towards the imported namespace.  */
	  if (current->declaration
	      && strcmp (name, current->alias
			 ? current->alias : current->declaration) == 0)
	    sym = cp_lookup_symbol_in_namespace (current->import_src,
						 current->declaration,
						 block, domain, 1);

	  /* If this is a DECLARATION_ONLY search or a symbol was found
	     or this import statement was an import declaration, the
	     search of this import is complete.  */
	  if (declaration_only || sym.symbol != NULL || current->declaration)
	    {
	      current->searched = 0;
	      discard_cleanups (searched_cleanup);

	      if (sym.symbol != NULL)
		return sym;

	      continue;
	    }

	  /* Do not follow CURRENT if NAME matches its EXCLUDES.  */
	  for (excludep = current->excludes; *excludep; excludep++)
	    if (strcmp (name, *excludep) == 0)
	      break;
	  if (*excludep)
	    {
	      discard_cleanups (searched_cleanup);
	      continue;
	    }

	  if (current->alias != NULL
	      && strcmp (name, current->alias) == 0)
	    /* If the import is creating an alias and the alias matches
	       the sought name.  Pass current->import_src as the NAME to
	       direct the search towards the aliased namespace.  */
	    {
	      sym = cp_lookup_symbol_in_namespace (scope,
						   current->import_src,
						   block, domain, 1);
	    }
	  else if (current->alias == NULL)
	    {
	      /* If this import statement creates no alias, pass
		 current->inner as NAMESPACE to direct the search
		 towards the imported namespace.  */
	      sym = cp_lookup_symbol_via_imports (current->import_src,
						  name, block,
						  domain, 1, 0, 0);
	    }
	  current->searched = 0;
	  discard_cleanups (searched_cleanup);

	  if (sym.symbol != NULL)
	    return sym;
	}
    }

  return null_block_symbol;
}
Esempio n. 21
0
struct event_location *
string_to_explicit_location (const char **argp,
			     const struct language_defn *language,
			     int dont_throw)
{
  struct cleanup *cleanup;
  struct event_location *location;

  /* It is assumed that input beginning with '-' and a non-digit
     character is an explicit location.  "-p" is reserved, though,
     for probe locations.  */
  if (argp == NULL
      || *argp == '\0'
      || *argp[0] != '-'
      || !isalpha ((*argp)[1])
      || ((*argp)[0] == '-' && (*argp)[1] == 'p'))
    return NULL;

  location = new_explicit_location (NULL);
  cleanup = make_cleanup_delete_event_location (location);

  /* Process option/argument pairs.  dprintf_command
     requires that processing stop on ','.  */
  while ((*argp)[0] != '\0' && (*argp)[0] != ',')
    {
      int len;
      char *opt, *oarg;
      const char *start;
      struct cleanup *opt_cleanup, *oarg_cleanup;

      /* If *ARGP starts with a keyword, stop processing
	 options.  */
      if (linespec_lexer_lex_keyword (*argp) != NULL)
	break;

      /* Mark the start of the string in case we need to rewind.  */
      start = *argp;

      /* Get the option string.  */
      opt = explicit_location_lex_one (argp, language);
      opt_cleanup = make_cleanup (xfree, opt);

      *argp = skip_spaces_const (*argp);

      /* Get the argument string.  */
      oarg = explicit_location_lex_one (argp, language);
      oarg_cleanup = make_cleanup (xfree, oarg);
      *argp = skip_spaces_const (*argp);

      /* Use the length of the option to allow abbreviations.  */
      len = strlen (opt);

      /* All options have a required argument.  Checking for this required
	 argument is deferred until later.  */
      if (strncmp (opt, "-source", len) == 0)
	EL_EXPLICIT (location)->source_filename = oarg;
      else if (strncmp (opt, "-function", len) == 0)
	EL_EXPLICIT (location)->function_name = oarg;
      else if (strncmp (opt, "-line", len) == 0)
	{
	  if (oarg != NULL)
	    {
	      EL_EXPLICIT (location)->line_offset
		= linespec_parse_line_offset (oarg);
	      do_cleanups (oarg_cleanup);
	      do_cleanups (opt_cleanup);
	      continue;
	    }
	}
      else if (strncmp (opt, "-label", len) == 0)
	EL_EXPLICIT (location)->label_name = oarg;
      /* Only emit an "invalid argument" error for options
	 that look like option strings.  */
      else if (opt[0] == '-' && !isdigit (opt[1]))
	{
	  if (!dont_throw)
	    error (_("invalid explicit location argument, \"%s\""), opt);
	}
      else
	{
	  /* End of the explicit location specification.
	     Stop parsing and return whatever explicit location was
	     parsed.  */
	  *argp = start;
	  discard_cleanups (oarg_cleanup);
	  do_cleanups (opt_cleanup);
	  discard_cleanups (cleanup);
	  return location;
	}

      /* It's a little lame to error after the fact, but in this
	 case, it provides a much better user experience to issue
	 the "invalid argument" error before any missing
	 argument error.  */
      if (oarg == NULL && !dont_throw)
	error (_("missing argument for \"%s\""), opt);

      /* The option/argument pair was successfully processed;
	 oarg belongs to the explicit location, and opt should
	 be freed.  */
      discard_cleanups (oarg_cleanup);
      do_cleanups (opt_cleanup);
    }

  /* One special error check:  If a source filename was given
     without offset, function, or label, issue an error.  */
  if (EL_EXPLICIT (location)->source_filename != NULL
      && EL_EXPLICIT (location)->function_name == NULL
      && EL_EXPLICIT (location)->label_name == NULL
      && (EL_EXPLICIT (location)->line_offset.sign == LINE_OFFSET_UNKNOWN)
      && !dont_throw)
    {
      error (_("Source filename requires function, label, or "
	       "line offset."));
    }

  discard_cleanups (cleanup);
  return location;
}
Esempio n. 22
0
static struct block_symbol
d_lookup_symbol_imports (const char *scope, const char *name,
			 const struct block *block,
			 const domain_enum domain)
{
  struct using_direct *current;
  struct block_symbol sym;
  struct cleanup *searched_cleanup;

  /* First, try to find the symbol in the given module.  */
  sym = d_lookup_symbol_in_module (scope, name, block, domain, 1);

  if (sym.symbol != NULL)
    return sym;

  /* Go through the using directives.  If any of them add new names to
     the module we're searching in, see if we can find a match by
     applying them.  */

  for (current = block_using (block);
       current != NULL;
       current = current->next)
    {
      const char **excludep;

      /* If the import destination is the current scope then search it.  */
      if (!current->searched && strcmp (scope, current->import_dest) == 0)
	{
	  /* Mark this import as searched so that the recursive call
	     does not search it again.  */
	  current->searched = 1;
	  searched_cleanup = make_cleanup (reset_directive_searched,
					   current);

	  /* If there is an import of a single declaration, compare the
	     imported declaration (after optional renaming by its alias)
	     with the sought out name.  If there is a match pass
	     current->import_src as MODULE to direct the search towards
	     the imported module.  */
	  if (current->declaration
	      && strcmp (name, current->alias
			 ? current->alias : current->declaration) == 0)
	    sym = d_lookup_symbol_in_module (current->import_src,
					     current->declaration,
					     block, domain, 1);

	  /* If a symbol was found or this import statement was an import
	     declaration, the search of this import is complete.  */
	  if (sym.symbol != NULL || current->declaration)
	    {
	      current->searched = 0;
	      discard_cleanups (searched_cleanup);

	      if (sym.symbol != NULL)
		return sym;

	      continue;
	    }

	  /* Do not follow CURRENT if NAME matches its EXCLUDES.  */
	  for (excludep = current->excludes; *excludep; excludep++)
	    if (strcmp (name, *excludep) == 0)
	      break;
	  if (*excludep)
	    {
	      discard_cleanups (searched_cleanup);
	      continue;
	    }

	  /* If the import statement is creating an alias.  */
	  if (current->alias != NULL)
	    {
	      if (strcmp (name, current->alias) == 0)
		{
		  /* If the alias matches the sought name.  Pass
		     current->import_src as the NAME to direct the
		     search towards the aliased module.  */
		  sym = lookup_module_scope (NULL, current->import_src, block,
					     domain, scope, 0);
		}
	      else
		{
		  /* If the alias matches the first component of the
		     sought name, pass current->import_src as MODULE
		     to direct the search, skipping over the aliased
		     component in NAME.  */
		  int name_scope = d_find_first_component (name);

		  if (name[name_scope] != '\0'
		      && strncmp (name, current->alias, name_scope) == 0)
		    {
		      /* Skip the '.'  */
		      name_scope++;
		      sym = d_lookup_symbol_imports (current->import_src,
						     name + name_scope,
						     block, domain);
		    }
		}
	    }
	  else
	    {
	      /* If this import statement creates no alias, pass
		 current->import_src as MODULE to direct the search
		 towards the imported module.  */
	      sym = d_lookup_symbol_imports (current->import_src,
					     name, block, domain);
	    }
	  current->searched = 0;
	  discard_cleanups (searched_cleanup);

	  if (sym.symbol != NULL)
	    return sym;
	}
    }

  return null_block_symbol;
}
Esempio n. 23
0
struct compile_module *
compile_object_load (const char *object_file, const char *source_file)
{
  struct cleanup *cleanups, *cleanups_free_objfile;
  bfd *abfd;
  struct setup_sections_data setup_sections_data;
  CORE_ADDR addr, func_addr, regs_addr;
  struct bound_minimal_symbol bmsym;
  long storage_needed;
  asymbol **symbol_table, **symp;
  long number_of_symbols, missing_symbols;
  struct type *dptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
  unsigned dptr_type_len = TYPE_LENGTH (dptr_type);
  struct compile_module *retval;
  struct type *regs_type;
  char *filename, **matching;
  struct objfile *objfile;

  filename = tilde_expand (object_file);
  cleanups = make_cleanup (xfree, filename);

  abfd = gdb_bfd_open (filename, gnutarget, -1);
  if (abfd == NULL)
    error (_("\"%s\": could not open as compiled module: %s"),
          filename, bfd_errmsg (bfd_get_error ()));
  make_cleanup_bfd_unref (abfd);

  if (!bfd_check_format_matches (abfd, bfd_object, &matching))
    error (_("\"%s\": not in loadable format: %s"),
          filename, gdb_bfd_errmsg (bfd_get_error (), matching));

  if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) != 0)
    error (_("\"%s\": not in object format."), filename);

  setup_sections_data.last_size = 0;
  setup_sections_data.last_section_first = abfd->sections;
  setup_sections_data.last_prot = -1;
  setup_sections_data.last_max_alignment = 1;
  bfd_map_over_sections (abfd, setup_sections, &setup_sections_data);
  setup_sections (abfd, NULL, &setup_sections_data);

  storage_needed = bfd_get_symtab_upper_bound (abfd);
  if (storage_needed < 0)
    error (_("Cannot read symbols of compiled module \"%s\": %s"),
          filename, bfd_errmsg (bfd_get_error ()));

  /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in
     "Reading symbols from ..." message for automatically generated file.  */
  objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL);
  cleanups_free_objfile = make_cleanup_free_objfile (objfile);

  bmsym = lookup_minimal_symbol_text (GCC_FE_WRAPPER_FUNCTION, objfile);
  if (bmsym.minsym == NULL || MSYMBOL_TYPE (bmsym.minsym) == mst_file_text)
    error (_("Could not find symbol \"%s\" of compiled module \"%s\"."),
	   GCC_FE_WRAPPER_FUNCTION, filename);
  func_addr = BMSYMBOL_VALUE_ADDRESS (bmsym);

  /* The memory may be later needed
     by bfd_generic_get_relocated_section_contents
     called from default_symfile_relocate.  */
  symbol_table = obstack_alloc (&objfile->objfile_obstack, storage_needed);
  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
  if (number_of_symbols < 0)
    error (_("Cannot parse symbols of compiled module \"%s\": %s"),
          filename, bfd_errmsg (bfd_get_error ()));

  missing_symbols = 0;
  for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++)
    {
      asymbol *sym = *symp;

      if (sym->flags != 0)
	continue;
      if (compile_debug)
	fprintf_unfiltered (gdb_stdout,
			    "lookup undefined ELF symbol \"%s\"\n",
			    sym->name);
      sym->flags = BSF_GLOBAL;
      sym->section = bfd_abs_section_ptr;
      if (strcmp (sym->name, "_GLOBAL_OFFSET_TABLE_") == 0)
	{
	  sym->value = 0;
	  continue;
	}
      bmsym = lookup_minimal_symbol (sym->name, NULL, NULL);
      switch (bmsym.minsym == NULL
	      ? mst_unknown : MSYMBOL_TYPE (bmsym.minsym))
	{
	case mst_text:
	  sym->value = BMSYMBOL_VALUE_ADDRESS (bmsym);
	  break;
	default:
	  warning (_("Could not find symbol \"%s\" "
		     "for compiled module \"%s\"."),
		   sym->name, filename);
	  missing_symbols++;
	}
    }
  if (missing_symbols)
    error (_("%ld symbols were missing, cannot continue."), missing_symbols);

  bfd_map_over_sections (abfd, copy_sections, symbol_table);

  regs_type = get_regs_type (objfile);
  if (regs_type == NULL)
    regs_addr = 0;
  else
    {
      /* Use read-only non-executable memory protection.  */
      regs_addr = gdbarch_infcall_mmap (target_gdbarch (),
					TYPE_LENGTH (regs_type),
					GDB_MMAP_PROT_READ);
      gdb_assert (regs_addr != 0);
      store_regs (regs_type, regs_addr);
    }

  discard_cleanups (cleanups_free_objfile);
  do_cleanups (cleanups);

  retval = xmalloc (sizeof (*retval));
  retval->objfile = objfile;
  retval->source_file = xstrdup (source_file);
  retval->func_addr = func_addr;
  retval->regs_addr = regs_addr;
  return retval;
}
Esempio n. 24
0
File: inf-loop.c Progetto: 5kg/gdb
/* General function to handle events in the inferior.  So far it just
   takes care of detecting errors reported by select() or poll(),
   otherwise it assumes that all is OK, and goes on reading data from
   the fd.  This however may not always be what we want to do.  */
void
inferior_event_handler (enum inferior_event_type event_type, 
			gdb_client_data client_data)
{
  struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup ();

  switch (event_type)
    {
    case INF_REG_EVENT:
      /* Use catch errors for now, until the inner layers of
	 fetch_inferior_event (i.e. readchar) can return meaningful
	 error status.  If an error occurs while getting an event from
	 the target, just cancel the current command.  */
      if (!catch_errors (fetch_inferior_event_wrapper, 
			 client_data, "", RETURN_MASK_ALL))
	{
	  bpstat_clear_actions ();
	  do_all_intermediate_continuations (1);
	  do_all_continuations (1);
	  async_enable_stdin ();
	  display_gdb_prompt (0);
	}
      break;

    case INF_EXEC_COMPLETE:
      if (!non_stop)
	{
	  /* Unregister the inferior from the event loop.  This is done
	     so that when the inferior is not running we don't get
	     distracted by spurious inferior output.  */
	  if (target_has_execution)
	    target_async (NULL, 0);
	}

      /* Do all continuations associated with the whole inferior (not
	 a particular thread).  */
      if (!ptid_equal (inferior_ptid, null_ptid))
	do_all_inferior_continuations (0);

      /* If we were doing a multi-step (eg: step n, next n), but it
	 got interrupted by a breakpoint, still do the pending
	 continuations.  The continuation itself is responsible for
	 distinguishing the cases.  The continuations are allowed to
	 touch the inferior memory, e.g. to remove breakpoints, so run
	 them before running breakpoint commands, which may resume the
	 target.  */
      if (non_stop
	  && target_has_execution
	  && !ptid_equal (inferior_ptid, null_ptid))
	do_all_intermediate_continuations_thread (inferior_thread (), 0);
      else
	do_all_intermediate_continuations (0);

      /* Always finish the previous command before running any
	 breakpoint commands.  Any stop cancels the previous command.
	 E.g. a "finish" or "step-n" command interrupted by an
	 unrelated breakpoint is canceled.  */
      if (non_stop
	  && target_has_execution
	  && !ptid_equal (inferior_ptid, null_ptid))
	do_all_continuations_thread (inferior_thread (), 0);
      else
	do_all_continuations (0);

      /* When running a command list (from a user command, say), these
	 are only run when the command list is all done.  */
      if (interpreter_async)
	{
	  volatile struct gdb_exception e;

	  check_frame_language_change ();

	  /* Don't propagate breakpoint commands errors.  Either we're
	     stopping or some command resumes the inferior.  The user will
	     be informed.  */
	  TRY_CATCH (e, RETURN_MASK_ALL)
	    {
	      bpstat_do_actions ();
	    }
	  exception_print (gdb_stderr, e);
	}
      break;

    case INF_EXEC_CONTINUE:
      /* Is there anything left to do for the command issued to
         complete?  */

      if (non_stop)
	do_all_intermediate_continuations_thread (inferior_thread (), 0);
      else
	do_all_intermediate_continuations (0);
      break;

    case INF_TIMER:
    default:
      printf_unfiltered (_("Event type not recognized.\n"));
      break;
    }

  discard_cleanups (cleanup_if_error);
}
static void
tfile_open (const char *arg, int from_tty)
{
  char *temp;
  struct cleanup *old_chain;
  int flags;
  int scratch_chan;
  char header[TRACE_HEADER_SIZE];
  char linebuf[1000]; /* Should be max remote packet size or so.  */
  gdb_byte byte;
  int bytes, i;
  struct trace_status *ts;
  struct uploaded_tp *uploaded_tps = NULL;
  struct uploaded_tsv *uploaded_tsvs = NULL;
  char *filename;

  target_preopen (from_tty);
  if (!arg)
    error (_("No trace file specified."));

  filename = tilde_expand (arg);
  if (!IS_ABSOLUTE_PATH(filename))
    {
      temp = concat (current_directory, "/", filename, (char *) NULL);
      xfree (filename);
      filename = temp;
    }

  old_chain = make_cleanup (xfree, filename);

  flags = O_BINARY | O_LARGEFILE;
  flags |= O_RDONLY;
  scratch_chan = gdb_open_cloexec (filename, flags, 0);
  if (scratch_chan < 0)
    perror_with_name (filename);

  /* Looks semi-reasonable.  Toss the old trace file and work on the new.  */

  discard_cleanups (old_chain);	/* Don't free filename any more.  */
  unpush_target (&tfile_ops);

  trace_filename = xstrdup (filename);
  trace_fd = scratch_chan;

  /* Make sure this is clear.  */
  buffer_free (&trace_tdesc);

  bytes = 0;
  /* Read the file header and test for validity.  */
  tfile_read ((gdb_byte *) &header, TRACE_HEADER_SIZE);

  bytes += TRACE_HEADER_SIZE;
  if (!(header[0] == 0x7f
	&& (startswith (header + 1, "TRACE0\n"))))
    error (_("File is not a valid trace file."));

  push_target (&tfile_ops);

  trace_regblock_size = 0;
  ts = current_trace_status ();
  /* We know we're working with a file.  Record its name.  */
  ts->filename = trace_filename;
  /* Set defaults in case there is no status line.  */
  ts->running_known = 0;
  ts->stop_reason = trace_stop_reason_unknown;
  ts->traceframe_count = -1;
  ts->buffer_free = 0;
  ts->disconnected_tracing = 0;
  ts->circular_buffer = 0;

  TRY
    {
      /* Read through a section of newline-terminated lines that
	 define things like tracepoints.  */
      i = 0;
      while (1)
	{
	  tfile_read (&byte, 1);

	  ++bytes;
	  if (byte == '\n')
	    {
	      /* Empty line marks end of the definition section.  */
	      if (i == 0)
		break;
	      linebuf[i] = '\0';
	      i = 0;
	      tfile_interp_line (linebuf, &uploaded_tps, &uploaded_tsvs);
	    }
	  else
	    linebuf[i++] = byte;
	  if (i >= 1000)
	    error (_("Excessively long lines in trace file"));
	}

      /* By now, tdesc lines have been read from tfile - let's parse them.  */
      target_find_description ();

      /* Record the starting offset of the binary trace data.  */
      trace_frames_offset = bytes;

      /* If we don't have a blocksize, we can't interpret the
	 traceframes.  */
      if (trace_regblock_size == 0)
	error (_("No register block size recorded in trace file"));
    }
  CATCH (ex, RETURN_MASK_ALL)
    {
      /* Remove the partially set up target.  */
      unpush_target (&tfile_ops);
      throw_exception (ex);
    }
Esempio n. 26
0
struct compile_module *
compile_object_load (const char *object_file, const char *source_file,
		     enum compile_i_scope_types scope, void *scope_data)
{
  struct cleanup *cleanups, *cleanups_free_objfile;
  bfd *abfd;
  struct setup_sections_data setup_sections_data;
  CORE_ADDR addr, regs_addr, out_value_addr = 0;
  struct symbol *func_sym;
  struct type *func_type;
  struct bound_minimal_symbol bmsym;
  long storage_needed;
  asymbol **symbol_table, **symp;
  long number_of_symbols, missing_symbols;
  struct type *dptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
  unsigned dptr_type_len = TYPE_LENGTH (dptr_type);
  struct compile_module *retval;
  struct type *regs_type, *out_value_type = NULL;
  char *filename, **matching;
  struct objfile *objfile;
  int expect_parameters;
  struct type *expect_return_type;
  struct munmap_list *munmap_list_head = NULL;

  filename = tilde_expand (object_file);
  cleanups = make_cleanup (xfree, filename);

  abfd = gdb_bfd_open (filename, gnutarget, -1);
  if (abfd == NULL)
    error (_("\"%s\": could not open as compiled module: %s"),
          filename, bfd_errmsg (bfd_get_error ()));
  make_cleanup_bfd_unref (abfd);

  if (!bfd_check_format_matches (abfd, bfd_object, &matching))
    error (_("\"%s\": not in loadable format: %s"),
          filename, gdb_bfd_errmsg (bfd_get_error (), matching));

  if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) != 0)
    error (_("\"%s\": not in object format."), filename);

  setup_sections_data.last_size = 0;
  setup_sections_data.last_section_first = abfd->sections;
  setup_sections_data.last_prot = -1;
  setup_sections_data.last_max_alignment = 1;
  setup_sections_data.munmap_list_headp = &munmap_list_head;
  make_cleanup (munmap_listp_free_cleanup, &munmap_list_head);
  bfd_map_over_sections (abfd, setup_sections, &setup_sections_data);
  setup_sections (abfd, NULL, &setup_sections_data);

  storage_needed = bfd_get_symtab_upper_bound (abfd);
  if (storage_needed < 0)
    error (_("Cannot read symbols of compiled module \"%s\": %s"),
          filename, bfd_errmsg (bfd_get_error ()));

  /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in
     "Reading symbols from ..." message for automatically generated file.  */
  objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL);
  cleanups_free_objfile = make_cleanup_free_objfile (objfile);

  func_sym = lookup_global_symbol_from_objfile (objfile,
						GCC_FE_WRAPPER_FUNCTION,
						VAR_DOMAIN).symbol;
  if (func_sym == NULL)
    error (_("Cannot find function \"%s\" in compiled module \"%s\"."),
	   GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile));
  func_type = SYMBOL_TYPE (func_sym);
  if (TYPE_CODE (func_type) != TYPE_CODE_FUNC)
    error (_("Invalid type code %d of function \"%s\" in compiled "
	     "module \"%s\"."),
	   TYPE_CODE (func_type), GCC_FE_WRAPPER_FUNCTION,
	   objfile_name (objfile));

  switch (scope)
    {
    case COMPILE_I_SIMPLE_SCOPE:
      expect_parameters = 1;
      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
      break;
    case COMPILE_I_RAW_SCOPE:
      expect_parameters = 0;
      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
      break;
    case COMPILE_I_PRINT_ADDRESS_SCOPE:
    case COMPILE_I_PRINT_VALUE_SCOPE:
      expect_parameters = 2;
      expect_return_type = builtin_type (target_gdbarch ())->builtin_void;
      break;
    default:
      internal_error (__FILE__, __LINE__, _("invalid scope %d"), scope);
    }
  if (TYPE_NFIELDS (func_type) != expect_parameters)
    error (_("Invalid %d parameters of function \"%s\" in compiled "
	     "module \"%s\"."),
	   TYPE_NFIELDS (func_type), GCC_FE_WRAPPER_FUNCTION,
	   objfile_name (objfile));
  if (!types_deeply_equal (expect_return_type, TYPE_TARGET_TYPE (func_type)))
    error (_("Invalid return type of function \"%s\" in compiled "
	    "module \"%s\"."),
	  GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile));

  /* The memory may be later needed
     by bfd_generic_get_relocated_section_contents
     called from default_symfile_relocate.  */
  symbol_table = obstack_alloc (&objfile->objfile_obstack, storage_needed);
  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
  if (number_of_symbols < 0)
    error (_("Cannot parse symbols of compiled module \"%s\": %s"),
          filename, bfd_errmsg (bfd_get_error ()));

  missing_symbols = 0;
  for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++)
    {
      asymbol *sym = *symp;

      if (sym->flags != 0)
	continue;
      sym->flags = BSF_GLOBAL;
      sym->section = bfd_abs_section_ptr;
      if (strcmp (sym->name, "_GLOBAL_OFFSET_TABLE_") == 0)
	{
	  if (compile_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"ELF symbol \"%s\" relocated to zero\n",
				sym->name);

	  /* It seems to be a GCC bug, with -mcmodel=large there should be no
	     need for _GLOBAL_OFFSET_TABLE_.  Together with -fPIE the data
	     remain PC-relative even with _GLOBAL_OFFSET_TABLE_ as zero.  */
	  sym->value = 0;
	  continue;
	}
      bmsym = lookup_minimal_symbol (sym->name, NULL, NULL);
      switch (bmsym.minsym == NULL
	      ? mst_unknown : MSYMBOL_TYPE (bmsym.minsym))
	{
	case mst_text:
	  sym->value = BMSYMBOL_VALUE_ADDRESS (bmsym);
	  if (compile_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"ELF mst_text symbol \"%s\" relocated to %s\n",
				sym->name,
				paddress (target_gdbarch (), sym->value));
	  break;
	case mst_text_gnu_ifunc:
	  sym->value = gnu_ifunc_resolve_addr (target_gdbarch (),
					       BMSYMBOL_VALUE_ADDRESS (bmsym));
	  if (compile_debug)
	    fprintf_unfiltered (gdb_stdlog,
				"ELF mst_text_gnu_ifunc symbol \"%s\" "
				"relocated to %s\n",
				sym->name,
				paddress (target_gdbarch (), sym->value));
	  break;
	default:
	  warning (_("Could not find symbol \"%s\" "
		     "for compiled module \"%s\"."),
		   sym->name, filename);
	  missing_symbols++;
	}
    }
  if (missing_symbols)
    error (_("%ld symbols were missing, cannot continue."), missing_symbols);

  bfd_map_over_sections (abfd, copy_sections, symbol_table);

  regs_type = get_regs_type (func_sym, objfile);
  if (regs_type == NULL)
    regs_addr = 0;
  else
    {
      /* Use read-only non-executable memory protection.  */
      regs_addr = gdbarch_infcall_mmap (target_gdbarch (),
					TYPE_LENGTH (regs_type),
					GDB_MMAP_PROT_READ);
      gdb_assert (regs_addr != 0);
      munmap_list_add (&munmap_list_head, regs_addr, TYPE_LENGTH (regs_type));
      if (compile_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "allocated %s bytes at %s for registers\n",
			    paddress (target_gdbarch (),
				      TYPE_LENGTH (regs_type)),
			    paddress (target_gdbarch (), regs_addr));
      store_regs (regs_type, regs_addr);
    }

  if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE
      || scope == COMPILE_I_PRINT_VALUE_SCOPE)
    {
      out_value_type = get_out_value_type (func_sym, objfile, scope);
      if (out_value_type == NULL)
	{
	  do_cleanups (cleanups);
	  return NULL;
	}
      check_typedef (out_value_type);
      out_value_addr = gdbarch_infcall_mmap (target_gdbarch (),
					     TYPE_LENGTH (out_value_type),
					     (GDB_MMAP_PROT_READ
					      | GDB_MMAP_PROT_WRITE));
      gdb_assert (out_value_addr != 0);
      munmap_list_add (&munmap_list_head, out_value_addr,
		       TYPE_LENGTH (out_value_type));
      if (compile_debug)
	fprintf_unfiltered (gdb_stdlog,
			    "allocated %s bytes at %s for printed value\n",
			    paddress (target_gdbarch (),
				      TYPE_LENGTH (out_value_type)),
			    paddress (target_gdbarch (), out_value_addr));
    }

  discard_cleanups (cleanups_free_objfile);

  retval = xmalloc (sizeof (*retval));
  retval->objfile = objfile;
  retval->source_file = xstrdup (source_file);
  retval->func_sym = func_sym;
  retval->regs_addr = regs_addr;
  retval->scope = scope;
  retval->scope_data = scope_data;
  retval->out_value_type = out_value_type;
  retval->out_value_addr = out_value_addr;

  /* CLEANUPS will free MUNMAP_LIST_HEAD.  */
  retval->munmap_list_head = munmap_list_head;
  munmap_list_head = NULL;

  do_cleanups (cleanups);

  return retval;
}
Esempio n. 27
0
static void
kgdb_trgt_open(char *filename, int from_tty)
{
	struct cleanup *old_chain;
	struct thread_info *ti;
	struct kthr *kt;
	kvm_t *nkvm;
	char *temp;
	int ontop;

	target_preopen (from_tty);
	if (!filename)
		error ("No vmcore file specified.");
	if (!exec_bfd)
		error ("Can't open a vmcore without a kernel");

	filename = tilde_expand (filename);
	if (filename[0] != '/') {
		temp = concat (current_directory, "/", filename, NULL);
		xfree(filename);
		filename = temp;
	}

	old_chain = make_cleanup (xfree, filename);

	nkvm = kvm_openfiles(bfd_get_filename(exec_bfd), filename, NULL,
	    write_files ? O_RDWR : O_RDONLY, kvm_err);
	if (nkvm == NULL)
		error ("Failed to open vmcore: %s", kvm_err);

	/* Don't free the filename now and close any previous vmcore. */
	discard_cleanups(old_chain);
	unpush_target(&kgdb_trgt_ops);

	kvm = nkvm;
	vmcore = filename;
	old_chain = make_cleanup(kgdb_core_cleanup, NULL);

	ontop = !push_target (&kgdb_trgt_ops);
	discard_cleanups (old_chain);

	kgdb_dmesg();

	init_thread_list();
	kt = kgdb_thr_init();
	while (kt != NULL) {
		ti = add_thread(pid_to_ptid(kt->tid));
		kt = kgdb_thr_next(kt);
	}
	if (curkthr != 0)
		inferior_ptid = pid_to_ptid(curkthr->tid);

	if (ontop) {
		/* XXX: fetch registers? */
		kld_init();
		flush_cached_frames();
		select_frame (get_current_frame());
		print_stack_frame(get_selected_frame(),
		    frame_relative_level(get_selected_frame()), 1);
	} else
		warning(
	"you won't be able to access this vmcore until you terminate\n\
your %s; do ``info files''", target_longname);
}
Esempio n. 28
0
File: macroexp.c Progetto: 5kg/gdb
static struct macro_buffer *
gather_arguments (const char *name, struct macro_buffer *src,
		  int nargs, int *argc_p)
{
  struct macro_buffer tok;
  int args_len, args_size;
  struct macro_buffer *args = NULL;
  struct cleanup *back_to = make_cleanup (free_current_contents, &args);

  /* Does SRC start with an opening paren token?  Read from a copy of
     SRC, so SRC itself is unaffected if we don't find an opening
     paren.  */
  {
    struct macro_buffer temp;

    init_shared_buffer (&temp, src->text, src->len);

    if (! get_token (&tok, &temp)
        || tok.len != 1
        || tok.text[0] != '(')
      {
        discard_cleanups (back_to);
        return 0;
      }
  }

  /* Consume SRC's opening paren.  */
  get_token (&tok, src);

  args_len = 0;
  args_size = 6;
  args = (struct macro_buffer *) xmalloc (sizeof (*args) * args_size);

  for (;;)
    {
      struct macro_buffer *arg;
      int depth;

      /* Make sure we have room for the next argument.  */
      if (args_len >= args_size)
        {
          args_size *= 2;
          args = xrealloc (args, sizeof (*args) * args_size);
        }

      /* Initialize the next argument.  */
      arg = &args[args_len++];
      set_token (arg, src->text, src->text);

      /* Gather the argument's tokens.  */
      depth = 0;
      for (;;)
        {
          if (! get_token (&tok, src))
            error (_("Malformed argument list for macro `%s'."), name);
      
          /* Is tok an opening paren?  */
          if (tok.len == 1 && tok.text[0] == '(')
            depth++;

          /* Is tok is a closing paren?  */
          else if (tok.len == 1 && tok.text[0] == ')')
            {
              /* If it's a closing paren at the top level, then that's
                 the end of the argument list.  */
              if (depth == 0)
                {
		  /* In the varargs case, the last argument may be
		     missing.  Add an empty argument in this case.  */
		  if (nargs != -1 && args_len == nargs - 1)
		    {
		      /* Make sure we have room for the argument.  */
		      if (args_len >= args_size)
			{
			  args_size++;
			  args = xrealloc (args, sizeof (*args) * args_size);
			}
		      arg = &args[args_len++];
		      set_token (arg, src->text, src->text);
		    }

                  discard_cleanups (back_to);
                  *argc_p = args_len;
                  return args;
                }

              depth--;
            }

          /* If tok is a comma at top level, then that's the end of
             the current argument.  However, if we are handling a
             variadic macro and we are computing the last argument, we
             want to include the comma and remaining tokens.  */
          else if (tok.len == 1 && tok.text[0] == ',' && depth == 0
		   && (nargs == -1 || args_len < nargs))
            break;

          /* Extend the current argument to enclose this token.  If
             this is the current argument's first token, leave out any
             leading whitespace, just for aesthetics.  */
          if (arg->len == 0)
            {
              arg->text = tok.text;
              arg->len = tok.len;
              arg->last_token = 0;
            }
          else
            {
              arg->len = (tok.text + tok.len) - arg->text;
              arg->last_token = tok.text - arg->text;
            }
        }
    }
}
Esempio n. 29
0
static void
core_open (char *filename, int from_tty)
{
  const char *p;
  int siggy;
  struct cleanup *old_chain;
  char *temp;
  bfd *temp_bfd;
  int scratch_chan;
  int flags;
  volatile struct gdb_exception except;

  target_preopen (from_tty);
  if (!filename)
    {
      if (core_bfd)
	error (_("No core file specified.  (Use `detach' "
		 "to stop debugging a core file.)"));
      else
	error (_("No core file specified."));
    }

  filename = tilde_expand (filename);
  if (!IS_ABSOLUTE_PATH (filename))
    {
      temp = concat (current_directory, "/",
		     filename, (char *) NULL);
      xfree (filename);
      filename = temp;
    }

  old_chain = make_cleanup (xfree, filename);

  flags = O_BINARY | O_LARGEFILE;
  if (write_files)
    flags |= O_RDWR;
  else
    flags |= O_RDONLY;
  scratch_chan = open (filename, flags, 0);
  if (scratch_chan < 0)
    perror_with_name (filename);

  temp_bfd = bfd_fopen (filename, gnutarget, 
			write_files ? FOPEN_RUB : FOPEN_RB,
			scratch_chan);
  if (temp_bfd == NULL)
    perror_with_name (filename);

  if (!bfd_check_format (temp_bfd, bfd_core)
      && !gdb_check_format (temp_bfd))
    {
      /* Do it after the err msg */
      /* FIXME: should be checking for errors from bfd_close (for one
         thing, on error it does not free all the storage associated
         with the bfd).  */
      make_cleanup_bfd_close (temp_bfd);
      error (_("\"%s\" is not a core dump: %s"),
	     filename, bfd_errmsg (bfd_get_error ()));
    }

  /* Looks semi-reasonable.  Toss the old core file and work on the
     new.  */

  discard_cleanups (old_chain);	/* Don't free filename any more */
  unpush_target (&core_ops);
  core_bfd = temp_bfd;
  old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/);

  /* FIXME: kettenis/20031023: This is very dangerous.  The
     CORE_GDBARCH that results from this call may very well be
     different from CURRENT_GDBARCH.  However, its methods may only
     work if it is selected as the current architecture, because they
     rely on swapped data (see gdbarch.c).  We should get rid of that
     swapped data.  */
  core_gdbarch = gdbarch_from_bfd (core_bfd);

  /* Find a suitable core file handler to munch on core_bfd */
  core_vec = sniff_core_bfd (core_bfd);

  validate_files ();

  core_data = XZALLOC (struct target_section_table);

  /* Find the data section */
  if (build_section_table (core_bfd,
			   &core_data->sections,
			   &core_data->sections_end))
    error (_("\"%s\": Can't find sections: %s"),
	   bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));

  /* If we have no exec file, try to set the architecture from the
     core file.  We don't do this unconditionally since an exec file
     typically contains more information that helps us determine the
     architecture than a core file.  */
  if (!exec_bfd)
    set_gdbarch_from_file (core_bfd);

  push_target (&core_ops);
  discard_cleanups (old_chain);

  /* Do this before acknowledging the inferior, so if
     post_create_inferior throws (can happen easilly if you're loading
     a core file with the wrong exec), we aren't left with threads
     from the previous inferior.  */
  init_thread_list ();

  inferior_ptid = null_ptid;

  /* Need to flush the register cache (and the frame cache) from a
     previous debug session.  If inferior_ptid ends up the same as the
     last debug session --- e.g., b foo; run; gcore core1; step; gcore
     core2; core core1; core core2 --- then there's potential for
     get_current_regcache to return the cached regcache of the
     previous session, and the frame cache being stale.  */
  registers_changed ();

  /* Build up thread list from BFD sections, and possibly set the
     current thread to the .reg/NN section matching the .reg
     section.  */
  bfd_map_over_sections (core_bfd, add_to_thread_list,
			 bfd_get_section_by_name (core_bfd, ".reg"));

  if (ptid_equal (inferior_ptid, null_ptid))
    {
      /* Either we found no .reg/NN section, and hence we have a
	 non-threaded core (single-threaded, from gdb's perspective),
	 or for some reason add_to_thread_list couldn't determine
	 which was the "main" thread.  The latter case shouldn't
	 usually happen, but we're dealing with input here, which can
	 always be broken in different ways.  */
      struct thread_info *thread = first_thread_of_process (-1);

      if (thread == NULL)
	{
	  inferior_appeared (current_inferior (), CORELOW_PID);
	  inferior_ptid = pid_to_ptid (CORELOW_PID);
	  add_thread_silent (inferior_ptid);
	}
      else
	switch_to_thread (thread->ptid);
    }

  post_create_inferior (&core_ops, from_tty);

  /* Now go through the target stack looking for threads since there
     may be a thread_stratum target loaded on top of target core by
     now.  The layer above should claim threads found in the BFD
     sections.  */
  TRY_CATCH (except, RETURN_MASK_ERROR)
    {
      target_find_new_threads ();
    }

  if (except.reason < 0)
    exception_print (gdb_stderr, except);

  p = bfd_core_file_failing_command (core_bfd);
  if (p)
    printf_filtered (_("Core was generated by `%s'.\n"), p);

  siggy = bfd_core_file_failing_signal (core_bfd);
  if (siggy > 0)
    {
      /* If we don't have a CORE_GDBARCH to work with, assume a native
	 core (map gdb_signal from host signals).  If we do have
	 CORE_GDBARCH to work with, but no gdb_signal_from_target
	 implementation for that gdbarch, as a fallback measure,
	 assume the host signal mapping.  It'll be correct for native
	 cores, but most likely incorrect for cross-cores.  */
      enum gdb_signal sig = (core_gdbarch != NULL
			     && gdbarch_gdb_signal_from_target_p (core_gdbarch)
			     ? gdbarch_gdb_signal_from_target (core_gdbarch,
							       siggy)
			     : gdb_signal_from_host (siggy));

      printf_filtered (_("Program terminated with signal %d, %s.\n"),
		       siggy, gdb_signal_to_string (sig));
    }

  /* Fetch all registers from core file.  */
  target_fetch_registers (get_current_regcache (), -1);

  /* Now, set up the frame cache, and print the top of stack.  */
  reinit_frame_cache ();
  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
}
Esempio n. 30
0
static void
kgdb_trgt_open(char *filename, int from_tty)
{
	struct cleanup *old_chain;
	struct kthr *kt;
	struct inferior *inf8;
	struct program_space *pspace;
	kvm_t *nkvm;
	char *temp;
	int first_inferior = 1;

	target_preopen (from_tty);
	if (!filename)
		error ("No vmcore file specified.");
	if (!exec_bfd)
		error ("Can't open a vmcore without a kernel");

	filename = tilde_expand (filename);
	if (filename[0] != '/') {
		temp = concat (current_directory, "/", filename, NULL);
		xfree(filename);
		filename = temp;
	}

	old_chain = make_cleanup (xfree, filename);

	nkvm = kvm_openfiles(bfd_get_filename(exec_bfd), filename, NULL,
	    write_files ? O_RDWR : O_RDONLY, kvm_err);
	if (nkvm == NULL)
		error ("Failed to open vmcore: %s", kvm_err);

	/* Don't free the filename now and close any previous vmcore. */
	discard_cleanups(old_chain);
	unpush_target(&kgdb_trgt_ops);

	kvm = nkvm;
	vmcore = filename;
	old_chain = make_cleanup(kgdb_core_cleanup, NULL);

	push_target (&kgdb_trgt_ops);
	discard_cleanups (old_chain);

	kgdb_dmesg();

	init_thread_list();
	kt = kgdb_thr_init();
	while (kt != NULL) {
		if (!in_inferior_list(kt->pid)) {
                     if (first_inferior) {
                       first_inferior = 0;
                       inf8 = current_inferior();
                       inf8->pid = kt->pid;
                       inferior_appeared (inf8, kt->pid);
                       pspace = current_program_space;
                       pspace->ebfd = 0;
                       pspace->ebfd_mtime = 0;
                     } else {                    
                       inf8 = add_inferior(kt->pid);
                       pspace = add_program_space(new_address_space());
                       pspace->symfile_object_file = symfile_objfile;
                       pspace->objfiles = object_files;
                     }
                     inf8->pspace = pspace;
                     inf8->aspace = pspace->aspace;
                }
		add_thread(ptid_build(kt->pid, 0, kt->tid));
		kt = kgdb_thr_next(kt);
	}
	if (curkthr != 0)
		inferior_ptid = ptid_build(curkthr->pid, 0, curkthr->tid);

	frame_unwind_prepend_unwinder(get_frame_arch(get_current_frame()), &kgdb_trgt_trapframe_unwind);

	/* XXX: fetch registers? */
	kld_init();
	reinit_frame_cache();
	select_frame (get_current_frame());
	print_stack_frame(get_selected_frame(NULL),
	  frame_relative_level(get_selected_frame(NULL)), 1);
}