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]

[RFA] addresses/pointers vs numbers and expression evaluation


The following patch concerns bugs brought to light during a port of
gdb to a target with separate instruction and data.

The bugs will potentially impact any port which defines
POINTER_TO_ADDRESS to have any value other than the default value.

There are undoubtably additional bugs still lurking in the expression
evaluation code.

Several places in gdb it calls

    parse_and_eval_address

when the expression is *NOT* an address, but rather is just a number!
For example, it calls parse_and_eval_address when you type:

    set height 24

For this processor, treating 24 as a pointer resulted in an address of
0x01000018 -- 16 meg plus 24!  Similarly, it does this for the count
given to the continue and step commands as well as a few other places.

To fix this, I have create a new function called parse_and_eval_long
and changed 17 of the calls to parse_and_eval_address.

I have tested this on solaris native and on solaris x d10v (using the
simulator).  There were no regressions.

Here's the ChangeLog entry and the patch:

	* parse.c (parse_and_eval_long): New function.
	(value.h): Declare it.
	
	* breakpoint.c (breakpoints_info, maintenance_info_breakpoints):
	Call parse_and_eval_long, not parse_and_eval_address.
	* command.c (do_setshow_command): Ditto.
	* infcmd.c (step_1, signal_command, continue_command): Ditto.
	* infrun.c (signals_info): Ditto.
	* stack.c (set_backtrace_limit_command, backtrace_command_1,
	up_silently_base, down_silently_base): Ditto.
	* tracepoints.c (tracepoints_info, trace_find_command,
 	trace_find_tracepoint_command): Ditto.
	* valprint.c (set_radix): Ditto.
	* values (show_values): Ditto.
	
Index: breakpoint.c
===================================================================
RCS file: /cvs/src/src/gdb/breakpoint.c,v
retrieving revision 1.17
diff -c -r1.17 breakpoint.c
*** breakpoint.c	2000/08/30 00:58:58	1.17
--- breakpoint.c	2000/10/12 13:57:06
***************
*** 3638,3644 ****
    int bnum = -1;
  
    if (bnum_exp)
!     bnum = parse_and_eval_address (bnum_exp);
  
    breakpoint_1 (bnum, 0);
  }
--- 3638,3644 ----
    int bnum = -1;
  
    if (bnum_exp)
!     bnum = parse_and_eval_long (bnum_exp);
  
    breakpoint_1 (bnum, 0);
  }
***************
*** 3650,3656 ****
    int bnum = -1;
  
    if (bnum_exp)
!     bnum = parse_and_eval_address (bnum_exp);
  
    breakpoint_1 (bnum, 1);
  }
--- 3650,3656 ----
    int bnum = -1;
  
    if (bnum_exp)
!     bnum = parse_and_eval_long (bnum_exp);
  
    breakpoint_1 (bnum, 1);
  }
Index: command.c
===================================================================
RCS file: /cvs/src/src/gdb/command.c,v
retrieving revision 1.17
diff -c -r1.17 command.c
*** command.c	2000/08/08 00:17:39	1.17
--- command.c	2000/10/12 13:57:08
***************
*** 1622,1628 ****
  	case var_uinteger:
  	  if (arg == NULL)
  	    error_no_arg ("integer to set it to.");
! 	  *(unsigned int *) c->var = parse_and_eval_address (arg);
  	  if (*(unsigned int *) c->var == 0)
  	    *(unsigned int *) c->var = UINT_MAX;
  	  break;
--- 1622,1628 ----
  	case var_uinteger:
  	  if (arg == NULL)
  	    error_no_arg ("integer to set it to.");
! 	  *(unsigned int *) c->var = parse_and_eval_long (arg);
  	  if (*(unsigned int *) c->var == 0)
  	    *(unsigned int *) c->var = UINT_MAX;
  	  break;
***************
*** 1631,1637 ****
  	    unsigned int val;
  	    if (arg == NULL)
  	      error_no_arg ("integer to set it to.");
! 	    val = parse_and_eval_address (arg);
  	    if (val == 0)
  	      *(int *) c->var = INT_MAX;
  	    else if (val >= INT_MAX)
--- 1631,1637 ----
  	    unsigned int val;
  	    if (arg == NULL)
  	      error_no_arg ("integer to set it to.");
! 	    val = parse_and_eval_long (arg);
  	    if (val == 0)
  	      *(int *) c->var = INT_MAX;
  	    else if (val >= INT_MAX)
***************
*** 1643,1649 ****
  	case var_zinteger:
  	  if (arg == NULL)
  	    error_no_arg ("integer to set it to.");
