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] More tracepoint fixes


This is a more complicated tracepoint fix.  The variable tracing mechanism
does not cope with COMPUTED_LOC and ARG_COMPUTED_LOC symbols, as generated
by gcc 3.4.  Expressions containing said symbols are dealt with.  This
patch rearranges 'collect_symbol' and 'add_local_symbols' to deal with
such computed symbols.  These are dumped as if they were expressions --
hence the breakout of the expression dumping from encode_actions.

built & tested on i686-pc-linux-gnu, and an unreleased remote
architecture. ok?

nathan

--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2005-02-09  Nathan Sidwell  <nathan@codesourcery.com>

	* tracepoint.c: #include gdb_assert.h
	(collect_symbol): Take a PC and EXP, not a symbol.  Adjust. Add
	LOC_COMPUTED and LOC_COMPUTED_ARG cases.
	(add_local_symbols): Describe the symbol with an expression,
	adjust collect_symbol calls, add LOC_COMPUTED and LOC_COMPUTED_ARG
	cases.
	(encode_actions): Break out expression processing into ...
	(add_expression): ... here. New function.

Index: tracepoint.c
===================================================================
RCS file: /cvs/src/src/gdb/tracepoint.c,v
retrieving revision 1.68
diff -c -3 -p -r1.68 tracepoint.c
*** tracepoint.c	2 Feb 2005 00:20:05 -0000	1.68
--- tracepoint.c	9 Feb 2005 09:26:24 -0000
***************
*** 30,35 ****
--- 30,36 ----
  #include "target.h"
  #include "language.h"
  #include "gdb_string.h"
+ #include "gdb_assert.h"
  #include "inferior.h"
  #include "tracepoint.h"
  #include "remote.h"
