mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-11 13:02:10 +08:00
gdb
* dwarf2loc.c (read_pieced_value): Work properly when 'v' has an offset. (write_pieced_value): Likewise. gdb/testsuite * gdb.dwarf2.pieces.exp: New file. * gdb.dwarf2.pieces.S: New file. * gdb.dwarf2.pieces.c: New file.
This commit is contained in:
parent
90e7c2c53d
commit
afd74c5ff7
@ -1,3 +1,9 @@
|
||||
2010-05-21 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* dwarf2loc.c (read_pieced_value): Work properly when 'v' has an
|
||||
offset.
|
||||
(write_pieced_value): Likewise.
|
||||
|
||||
2010-05-21 Pierre Muller <muller@ics.u-strasbg.fr>
|
||||
|
||||
* dwarf2read.c (process_die): Also allow DW_TAG_const_type
|
||||
|
136
gdb/dwarf2loc.c
136
gdb/dwarf2loc.c
@ -264,14 +264,46 @@ read_pieced_value (struct value *v)
|
||||
{
|
||||
int i;
|
||||
long offset = 0;
|
||||
ULONGEST bytes_to_skip;
|
||||
gdb_byte *contents;
|
||||
struct piece_closure *c = (struct piece_closure *) value_computed_closure (v);
|
||||
struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (v));
|
||||
size_t type_len;
|
||||
|
||||
if (value_type (v) != value_enclosing_type (v))
|
||||
internal_error (__FILE__, __LINE__,
|
||||
_("Should not be able to create a lazy value with "
|
||||
"an enclosing type"));
|
||||
|
||||
contents = value_contents_raw (v);
|
||||
for (i = 0; i < c->n_pieces; i++)
|
||||
bytes_to_skip = value_offset (v);
|
||||
type_len = TYPE_LENGTH (value_type (v));
|
||||
for (i = 0; i < c->n_pieces && offset < type_len; i++)
|
||||
{
|
||||
struct dwarf_expr_piece *p = &c->pieces[i];
|
||||
size_t this_size;
|
||||
long dest_offset, source_offset;
|
||||
|
||||
if (bytes_to_skip > 0 && bytes_to_skip >= p->size)
|
||||
{
|
||||
bytes_to_skip -= p->size;
|
||||
continue;
|
||||
}
|
||||
this_size = p->size;
|
||||
if (this_size > type_len - offset)
|
||||
this_size = type_len - offset;
|
||||
if (bytes_to_skip > 0)
|
||||
{
|
||||
dest_offset = 0;
|
||||
source_offset = bytes_to_skip;
|
||||
this_size -= bytes_to_skip;
|
||||
bytes_to_skip = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dest_offset = offset;
|
||||
source_offset = 0;
|
||||
}
|
||||
|
||||
switch (p->location)
|
||||
{
|
||||
@ -280,17 +312,17 @@ read_pieced_value (struct value *v)
|
||||
struct gdbarch *arch = get_frame_arch (frame);
|
||||
int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch,
|
||||
p->v.expr.value);
|
||||
int reg_offset = 0;
|
||||
int reg_offset = source_offset;
|
||||
|
||||
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
|
||||
&& p->size < register_size (arch, gdb_regnum))
|
||||
&& this_size < register_size (arch, gdb_regnum))
|
||||
/* Big-endian, and we want less than full size. */
|
||||
reg_offset = register_size (arch, gdb_regnum) - p->size;
|
||||
reg_offset = register_size (arch, gdb_regnum) - this_size;
|
||||
|
||||
if (gdb_regnum != -1)
|
||||
{
|
||||
get_frame_register_bytes (frame, gdb_regnum, reg_offset,
|
||||
p->size, contents + offset);
|
||||
this_size, contents + dest_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -302,38 +334,60 @@ read_pieced_value (struct value *v)
|
||||
|
||||
case DWARF_VALUE_MEMORY:
|
||||
if (p->v.expr.in_stack_memory)
|
||||
read_stack (p->v.expr.value, contents + offset, p->size);
|
||||
read_stack (p->v.expr.value + source_offset,
|
||||
contents + dest_offset, this_size);
|
||||
else
|
||||
read_memory (p->v.expr.value, contents + offset, p->size);
|
||||
read_memory (p->v.expr.value + source_offset,
|
||||
contents + dest_offset, this_size);
|
||||
break;
|
||||
|
||||
case DWARF_VALUE_STACK:
|
||||
{
|
||||
struct gdbarch *gdbarch = get_type_arch (value_type (v));
|
||||
size_t n = p->size;
|
||||
size_t n = this_size;
|
||||
|
||||
if (n > c->addr_size)
|
||||
n = c->addr_size;
|
||||
store_unsigned_integer (contents + offset, n,
|
||||
gdbarch_byte_order (gdbarch),
|
||||
p->v.expr.value);
|
||||
if (n > c->addr_size - source_offset)
|
||||
n = (c->addr_size >= source_offset
|
||||
? c->addr_size - source_offset
|
||||
: 0);
|
||||
if (n == 0)
|
||||
{
|
||||
/* Nothing. */
|
||||
}
|
||||
else if (source_offset == 0)
|
||||
store_unsigned_integer (contents + dest_offset, n,
|
||||
gdbarch_byte_order (gdbarch),
|
||||
p->v.expr.value);
|
||||
else
|
||||
{
|
||||
gdb_byte bytes[sizeof (ULONGEST)];
|
||||
|
||||
store_unsigned_integer (bytes, n + source_offset,
|
||||
gdbarch_byte_order (gdbarch),
|
||||
p->v.expr.value);
|
||||
memcpy (contents + dest_offset, bytes + source_offset, n);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case DWARF_VALUE_LITERAL:
|
||||
{
|
||||
size_t n = p->size;
|
||||
size_t n = this_size;
|
||||
|
||||
if (n > p->v.literal.length)
|
||||
n = p->v.literal.length;
|
||||
memcpy (contents + offset, p->v.literal.data, n);
|
||||
if (n > p->v.literal.length - source_offset)
|
||||
n = (p->v.literal.length >= source_offset
|
||||
? p->v.literal.length - source_offset
|
||||
: 0);
|
||||
if (n != 0)
|
||||
memcpy (contents + dest_offset,
|
||||
p->v.literal.data + source_offset, n);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__, _("invalid location type"));
|
||||
}
|
||||
offset += p->size;
|
||||
offset += this_size;
|
||||
}
|
||||
}
|
||||
|
||||
@ -342,9 +396,11 @@ write_pieced_value (struct value *to, struct value *from)
|
||||
{
|
||||
int i;
|
||||
long offset = 0;
|
||||
gdb_byte *contents;
|
||||
ULONGEST bytes_to_skip;
|
||||
const gdb_byte *contents;
|
||||
struct piece_closure *c = (struct piece_closure *) value_computed_closure (to);
|
||||
struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (to));
|
||||
size_t type_len;
|
||||
|
||||
if (frame == NULL)
|
||||
{
|
||||
@ -352,10 +408,35 @@ write_pieced_value (struct value *to, struct value *from)
|
||||
return;
|
||||
}
|
||||
|
||||
contents = value_contents_raw (from);
|
||||
for (i = 0; i < c->n_pieces; i++)
|
||||
contents = value_contents (from);
|
||||
bytes_to_skip = value_offset (to);
|
||||
type_len = TYPE_LENGTH (value_type (to));
|
||||
for (i = 0; i < c->n_pieces && offset < type_len; i++)
|
||||
{
|
||||
struct dwarf_expr_piece *p = &c->pieces[i];
|
||||
size_t this_size;
|
||||
long dest_offset, source_offset;
|
||||
|
||||
if (bytes_to_skip > 0 && bytes_to_skip >= p->size)
|
||||
{
|
||||
bytes_to_skip -= p->size;
|
||||
continue;
|
||||
}
|
||||
this_size = p->size;
|
||||
if (this_size > type_len - offset)
|
||||
this_size = type_len - offset;
|
||||
if (bytes_to_skip > 0)
|
||||
{
|
||||
dest_offset = bytes_to_skip;
|
||||
source_offset = 0;
|
||||
this_size -= bytes_to_skip;
|
||||
bytes_to_skip = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
dest_offset = 0;
|
||||
source_offset = offset;
|
||||
}
|
||||
|
||||
switch (p->location)
|
||||
{
|
||||
@ -363,17 +444,17 @@ write_pieced_value (struct value *to, struct value *from)
|
||||
{
|
||||
struct gdbarch *arch = get_frame_arch (frame);
|
||||
int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.expr.value);
|
||||
int reg_offset = 0;
|
||||
int reg_offset = dest_offset;
|
||||
|
||||
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
|
||||
&& p->size < register_size (arch, gdb_regnum))
|
||||
&& this_size <= register_size (arch, gdb_regnum))
|
||||
/* Big-endian, and we want less than full size. */
|
||||
reg_offset = register_size (arch, gdb_regnum) - p->size;
|
||||
reg_offset = register_size (arch, gdb_regnum) - this_size;
|
||||
|
||||
if (gdb_regnum != -1)
|
||||
{
|
||||
put_frame_register_bytes (frame, gdb_regnum, reg_offset,
|
||||
p->size, contents + offset);
|
||||
this_size, contents + source_offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -383,13 +464,14 @@ write_pieced_value (struct value *to, struct value *from)
|
||||
}
|
||||
break;
|
||||
case DWARF_VALUE_MEMORY:
|
||||
write_memory (p->v.expr.value, contents + offset, p->size);
|
||||
write_memory (p->v.expr.value + dest_offset,
|
||||
contents + source_offset, this_size);
|
||||
break;
|
||||
default:
|
||||
set_value_optimized_out (to, 1);
|
||||
return;
|
||||
}
|
||||
offset += p->size;
|
||||
offset += this_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2010-05-21 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* gdb.dwarf2.pieces.exp: New file.
|
||||
* gdb.dwarf2.pieces.S: New file.
|
||||
* gdb.dwarf2.pieces.c: New file.
|
||||
|
||||
2010-05-20 Pedro Alves <pedro@codesourcery.com>
|
||||
Joel Brobecker <brobecker@adacore.com>
|
||||
|
||||
|
1655
gdb/testsuite/gdb.dwarf2/pieces.S
Normal file
1655
gdb/testsuite/gdb.dwarf2/pieces.S
Normal file
File diff suppressed because it is too large
Load Diff
98
gdb/testsuite/gdb.dwarf2/pieces.c
Normal file
98
gdb/testsuite/gdb.dwarf2/pieces.c
Normal file
@ -0,0 +1,98 @@
|
||||
/* Copyright (C) 2010 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* The original program corresponding to pieces.S.
|
||||
This came from https://bugzilla.redhat.com/show_bug.cgi?id=589467
|
||||
Note that it is not ever compiled, pieces.S is used instead.
|
||||
However, it is used to extract breakpoint line numbers. */
|
||||
|
||||
struct A { int i; int j; };
|
||||
struct B { int : 4; int i : 12; int j : 12; int : 4; };
|
||||
|
||||
__attribute__((noinline)) void
|
||||
bar (int x)
|
||||
{
|
||||
asm volatile ("" : : "r" (x) : "memory");
|
||||
}
|
||||
|
||||
__attribute__((noinline)) int
|
||||
f1 (int k)
|
||||
{
|
||||
struct A a = { 4, k + 6 };
|
||||
asm ("" : "+r" (a.i));
|
||||
a.j++;
|
||||
bar (a.i); /* { dg-final { gdb-test 20 "a.i" "4" } } */
|
||||
bar (a.j); /* { dg-final { gdb-test 20 "a.j" "14" } } */
|
||||
return a.i + a.j; /* f1 breakpoint */
|
||||
}
|
||||
|
||||
__attribute__((noinline)) int
|
||||
f2 (int k)
|
||||
{
|
||||
int a[2] = { 4, k + 6 };
|
||||
asm ("" : "+r" (a[0]));
|
||||
a[1]++;
|
||||
bar (a[0]); /* { dg-final { gdb-test 31 "a\[0\]" "4" } } */
|
||||
bar (a[1]); /* { dg-final { gdb-test 31 "a\[1\]" "14" } } */
|
||||
return a[0] + a[1]; /* f2 breakpoint */
|
||||
}
|
||||
|
||||
__attribute__((noinline)) int
|
||||
f3 (int k)
|
||||
{
|
||||
struct B a = { 4, k + 6 };
|
||||
asm ("" : "+r" (a.i));
|
||||
a.j++;
|
||||
bar (a.i); /* { dg-final { gdb-test 42 "a.i" "4" } } */
|
||||
bar (a.j); /* { dg-final { gdb-test 42 "a.j" "14" } } */
|
||||
return a.i + a.j; /* f3 breakpoint */
|
||||
}
|
||||
|
||||
__attribute__((noinline)) int
|
||||
f4 (int k)
|
||||
{
|
||||
int a[2] = { k, k };
|
||||
asm ("" : "+r" (a[0]));
|
||||
a[1]++;
|
||||
bar (a[0]);
|
||||
bar (a[1]);
|
||||
return a[0] + a[1]; /* f4 breakpoint */
|
||||
}
|
||||
|
||||
__attribute__((noinline)) int
|
||||
f5 (int k)
|
||||
{
|
||||
struct A a = { k, k };
|
||||
asm ("" : "+r" (a.i));
|
||||
a.j++;
|
||||
bar (a.i);
|
||||
bar (a.j);
|
||||
return a.i + a.j; /* f5 breakpoint */
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int k;
|
||||
asm ("" : "=r" (k) : "0" (7));
|
||||
f1 (k);
|
||||
f2 (k);
|
||||
f3 (k);
|
||||
f4 (k);
|
||||
f5 (k);
|
||||
return 0;
|
||||
}
|
57
gdb/testsuite/gdb.dwarf2/pieces.exp
Normal file
57
gdb/testsuite/gdb.dwarf2/pieces.exp
Normal file
@ -0,0 +1,57 @@
|
||||
# Copyright 2010 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Test some DWARF piece operators.
|
||||
|
||||
# This test can only be run on targets which support DWARF-2 and use gas.
|
||||
# For now pick a sampling of likely targets.
|
||||
if {![istarget *-*-linux*]
|
||||
&& ![istarget *-*-gnu*]
|
||||
&& ![istarget *-*-elf*]
|
||||
&& ![istarget *-*-openbsd*]
|
||||
&& ![istarget arm-*-eabi*]
|
||||
&& ![istarget powerpc-*-eabi*]} {
|
||||
return 0
|
||||
}
|
||||
# This test can only be run on x86 targets.
|
||||
if {![istarget i?86-*]} {
|
||||
return 0
|
||||
}
|
||||
|
||||
set testfile "pieces"
|
||||
set srcfile ${testfile}.S
|
||||
set csrcfile ${testfile}.c
|
||||
set binfile ${objdir}/${subdir}/${testfile}.x
|
||||
|
||||
if {[prepare_for_testing ${testfile}.exp ${testfile}.x $srcfile]} {
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![runto_main] {
|
||||
return -1
|
||||
}
|
||||
|
||||
# Function f1 tests a particular gdb bug involving DW_OP_piece.
|
||||
proc pieces_test_f1 {} {
|
||||
global csrcfile
|
||||
set line [gdb_get_line_number "f1 breakpoint" $csrcfile]
|
||||
gdb_test "break pieces.c:$line" "Breakpoint 2.*" \
|
||||
"set f1 breakpoint for pieces"
|
||||
gdb_continue_to_breakpoint "continue to f1 breakpoint for pieces"
|
||||
gdb_test "print a" " = {i = 4, j = 14}" "print a in pieces:f1"
|
||||
gdb_test "print a.j" " = 14" "print a.j in pieces:f1"
|
||||
}
|
||||
|
||||
pieces_test_f1
|
Loading…
Reference in New Issue
Block a user