mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-24 12:39:59 +00:00
gdb/
PR gdb/9675: * dwarf2read.c (unsigned_int_compar, inherit_abstract_dies): New. (read_func_scope): Call inherit_abstract_dies. gdb/testsuite/ * gdb.cp/abstract-origin.exp, gdb.cp/abstract-origin.cc: New test.
This commit is contained in:
parent
8f3e5e92ce
commit
d389af10b7
@ -1,3 +1,9 @@
|
||||
2009-04-27 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
PR gdb/9675:
|
||||
* dwarf2read.c (unsigned_int_compar, inherit_abstract_dies): New.
|
||||
(read_func_scope): Call inherit_abstract_dies.
|
||||
|
||||
2009-04-25 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* Makefile.in (ALLDEPFILES): Remove duplicate entries for
|
||||
|
@ -3089,6 +3089,103 @@ add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc,
|
||||
cu->last_fn = thisfn;
|
||||
}
|
||||
|
||||
/* qsort helper for inherit_abstract_dies. */
|
||||
|
||||
static int
|
||||
unsigned_int_compar (const void *ap, const void *bp)
|
||||
{
|
||||
unsigned int a = *(unsigned int *) ap;
|
||||
unsigned int b = *(unsigned int *) bp;
|
||||
|
||||
return (a > b) - (b > a);
|
||||
}
|
||||
|
||||
/* DW_AT_abstract_origin inherits whole DIEs (not just their attributes).
|
||||
Inherit only the children of the DW_AT_abstract_origin DIE not being already
|
||||
referenced by DW_AT_abstract_origin from the children of the current DIE. */
|
||||
|
||||
static void
|
||||
inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
|
||||
{
|
||||
struct die_info *child_die;
|
||||
unsigned die_children_count;
|
||||
/* CU offsets which were referenced by children of the current DIE. */
|
||||
unsigned *offsets;
|
||||
unsigned *offsets_end, *offsetp;
|
||||
/* Parent of DIE - referenced by DW_AT_abstract_origin. */
|
||||
struct die_info *origin_die;
|
||||
/* Iterator of the ORIGIN_DIE children. */
|
||||
struct die_info *origin_child_die;
|
||||
struct cleanup *cleanups;
|
||||
struct attribute *attr;
|
||||
|
||||
attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);
|
||||
if (!attr)
|
||||
return;
|
||||
|
||||
origin_die = follow_die_ref (die, attr, &cu);
|
||||
if (die->tag != origin_die->tag)
|
||||
complaint (&symfile_complaints,
|
||||
_("DIE 0x%x and its abstract origin 0x%x have different tags"),
|
||||
die->offset, origin_die->offset);
|
||||
|
||||
child_die = die->child;
|
||||
die_children_count = 0;
|
||||
while (child_die && child_die->tag)
|
||||
{
|
||||
child_die = sibling_die (child_die);
|
||||
die_children_count++;
|
||||
}
|
||||
offsets = xmalloc (sizeof (*offsets) * die_children_count);
|
||||
cleanups = make_cleanup (xfree, offsets);
|
||||
|
||||
offsets_end = offsets;
|
||||
child_die = die->child;
|
||||
while (child_die && child_die->tag)
|
||||
{
|
||||
attr = dwarf2_attr (child_die, DW_AT_abstract_origin, cu);
|
||||
/* According to DWARF3 3.3.8.2 #3 new entries without their abstract
|
||||
counterpart may exist. */
|
||||
if (attr)
|
||||
{
|
||||
struct die_info *child_origin_die;
|
||||
|
||||
child_origin_die = follow_die_ref (child_die, attr, &cu);
|
||||
if (child_die->tag != child_origin_die->tag)
|
||||
complaint (&symfile_complaints,
|
||||
_("Child DIE 0x%x and its abstract origin 0x%x have "
|
||||
"different tags"), child_die->offset,
|
||||
child_origin_die->offset);
|
||||
*offsets_end++ = child_origin_die->offset;
|
||||
}
|
||||
child_die = sibling_die (child_die);
|
||||
}
|
||||
qsort (offsets, offsets_end - offsets, sizeof (*offsets),
|
||||
unsigned_int_compar);
|
||||
for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++)
|
||||
if (offsetp[-1] == *offsetp)
|
||||
complaint (&symfile_complaints, _("Multiple children of DIE 0x%x refer "
|
||||
"to DIE 0x%x as their abstract origin"),
|
||||
die->offset, *offsetp);
|
||||
|
||||
offsetp = offsets;
|
||||
origin_child_die = origin_die->child;
|
||||
while (origin_child_die && origin_child_die->tag)
|
||||
{
|
||||
/* Is ORIGIN_CHILD_DIE referenced by any of the DIE children? */
|
||||
while (offsetp < offsets_end && *offsetp < origin_child_die->offset)
|
||||
offsetp++;
|
||||
if (offsetp >= offsets_end || *offsetp > origin_child_die->offset)
|
||||
{
|
||||
/* Found that ORIGIN_CHILD_DIE is really not referenced. */
|
||||
process_die (origin_child_die, cu);
|
||||
}
|
||||
origin_child_die = sibling_die (origin_child_die);
|
||||
}
|
||||
|
||||
do_cleanups (cleanups);
|
||||
}
|
||||
|
||||
static void
|
||||
read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||
{
|
||||
@ -3147,6 +3244,8 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
|
||||
}
|
||||
}
|
||||
|
||||
inherit_abstract_dies (die, cu);
|
||||
|
||||
new = pop_context ();
|
||||
/* Make a block for the local symbols within. */
|
||||
block = finish_block (new->name, &local_symbols, new->old_blocks,
|
||||
|
@ -1,3 +1,7 @@
|
||||
2009-04-27 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* gdb.cp/abstract-origin.exp, gdb.cp/abstract-origin.cc: New test.
|
||||
|
||||
2009-04-22 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* lib/gdb.exp (get_compiler_info): Use -E -o in remote-host case.
|
||||
|
42
gdb/testsuite/gdb.cp/abstract-origin.cc
Normal file
42
gdb/testsuite/gdb.cp/abstract-origin.cc
Normal file
@ -0,0 +1,42 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2009 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/>.
|
||||
*/
|
||||
|
||||
extern void f (int *);
|
||||
|
||||
class A
|
||||
{
|
||||
public:
|
||||
A(int i);
|
||||
};
|
||||
|
||||
A::A(int i)
|
||||
{
|
||||
static int *problem = new int(i);
|
||||
f (problem); /* break-here */
|
||||
}
|
||||
|
||||
void f (int *)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
A a(42);
|
||||
return 0;
|
||||
}
|
31
gdb/testsuite/gdb.cp/abstract-origin.exp
Normal file
31
gdb/testsuite/gdb.cp/abstract-origin.exp
Normal file
@ -0,0 +1,31 @@
|
||||
# Copyright 2009 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/>.
|
||||
|
||||
set testfile abstract-origin
|
||||
set srcfile ${testfile}.cc
|
||||
if [prepare_for_testing $testfile.exp $testfile $srcfile {debug c++}] {
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![runto_main] {
|
||||
untested abstract-origin
|
||||
return -1
|
||||
}
|
||||
|
||||
gdb_breakpoint [gdb_get_line_number "break-here"]
|
||||
gdb_continue_to_breakpoint "break-here"
|
||||
|
||||
# The Bug was: No symbol "problem" in current context.
|
||||
gdb_test "p problem" " = \\(int \\*\\) 0x.*"
|
Loading…
Reference in New Issue
Block a user