Rework value_of_register in terms of value_of_register_lazy.
authorPedro Alves <palves@redhat.com>
Thu, 5 Sep 2013 14:02:16 +0000 (14:02 +0000)
committerPedro Alves <palves@redhat.com>
Thu, 5 Sep 2013 14:02:16 +0000 (14:02 +0000)
I noticed that value_of_register (used for getting values _of_
registers ($pc, $rax, etc.), rather than variables _in_ registers),
kind of builds a franken-value, by propagating the lval and address of
the frame register value, but not the entire location, like necessary
for lval_computed (if some unwinder ever returns that, the resulting
value will misbehave).  This gets in the way of printing optimized out
(not saved) lval_registers differently from other optimized out
values, as it doesn't make sure the resulting value is lval_register.

I started out by just doing something like:

-  VALUE_LVAL (reg_val) = lval;
-  set_value_address (reg_val, addr);
+  VALUE_LVAL (reg_val) = lval_register;

... just like value_of_register_lazy below.  That's sufficient to fix
the issue.

Then I noticed this is using frame_register, which we should avoid
nowadays, for it returns elements of a value, but not all that's
sometimes necessary (unavailable-ness is all or nothing with it, for
instance), and considered using get_frame_register_value instead
(which returns a struct value), and value_contents_copy, just like
value_fetch_lazy's handling of lval_register.  But at that point, I
realized we might as well just defer all that work to
value_of_register_lazy/value_fetch_lazy...

Doing it this way adds a frame_find_by_id lookup (from within
value_fetch_lazy), while we already have a frame pointer handy in
value_of_register.  I considered factoring out the lazy register
fetching out of value_fetch_lazy, into a function that takes a frame
pointer and call that instead, avoiding the lookup, but then it looked
like too much complication for an early optimization, and went back to
keeping it simple.

Tested on x86_64 Fedora 17.

gdb/
2013-09-05  Pedro Alves  <palves@redhat.com>

* findvar.c (value_of_register): Rework in terms of
value_of_register_lazy.

gdb/ChangeLog
gdb/findvar.c

index 9c4bd383e8a635c947e9fdf4374757d17e7da4ae..ee1e4aa490298b5dd6ee5c5fa0eb1dd5df8ad688 100644 (file)
@@ -1,3 +1,8 @@
+2013-09-05  Pedro Alves  <palves@redhat.com>
+
+       * findvar.c (value_of_register): Rework in terms of
+       value_of_register_lazy.
+
 2013-09-05  Muhammad Bilal  <mbilal@codesourcery.com>
 
        * symfile.c (add_symbol_file_command): Remove trailing
index d59bee1aedc0735cccc78d5593cc6c1d8d84aef8..25242bea71adb22a103e7eca4a033c5892464e67 100644 (file)
@@ -262,14 +262,7 @@ struct value *
 value_of_register (int regnum, struct frame_info *frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  CORE_ADDR addr;
-  int optim;
-  int unavail;
   struct value *reg_val;
-  struct type *reg_type;
-  int realnum;
-  gdb_byte raw_buffer[MAX_REGISTER_SIZE];
-  enum lval_type lval;
 
   /* User registers lie completely outside of the range of normal
      registers.  Catch them early so that the target never sees them.  */
@@ -277,28 +270,8 @@ value_of_register (int regnum, struct frame_info *frame)
                + gdbarch_num_pseudo_regs (gdbarch))
     return value_of_user_reg (regnum, frame);
 
-  frame_register (frame, regnum, &optim, &unavail,
-                 &lval, &addr, &realnum, raw_buffer);
-
-  reg_type = register_type (gdbarch, regnum);
-  if (optim)
-    reg_val = allocate_optimized_out_value (reg_type);
-  else
-    reg_val = allocate_value (reg_type);
-
-  if (!optim && !unavail)
-    memcpy (value_contents_raw (reg_val), raw_buffer,
-           register_size (gdbarch, regnum));
-  else
-    memset (value_contents_raw (reg_val), 0,
-           register_size (gdbarch, regnum));
-
-  VALUE_LVAL (reg_val) = lval;
-  set_value_address (reg_val, addr);
-  VALUE_REGNUM (reg_val) = regnum;
-  if (unavail)
-    mark_value_bytes_unavailable (reg_val, 0, register_size (gdbarch, regnum));
-  VALUE_FRAME_ID (reg_val) = get_frame_id (frame);
+  reg_val = value_of_register_lazy (frame, regnum);
+  value_fetch_lazy (reg_val);
   return reg_val;
 }