*************** static void trace_dump_command (char *, 
*** 149,154 ****
--- 150,157 ----
  static void trace_mention (struct tracepoint *);
  
  struct collection_list;
+ static void add_expression (struct collection_list *, CORE_ADDR pc,
+ 			    struct expression *);
  static void add_aexpr (struct collection_list *, struct agent_expr *);
  static unsigned char *mem2hex (unsigned char *, unsigned char *, int);
  static void add_register (struct collection_list *collection,
*************** add_memrange (struct collection_list *me
*** 1191,1204 ****
  
  /* Add a symbol to a collection list.  */
  static void
! collect_symbol (struct collection_list *collect, 
! 		struct symbol *sym,
  		long frame_regno, long frame_offset)
  {
    unsigned long len;
    unsigned int reg;
    bfd_signed_vma offset;
! 
    len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
    switch (SYMBOL_CLASS (sym))
      {
--- 1194,1210 ----
  
  /* Add a symbol to a collection list.  */
  static void
! collect_symbol (struct collection_list *collect, CORE_ADDR pc,
! 		struct expression *exp,
  		long frame_regno, long frame_offset)
  {
    unsigned long len;
    unsigned int reg;
    bfd_signed_vma offset;
!   struct symbol *sym;
!   
!   gdb_assert (exp->elts[0].opcode == OP_VAR_VALUE);
!   sym = exp->elts[2].symbol;
    len = TYPE_LENGTH (check_typedef (SYMBOL_TYPE (sym)));
    switch (SYMBOL_CLASS (sym))
      {
*************** collect_symbol (struct collection_list *
*** 1300,1305 ****
--- 1306,1319 ----
        printf_filtered ("%s has been optimized out of existence.\n",
  		       DEPRECATED_SYMBOL_NAME (sym));
        break;
+     case LOC_COMPUTED:
+     case LOC_COMPUTED_ARG:
+       /* collect the expression.  */
+       if (info_verbose)
+ 	SYMBOL_OPS (sym)->describe_location (sym, gdb_stdout);
+ 	
+       add_expression (collect, pc, exp);
+       break;
      }
  }
  
*************** add_local_symbols (struct collection_lis
*** 1312,1324 ****
    struct block *block;
    struct dict_iterator iter;
    int count = 0;
! 
    block = block_for_pc (pc);
    while (block != 0)
      {
        QUIT;			/* allow user to bail out with ^C */
        ALL_BLOCK_SYMBOLS (block, iter, sym)
  	{
  	  switch (SYMBOL_CLASS (sym))
  	    {
  	    default:
--- 1326,1355 ----
    struct block *block;
    struct dict_iterator iter;
    int count = 0;
!   struct expression *exp;
!   struct cleanup *old_chain = NULL;
!   
!   exp = xmalloc (sizeof (struct expression) + EXP_ELEM_TO_BYTES (4));
!   
!   exp->language_defn = NULL;
!   exp->nelts = 4;
!   exp->elts[0].opcode = OP_VAR_VALUE;
!   exp->elts[1].block = NULL;
!   exp->elts[2].symbol = NULL;
!   exp->elts[3].opcode = OP_VAR_VALUE;
!   
!   old_chain = make_cleanup (free_current_contents, &exp);
!   
    block = block_for_pc (pc);
    while (block != 0)
      {
+       exp->elts[1].block = block;
+ 
        QUIT;			/* allow user to bail out with ^C */
        ALL_BLOCK_SYMBOLS (block, iter, sym)
  	{
+ 	  exp->elts[2].symbol = sym;
+ 	  
  	  switch (SYMBOL_CLASS (sym))
  	    {
  	    default:
*************** add_local_symbols (struct collection_lis
*** 1328,1338 ****
  	    case LOC_STATIC:
  	    case LOC_REGISTER:
  	    case LOC_BASEREG:
  	      if (type == 'L')	/* collecting Locals */
  		{
  		  count++;
! 		  collect_symbol (collect, sym, frame_regno, 
! 				  frame_offset);
  		}
  	      break;
  	    case LOC_ARG:
--- 1359,1370 ----
  	    case LOC_STATIC:
  	    case LOC_REGISTER:
  	    case LOC_BASEREG:
+ 	    case LOC_COMPUTED:
  	      if (type == 'L')	/* collecting Locals */
  		{
  		  count++;
! 		  collect_symbol (collect, pc, exp,
! 				  frame_regno, frame_offset);
  		}
  	      break;
  	    case LOC_ARG:
*************** add_local_symbols (struct collection_lis
*** 1341,1351 ****
  	    case LOC_REGPARM:
  	    case LOC_REGPARM_ADDR:
  	    case LOC_BASEREG_ARG:
  	      if (type == 'A')	/* collecting Arguments */
  		{
  		  count++;
! 		  collect_symbol (collect, sym, frame_regno, 
! 				  frame_offset);
  		}
  	    }
  	}
--- 1373,1384 ----
  	    case LOC_REGPARM:
  	    case LOC_REGPARM_ADDR:
  	    case LOC_BASEREG_ARG:
+ 	    case LOC_COMPUTED_ARG:
  	      if (type == 'A')	/* collecting Arguments */
  		{
  		  count++;
! 		  collect_symbol (collect, pc, exp,
! 				  frame_regno, frame_offset);
  		}
  	    }
  	}
*************** add_local_symbols (struct collection_lis
*** 1354,1359 ****
--- 1387,1395 ----
        else
  	block = BLOCK_SUPERBLOCK (block);
      }
+ 
+   do_cleanups (old_chain);
+   
    if (count == 0)
      warning ("No %s found in scope.", 
  	     type == 'L' ? "locals" : "args");
*************** encode_actions (struct tracepoint *t, ch
*** 1509,1515 ****
    struct value *tempval;
    struct collection_list *collect;
    struct cmd_list_element *cmd;
-   struct agent_expr *aexpr;
    int frame_reg;
    LONGEST frame_offset;
  
--- 1545,1550 ----
*************** encode_actions (struct tracepoint *t, ch
*** 1571,1580 ****
  		}
  	      else
  		{
- 		  unsigned long addr, len;
  		  struct cleanup *old_chain = NULL;
! 		  struct cleanup *old_chain1 = NULL;
! 		  struct agent_reqs areqs;
  
  		  exp = parse_exp_1 (&action_exp, 
  				     block_for_pc (t->address), 1);
--- 1606,1613 ----
  		}
  	      else
  		{
  		  struct cleanup *old_chain = NULL;
! 		  unsigned long addr, len;
  
  		  exp = parse_exp_1 (&action_exp, 
  				     block_for_pc (t->address), 1);
*************** encode_actions (struct tracepoint *t, ch
*** 1598,1646 ****
  		      break;
  
  		    case OP_VAR_VALUE:
! 		      collect_symbol (collect,
! 				      exp->elts[2].symbol,
! 				      frame_reg,
! 				      frame_offset);
  		      break;
  
  		    default:	/* full-fledged expression */
! 		      aexpr = gen_trace_for_expr (t->address, exp);
! 
! 		      old_chain1 = make_cleanup_free_agent_expr (aexpr);
! 
! 		      ax_reqs (aexpr, &areqs);
! 		      if (areqs.flaw != agent_flaw_none)
! 			error ("malformed expression");
! 
! 		      if (areqs.min_height < 0)
! 			error ("gdb: Internal error: expression has min height < 0");
! 		      if (areqs.max_height > 20)
! 			error ("expression too complicated, try simplifying");
! 
! 		      discard_cleanups (old_chain1);
! 		      add_aexpr (collect, aexpr);
! 
! 		      /* take care of the registers */
! 		      if (areqs.reg_mask_len > 0)
! 			{
! 			  int ndx1;
! 			  int ndx2;
! 
! 			  for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
! 			    {
! 			      QUIT;	/* allow user to bail out with ^C */
! 			      if (areqs.reg_mask[ndx1] != 0)
! 				{
! 				  /* assume chars have 8 bits */
! 				  for (ndx2 = 0; ndx2 < 8; ndx2++)
! 				    if (areqs.reg_mask[ndx1] & (1 << ndx2))
! 				      /* it's used -- record it */
! 				      add_register (collect, 
! 						    ndx1 * 8 + ndx2);
! 				}
! 			    }
! 			}
  		      break;
  		    }		/* switch */
  		  do_cleanups (old_chain);
--- 1631,1642 ----
  		      break;
  
  		    case OP_VAR_VALUE:
! 		      collect_symbol (collect, t->address, exp,
! 				      frame_reg, frame_offset);
  		      break;
  
  		    default:	/* full-fledged expression */
! 		      add_expression (collect, t->address, exp);
  		      break;
  		    }		/* switch */
  		  do_cleanups (old_chain);
*************** encode_actions (struct tracepoint *t, ch
*** 1669,1674 ****
--- 1665,1719 ----
  						 step_buff);
  }
  
+ /* Add an arbitrary expression.  */
+ 
+ static void
+ add_expression (struct collection_list *collect, CORE_ADDR pc,
+ 		struct expression *exp)
+ {
+   struct agent_expr *aexpr;
+   struct agent_reqs areqs;
+   struct cleanup *old_chain = NULL;
+   
+   aexpr = gen_trace_for_expr (pc, exp);
+ 
+   old_chain = make_cleanup_free_agent_expr (aexpr);
+ 
+   ax_reqs (aexpr, &areqs);
+   if (areqs.flaw != agent_flaw_none)
+     error ("malformed expression");
+ 
+   if (areqs.min_height < 0)
+     error ("gdb: Internal error: expression has min height < 0");
+   if (areqs.max_height > 20)
+     error ("expression too complicated, try simplifying");
+ 
+   discard_cleanups (old_chain);
+ 
+   add_aexpr (collect, aexpr);
+ 
+    /* take care of the registers */
+   if (areqs.reg_mask_len > 0)
+     {
+       int ndx1;
+       int ndx2;
+       
+       for (ndx1 = 0; ndx1 < areqs.reg_mask_len; ndx1++)
+ 	{
+ 	  QUIT;	/* allow user to bail out with ^C */
+ 	  if (areqs.reg_mask[ndx1] != 0)
+ 	    {
+ 	      /* assume chars have 8 bits */
+ 	      for (ndx2 = 0; ndx2 < 8; ndx2++)
+ 		if (areqs.reg_mask[ndx1] & (1 << ndx2))
+ 		  /* it's used -- record it */
+ 		  add_register (collect, ndx1 * 8 + ndx2);
+ 	    }
+ 	}
+     }
+   return;
+ }
+ 
  static void
  add_aexpr (struct collection_list *collect, struct agent_expr *aexpr)
  {

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