aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2loc.c
diff options
context:
space:
mode:
authorAndreas Arnez <arnez@linux.vnet.ibm.com>2017-02-01 16:59:00 +0100
committerAndreas Arnez <arnez@linux.vnet.ibm.com>2017-02-01 16:59:00 +0100
commit7346ef59bb33e28161d78ab478c3476b3dab2e8e (patch)
tree9aa97840ceb8bb26016e1921210e6add8819f409 /gdb/dwarf2loc.c
parent787f00256b3eabe34b8599fca4df0243df80d5ca (diff)
downloadgdb-7346ef59bb33e28161d78ab478c3476b3dab2e8e.zip
gdb-7346ef59bb33e28161d78ab478c3476b3dab2e8e.tar.gz
gdb-7346ef59bb33e28161d78ab478c3476b3dab2e8e.tar.bz2
Big-endian targets: Don't ignore offset into DW_OP_implicit_value
When a variable's location is expressed as DW_OP_implicit_value, but the given value is longer than needed, which bytes should be used? GDB's current logic was introduced with a patch from 2011 and uses the "least significant" bytes: https://sourceware.org/ml/gdb-patches/2011-08/msg00123.html Now consider a sub-value from such a location at a given offset, accessed through DW_OP_implicit_pointer. Which bytes should be used for that? The patch above *always* uses the last bytes on big-endian targets, ignoring the offset. E.g., given the code snippet const char foo[] = "Hello, world!"; const char *a = &foo[0]; const char *b = &foo[7]; assume that `foo' is described as DW_OP_implicit_value and `a' and `b' each as DW_OP_implicit_pointer into that value. Then with current GDB `*a' and `*b' yield the same result -- the string's zero terminator. This patch basically reverts the portion of the patch above that deals with DW_OP_implicit_value. This fixes the offset handling and also goes back to dropping the last instead of the first bytes on big-endian targets if the implicit value is longer than needed. The latter aspect of the change probably doesn't matter for actual programs, but simplifies the logic. The patch also cleans up the original code a bit and adds appropriate test cases. gdb/testsuite/ChangeLog: * gdb.dwarf2/dw2-op-stack-value.exp: Adjust expected result of taking a 2-byte value out of a 4-byte DWARF implicit value on big-endian targets. * gdb.dwarf2/nonvar-access.exp: Add more comments to existing logic. Add test cases for DW_OP_implicit. gdb/ChangeLog: * dwarf2loc.c (dwarf2_evaluate_loc_desc_full): For DWARF_VALUE_LITERAL, no longer ignore the offset on big-endian targets. And if the implicit value is longer than needed, extract the first bytes instead of the "least significant" ones.
Diffstat (limited to 'gdb/dwarf2loc.c')
-rw-r--r--gdb/dwarf2loc.c19
1 files changed, 3 insertions, 16 deletions
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 7fca76b..a592b66 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -2442,28 +2442,15 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
case DWARF_VALUE_LITERAL:
{
bfd_byte *contents;
- const bfd_byte *ldata;
- size_t n = ctx.len;
+ size_t n = TYPE_LENGTH (type);
- if (byte_offset + TYPE_LENGTH (type) > n)
+ if (byte_offset + n > ctx.len)
invalid_synthetic_pointer ();
free_values.free_to_mark ();
retval = allocate_value (type);
contents = value_contents_raw (retval);
-
- ldata = ctx.data + byte_offset;
- n -= byte_offset;
-
- if (n > TYPE_LENGTH (type))
- {
- struct gdbarch *objfile_gdbarch = get_objfile_arch (objfile);
-
- if (gdbarch_byte_order (objfile_gdbarch) == BFD_ENDIAN_BIG)
- ldata += n - TYPE_LENGTH (type);
- n = TYPE_LENGTH (type);
- }
- memcpy (contents, ldata, n);
+ memcpy (contents, ctx.data + byte_offset, n);
}
break;