[AVR] inferior call of subprogram with pointer as argument
authorJoel Brobecker <brobecker@gnat.com>
Tue, 20 Apr 2010 22:40:36 +0000 (22:40 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Tue, 20 Apr 2010 22:40:36 +0000 (22:40 +0000)
On AVR, the gdb view of an address is different from the machine view of the
same address.  We need to use special machinery implemented by value_pointer
to take the pointer of a value.

For instance, considering the following function...

  procedure Trace (Unit    : T; Message : String);

... where T is an access Integer (a pointer to an integer), call to this
function currently triggers the following warnings:

    (gdb) call debug.trace (me, "You")
    warning: Value does not fit in 16 bits.
    warning: Value does not fit in 16 bits.
    Tracing message: You

It could have been worse if Trace actually tried to dereference the Unit
argument...

gdb/ChangeLog (from Tristan Gingold):

* ada-lang.c (value_pointer): New function.
(make_array_descriptor): Call value_pointer to convert addresses to
pointers.

Tested on avr and x86_64-linux.

gdb/ChangeLog
gdb/ada-lang.c

index e56a6a1..f220340 100644 (file)
@@ -1,5 +1,11 @@
 2010-04-20  Joel Brobecker  <brobecker@adacore.com>
 
+       * ada-lang.c (value_pointer): New function.
+       (make_array_descriptor): Call value_pointer to convert addresses to
+       pointers.
+
+2010-04-20  Joel Brobecker  <brobecker@adacore.com>
+
        * rs6000-aix-tdep.c: #include exceptions.h.
        (rs6000_convert_from_func_ptr_addr): If an exception is thrown
        while reading the memory at ADDR, then ADDR cannot be a function
index a598c6d..abc9c9f 100644 (file)
@@ -3863,6 +3863,25 @@ ada_convert_actual (struct value *actual, struct type *formal_type0,
   return actual;
 }
 
+/* Convert VALUE (which must be an address) to a CORE_ADDR that is a pointer of
+   type TYPE.  This is usually an inefficient no-op except on some targets
+   (such as AVR) where the representation of a pointer and an address
+   differs.  */
+
+static CORE_ADDR
+value_pointer (struct value *value, struct type *type)
+{
+  struct gdbarch *gdbarch = get_type_arch (type);
+  unsigned len = TYPE_LENGTH (type);
+  gdb_byte *buf = alloca (len);
+  CORE_ADDR addr;
+
+  addr = value_address (value);
+  gdbarch_address_to_pointer (gdbarch, type, buf, addr);
+  addr = extract_unsigned_integer (buf, len, gdbarch_byte_order (gdbarch));
+  return addr;
+}
+
 
 /* Push a descriptor of type TYPE for array value ARR on the stack at
    *SP, updating *SP to reflect the new descriptor.  Return either
@@ -3898,13 +3917,15 @@ make_array_descriptor (struct type *type, struct value *arr,
 
   modify_general_field (value_type (descriptor),
                        value_contents_writeable (descriptor),
-                        value_address (ensure_lval (arr, gdbarch, sp)),
+                        value_pointer (ensure_lval (arr, gdbarch, sp),
+                                       TYPE_FIELD_TYPE (desc_type, 0)),
                         fat_pntr_data_bitpos (desc_type),
                         fat_pntr_data_bitsize (desc_type));
 
   modify_general_field (value_type (descriptor),
                        value_contents_writeable (descriptor),
-                        value_address (bounds),
+                        value_pointer (bounds,
+                                       TYPE_FIELD_TYPE (desc_type, 1)),
                         fat_pntr_bounds_bitpos (desc_type),
                         fat_pntr_bounds_bitsize (desc_type));