Beispiel #1
0
unsigned char
mywait (char *status)
{
  int pid;
  union wait w;

  enable_async_io ();
  pid = waitpid (inferior_pid, &w, 0);
  disable_async_io ();
  if (pid != inferior_pid)
    perror_with_name ("wait");

  if (WIFEXITED (w))
    {
      fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
      *status = 'W';
      return ((unsigned char) WEXITSTATUS (w));
    }
  else if (!WIFSTOPPED (w))
    {
      fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
      *status = 'X';
      return ((unsigned char) WTERMSIG (w));
    }

  fetch_inferior_registers (0);

  *status = 'T';
  return ((unsigned char) WSTOPSIG (w));
}
static void validate_inferior_registers(int regno)
{
  int i;
  if (regno == -1) {
      for ((i = 0); (i < NUM_GREGS); i++) {
          if (!register_cached(i)) {
            fetch_inferior_registers(i);
          }
      }
      if (!register_cached(ARM_PS_REGNUM)) {
	fetch_inferior_registers(ARM_PS_REGNUM);
      }
  } else if (!register_cached(regno)) {
      fetch_inferior_registers(regno);
  }
}
Beispiel #3
0
unsigned char
mywait (char *status)
{
  int sigrc;
  enum sim_stop reason;

  sim_stop_reason (gdbsim_desc, &reason, &sigrc);
  switch (reason)
    {
    case sim_exited:
      if (remote_debug)
	printf ("\nChild exited with retcode = %x \n", sigrc);
      *status = 'W';
      return sigrc;

#if 0
    case sim_stopped:
      if (remote_debug)
	printf ("\nChild terminated with signal = %x \n", sigrc);
      *status = 'X';
      return sigrc;
#endif /* 0 */

    default:		/* should this be sim_signalled or sim_stopped?  FIXME!! */
      if (remote_debug)
	printf ("\nChild received signal = %x \n", sigrc);
      fetch_inferior_registers (0);
      *status = 'T';
      return (unsigned char) sigrc;
    }
}
static void
validate_inferior_registers (int regno)
{
  int i;
  if (regno == -1)
    {
      for (i = 0; i < NUM_REGS; i++)
        {
          if (!register_cached (i))
            fetch_inferior_registers (i);
        }
    }
  else if (!register_cached (regno))
    {
      fetch_inferior_registers (regno);
    }
}
static void
fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
		      CORE_ADDR reg_addr)
{
  struct st_entry s;
  unsigned int regno;

  for (regno = 0; regno < NUM_REGS; regno++)
    if (regmap[regno] != -1)
      supply_register (regno, core_reg_sect + offsetof (st_t, ec)
		       + regmap[regno]);

#ifdef SPARC
/* Fetching this register causes all of the I & L regs to be read from the
   stack and validated.  */

  fetch_inferior_registers (I0_REGNUM);
#endif
}
Beispiel #6
0
static struct inferior_regcache_data *
get_regcache(struct thread_info *inf, int fetch)
{
  struct inferior_regcache_data *regcache;

  regcache = (struct inferior_regcache_data *)inferior_regcache_data(inf);

  if (regcache == NULL)
    fatal("no register cache");

  /* FIXME: fetch registers for INF */
  if (fetch && (regcache->registers_valid == 0))
    {
      fetch_inferior_registers (0);
      regcache->registers_valid = 1;
    }

  return regcache;
}
Beispiel #7
0
struct regcache *
get_thread_regcache (struct thread_info *thread, int fetch)
{
  struct regcache *regcache;

  regcache = (struct regcache *) inferior_regcache_data (thread);

  /* Threads' regcaches are created lazily, because biarch targets add
     the main thread/lwp before seeing it stop for the first time, and
     it is only after the target sees the thread stop for the first
     time that the target has a chance of determining the process's
     architecture.  IOW, when we first add the process's main thread
     we don't know which architecture/tdesc its regcache should
     have.  */
  if (regcache == NULL)
    {
      struct process_info *proc = get_thread_process (thread);

      gdb_assert (proc->tdesc != NULL);

      regcache = new_register_cache (proc->tdesc);
      set_inferior_regcache_data (thread, regcache);
    }

  if (fetch && regcache->registers_valid == 0)
    {
      struct thread_info *saved_thread = current_thread;

      current_thread = thread;
      /* Invalidate all registers, to prevent stale left-overs.  */
      memset (regcache->register_status, REG_UNAVAILABLE,
	      regcache->tdesc->num_registers);
      fetch_inferior_registers (regcache, -1);
      current_thread = saved_thread;
      regcache->registers_valid = 1;
    }

  return regcache;
}
struct regcache *
get_thread_regcache (struct thread_info *thread, int fetch)
{
  struct regcache *regcache;

  regcache = (struct regcache *) inferior_regcache_data (thread);

  if (regcache == NULL)
    fatal ("no register cache");

  if (fetch && regcache->registers_valid == 0)
    {
      struct thread_info *saved_inferior = current_inferior;

      current_inferior = thread;
      fetch_inferior_registers (regcache, -1);
      current_inferior = saved_inferior;
      regcache->registers_valid = 1;
    }

  return regcache;
}
Beispiel #9
0
struct regcache *
get_thread_regcache (struct thread_info *thread, int fetch)
{
  struct regcache *regcache;

  regcache = (struct regcache *) inferior_regcache_data (thread);

  /* Threads' regcaches are created lazily, because biarch targets add
     the main thread/lwp before seeing it stop for the first time, and
     it is only after the target sees the thread stop for the first
     time that the target has a chance of determining the process's
     architecture.  IOW, when we first add the process's main thread
     we don't know which architecture/tdesc its regcache should
     have.  */
  if (regcache == NULL)
    {
      struct process_info *proc = get_thread_process (thread);

      if (proc->tdesc == NULL)
	fatal ("no target description");

      regcache = new_register_cache (proc->tdesc);
      set_inferior_regcache_data (thread, regcache);
    }

  if (fetch && regcache->registers_valid == 0)
    {
      struct thread_info *saved_inferior = current_inferior;

      current_inferior = thread;
      fetch_inferior_registers (regcache, -1);
      current_inferior = saved_inferior;
      regcache->registers_valid = 1;
    }

  return regcache;
}
Beispiel #10
0
static void
s390_arch_setup (void)
{
  const struct target_desc *tdesc;
  struct regset_info *regset;

  /* Check whether the kernel supports extra register sets.  */
  int pid = pid_of (get_thread_lwp (current_inferior));
  int have_regset_last_break
    = s390_check_regset (pid, NT_S390_LAST_BREAK, 8);
  int have_regset_system_call
    = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4);
  int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256);

  /* Update target_regsets according to available register sets.  */
  for (regset = s390_regsets; regset->fill_function != NULL; regset++)
    if (regset->get_request == PTRACE_GETREGSET)
      switch (regset->nt_type)
	{
	case NT_S390_LAST_BREAK:
	  regset->size = have_regset_last_break? 8 : 0;
	  break;
	case NT_S390_SYSTEM_CALL:
	  regset->size = have_regset_system_call? 4 : 0;
	  break;
	case NT_S390_TDB:
	  regset->size = have_regset_tdb ? 256 : 0;
	default:
	  break;
	}

  /* Assume 31-bit inferior process.  */
  if (have_regset_system_call)
    tdesc = tdesc_s390_linux32v2;
  else if (have_regset_last_break)
    tdesc = tdesc_s390_linux32v1;
  else
    tdesc = tdesc_s390_linux32;

  /* On a 64-bit host, check the low bit of the (31-bit) PSWM
     -- if this is one, we actually have a 64-bit inferior.  */
