This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Separate remote.c from register cache (almost)


Hello,

The attached patch (draft posted earlier) (almost) completly separates 
remote.c from GDB's internal register cache.

The relevant code (P packet, [gG] packet) uses local to remote data 
structures to map between the remote protocol and the internal reg-cache.

The ``almost'' is because the code is still using knowledge about the 
remote cache to construct that internal table.  I guess that is the next 
thing to fix.

enjoy,
Andrew
2001-11-12  Andrew Cagney  <ac131313@redhat.com>

	* remote.c (struct packet_reg): Declare.
	(struct remote_state): Add fields sizeof_g_packet and g_packet.
	(init_remote_state): Initialize sizeof_g_packet and g_packet.
	(free_remote_state): Free g_packet.
	(packet_reg_from_pnum, packet_reg_by_regnum): New functions.
	(remote_wait): Use above instead of gdbarch methods
	REGISTER_RAW_SIZE and REGISTER_BYTES.
	(remote_async_wait): Ditto.
	(remote_fetch_registers, remote_store_registers): Ditto.
	(store_register_using_P): Ditto.
	
Index: remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.68
diff -p -r1.68 remote.c
*** remote.c	2001/11/15 20:30:41	1.68
--- remote.c	2001/11/15 20:35:17
*************** void _initialize_remote (void);
*** 217,224 ****
--- 217,237 ----
     the moment keep the information in the target's architecture
     object.  Sigh..  */
  
