forked from Imagelibrary/binutils-gdb
PR symtab/18258
gdb/ChangeLog: * block.c (block_find_symbol): New function. (block_find_non_opaque_type): Ditto. (block_find_non_opaque_type_preferred): Ditto. * block.h (block_symbol_matcher_ftype): New typedef. (block_find_symbol): Declare. (block_find_non_opaque_type): Ditto. (block_find_non_opaque_type_preferred): Ditto. * dwarf2read.c (dw2_lookup_symbol): Call block_find_symbol. * psymtab.c (psym_lookup_symbol): Ditto. * symtab.c (basic_lookup_transparent_type_1): New function. (basic_lookup_transparent_type): Call it. gdb/testsuite/ChangeLog: * gdb.dwarf2/opaque-type-lookup-2.c: New file. * gdb.dwarf2/opaque-type-lookup.c: New file. * gdb.dwarf2/opaque-type-lookup.exp: New file.
This commit is contained in:
@@ -1,3 +1,18 @@
|
|||||||
|
2015-05-27 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
|
PR symtab/18258
|
||||||
|
* block.c (block_find_symbol): New function.
|
||||||
|
(block_find_non_opaque_type): Ditto.
|
||||||
|
(block_find_non_opaque_type_preferred): Ditto.
|
||||||
|
* block.h (block_symbol_matcher_ftype): New typedef.
|
||||||
|
(block_find_symbol): Declare.
|
||||||
|
(block_find_non_opaque_type): Ditto.
|
||||||
|
(block_find_non_opaque_type_preferred): Ditto.
|
||||||
|
* dwarf2read.c (dw2_lookup_symbol): Call block_find_symbol.
|
||||||
|
* psymtab.c (psym_lookup_symbol): Ditto.
|
||||||
|
* symtab.c (basic_lookup_transparent_type_1): New function.
|
||||||
|
(basic_lookup_transparent_type): Call it.
|
||||||
|
|
||||||
2015-05-27 Yao Qi <yao.qi@linaro.org>
|
2015-05-27 Yao Qi <yao.qi@linaro.org>
|
||||||
|
|
||||||
* aarch64-tdep.c (aarch64_record_data_proc_simd_fp): Return
|
* aarch64-tdep.c (aarch64_record_data_proc_simd_fp): Return
|
||||||
|
|||||||
47
gdb/block.c
47
gdb/block.c
@@ -797,3 +797,50 @@ block_lookup_symbol_primary (const struct block *block, const char *name,
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See block.h. */
|
||||||
|
|
||||||
|
struct symbol *
|
||||||
|
block_find_symbol (const struct block *block, const char *name,
|
||||||
|
const domain_enum domain,
|
||||||
|
block_symbol_matcher_ftype *matcher, void *data)
|
||||||
|
{
|
||||||
|
struct block_iterator iter;
|
||||||
|
struct symbol *sym;
|
||||||
|
|
||||||
|
/* Verify BLOCK is STATIC_BLOCK or GLOBAL_BLOCK. */
|
||||||
|
gdb_assert (BLOCK_SUPERBLOCK (block) == NULL
|
||||||
|
|| BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL);
|
||||||
|
|
||||||
|
ALL_BLOCK_SYMBOLS_WITH_NAME (block, name, iter, sym)
|
||||||
|
{
|
||||||
|
/* MATCHER is deliberately called second here so that it never sees
|
||||||
|
a non-domain-matching symbol. */
|
||||||
|
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
||||||
|
SYMBOL_DOMAIN (sym), domain)
|
||||||
|
&& matcher (sym, data))
|
||||||
|
return sym;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See block.h. */
|
||||||
|
|
||||||
|
int
|
||||||
|
block_find_non_opaque_type (struct symbol *sym, void *data)
|
||||||
|
{
|
||||||
|
return !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* See block.h. */
|
||||||
|
|
||||||
|
int
|
||||||
|
block_find_non_opaque_type_preferred (struct symbol *sym, void *data)
|
||||||
|
{
|
||||||
|
struct symbol **best = data;
|
||||||
|
|
||||||
|
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
|
||||||
|
return 1;
|
||||||
|
*best = sym;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
34
gdb/block.h
34
gdb/block.h
@@ -292,6 +292,40 @@ extern struct symbol *block_lookup_symbol_primary (const struct block *block,
|
|||||||
const char *name,
|
const char *name,
|
||||||
const domain_enum domain);
|
const domain_enum domain);
|
||||||
|
|
||||||
|
/* The type of the MATCHER argument to block_find_symbol. */
|
||||||
|
|
||||||
|
typedef int (block_symbol_matcher_ftype) (struct symbol *, void *);
|
||||||
|
|
||||||
|
/* Find symbol NAME in BLOCK and in DOMAIN that satisfies MATCHER.
|
||||||
|
DATA is passed unchanged to MATCHER.
|
||||||
|
BLOCK must be STATIC_BLOCK or GLOBAL_BLOCK. */
|
||||||
|
|
||||||
|
extern struct symbol *block_find_symbol (const struct block *block,
|
||||||
|
const char *name,
|
||||||
|
const domain_enum domain,
|
||||||
|
block_symbol_matcher_ftype *matcher,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/* A matcher function for block_find_symbol to find only symbols with
|
||||||
|
non-opaque types. */
|
||||||
|
|
||||||
|
extern int block_find_non_opaque_type (struct symbol *sym, void *data);
|
||||||
|
|
||||||
|
/* A matcher function for block_find_symbol to prefer symbols with
|
||||||
|
non-opaque types. The way to use this function is as follows:
|
||||||
|
|
||||||
|
struct symbol *with_opaque = NULL;
|
||||||
|
struct symbol *sym
|
||||||
|
= block_find_symbol (block, name, domain,
|
||||||
|
block_find_non_opaque_type_preferred, &with_opaque);
|
||||||
|
|
||||||
|
At this point if SYM is non-NULL then a non-opaque type has been found.
|
||||||
|
Otherwise, if WITH_OPAQUE is non-NULL then an opaque type has been found.
|
||||||
|
Otherwise, the symbol was not found. */
|
||||||
|
|
||||||
|
extern int block_find_non_opaque_type_preferred (struct symbol *sym,
|
||||||
|
void *data);
|
||||||
|
|
||||||
/* Macro to loop through all symbols in BLOCK, in no particular
|
/* Macro to loop through all symbols in BLOCK, in no particular
|
||||||
order. ITER helps keep track of the iteration, and must be a
|
order. ITER helps keep track of the iteration, and must be a
|
||||||
struct block_iterator. SYM points to the current symbol. */
|
struct block_iterator. SYM points to the current symbol. */
|
||||||
|
|||||||
@@ -3665,23 +3665,25 @@ dw2_lookup_symbol (struct objfile *objfile, int block_index,
|
|||||||
|
|
||||||
while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
|
while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
|
||||||
{
|
{
|
||||||
struct symbol *sym = NULL;
|
struct symbol *sym, *with_opaque = NULL;
|
||||||
struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu);
|
struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu);
|
||||||
const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
|
const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
|
||||||
struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
|
struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
|
||||||
|
|
||||||
|
sym = block_find_symbol (block, name, domain,
|
||||||
|
block_find_non_opaque_type_preferred,
|
||||||
|
&with_opaque);
|
||||||
|
|
||||||
/* Some caution must be observed with overloaded functions
|
/* Some caution must be observed with overloaded functions
|
||||||
and methods, since the index will not contain any overload
|
and methods, since the index will not contain any overload
|
||||||
information (but NAME might contain it). */
|
information (but NAME might contain it). */
|
||||||
sym = block_lookup_symbol (block, name, domain);
|
|
||||||
|
|
||||||
if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
|
if (sym != NULL
|
||||||
{
|
&& strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
|
||||||
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
|
return stab;
|
||||||
return stab;
|
if (with_opaque != NULL
|
||||||
|
&& strcmp_iw (SYMBOL_SEARCH_NAME (with_opaque), name) == 0)
|
||||||
stab_best = stab;
|
stab_best = stab;
|
||||||
}
|
|
||||||
|
|
||||||
/* Keep looking through other CUs. */
|
/* Keep looking through other CUs. */
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -516,7 +516,7 @@ psym_lookup_symbol (struct objfile *objfile,
|
|||||||
if (!ps->readin && lookup_partial_symbol (objfile, ps, name,
|
if (!ps->readin && lookup_partial_symbol (objfile, ps, name,
|
||||||
psymtab_index, domain))
|
psymtab_index, domain))
|
||||||
{
|
{
|
||||||
struct symbol *sym = NULL;
|
struct symbol *sym, *with_opaque = NULL;
|
||||||
struct compunit_symtab *stab = psymtab_to_symtab (objfile, ps);
|
struct compunit_symtab *stab = psymtab_to_symtab (objfile, ps);
|
||||||
/* Note: While psymtab_to_symtab can return NULL if the partial symtab
|
/* Note: While psymtab_to_symtab can return NULL if the partial symtab
|
||||||
is empty, we can assume it won't here because lookup_partial_symbol
|
is empty, we can assume it won't here because lookup_partial_symbol
|
||||||
@@ -524,18 +524,20 @@ psym_lookup_symbol (struct objfile *objfile,
|
|||||||
const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
|
const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
|
||||||
struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
|
struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
|
||||||
|
|
||||||
|
sym = block_find_symbol (block, name, domain,
|
||||||
|
block_find_non_opaque_type_preferred,
|
||||||
|
&with_opaque);
|
||||||
|
|
||||||
/* Some caution must be observed with overloaded functions
|
/* Some caution must be observed with overloaded functions
|
||||||
and methods, since the psymtab will not contain any overload
|
and methods, since the index will not contain any overload
|
||||||
information (but NAME might contain it). */
|
information (but NAME might contain it). */
|
||||||
sym = block_lookup_symbol (block, name, domain);
|
|
||||||
|
|
||||||
if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
|
if (sym != NULL
|
||||||
{
|
&& strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
|
||||||
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
|
return stab;
|
||||||
return stab;
|
if (with_opaque != NULL
|
||||||
|
&& strcmp_iw (SYMBOL_SEARCH_NAME (with_opaque), name) == 0)
|
||||||
stab_best = stab;
|
stab_best = stab;
|
||||||
}
|
|
||||||
|
|
||||||
/* Keep looking through other psymtabs. */
|
/* Keep looking through other psymtabs. */
|
||||||
}
|
}
|
||||||
|
|||||||
61
gdb/symtab.c
61
gdb/symtab.c
@@ -2804,12 +2804,39 @@ basic_lookup_transparent_type_quick (struct objfile *objfile, int block_index,
|
|||||||
|
|
||||||
bv = COMPUNIT_BLOCKVECTOR (cust);
|
bv = COMPUNIT_BLOCKVECTOR (cust);
|
||||||
block = BLOCKVECTOR_BLOCK (bv, block_index);
|
block = BLOCKVECTOR_BLOCK (bv, block_index);
|
||||||
sym = block_lookup_symbol (block, name, STRUCT_DOMAIN);
|
sym = block_find_symbol (block, name, STRUCT_DOMAIN,
|
||||||
if (!sym)
|
block_find_non_opaque_type, NULL);
|
||||||
|
if (sym == NULL)
|
||||||
error_in_psymtab_expansion (block_index, name, cust);
|
error_in_psymtab_expansion (block_index, name, cust);
|
||||||
|
gdb_assert (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)));
|
||||||
|
return SYMBOL_TYPE (sym);
|
||||||
|
}
|
||||||
|
|
||||||
if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
|
/* Subroutine of basic_lookup_transparent_type to simplify it.
|
||||||
return SYMBOL_TYPE (sym);
|
Look up the non-opaque definition of NAME in BLOCK_INDEX of OBJFILE.
|
||||||
|
BLOCK_INDEX is either GLOBAL_BLOCK or STATIC_BLOCK. */
|
||||||
|
|
||||||
|
static struct type *
|
||||||
|
basic_lookup_transparent_type_1 (struct objfile *objfile, int block_index,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
const struct compunit_symtab *cust;
|
||||||
|
const struct blockvector *bv;
|
||||||
|
const struct block *block;
|
||||||
|
const struct symbol *sym;
|
||||||
|
|
||||||
|
ALL_OBJFILE_COMPUNITS (objfile, cust)
|
||||||
|
{
|
||||||
|
bv = COMPUNIT_BLOCKVECTOR (cust);
|
||||||
|
block = BLOCKVECTOR_BLOCK (bv, block_index);
|
||||||
|
sym = block_find_symbol (block, name, STRUCT_DOMAIN,
|
||||||
|
block_find_non_opaque_type, NULL);
|
||||||
|
if (sym != NULL)
|
||||||
|
{
|
||||||
|
gdb_assert (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)));
|
||||||
|
return SYMBOL_TYPE (sym);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -2837,16 +2864,9 @@ basic_lookup_transparent_type (const char *name)
|
|||||||
|
|
||||||
ALL_OBJFILES (objfile)
|
ALL_OBJFILES (objfile)
|
||||||
{
|
{
|
||||||
ALL_OBJFILE_COMPUNITS (objfile, cust)
|
t = basic_lookup_transparent_type_1 (objfile, GLOBAL_BLOCK, name);
|
||||||
{
|
if (t)
|
||||||
bv = COMPUNIT_BLOCKVECTOR (cust);
|
return t;
|
||||||
block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
|
|
||||||
sym = block_lookup_symbol (block, name, STRUCT_DOMAIN);
|
|
||||||
if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
|
|
||||||
{
|
|
||||||
return SYMBOL_TYPE (sym);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ALL_OBJFILES (objfile)
|
ALL_OBJFILES (objfile)
|
||||||
@@ -2865,16 +2885,9 @@ basic_lookup_transparent_type (const char *name)
|
|||||||
|
|
||||||
ALL_OBJFILES (objfile)
|
ALL_OBJFILES (objfile)
|
||||||
{
|
{
|
||||||
ALL_OBJFILE_COMPUNITS (objfile, cust)
|
t = basic_lookup_transparent_type_1 (objfile, STATIC_BLOCK, name);
|
||||||
{
|
if (t)
|
||||||
bv = COMPUNIT_BLOCKVECTOR (cust);
|
return t;
|
||||||
block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
|
|
||||||
sym = block_lookup_symbol (block, name, STRUCT_DOMAIN);
|
|
||||||
if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
|
|
||||||
{
|
|
||||||
return SYMBOL_TYPE (sym);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ALL_OBJFILES (objfile)
|
ALL_OBJFILES (objfile)
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
2015-05-27 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
|
* gdb.dwarf2/opaque-type-lookup-2.c: New file.
|
||||||
|
* gdb.dwarf2/opaque-type-lookup.c: New file.
|
||||||
|
* gdb.dwarf2/opaque-type-lookup.exp: New file.
|
||||||
|
|
||||||
2015-05-26 Doug Evans <dje@google.com>
|
2015-05-26 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
* gdb.cp/iostream.cc: New file.
|
* gdb.cp/iostream.cc: New file.
|
||||||
|
|||||||
24
gdb/testsuite/gdb.dwarf2/opaque-type-lookup-2.c
Normal file
24
gdb/testsuite/gdb.dwarf2/opaque-type-lookup-2.c
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2015 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/>. */
|
||||||
|
|
||||||
|
/* These are actually struct struct_{a,b}, but that's handled by the dwarf
|
||||||
|
in opaque-type-lookup.exp.
|
||||||
|
IWBN to give these a different name than what's in the dwarf so that minsym
|
||||||
|
lookup doesn't interfere with the testing. However, that currently doesn't
|
||||||
|
work (we don't record the linkage name of the symbol). */
|
||||||
|
char variable_a = 'a';
|
||||||
|
char variable_b = 'b';
|
||||||
23
gdb/testsuite/gdb.dwarf2/opaque-type-lookup.c
Normal file
23
gdb/testsuite/gdb.dwarf2/opaque-type-lookup.c
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/* This testcase is part of GDB, the GNU debugger.
|
||||||
|
|
||||||
|
Copyright 2015 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/>. */
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
asm ("main_label: .globl main_label");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
200
gdb/testsuite/gdb.dwarf2/opaque-type-lookup.exp
Normal file
200
gdb/testsuite/gdb.dwarf2/opaque-type-lookup.exp
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
# Copyright 2013-2015 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 PR 18258.
|
||||||
|
|
||||||
|
load_lib dwarf.exp
|
||||||
|
|
||||||
|
# This test can only be run on targets which support DWARF-2 and use gas.
|
||||||
|
if {![dwarf2_support]} {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
standard_testfile opaque-type-lookup.c opaque-type-lookup-1.S opaque-type-lookup-2.c
|
||||||
|
|
||||||
|
# Create the DWARF.
|
||||||
|
set asm_file [standard_output_file $srcfile2]
|
||||||
|
Dwarf::assemble $asm_file {
|
||||||
|
declare_labels partial_unit_defining_a partial_unit_defining_b
|
||||||
|
declare_labels partial_unit_with_opaque
|
||||||
|
declare_labels struct_a_label struct_b_label
|
||||||
|
declare_labels opaque_struct_a_label opaque_struct_b_label
|
||||||
|
declare_labels char_type1_label char_type2_label
|
||||||
|
global srcdir subdir srcfile
|
||||||
|
|
||||||
|
extern main
|
||||||
|
|
||||||
|
# The partial units are laid out so we're not dependent on the order that
|
||||||
|
# they appear in compunit_symtab.includes. We need the one with the
|
||||||
|
# opaque definition to appear first to gdb, so we put it in the middle.
|
||||||
|
# Either the handling of variable_a or variable_b will be broken (in an
|
||||||
|
# unpatched gdb).
|
||||||
|
#
|
||||||
|
# However, once a partial unit with a non-opaque type is read in we can
|
||||||
|
# no longer see the bug as gdb will keep looking until it eventually gets
|
||||||
|
# to the defining partial unit, setting aside the symbol lookup cache.
|
||||||
|
# So heads up!
|
||||||
|
|
||||||
|
cu {} {
|
||||||
|
compile_unit {
|
||||||
|
{language @DW_LANG_C}
|
||||||
|
{name opaque_before}
|
||||||
|
} {
|
||||||
|
imported_unit {
|
||||||
|
{import $partial_unit_with_opaque ref_addr}
|
||||||
|
}
|
||||||
|
|
||||||
|
imported_unit {
|
||||||
|
{import $partial_unit_defining_a ref_addr}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cu {} {
|
||||||
|
compile_unit {
|
||||||
|
{language @DW_LANG_C}
|
||||||
|
{name opaque_after}
|
||||||
|
} {
|
||||||
|
imported_unit {
|
||||||
|
{import $partial_unit_defining_b ref_addr}
|
||||||
|
}
|
||||||
|
|
||||||
|
imported_unit {
|
||||||
|
{import $partial_unit_with_opaque ref_addr}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cu {} {
|
||||||
|
partial_unit_with_opaque: partial_unit {
|
||||||
|
{name "partial_unit_with_opaque"}
|
||||||
|
} {
|
||||||
|
# Normally gdb doesn't add opaque types to the symbol table
|
||||||
|
# but there are times when it will, and in order to exercise
|
||||||
|
# this bug we need this entry in the symbol table.
|
||||||
|
# By giving it a size of 1 we achieve this.
|
||||||
|
|
||||||
|
opaque_struct_a_label: structure_type {
|
||||||
|
{name struct_a}
|
||||||
|
{declaration 1 flag}
|
||||||
|
{byte_size 1 DW_FORM_sdata}
|
||||||
|
}
|
||||||
|
|
||||||
|
opaque_struct_b_label: structure_type {
|
||||||
|
{name struct_b}
|
||||||
|
{declaration 1 flag}
|
||||||
|
{byte_size 1 DW_FORM_sdata}
|
||||||
|
}
|
||||||
|
|
||||||
|
DW_TAG_variable {
|
||||||
|
{name variable_a}
|
||||||
|
{type :$opaque_struct_a_label}
|
||||||
|
{external 1 flag}
|
||||||
|
{declaration 1 flag}
|
||||||
|
}
|
||||||
|
|
||||||
|
DW_TAG_variable {
|
||||||
|
{name variable_b}
|
||||||
|
{type :$opaque_struct_b_label}
|
||||||
|
{external 1 flag}
|
||||||
|
{declaration 1 flag}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cu {} {
|
||||||
|
partial_unit_defining_a: partial_unit {
|
||||||
|
{name "partial_unit_defining_a"}
|
||||||
|
} {
|
||||||
|
char_type1_label: base_type {
|
||||||
|
{name "signed char"}
|
||||||
|
{encoding @DW_ATE_signed}
|
||||||
|
{byte_size 1 DW_FORM_sdata}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct_a_label: structure_type {
|
||||||
|
{name struct_a}
|
||||||
|
{byte_size 1 DW_FORM_sdata}
|
||||||
|
} {
|
||||||
|
member {
|
||||||
|
{name xyz}
|
||||||
|
{type :$char_type1_label}
|
||||||
|
{data_member_location 0 DW_FORM_sdata}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DW_TAG_variable {
|
||||||
|
{name variable_a}
|
||||||
|
{type :$struct_a_label}
|
||||||
|
{external 1 flag}
|
||||||
|
{linkage_name variable_a}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cu {} {
|
||||||
|
partial_unit_defining_b: partial_unit {
|
||||||
|
{name "partial_unit_defining_b"}
|
||||||
|
} {
|
||||||
|
char_type2_label: base_type {
|
||||||
|
{name "signed char"}
|
||||||
|
{encoding @DW_ATE_signed}
|
||||||
|
{byte_size 1 DW_FORM_sdata}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct_b_label: structure_type {
|
||||||
|
{name struct_b}
|
||||||
|
{byte_size 1 DW_FORM_sdata}
|
||||||
|
} {
|
||||||
|
member {
|
||||||
|
{name xyz}
|
||||||
|
{type :$char_type2_label}
|
||||||
|
{data_member_location 0 DW_FORM_sdata}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DW_TAG_variable {
|
||||||
|
{name variable_b}
|
||||||
|
{type :$struct_b_label}
|
||||||
|
{external 1 flag}
|
||||||
|
{linkage_name variable_b}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# GDB expands the symbol table with main at start up,
|
||||||
|
# so keep this separate.
|
||||||
|
cu {} {
|
||||||
|
compile_unit {
|
||||||
|
{language @DW_LANG_C}
|
||||||
|
{name main}
|
||||||
|
} {
|
||||||
|
subprogram {
|
||||||
|
{MACRO_AT_func { main ${srcdir}/${subdir}/${srcfile} }}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if [prepare_for_testing ${testfile}.exp $testfile "${asm_file} ${srcfile} ${srcfile3}" {nodebug}] {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ![runto_main] {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_test "p variable_a" " = {xyz = 97 'a'}"
|
||||||
|
gdb_test "p variable_b" " = {xyz = 98 'b'}"
|
||||||
Reference in New Issue
Block a user