extract_unsigned_integer API (Re: [PATCH] Remove MAX_REGISTER_SIZE from frame.c)

Message ID 86d1ctlhin.fsf@gmail.com
State New, archived
Headers

Commit Message

Yao Qi April 3, 2017, 1:58 p.m. UTC
  Pedro Alves <palves@redhat.com> writes:

> Thinking about this a bit more, if we went this direction, I think the
> simplest would be to add an extract::size() method that returned the
> size of the buffer, and use that for bounds when filling in the
> data, like:
>
>    extractor extr;
>    frame_unwind_register (frame, regnum, ext.buffer (), ext.size ());
>    return extr.extract (type_len, byte_order);
>
> If type_len is larger than the buffer size, then we'll still get an
> error either inside extractor::extract, and maybe earlier
> inside frame_unwind_register (if it had that size parameter).

Yes, that is the simplest way.

>
> Though for the particular case of frame_unwind_register, since the
> frame machinery works with struct value's, inside frame_unwind_register
> there's going to be a value created already, and that has a contents
> buffer we could access directly.  So e.g.,
> inside frame_unwind_register_signed, we should be able to use
> frame_unwind_register_value directly thus avoid the need for the local
> buffer and copying data.

How is the patch below?
  

Comments

Pedro Alves April 4, 2017, 11:01 a.m. UTC | #1
On 04/03/2017 02:58 PM, Yao Qi wrote:

>>
>> Though for the particular case of frame_unwind_register, since the
>> frame machinery works with struct value's, inside frame_unwind_register
>> there's going to be a value created already, and that has a contents
>> buffer we could access directly.  So e.g.,
>> inside frame_unwind_register_signed, we should be able to use
>> frame_unwind_register_value directly thus avoid the need for the local
>> buffer and copying data.
> 
> How is the patch below?
> 

Fine with me.

Thanks,
Pedro Alves
  
Yao Qi April 5, 2017, 1:56 p.m. UTC | #2
Pedro Alves <palves@redhat.com> writes:

> Fine with me.

Patch is pushed in.
  

Patch

diff --git a/gdb/frame.c b/gdb/frame.c
index d98003d..a10f3e5 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1270,10 +1270,27 @@  frame_unwind_register_unsigned (struct frame_info *frame, int regnum)
   struct gdbarch *gdbarch = frame_unwind_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   int size = register_size (gdbarch, regnum);
-  gdb_byte buf[MAX_REGISTER_SIZE];
+  struct value *value = frame_unwind_register_value (frame, regnum);
 
-  frame_unwind_register (frame, regnum, buf);
-  return extract_unsigned_integer (buf, size, byte_order);
+  gdb_assert (value != NULL);
+
+  if (value_optimized_out (value))
+    {
+      throw_error (OPTIMIZED_OUT_ERROR,
+		   _("Register %d was not saved"), regnum);
+    }
+  if (!value_entirely_available (value))
+    {
+      throw_error (NOT_AVAILABLE_ERROR,
+		   _("Register %d is not available"), regnum);
+    }
+
+  ULONGEST r = extract_unsigned_integer (value_contents_all (value), size,
+					 byte_order);
+
+  release_value (value);
+  value_free (value);
+  return r;
 }
 
 ULONGEST