+ struct packet_reg
+ {
+   long offset; /* Offset into G packet.  */
+   long regnum; /* GDB's internal register number.  */
+   LONGEST pnum; /* Remote protocol register number.  */
+   /* long size in bytes;  == REGISTER_RAW_SIZE (regnum); at present.  */
+   /* char *name; == REGISTER_NAME (regnum); at present.  */
+ };
+ 
  struct remote_state
  {
+   /* Description of the remote protocol registers.  */
+   long sizeof_g_packet;
+   struct packet_reg *g_packet; /* NULL terminated.  */
+ 
    /* This is the size (in chars) of the first response to the ``g''
       packet.  It is used as a heuristic when determining the maximum
       size of memory-read and memory-write packets.  A target will
*************** init_remote_state (struct gdbarch *gdbar
*** 247,252 ****
--- 260,283 ----
    int regnum;
    struct remote_state *rs = xmalloc (sizeof (struct remote_state));
  
+   /* Start out by having the remote protocol mimic the existing
+      behavour - just copy in the description of the register cache.  */
+   rs->sizeof_g_packet = REGISTER_BYTES; /* OK use.   */
+ 
+   /* Since, for the moment, the regcache is still being direct mapped,
+      there are exactly NUM_REGS.  Zero allocate a buffer adding space
+      for a sentinal.  */
+   rs->g_packet = xcalloc (NUM_REGS + 1, sizeof (struct packet_reg));
+   rs->g_packet[NUM_REGS].offset = -1;
+   for (regnum = 0; regnum < NUM_REGS; regnum++)
+     {
+       rs->g_packet[regnum].pnum = regnum;
+       rs->g_packet[regnum].regnum = regnum;
+       rs->g_packet[regnum].offset = REGISTER_BYTE (regnum);
+       /* ...size = REGISTER_RAW_SIZE (regnum); */
+       /* ...name = REGISTER_NAME (regnum); */
+     }
+ 
    /* Default maximum number of characters in a packet body. Many
       remote stubs have a hardwired buffer size of 400 bytes
       (c.f. BUFMAX in m68k-stub.c and i386-stub.c).  BUFMAX-1 is used
*************** init_remote_state (struct gdbarch *gdbar
*** 256,269 ****
       already a full buffer (As of 1999-12-04 that was most stubs. */
    rs->remote_packet_size = 400 - 1;
  
!   /* Should REGISTER_BYTES needs more space than the default, adjust
!      the size accordingly. Remember that each byte is encoded as two
!      characters. 32 is the overhead for the packet header /
!      footer. NOTE: cagney/1999-10-26: I suspect that 8
       (``$NN:G...#NN'') is a better guess, the below has been padded a
       little. */
!   if (REGISTER_BYTES > ((rs->remote_packet_size - 32) / 2))
!     rs->remote_packet_size = (REGISTER_BYTES * 2 + 32);
    
    /* This one is filled in when a ``g'' packet is received. */
    rs->actual_register_packet_size = 0;
--- 287,300 ----
       already a full buffer (As of 1999-12-04 that was most stubs. */
    rs->remote_packet_size = 400 - 1;
  
!   /* Should rs->sizeof_g_packet needs more space than the
!      default, adjust the size accordingly. Remember that each byte is
!      encoded as two characters. 32 is the overhead for the packet
!      header / footer. NOTE: cagney/1999-10-26: I suspect that 8
       (``$NN:G...#NN'') is a better guess, the below has been padded a
       little. */
!   if (rs->sizeof_g_packet > ((rs->remote_packet_size - 32) / 2))
!     rs->remote_packet_size = (rs->sizeof_g_packet * 2 + 32);
    
    /* This one is filled in when a ``g'' packet is received. */
    rs->actual_register_packet_size = 0;
*************** init_remote_state (struct gdbarch *gdbar
*** 273,281 ****
  
  static void
  free_remote_state (struct gdbarch *gdbarch, void *pointer)
  {
!   struct remote_state *state = pointer;
!   xfree (state);
  }
  
  /* */
--- 304,337 ----
  
  static void
  free_remote_state (struct gdbarch *gdbarch, void *pointer)
+ {
+   struct remote_state *data = pointer;
+   xfree (data->g_packet);
+   xfree (data);
+ }
+ 
+ static struct packet_reg *
+ packet_reg_from_regnum (struct remote_state *rs, long regnum)
+ {
+   struct packet_reg *reg;
+   for (reg = rs->g_packet; reg->offset >= 0; reg++)
+     {
+       if (reg->regnum == regnum)
+ 	return reg;
+     }
+   return NULL;
+ }
+ 
+ static struct packet_reg *
+ packet_reg_from_pnum (struct remote_state *rs, LONGEST pnum)
  {
!   struct packet_reg *reg;
!   for (reg = rs->g_packet; reg->offset >= 0; reg++)
!     {
!       if (reg->pnum == pnum)
! 	return reg;
!     }
!   return NULL;
  }
  
  /* */
*************** static int remote_async_terminal_ours_p;
*** 336,347 ****
  
  
  /* User configurable variables for the number of characters in a
!    memory read/write packet.  MIN ((rs->remote_packet_size), g-packet-size) is the
!    default.  Some targets need smaller values (fifo overruns, et.al.)
!    and some users need larger values (speed up transfers).  The
!    variables ``preferred_*'' (the user request), ``current_*'' (what
!    was actually set) and ``forced_*'' (Positive - a soft limit,
!    negative - a hard limit). */
  
  struct memory_packet_config
  {
--- 392,403 ----
  
  
  /* User configurable variables for the number of characters in a
!    memory read/write packet.  MIN ((rs->remote_packet_size),
!    rs->sizeof_g_packet) is the default.  Some targets need smaller
!    values (fifo overruns, et.al.)  and some users need larger values
!    (speed up transfers).  The variables ``preferred_*'' (the user
!    request), ``current_*'' (what was actually set) and ``forced_*''
!    (Positive - a soft limit, negative - a hard limit). */
  
  struct memory_packet_config
  {
*************** remote_wait (ptid_t ptid, struct target_
*** 2927,2933 ****
  	case 'T':		/* Status with PC, SP, FP, ... */
  	  {
  	    int i;
- 	    long regno;
  	    char* regs = (char*) alloca (MAX_REGISTER_RAW_SIZE);
  
  	    /* Expedited reply, containing Signal, {regno, reg} repeat */
--- 2983,2988 ----
*************** remote_wait (ptid_t ptid, struct target_
*** 2944,2951 ****
  		char *p_temp;
  		int fieldsize;
  
! 		/* Read the register number */
! 		regno = strtol ((const char *) p, &p_temp, 16);
  		p1 = (unsigned char *) p_temp;
  
  		if (p1 == p)	/* No register number present here */
--- 2999,3006 ----
  		char *p_temp;
  		int fieldsize;
  
! 		/* Read the ``P'' register number.  */
! 		LONGEST pnum = strtol ((const char *) p, &p_temp, 16);
  		p1 = (unsigned char *) p_temp;
  
  		if (p1 == p)	/* No register number present here */
*************** Packet: '%s'\n",
*** 2964,2969 ****
--- 3019,3025 ----
  		  }
  		else
  		  {
+ 		    struct packet_reg *reg = packet_reg_from_pnum (rs, pnum);
  		    p = p1;
  
  		    if (*p++ != ':')
*************** Packet: '%s'\n",
*** 2971,2986 ****
  Packet: '%s'\n",
  			       p, buf);
  
! 		    if (regno >= NUM_REGS)
! 		      warning ("Remote sent bad register number %ld: %s\n\
  Packet: '%s'\n",
! 			       regno, p, buf);
  
! 		    fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (regno));
  		    p += 2 * fieldsize;
! 		    if (fieldsize < REGISTER_RAW_SIZE (regno))
  		      warning ("Remote reply is too short: %s", buf);
! 		    supply_register (regno, regs);
  		  }
  
  		if (*p++ != ';')
--- 3027,3042 ----
  Packet: '%s'\n",
  			       p, buf);
  
! 		    if (reg == NULL)
! 		      warning ("Remote sent bad register number %s: %s\n\
  Packet: '%s'\n",
! 			       phex_nz (pnum, 0), p, buf);
  
! 		    fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (reg->regnum));
  		    p += 2 * fieldsize;
! 		    if (fieldsize < REGISTER_RAW_SIZE (reg->regnum))
  		      warning ("Remote reply is too short: %s", buf);
! 		    supply_register (reg->regnum, regs);
  		  }
  
  		if (*p++ != ';')
*************** remote_async_wait (ptid_t ptid, struct t
*** 3147,3153 ****
  	case 'T':		/* Status with PC, SP, FP, ... */
  	  {
  	    int i;
- 	    long regno;
  	    char* regs = (char*) alloca (MAX_REGISTER_RAW_SIZE);
  
  	    /* Expedited reply, containing Signal, {regno, reg} repeat */
--- 3203,3208 ----
*************** remote_async_wait (ptid_t ptid, struct t
*** 3165,3171 ****
  		int fieldsize;
  
  		/* Read the register number */
! 		regno = strtol ((const char *) p, &p_temp, 16);
  		p1 = (unsigned char *) p_temp;
  
  		if (p1 == p)	/* No register number present here */
--- 3220,3226 ----
  		int fieldsize;
  
  		/* Read the register number */
! 		long pnum = strtol ((const char *) p, &p_temp, 16);
  		p1 = (unsigned char *) p_temp;
  
  		if (p1 == p)	/* No register number present here */
*************** Packet: '%s'\n",
*** 3184,3206 ****
  		  }
  		else
  		  {
  		    p = p1;
- 
  		    if (*p++ != ':')
  		      warning ("Malformed packet(b) (missing colon): %s\n\
  Packet: '%s'\n",
  			       p, buf);
  
! 		    if (regno >= NUM_REGS)
  		      warning ("Remote sent bad register number %ld: %s\n\
  Packet: '%s'\n",
! 			       regno, p, buf);
  
! 		    fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (regno));
  		    p += 2 * fieldsize;
! 		    if (fieldsize < REGISTER_RAW_SIZE (regno))
  		      warning ("Remote reply is too short: %s", buf);
! 		    supply_register (regno, regs);
  		  }
  
  		if (*p++ != ';')
--- 3239,3261 ----
  		  }
  		else
  		  {
+ 		    struct packet_reg *reg = packet_reg_from_pnum (rs, pnum);
  		    p = p1;
  		    if (*p++ != ':')
  		      warning ("Malformed packet(b) (missing colon): %s\n\
  Packet: '%s'\n",
  			       p, buf);
  
! 		    if (reg == NULL)
  		      warning ("Remote sent bad register number %ld: %s\n\
  Packet: '%s'\n",
! 			       pnum, p, buf);
  
! 		    fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (reg->regnum));
  		    p += 2 * fieldsize;
! 		    if (fieldsize < REGISTER_RAW_SIZE (reg->regnum))
  		      warning ("Remote reply is too short: %s", buf);
! 		    supply_register (reg->regnum, regs);
  		  }
  
  		if (*p++ != ';')
*************** got_status:
*** 3337,3353 ****
  static int register_bytes_found;
  
  /* Read the remote registers into the block REGS.  */
! /* Currently we just read all the registers, so we don't use regno.  */
  
  /* ARGSUSED */
  static void
! remote_fetch_registers (int regno)
  {
    struct remote_state *rs = get_remote_state ();
    char *buf = alloca (rs->remote_packet_size);
    int i;
    char *p;
!   char *regs = alloca (REGISTER_BYTES);
  
    set_thread (PIDGET (inferior_ptid), 1);
  
--- 3392,3408 ----
  static int register_bytes_found;
  
  /* Read the remote registers into the block REGS.  */
! /* Currently we just read all the registers, so we don't use regnum.  */
  
  /* ARGSUSED */
  static void
! remote_fetch_registers (int regnum)
  {
    struct remote_state *rs = get_remote_state ();
    char *buf = alloca (rs->remote_packet_size);
    int i;
    char *p;
!   char *regs = alloca (rs->sizeof_g_packet);
  
    set_thread (PIDGET (inferior_ptid), 1);
  
*************** remote_fetch_registers (int regno)
*** 3361,3367 ****
      (rs->actual_register_packet_size) = strlen (buf);
  
    /* Unimplemented registers read as all bits zero.  */
!   memset (regs, 0, REGISTER_BYTES);
  
    /* We can get out of synch in various cases.  If the first character
       in the buffer is not a hex character, assume that has happened
--- 3416,3422 ----
      (rs->actual_register_packet_size) = strlen (buf);
  
    /* Unimplemented registers read as all bits zero.  */
!   memset (regs, 0, rs->sizeof_g_packet);
  
    /* We can get out of synch in various cases.  If the first character
       in the buffer is not a hex character, assume that has happened
*************** remote_fetch_registers (int regno)
*** 3381,3387 ****
       register cacheing/storage mechanism.  */
  
    p = buf;
!   for (i = 0; i < REGISTER_BYTES; i++)
      {
        if (p[0] == 0)
  	break;
--- 3436,3442 ----
       register cacheing/storage mechanism.  */
  
    p = buf;
!   for (i = 0; i < rs->sizeof_g_packet; i++)
      {
        if (p[0] == 0)
  	break;
*************** remote_fetch_registers (int regno)
*** 3408,3419 ****
      }
  
  supply_them:
!   for (i = 0; i < NUM_REGS; i++)
!     {
!       supply_register (i, &regs[REGISTER_BYTE (i)]);
!       if (buf[REGISTER_BYTE (i) * 2] == 'x')
! 	set_register_cached (i, -1);
!     }
  }
  
  /* Prepare to store registers.  Since we may send them all (using a
--- 3463,3477 ----
      }
  
  supply_them:
!   {
!     struct packet_reg *g;
!     for (g = rs->g_packet; g->offset >= 0; g++)
!       {
! 	supply_register (g->regnum, regs + g->offset);
! 	if (buf[g->offset * 2] == 'x')
! 	  set_register_cached (i, -1);
!       }
!   }
  }
  
  /* Prepare to store registers.  Since we may send them all (using a
*************** remote_prepare_to_store (void)
*** 3428,3468 ****
      {
      case PACKET_DISABLE:
      case PACKET_SUPPORT_UNKNOWN:
!       read_register_bytes (0, (char *) NULL, REGISTER_BYTES);
        break;
      case PACKET_ENABLE:
        break;
      }
  }
  
! /* Helper: Attempt to store REGNO using the P packet.  Return fail IFF
     packet was not recognized. */
  
  static int
! store_register_using_P (int regno)
  {
    struct remote_state *rs = get_remote_state ();
    /* Try storing a single register.  */
    char *buf = alloca (rs->remote_packet_size);
    char *regp = alloca (MAX_REGISTER_RAW_SIZE);
    char *p;
    int i;
  
!   sprintf (buf, "P%x=", regno);
    p = buf + strlen (buf);
!   regcache_collect (regno, regp);
!   bin2hex (regp, p, REGISTER_RAW_SIZE (regno));
!   remote_send (buf, (rs->remote_packet_size));
  
    return buf[0] != '\0';
  }
  
  
! /* Store register REGNO, or all registers if REGNO == -1, from the contents
     of the register cache buffer.  FIXME: ignores errors.  */
  
  static void
! remote_store_registers (int regno)
  {
    struct remote_state *rs = get_remote_state ();
    char *buf;
--- 3486,3530 ----
      {
      case PACKET_DISABLE:
      case PACKET_SUPPORT_UNKNOWN:
!       /* NOTE: This isn't rs->sizeof_g_packet because here, we are
!          forcing the register cache to read its and not the target
!          registers.  */
!       read_register_bytes (0, (char *) NULL, REGISTER_BYTES); /* OK use.  */
        break;
      case PACKET_ENABLE:
        break;
      }
  }
  
! /* Helper: Attempt to store REGNUM using the P packet.  Return fail IFF
     packet was not recognized. */
  
  static int
! store_register_using_P (int regnum)
  {
    struct remote_state *rs = get_remote_state ();
+   struct packet_reg *reg = packet_reg_from_regnum (rs, regnum);
    /* Try storing a single register.  */
    char *buf = alloca (rs->remote_packet_size);
    char *regp = alloca (MAX_REGISTER_RAW_SIZE);
    char *p;
    int i;
  
!   sprintf (buf, "P%s=", phex_nz (reg->pnum, 0));
    p = buf + strlen (buf);
!   regcache_collect (reg->regnum, regp);
!   bin2hex (regp, p, REGISTER_RAW_SIZE (reg->regnum));
!   remote_send (buf, rs->remote_packet_size);
  
    return buf[0] != '\0';
  }
  
  
! /* Store register REGNUM, or all registers if REGNUM == -1, from the contents
     of the register cache buffer.  FIXME: ignores errors.  */
  
  static void
! remote_store_registers (int regnum)
  {
    struct remote_state *rs = get_remote_state ();
    char *buf;
*************** remote_store_registers (int regno)
*** 3472,3490 ****
  
    set_thread (PIDGET (inferior_ptid), 1);
  
!   if (regno >= 0)
      {
        switch (remote_protocol_P.support)
  	{
  	case PACKET_DISABLE:
  	  break;
  	case PACKET_ENABLE:
! 	  if (store_register_using_P (regno))
  	    return;
  	  else
  	    error ("Protocol error: P packet not recognized by stub");
  	case PACKET_SUPPORT_UNKNOWN:
! 	  if (store_register_using_P (regno))
  	    {
  	      /* The stub recognized the 'P' packet.  Remember this.  */
  	      remote_protocol_P.support = PACKET_ENABLE;
--- 3534,3552 ----
  
    set_thread (PIDGET (inferior_ptid), 1);
  
!   if (regnum >= 0)
      {
        switch (remote_protocol_P.support)
  	{
  	case PACKET_DISABLE:
  	  break;
  	case PACKET_ENABLE:
! 	  if (store_register_using_P (regnum))
  	    return;
  	  else
  	    error ("Protocol error: P packet not recognized by stub");
  	case PACKET_SUPPORT_UNKNOWN:
! 	  if (store_register_using_P (regnum))
  	    {
  	      /* The stub recognized the 'P' packet.  Remember this.  */
  	      remote_protocol_P.support = PACKET_ENABLE;
*************** remote_store_registers (int regno)
*** 3504,3515 ****
    /* Extract all the registers in the regcache copying them into a
       local buffer.  */
    {
!     int i;
!     regs = alloca (REGISTER_BYTES);
!     memset (regs, REGISTER_BYTES, 0);
!     for (i = 0; i < NUM_REGS; i++)
        {
! 	regcache_collect (i, regs + REGISTER_BYTE (i));
        }
    }
  
--- 3566,3577 ----
    /* Extract all the registers in the regcache copying them into a
       local buffer.  */
    {
!     struct packet_reg *g;
!     regs = alloca (rs->sizeof_g_packet);
!     memset (regs, rs->sizeof_g_packet, 0);
!     for (g = rs->g_packet; g->offset >= 0; g++)
        {
! 	regcache_collect (g->regnum, regs + g->offset);
        }
    }
  

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]