#ifdef __s390x__
  {
    unsigned int pswm;
    struct regcache *regcache = new_register_cache (tdesc);
    fetch_inferior_registers (regcache, find_regno (tdesc, "pswm"));
    collect_register_by_name (regcache, "pswm", &pswm);
    free_register_cache (regcache);

    if (pswm & 1)
      {
	if (have_regset_tdb)
	  tdesc = tdesc_s390x_te_linux64;
	if (have_regset_system_call)
	  tdesc = tdesc_s390x_linux64v2;
	else if (have_regset_last_break)
	  tdesc = tdesc_s390x_linux64v1;
	else
	  tdesc = tdesc_s390x_linux64;
      }

    /* For a 31-bit inferior, check whether the kernel supports
       using the full 64-bit GPRs.  */
    else if (s390_get_hwcap (tdesc) & HWCAP_S390_HIGH_GPRS)
      {
	have_hwcap_s390_high_gprs = 1;

	if (have_regset_tdb)
	  tdesc = tdesc_s390_te_linux64;
	else if (have_regset_system_call)
	  tdesc = tdesc_s390_linux64v2;
	else if (have_regset_last_break)
	  tdesc = tdesc_s390_linux64v1;
	else
	  tdesc = tdesc_s390_linux64;
      }
  }
#endif
  current_process ()->tdesc = tdesc;
}
Beispiel #11
0
void do_action (unsigned int tp_id, action * current_action, frame_buffer * record_fb)
{
    int size;
    unsigned char * buffer ;
    collect_record * current_collect_record;
    unsigned int base_reg_val;
    unsigned char *registers;

    //point to the lase record in the frame buffer
    if (record_fb==NULL) return;
    if (record_fb->head_record !=NULL)
    {
        current_collect_record =record_fb->head_record;
        while (current_collect_record->next !=NULL)
        {
            current_collect_record = current_collect_record->next;
        }
        current_collect_record->next = (collect_record *) malloc (sizeof (collect_record));
        current_collect_record=current_collect_record->next;
    }
    else
    {
        record_fb->head_record = (collect_record *) malloc (sizeof (collect_record));
        current_collect_record=record_fb->head_record;
    }

    if (current_action!=NULL)
    {
        switch (current_action->type)
        {
        case ACTION_COLLECT :
        {
            switch (current_action->action_data.ca.type)
            {
            case COLLECT_REGISTERS:
            {
                current_collect_record->collect_data= (char *)malloc (current_reg_type->register_bytes);
                fetch_inferior_registers (-1, current_collect_record ->collect_data);
                current_collect_record->collect_data_length=current_reg_type->register_bytes;
                current_collect_record->ca=&(current_action->action_data.ca);
                current_collect_record->next=NULL;
            }
            break;
            case COLLECT_MEMORY:
            {
                current_collect_record->collect_data= (char *)malloc(current_action->action_data.ca.description.mc.length);
                //should be the content of basereg
                if (current_action->action_data.ca.description.mc.base_reg == -1)
                {
                    base_reg_val=0;
                }
                else
                {
                    registers = (unsigned char *)malloc(current_reg_type->register_bytes);

                    fetch_inferior_registers (current_action->action_data.ca.description.mc.base_reg, registers);
                    base_reg_val=registers[current_reg_type->register_byte (current_action->action_data.ca.description.mc.base_reg)];
                    free (registers);

                }
                current_collect_record->collect_data_length=sim_read (base_reg_val+current_action->action_data.ca.description.mc.offset, current_collect_record->collect_data, current_action->action_data.ca.description.mc.length);
                current_collect_record->ca=&(current_action->action_data.ca);
                current_collect_record->next=NULL;
            }
            break;;
            case COLLECT_EXPRESSION :
                ;
            default :
                break;

            }
        }
        break;

        case ACTION_WHILE :
            ;
        default :
            break;

        }
    }
}
Beispiel #12
0
void
store_inferior_registers (register int regno)
{
  thread_state_data_t state;
  kern_return_t ret;

  if (!MACH_PORT_VALID (current_thread))
    error ("store inferior registers: Invalid thread");

  /* Check for read only regs.
   * @@ If some of these is can be changed, fix this
   */
  if (regno == ZERO_REGNUM ||
      regno == PS_REGNUM ||
      regno == BADVADDR_REGNUM ||
      regno == CAUSE_REGNUM ||
      regno == FCRIR_REGNUM)
    {
      message ("You can not alter read-only register `%s'",
	       REGISTER_NAME (regno));
      fetch_inferior_registers (regno);
      return;
    }

  if (regno == -1)
    {
      /* Don't allow these to change */

      /* ZERO_REGNUM */
      *(int *) registers = 0;

      fetch_inferior_registers (PS_REGNUM);
      fetch_inferior_registers (BADVADDR_REGNUM);
      fetch_inferior_registers (CAUSE_REGNUM);
      fetch_inferior_registers (FCRIR_REGNUM);
    }

  if (regno == -1 || (ZERO_REGNUM < regno && regno <= PC_REGNUM))
    {
#if 1
      /* Mach 3.0 saves thread's FP to MACH_FP_REGNUM.
       * GDB wants assigns a pseudo register FP_REGNUM for frame pointer.
       *
       * @@@ Here I assume (!) that gdb's FP has the value that
       *     should go to threads frame pointer. If not true, this
       *     fails badly!!!!!
       */
      memcpy (&registers[REGISTER_BYTE (MACH_FP_REGNUM)],
	      &registers[REGISTER_BYTE (FP_REGNUM)],
	      REGISTER_RAW_SIZE (FP_REGNUM));
#endif

      /* Save gdb's regs 1..31 to thread saved regs 1..31
       * Luckily, they are contiquous
       */
      STORE_REGS (state, 1, 31);

      /* Save mdlo, mdhi */
      STORE_REGS (state, LO_REGNUM, 2);

      /* Save PC */
      STORE_REGS (state, PC_REGNUM, 1);

      ret = thread_set_state (current_thread,
			      MIPS_THREAD_STATE,
			      state,
			      MIPS_FLOAT_STATE_COUNT);
      CHK ("store inferior regs : thread_set_state", ret);
    }

  if (regno == -1 || regno >= FP0_REGNUM)
    {
      /* If thread has floating state, save it */
      if (read_register (PS_REGNUM) & MIPS_STATUS_USE_COP1)
	{
	  /* Do NOT save FCRIR_REGNUM */
	  STORE_REGS (state, FP0_REGNUM, 33);

	  ret = thread_set_state (current_thread,
				  MIPS_FLOAT_STATE,
				  state,
				  MIPS_FLOAT_STATE_COUNT);
	  CHK ("store inferior registers (floats): thread_set_state", ret);
	}
      else if (regno != -1)
	message
	  ("Thread does not use floating point unit, floating regs not saved");
    }
}
Beispiel #13
0
int
main (int argc, char *argv[])
{
  char ch, status, own_buf[PBUFSIZ], mem_buf[2000];
  int i = 0;
  unsigned char signal;
  unsigned int len;
  CORE_ADDR mem_addr;

  if (setjmp (toplevel))
    {
      fprintf (stderr, "Exiting\n");
      exit (1);
    }

  if (argc < 3)
    error ("Usage: gdbserver tty prog [args ...]");

  initialize_low ();

  /* Wait till we are at first instruction in program.  */
  signal = start_inferior (&argv[2], &status);

  /* We are now stopped at the first instruction of the target process */

  while (1)
    {
      remote_open (argv[1]);

    restart:
      setjmp (toplevel);
      while (getpkt (own_buf) > 0)
	{
	  unsigned char sig;
	  i = 0;
	  ch = own_buf[i++];
	  switch (ch)
	    {
	    case 'd':
	      remote_debug = !remote_debug;
	      break;
	    case '!':
	      extended_protocol = 1;
	      prepare_resume_reply (own_buf, status, signal);
	      break;
	    case '?':
	      prepare_resume_reply (own_buf, status, signal);
	      break;
	    case 'H':
	      switch (own_buf[1])
		{
		case 'g':
		  general_thread = strtol (&own_buf[2], NULL, 16);
		  write_ok (own_buf);
		  fetch_inferior_registers (0);
		  break;
		case 'c':
		  cont_thread = strtol (&own_buf[2], NULL, 16);
		  write_ok (own_buf);
		  break;
		default:
		  /* Silently ignore it so that gdb can extend the protocol
		     without compatibility headaches.  */
		  own_buf[0] = '\0';
		  break;
		}
	      break;
	    case 'g':
	      convert_int_to_ascii (registers, own_buf, REGISTER_BYTES);
	      break;
	    case 'G':
	      convert_ascii_to_int (&own_buf[1], registers, REGISTER_BYTES);
	      store_inferior_registers (-1);
	      write_ok (own_buf);
	      break;
	    case 'm':
	      decode_m_packet (&own_buf[1], &mem_addr, &len);
	      read_inferior_memory (mem_addr, mem_buf, len);
	      convert_int_to_ascii (mem_buf, own_buf, len);
	      break;
	    case 'M':
	      decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
	      if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
		write_ok (own_buf);
	      else
		write_enn (own_buf);
	      break;
	    case 'C':
	      convert_ascii_to_int (own_buf + 1, &sig, 1);
	      myresume (0, sig);
	      signal = mywait (&status);
	      prepare_resume_reply (own_buf, status, signal);
	      break;
	    case 'S':
	      convert_ascii_to_int (own_buf + 1, &sig, 1);
	      myresume (1, sig);
	      signal = mywait (&status);
	      prepare_resume_reply (own_buf, status, signal);
	      break;
	    case 'c':
	      myresume (0, 0);
	      signal = mywait (&status);
	      prepare_resume_reply (own_buf, status, signal);
	      break;
	    case 's':
	      myresume (1, 0);
	      signal = mywait (&status);
	      prepare_resume_reply (own_buf, status, signal);
	      break;
	    case 'k':
	      fprintf (stderr, "Killing inferior\n");
	      kill_inferior ();
	      /* When using the extended protocol, we start up a new
	         debugging session.   The traditional protocol will
	         exit instead.  */
	      if (extended_protocol)
		{
		  write_ok (own_buf);
		  fprintf (stderr, "GDBserver restarting\n");

		  /* Wait till we are at 1st instruction in prog.  */
		  signal = start_inferior (&argv[2], &status);
		  goto restart;
		  break;
		}
	      else
		{
		  exit (0);
		  break;
		}
	    case 'T':
	      if (mythread_alive (strtol (&own_buf[1], NULL, 16)))
		write_ok (own_buf);
	      else
		write_enn (own_buf);
	      break;
	    case 'R':
	      /* Restarting the inferior is only supported in the
	         extended protocol.  */
	      if (extended_protocol)
		{
		  kill_inferior ();
		  write_ok (own_buf);
		  fprintf (stderr, "GDBserver restarting\n");

		  /* Wait till we are at 1st instruction in prog.  */
		  signal = start_inferior (&argv[2], &status);
		  goto restart;
		  break;
		}
	      else
		{
		  /* It is a request we don't understand.  Respond with an
		     empty packet so that gdb knows that we don't support this
		     request.  */
		  own_buf[0] = '\0';
		  break;
		}
	    default:
	      /* It is a request we don't understand.  Respond with an
	         empty packet so that gdb knows that we don't support this
	         request.  */
	      own_buf[0] = '\0';
	      break;
	    }

	  putpkt (own_buf);

	  if (status == 'W')
	    fprintf (stderr,
		     "\nChild exited with status %d\n", sig);
	  if (status == 'X')
	    fprintf (stderr, "\nChild terminated with signal = 0x%x\n", sig);
	  if (status == 'W' || status == 'X')
	    {
	      if (extended_protocol)
		{
		  fprintf (stderr, "Killing inferior\n");
		  kill_inferior ();
		  write_ok (own_buf);
		  fprintf (stderr, "GDBserver restarting\n");

		  /* Wait till we are at 1st instruction in prog.  */
		  signal = start_inferior (&argv[2], &status);
		  goto restart;
		  break;
		}
	      else
		{
		  fprintf (stderr, "GDBserver exiting\n");
		  exit (0);
		}
	    }
	}

      /* We come here when getpkt fails.

         For the extended remote protocol we exit (and this is the only
         way we gracefully exit!).

         For the traditional remote protocol close the connection,
         and re-open it at the top of the loop.  */
      if (extended_protocol)
	{
	  remote_close ();
	  exit (0);
	}
      else
	{
	  fprintf (stderr, "Remote side has terminated connection.  GDBserver will reopen the connection.\n");

	  remote_close ();
	}
    }
}