! 	  *(int *) c->var = parse_and_eval_address (arg);
  	  break;
  	case var_enum:
  	  {
--- 1643,1649 ----
  	case var_zinteger:
  	  if (arg == NULL)
  	    error_no_arg ("integer to set it to.");
! 	  *(int *) c->var = parse_and_eval_long (arg);
  	  break;
  	case var_enum:
  	  {
Index: eval.c
===================================================================
RCS file: /cvs/src/src/gdb/eval.c,v
retrieving revision 1.8
diff -c -r1.8 eval.c
*** eval.c	2000/09/01 23:50:17	1.8
--- eval.c	2000/10/12 13:57:09
***************
*** 103,108 ****
--- 103,123 ----
    return addr;
  }
  
+ /* Like parse_and_eval_address, but treats the value of the expression
+    as an integer, not an address, returns a LONGEST, not a CORE_ADDR */
+ LONGEST
+ parse_and_eval_long (char *exp)
+ {
+   struct expression *expr = parse_expression (exp);
+   register LONGEST retval;
+   register struct cleanup *old_chain =
+     make_cleanup (free_current_contents, &expr);
+ 
+   retval = value_as_long (evaluate_expression (expr));
+   do_cleanups (old_chain);
+   return (retval);
+ }
+ 
  value_ptr
  parse_and_eval (char *exp)
  {
Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.11
diff -c -r1.11 infcmd.c
*** infcmd.c	2000/09/02 00:07:13	1.11
--- infcmd.c	2000/10/12 13:57:11
***************
*** 381,387 ****
        while (num != 0)
  	{
  	  set_ignore_count (num,
! 			    parse_and_eval_address (proc_count_exp) - 1,
  			    from_tty);
  	  /* set_ignore_count prints a message ending with a period.
  	     So print two spaces before "Continuing.".  */
--- 381,387 ----
        while (num != 0)
  	{
  	  set_ignore_count (num,
! 			    parse_and_eval_long (proc_count_exp) - 1,
  			    from_tty);
  	  /* set_ignore_count prints a message ending with a period.
  	     So print two spaces before "Continuing.".  */
***************
*** 465,471 ****
        async_disable_stdin ();
      }
  
!   count = count_string ? parse_and_eval_address (count_string) : 1;
  
    if (!single_inst || skip_subroutines)		/* leave si command alone */
      {
--- 465,471 ----
        async_disable_stdin ();
      }
  
!   count = count_string ? parse_and_eval_long (count_string) : 1;
  
    if (!single_inst || skip_subroutines)		/* leave si command alone */
      {
***************
*** 777,783 ****
    if (oursig == TARGET_SIGNAL_UNKNOWN)
      {
        /* No, try numeric.  */
!       int num = parse_and_eval_address (signum_exp);
  
        if (num == 0)
  	oursig = TARGET_SIGNAL_0;
--- 777,783 ----
    if (oursig == TARGET_SIGNAL_UNKNOWN)
      {
        /* No, try numeric.  */
!       int num = parse_and_eval_long (signum_exp);
  
        if (num == 0)
  	oursig = TARGET_SIGNAL_0;
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.18
diff -c -r1.18 infrun.c
*** infrun.c	2000/09/02 00:08:05	1.18
--- infrun.c	2000/10/12 13:57:15
***************
*** 3899,3905 ****
  	{
  	  /* No, try numeric.  */
  	  oursig =
! 	    target_signal_from_command (parse_and_eval_address (signum_exp));
  	}
        sig_print_info (oursig);
        return;
--- 3899,3905 ----
  	{
  	  /* No, try numeric.  */
  	  oursig =
! 	    target_signal_from_command (parse_and_eval_long (signum_exp));
  	}
        sig_print_info (oursig);
        return;
Index: stack.c
===================================================================
RCS file: /cvs/src/src/gdb/stack.c,v
retrieving revision 1.7
diff -c -r1.7 stack.c
*** stack.c	2000/07/30 01:48:27	1.7
--- stack.c	2000/10/12 13:57:17
***************
*** 1038,1044 ****
  static void
  set_backtrace_limit_command (char *count_exp, int from_tty)
  {
!   int count = parse_and_eval_address (count_exp);
  
    if (count < 0)
      error ("Negative argument not meaningful as backtrace limit.");
--- 1038,1044 ----
  static void
  set_backtrace_limit_command (char *count_exp, int from_tty)
  {
!   int count = parse_and_eval_long (count_exp);
  
    if (count < 0)
      error ("Negative argument not meaningful as backtrace limit.");
***************
*** 1086,1092 ****
    trailing_level = 0;
    if (count_exp)
      {
!       count = parse_and_eval_address (count_exp);
        if (count < 0)
  	{
  	  struct frame_info *current;
--- 1086,1092 ----
    trailing_level = 0;
    if (count_exp)
      {
!       count = parse_and_eval_long (count_exp);
        if (count < 0)
  	{
  	  struct frame_info *current;
***************
*** 1740,1746 ****
    register struct frame_info *fi;
    int count = 1, count1;
    if (count_exp)
!     count = parse_and_eval_address (count_exp);
    count1 = count;
  
    if (target_has_stack == 0 || selected_frame == 0)
--- 1740,1746 ----
    register struct frame_info *fi;
    int count = 1, count1;
    if (count_exp)
!     count = parse_and_eval_long (count_exp);
    count1 = count;
  
    if (target_has_stack == 0 || selected_frame == 0)
***************
*** 1777,1783 ****
    register struct frame_info *frame;
    int count = -1, count1;
    if (count_exp)
!     count = -parse_and_eval_address (count_exp);
    count1 = count;
  
    if (target_has_stack == 0 || selected_frame == 0)
--- 1777,1783 ----
    register struct frame_info *frame;
    int count = -1, count1;
    if (count_exp)
!     count = -parse_and_eval_long (count_exp);
    count1 = count;
  
    if (target_has_stack == 0 || selected_frame == 0)
Index: tracepoint.c
===================================================================
RCS file: /cvs/src/src/gdb/tracepoint.c,v
retrieving revision 1.10
diff -c -r1.10 tracepoint.c
*** tracepoint.c	2000/09/01 00:12:10	1.10
--- tracepoint.c	2000/10/12 13:57:19
***************
*** 465,471 ****
    int tpnum = -1;
  
    if (tpnum_exp)
!     tpnum = parse_and_eval_address (tpnum_exp);
  
    ALL_TRACEPOINTS (t)
      if (tpnum == -1 || tpnum == t->number)
--- 465,471 ----
    int tpnum = -1;
  
    if (tpnum_exp)
!     tpnum = parse_and_eval_long (tpnum_exp);
  
    ALL_TRACEPOINTS (t)
      if (tpnum == -1 || tpnum == t->number)
***************
*** 1986,1992 ****
  	  frameno = traceframe_number - 1;
  	}
        else
! 	frameno = parse_and_eval_address (args);
  
        if (frameno < -1)
  	error ("invalid input (%d is less than zero)", frameno);
--- 1986,1992 ----
  	  frameno = traceframe_number - 1;
  	}
        else
! 	frameno = parse_and_eval_long (args);
  
        if (frameno < -1)
  	error ("invalid input (%d is less than zero)", frameno);
Index: valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/valprint.c,v
retrieving revision 1.6
diff -c -r1.6 valprint.c
*** valprint.c	2000/07/30 01:48:27	1.6
--- valprint.c	2000/10/12 13:57:20
***************
*** 1416,1422 ****
  {
    unsigned radix;
  
!   radix = (arg == NULL) ? 10 : parse_and_eval_address (arg);
    set_output_radix_1 (0, radix);
    set_input_radix_1 (0, radix);
    if (from_tty)
--- 1416,1422 ----
  {
    unsigned radix;
  
!   radix = (arg == NULL) ? 10 : parse_and_eval_long (arg);
    set_output_radix_1 (0, radix);
    set_input_radix_1 (0, radix);
    if (from_tty)
Index: value.h
===================================================================
RCS file: /cvs/src/src/gdb/value.h,v
retrieving revision 1.10
diff -c -r1.10 value.h
*** value.h	2000/09/04 08:29:25	1.10
--- value.h	2000/10/12 13:57:21
***************
*** 410,415 ****
--- 410,417 ----
  
  extern CORE_ADDR parse_and_eval_address_1 (char **expptr);
  
+ extern LONGEST parse_and_eval_long (char *exp);
+ 
  extern value_ptr access_value_history (int num);
  
  extern value_ptr value_of_internalvar (struct internalvar *var);
Index: values.c
===================================================================
RCS file: /cvs/src/src/gdb/values.c,v
retrieving revision 1.9
diff -c -r1.9 values.c
*** values.c	2000/07/30 01:48:27	1.9
--- values.c	2000/10/12 13:57:22
***************
*** 351,357 ****
        /* "info history +" should print from the stored position.
           "info history <exp>" should print around value number <exp>.  */
        if (num_exp[0] != '+' || num_exp[1] != '\0')
! 	num = parse_and_eval_address (num_exp) - 5;
      }
    else
      {
--- 351,357 ----
        /* "info history +" should print from the stored position.
           "info history <exp>" should print around value number <exp>.  */
        if (num_exp[0] != '+' || num_exp[1] != '\0')
! 	num = parse_and_eval_long (num_exp) - 5;
      }
    else
      {

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