[rfc] Handle DWARF-2 value pieces residing in *parts* of a register
Ulrich Weigand
uweigand@de.ibm.com
Mon Dec 21 15:32:00 GMT 2009
Hello,
when implementing support for 64-bit register set on s390-linux, I ran
into a problem with handling of DWARF-2 "piece" values. Specifically,
handling of value pieces that reside in a register, but do not occupy
the *whole* register.
For example, when a 64-bit value is passed as argument on s390-linux,
it is passed in a register pair, with a 32-bit piece in each register.
However, when using the 64-bit register set, this means that we have
pieces of size 4 bytes in registers of size 8 bytes.
The current code would simply always use the initial 4 bytes of the
register value in this case; in the case of a big-endian machine,
this is the most-significant part. That's wrong for the s390 case
described above; the value pieces are passed in the *least*-significant
parts of the register.
Now, according to the DWARF-2 standard, the location of register pieces
of smaller than full register size is defined by the platform ABI.
For the placement of a small value in a *single* register we have a
gdbarch callback (gdbarch_value_from_register); maybe we need something
like that for value pieces as well. At the very least, we ought to
you the same default as default_value_from_register does: assume
partial register use implies the least-significant part of the register.
The patch below implements this.
Tested on s390(x)-linux in conjunction with the "32-bit application
with 64-bit register set" patch.
Any comments? I'm planning to apply this next week.
Bye,
Ulrich
ChangeLog:
* dwarf2loc.c (read_pieced_value): If a piece occupies part of
a register, assume the least-signficant part is used.
(write_pieced_value): Likewise.
diff -urNp gdb-orig/gdb/dwarf2loc.c gdb-head/gdb/dwarf2loc.c
--- gdb-orig/gdb/dwarf2loc.c 2009-12-18 17:27:13.000000000 +0100
+++ gdb-head/gdb/dwarf2loc.c 2009-12-18 17:42:44.000000000 +0100
@@ -263,11 +263,17 @@ read_pieced_value (struct value *v)
case DWARF_VALUE_REGISTER:
{
struct gdbarch *arch = get_frame_arch (frame);
- bfd_byte regval[MAX_REGISTER_SIZE];
int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch,
p->v.expr.value);
- get_frame_register (frame, gdb_regnum, regval);
- memcpy (contents + offset, regval, p->size);
+ int reg_offset = 0;
+
+ if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
+ && p->size < register_size (arch, gdb_regnum))
+ /* Big-endian, and we want less than full size. */
+ reg_offset = register_size (arch, gdb_regnum) - p->size;
+
+ get_frame_register_bytes (frame, gdb_regnum, reg_offset, p->size,
+ contents + offset);
}
break;
@@ -334,7 +340,15 @@ write_pieced_value (struct value *to, st
{
struct gdbarch *arch = get_frame_arch (frame);
int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.expr.value);
- put_frame_register (frame, gdb_regnum, contents + offset);
+ int reg_offset = 0;
+
+ if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
+ && p->size < register_size (arch, gdb_regnum))
+ /* Big-endian, and we want less than full size. */
+ reg_offset = register_size (arch, gdb_regnum) - p->size;
+
+ put_frame_register_bytes (frame, gdb_regnum, reg_offset, p->size,
+ contents + offset);
}
break;
case DWARF_VALUE_MEMORY:
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
More information about the Gdb-patches
mailing list