Patchwork [RFA/RFC] fix PR gdb/22670 (pb looking up some symbols when they have a linkage name) (was: "Re: [RFC] regresssion(internal-error) printing subprogram argument")

login
register
mail settings
Submitter Joel Brobecker
Date Feb. 9, 2018, 9:09 a.m.
Message ID <20180209090919.lmwjll72hccopjsk@adacore.com>
Download mbox | patch
Permalink /patch/25882/
State New
Headers show

Comments

Joel Brobecker - Feb. 9, 2018, 9:09 a.m.
> All in all, I think a better solution would be to put that information
> directly in the language_defn itself, via a new "attribute".
> Something like a...

I ended up choosing this approach. lookup names is still a bit
foggy for me, so the comments I wrote and/or the name of the
new language_defn attribute might be a bit off. As always, I am
grateful for suggestions :).

gdb/ChangeLog:

        PR gdb/22670
        * dwarf2read.c (dwarf2_physname): Do not return the demangled
        symbol name is the CU's language stores symbol names in linkage
        format.
        * language.h (struct language_defn)
        <la_store_sym_names_in_linkage_form_p>: New field.  Adjust
        all instances of this struct.

gdb/testsuite/ChangeLog:

        * gdb.ada/maint_with_ada.exp: Remove PR gdb/22670 setup_kfail.

        * gdb.ada/notcplusplus: New testcase.

        * gdb.base/c-linkage-name.c: New file.
        * gdb.base/c-linkage-name.exp: New testcase.

Tested on x86_64-linux.
This also passes AdaCore's internal GDB testsuite.

OK to commit?

Thank you!
Joel Brobecker - Feb. 21, 2018, 3:02 a.m.
> > All in all, I think a better solution would be to put that information
> > directly in the language_defn itself, via a new "attribute".
> > Something like a...
> 
> I ended up choosing this approach. lookup names is still a bit
> foggy for me, so the comments I wrote and/or the name of the
> new language_defn attribute might be a bit off. As always, I am
> grateful for suggestions :).
> 
> gdb/ChangeLog:
> 
>         PR gdb/22670
>         * dwarf2read.c (dwarf2_physname): Do not return the demangled
>         symbol name is the CU's language stores symbol names in linkage
>         format.
>         * language.h (struct language_defn)
>         <la_store_sym_names_in_linkage_form_p>: New field.  Adjust
>         all instances of this struct.
> 
> gdb/testsuite/ChangeLog:
> 
>         * gdb.ada/maint_with_ada.exp: Remove PR gdb/22670 setup_kfail.
> 
>         * gdb.ada/notcplusplus: New testcase.
> 
>         * gdb.base/c-linkage-name.c: New file.
>         * gdb.base/c-linkage-name.exp: New testcase.
> 
> Tested on x86_64-linux.
> This also passes AdaCore's internal GDB testsuite.

Any comment on this patch?

Thanks!

> >From c22aef84cc86097d6d8b654b0586a3fbc1ff6af3 Mon Sep 17 00:00:00 2001
> From: Joel Brobecker <brobecker@adacore.com>
> Date: Fri, 9 Feb 2018 02:13:34 -0500
> Subject: [PATCH] problem looking up some symbols when they have a linkage name
> 
> This patch fixes a known failure in gdb.ada/maint_with_ada.exp
> (maintenance check-psymtabs). Another way to witness the same
> issue is by considering the following Ada declarations...
> 
>    type Wrapper is record
>       A : Integer;
>    end record;
>    u00045 : constant Wrapper := (A => 16#060287af#);
>    pragma Export (C, u00045, "symada__cS");
> 
> ... which declares a variable name "u00045" but with a linkage
> name which is "symada__cS". This variable is a record with one
> component, the Ada equivalent of a struct with one field in C.
> Trying to print that variable's value currently yields:
> 
>     (gdb) p /x <symada__cS>
>     'symada(char, signed)' has unknown type; cast it to its declared type
> 
> This indicates that GDB was only able to find the minimal symbol,
> but not the full symbol. The expected output is:
> 
>     (gdb) print /x <symada__cS>
>     $1 = (a => 0x60287af)
> 
> The error message gives a hint about what's happening: We processed
> the symbol through gdb_demangle, which in the case of this particular
> symbol name, ends up matching the C++ naming scheme. As a result,
> the demangler transforms our symbol name into 'symada(char, signed)',
> thus breaking Ada lookups.
> 
> This patch fixes the issue by first introducing a new language_defn
> attribute called la_store_sym_names_in_linkage_form_p, which is a boolean
> to be set to true for the few languages that do not want their symbols
> to have their names stored in demangled form, and false otherwise.
> We then use this language attribute to skip the call to gdb_demangle
> for all languages whose la_store_sym_names_in_linkage_form_p is true.
> 
> In terms of the selection of languages for which the new attribute
> is set to true, the selection errs on the side of preserving the
> existing behavior, and only changes the behavior for the languages
> where we are certain storing symbol names in demangling form is not
> needed. It is conceivable that other languages might be in the same
> situation, but I not knowing in detail the symbol name enconding
> strategy, I decided to play it safe and let other language maintainers
> potentially adjust their language if it makes sense to do so.
> 
> gdb/ChangeLog:
> 
>         PR gdb/22670
>         * dwarf2read.c (dwarf2_physname): Do not return the demangled
>         symbol name is the CU's language stores symbol names in linkage
>         format.
>         * language.h (struct language_defn)
>         <la_store_sym_names_in_linkage_form_p>: New field.  Adjust
>         all instances of this struct.
> 
> gdb/testsuite/ChangeLog:
> 
>         * gdb.ada/maint_with_ada.exp: Remove PR gdb/22670 setup_kfail.
> 
>         * gdb.ada/notcplusplus: New testcase.
> 
>         * gdb.base/c-linkage-name.c: New file.
>         * gdb.base/c-linkage-name.exp: New testcase.
> 
> Tested on x86_64-linux.
> This also passes AdaCore's internal GDB testsuite.
> ---
>  gdb/ada-lang.c                             |  1 +
>  gdb/c-lang.c                               |  4 +++
>  gdb/d-lang.c                               |  1 +
>  gdb/dwarf2read.c                           |  6 +++-
>  gdb/f-lang.c                               |  1 +
>  gdb/go-lang.c                              |  1 +
>  gdb/language.c                             |  2 ++
>  gdb/language.h                             | 20 +++++++++++++
>  gdb/m2-lang.c                              |  1 +
>  gdb/objc-lang.c                            |  1 +
>  gdb/opencl-lang.c                          |  1 +
>  gdb/p-lang.c                               |  1 +
>  gdb/rust-lang.c                            |  1 +
>  gdb/testsuite/gdb.ada/maint_with_ada.exp   |  1 -
>  gdb/testsuite/gdb.ada/notcplusplus.exp     | 45 ++++++++++++++++++++++++++++
>  gdb/testsuite/gdb.ada/notcplusplus/foo.adb | 21 +++++++++++++
>  gdb/testsuite/gdb.ada/notcplusplus/pck.adb | 21 +++++++++++++
>  gdb/testsuite/gdb.ada/notcplusplus/pck.ads | 19 ++++++++++++
>  gdb/testsuite/gdb.ada/notcplusplus/ver.ads | 22 ++++++++++++++
>  gdb/testsuite/gdb.base/c-linkage-name.c    | 44 ++++++++++++++++++++++++++++
>  gdb/testsuite/gdb.base/c-linkage-name.exp  | 47 ++++++++++++++++++++++++++++++
>  21 files changed, 259 insertions(+), 2 deletions(-)
>  create mode 100644 gdb/testsuite/gdb.ada/notcplusplus.exp
>  create mode 100644 gdb/testsuite/gdb.ada/notcplusplus/foo.adb
>  create mode 100644 gdb/testsuite/gdb.ada/notcplusplus/pck.adb
>  create mode 100644 gdb/testsuite/gdb.ada/notcplusplus/pck.ads
>  create mode 100644 gdb/testsuite/gdb.ada/notcplusplus/ver.ads
>  create mode 100644 gdb/testsuite/gdb.base/c-linkage-name.c
>  create mode 100644 gdb/testsuite/gdb.base/c-linkage-name.exp
> 
> diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
> index 0da58d9..7f99a2e 100644
> --- a/gdb/ada-lang.c
> +++ b/gdb/ada-lang.c
> @@ -14521,6 +14521,7 @@ extern const struct language_defn ada_language_defn = {
>    ada_read_var_value,		/* la_read_var_value */
>    NULL,                         /* Language specific skip_trampoline */
>    NULL,                         /* name_of_this */
> +  true,                         /* la_store_sym_names_in_linkage_form_p */
>    ada_lookup_symbol_nonlocal,   /* Looking up non-local symbols.  */
>    basic_lookup_transparent_type,        /* lookup_transparent_type */
>    ada_la_decode,                /* Language specific symbol demangler */
> diff --git a/gdb/c-lang.c b/gdb/c-lang.c
> index a0b553e..658c7f7 100644
> --- a/gdb/c-lang.c
> +++ b/gdb/c-lang.c
> @@ -853,6 +853,7 @@ extern const struct language_defn c_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    NULL,				/* Language specific skip_trampoline */
>    NULL,				/* name_of_this */
> +  true,				/* la_store_sym_names_in_linkage_form_p */
>    basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
>    basic_lookup_transparent_type,/* lookup_transparent_type */
>    NULL,				/* Language specific symbol demangler */
> @@ -998,6 +999,7 @@ extern const struct language_defn cplus_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    cplus_skip_trampoline,	/* Language specific skip_trampoline */
>    "this",                       /* name_of_this */
> +  false,			/* la_store_sym_names_in_linkage_form_p */
>    cp_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
>    cp_lookup_transparent_type,   /* lookup_transparent_type */
>    gdb_demangle,			/* Language specific symbol demangler */
> @@ -1052,6 +1054,7 @@ extern const struct language_defn asm_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    NULL,				/* Language specific skip_trampoline */
>    NULL,				/* name_of_this */
> +  true,				/* la_store_sym_names_in_linkage_form_p */
>    basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
>    basic_lookup_transparent_type,/* lookup_transparent_type */
>    NULL,				/* Language specific symbol demangler */
> @@ -1106,6 +1109,7 @@ extern const struct language_defn minimal_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    NULL,				/* Language specific skip_trampoline */
>    NULL,				/* name_of_this */
> +  true,				/* la_store_sym_names_in_linkage_form_p */
>    basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
>    basic_lookup_transparent_type,/* lookup_transparent_type */
>    NULL,				/* Language specific symbol demangler */
> diff --git a/gdb/d-lang.c b/gdb/d-lang.c
> index e0afe48..688ae98 100644
> --- a/gdb/d-lang.c
> +++ b/gdb/d-lang.c
> @@ -229,6 +229,7 @@ extern const struct language_defn d_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    NULL,				/* Language specific skip_trampoline.  */
>    "this",
> +  false,			/* la_store_sym_names_in_linkage_form_p */
>    d_lookup_symbol_nonlocal,
>    basic_lookup_transparent_type,
>    d_demangle,			/* Language specific symbol demangler.  */
> diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
> index d651725..b4c087f 100644
> --- a/gdb/dwarf2read.c
> +++ b/gdb/dwarf2read.c
> @@ -11142,7 +11142,11 @@ dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
>    if (mangled != NULL)
>      {
>  
> -      if (cu->language == language_go)
> +      if (language_def (cu->language)->la_store_sym_names_in_linkage_form_p)
> +	{
> +	  /* Do nothing (do not demangle the symbol name).  */
> +	}
> +      else if (cu->language == language_go)
>  	{
>  	  /* This is a lie, but we already lie to the caller new_symbol.
>  	     new_symbol assumes we return the mangled name.
> diff --git a/gdb/f-lang.c b/gdb/f-lang.c
> index 74f5622..81922f7 100644
> --- a/gdb/f-lang.c
> +++ b/gdb/f-lang.c
> @@ -269,6 +269,7 @@ extern const struct language_defn f_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    NULL,				/* Language specific skip_trampoline */
>    NULL,                    	/* name_of_this */
> +  false,			/* la_store_sym_names_in_linkage_form_p */
>    cp_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
>    basic_lookup_transparent_type,/* lookup_transparent_type */
>  
> diff --git a/gdb/go-lang.c b/gdb/go-lang.c
> index 022b8de..e9cba77 100644
> --- a/gdb/go-lang.c
> +++ b/gdb/go-lang.c
> @@ -590,6 +590,7 @@ extern const struct language_defn go_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    NULL,				/* Language specific skip_trampoline.  */
>    NULL,				/* name_of_this */
> +  false,			/* la_store_sym_names_in_linkage_form_p */
>    basic_lookup_symbol_nonlocal, 
>    basic_lookup_transparent_type,
>    go_demangle,			/* Language specific symbol demangler.  */
> diff --git a/gdb/language.c b/gdb/language.c
> index 0d8604b..22199e0 100644
> --- a/gdb/language.c
> +++ b/gdb/language.c
> @@ -864,6 +864,7 @@ const struct language_defn unknown_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    unk_lang_trampoline,		/* Language specific skip_trampoline */
>    "this",        	    	/* name_of_this */
> +  true,				/* store_sym_names_in_linkage_form_p */
>    basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
>    basic_lookup_transparent_type,/* lookup_transparent_type */
>    unk_lang_demangle,		/* Language specific symbol demangler */
> @@ -915,6 +916,7 @@ const struct language_defn auto_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    unk_lang_trampoline,		/* Language specific skip_trampoline */
>    "this",		        /* name_of_this */
> +  false,			/* store_sym_names_in_linkage_form_p */
>    basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
>    basic_lookup_transparent_type,/* lookup_transparent_type */
>    unk_lang_demangle,		/* Language specific symbol demangler */
> diff --git a/gdb/language.h b/gdb/language.h
> index 06b42ae..029de4a 100644
> --- a/gdb/language.h
> +++ b/gdb/language.h
> @@ -264,6 +264,26 @@ struct language_defn
>  
>      const char *la_name_of_this;
>  
> +    /* True if the symbols names should be stored in GDB's data structures
> +       for minimal/partial/full symbols using their linkage (aka mangled)
> +       form; false if the symbol names should be demangled first.
> +
> +       Most languages implement symbol lookup by comparing the demangled
> +       names, in which case it is advantageous to store that information
> +       already demangled, and so would set this field to false.
> +
> +       On the other hand, some languages have opted for doing symbol
> +       lookups by comparing mangled names instead, for reasons usually
> +       specific to the language.  Those languages should set this field
> +       to true.
> +
> +       And finally, other languages such as C or Asm do not have
> +       the concept of mangled vs demangled name, so those languages
> +       should set this field to true as well, to prevent any accidental
> +       demangling through an unrelated language's demangler.  */
> +
> +    const bool la_store_sym_names_in_linkage_form_p;
> +
>      /* This is a function that lookup_symbol will call when it gets to
>         the part of symbol lookup where C looks up static and global
>         variables.  */
> diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
> index 11ccab3..6e6434b 100644
> --- a/gdb/m2-lang.c
> +++ b/gdb/m2-lang.c
> @@ -377,6 +377,7 @@ extern const struct language_defn m2_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    NULL,				/* Language specific skip_trampoline */
>    NULL,		                /* name_of_this */
> +  false,			/* la_store_sym_names_in_linkage_form_p */
>    basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
>    basic_lookup_transparent_type,/* lookup_transparent_type */
>    NULL,				/* Language specific symbol demangler */
> diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
> index c714ec3..4f7dc36 100644
> --- a/gdb/objc-lang.c
> +++ b/gdb/objc-lang.c
> @@ -389,6 +389,7 @@ extern const struct language_defn objc_language_defn = {
>    default_read_var_value,	/* la_read_var_value */
>    objc_skip_trampoline, 	/* Language specific skip_trampoline */
>    "self",		        /* name_of_this */
> +  false,			/* la_store_sym_names_in_linkage_form_p */
>    basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
>    basic_lookup_transparent_type,/* lookup_transparent_type */
>    objc_demangle,		/* Language specific symbol demangler */
> diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c
> index 268c3c5..9c5b90c 100644
> --- a/gdb/opencl-lang.c
> +++ b/gdb/opencl-lang.c
> @@ -1065,6 +1065,7 @@ extern const struct language_defn opencl_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    NULL,				/* Language specific skip_trampoline */
>    NULL,                         /* name_of_this */
> +  false,			/* la_store_sym_names_in_linkage_form_p */
>    basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
>    basic_lookup_transparent_type,/* lookup_transparent_type */
>    NULL,				/* Language specific symbol demangler */
> diff --git a/gdb/p-lang.c b/gdb/p-lang.c
> index 03db2df..3ff7f56 100644
> --- a/gdb/p-lang.c
> +++ b/gdb/p-lang.c
> @@ -439,6 +439,7 @@ extern const struct language_defn pascal_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    NULL,				/* Language specific skip_trampoline */
>    "this",		        /* name_of_this */
> +  false,			/* la_store_sym_names_in_linkage_form_p */
>    basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
>    basic_lookup_transparent_type,/* lookup_transparent_type */
>    NULL,				/* Language specific symbol demangler */
> diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
> index 5ff80b2..2d7c1f7 100644
> --- a/gdb/rust-lang.c
> +++ b/gdb/rust-lang.c
> @@ -2290,6 +2290,7 @@ extern const struct language_defn rust_language_defn =
>    default_read_var_value,	/* la_read_var_value */
>    NULL,				/* Language specific skip_trampoline */
>    NULL,				/* name_of_this */
> +  false,			/* la_store_sym_names_in_linkage_form_p */
>    rust_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
>    basic_lookup_transparent_type,/* lookup_transparent_type */
>    gdb_demangle,			/* Language specific symbol demangler */
> diff --git a/gdb/testsuite/gdb.ada/maint_with_ada.exp b/gdb/testsuite/gdb.ada/maint_with_ada.exp
> index 73da613..9ede035 100644
> --- a/gdb/testsuite/gdb.ada/maint_with_ada.exp
> +++ b/gdb/testsuite/gdb.ada/maint_with_ada.exp
> @@ -32,7 +32,6 @@ gdb_breakpoint "adainit"
>  gdb_breakpoint "Var_Arr_Typedef"
>  gdb_breakpoint "Do_Nothing"
>  
> -setup_kfail gdb/22670 "*-*-*"
>  gdb_test_no_output "maintenance check-psymtabs"
>  
>  gdb_test_no_output "maintenance check-symtabs"
> diff --git a/gdb/testsuite/gdb.ada/notcplusplus.exp b/gdb/testsuite/gdb.ada/notcplusplus.exp
> new file mode 100644
> index 0000000..b2a24e8
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ada/notcplusplus.exp
> @@ -0,0 +1,45 @@
> +# Copyright 2018 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/>.
> +
> +load_lib "ada.exp"
> +
> +if { [skip_ada_tests] } { return -1 }
> +
> +standard_ada_testfile foo
> +
> +if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} {
> +    return -1
> +}
> +
> +clean_restart ${testfile}
> +
> +gdb_test "print /x <symada__cS>" \
> +         "= \\(a => 0x60287af\\)" \
> +         "print <symada__cS> before loading symbols from ver.ads"
> +
> +# Force the partial symbosl from ver.ads to be expanded into full symbols.
> +
> +gdb_test \
> +     "list ver.ads:16" \
> +     [multi_line ".*" \
> +                 "16\\s+package Ver is" \
> +                 "17\\s+type Wrapper is record" \
> +                 "18\\s+A : Integer;" \
> +                 "19\\s+end record;" \
> +                 "20\\s+u00045 : constant Wrapper := \\(A => 16#060287af#\\);"]
> +
> +gdb_test "print /x <symada__cS>" \
> +         "= \\(a => 0x60287af\\)" \
> +         "print <symada__cS> after loading symbols from ver.ads"
> diff --git a/gdb/testsuite/gdb.ada/notcplusplus/foo.adb b/gdb/testsuite/gdb.ada/notcplusplus/foo.adb
> new file mode 100644
> index 0000000..89e42f9
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ada/notcplusplus/foo.adb
> @@ -0,0 +1,21 @@
> +--  Copyright 2018 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/>.
> +
> +with Pck; use Pck;
> +with Ver; use Ver;
> +procedure Foo is
> +begin
> +   Do_Nothing (u00045'Address);
> +end Foo;
> diff --git a/gdb/testsuite/gdb.ada/notcplusplus/pck.adb b/gdb/testsuite/gdb.ada/notcplusplus/pck.adb
> new file mode 100644
> index 0000000..dcfb306
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ada/notcplusplus/pck.adb
> @@ -0,0 +1,21 @@
> +--  Copyright 2018 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/>.
> +
> +package body Pck is
> +   procedure Do_Nothing (A : System.Address) is
> +   begin
> +      null;
> +   end Do_Nothing;
> +end Pck;
> diff --git a/gdb/testsuite/gdb.ada/notcplusplus/pck.ads b/gdb/testsuite/gdb.ada/notcplusplus/pck.ads
> new file mode 100644
> index 0000000..33e369e
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ada/notcplusplus/pck.ads
> @@ -0,0 +1,19 @@
> +--  Copyright 2018 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/>.
> +
> +with System;
> +package Pck is
> +   procedure Do_Nothing (A : System.Address);
> +end Pck;
> diff --git a/gdb/testsuite/gdb.ada/notcplusplus/ver.ads b/gdb/testsuite/gdb.ada/notcplusplus/ver.ads
> new file mode 100644
> index 0000000..8f264d0
> --- /dev/null
> +++ b/gdb/testsuite/gdb.ada/notcplusplus/ver.ads
> @@ -0,0 +1,22 @@
> +--  Copyright 2018 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/>.
> +
> +package Ver is
> +   type Wrapper is record
> +      A : Integer;
> +   end record;
> +   u00045 : constant Wrapper := (A => 16#060287af#);
> +   pragma Export (C, u00045, "symada__cS");
> +end Ver;
> diff --git a/gdb/testsuite/gdb.base/c-linkage-name.c b/gdb/testsuite/gdb.base/c-linkage-name.c
> new file mode 100644
> index 0000000..925004c
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/c-linkage-name.c
> @@ -0,0 +1,44 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> +   Copyright 2018 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/>.  */
> +
> +struct wrapper
> +{
> +  int a;
> +};
> +
> +/* Create a global variable whose name in the assembly code
> +   (aka the "linkage name") is different from the name in
> +   the source code.  The goal is to create a symbol described
> +   in DWARF using a DW_AT_linkage_name attribute, with a name
> +   which follows the C++ mangling.
> +
> +   In this particular case, we chose "symada__cS" which, if it were
> +   demangled, would translate to "symada (char, signed)".  */
> +struct wrapper mundane asm ("symada__cS") = {0x060287af};
> +
> +void
> +do_something (struct wrapper *w)
> +{
> +  w->a++;
> +}
> +
> +int
> +main (void)
> +{
> +  do_something (&mundane);
> +  return 0;
> +}
> diff --git a/gdb/testsuite/gdb.base/c-linkage-name.exp b/gdb/testsuite/gdb.base/c-linkage-name.exp
> new file mode 100644
> index 0000000..c80a530
> --- /dev/null
> +++ b/gdb/testsuite/gdb.base/c-linkage-name.exp
> @@ -0,0 +1,47 @@
> +# Copyright 2018 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/>.
> +
> +# This file is part of the gdb testsuite.  It is intended to test that
> +# gdb can correctly print arrays with indexes for each element of the
> +# array.
> +
> +standard_testfile .c
> +
> +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
> +    untested "failed to compile"
> +    return -1
> +}
> +
> +clean_restart ${binfile}
> +
> +# Try to print MUNDANE, but using its linkage name.
> +
> +gdb_test "print symada__cS" \
> +         " = {a = 100829103}" \
> +         "print symada__cS before partial symtab expansion"
> +
> +# Force the symbols to be expanded for the unit that contains
> +# our symada__cS symbol by, e.g. inserting a breakpoint on one
> +# of the founction also provided by the same using.
> +
> +gdb_test "break main" \
> +         "Breakpoint $decimal at $hex: file .*$srcfile, line $decimal\\."
> +
> +# Try to print MUNDANE using its linkage name again, after partial
> +# symtab expansion.
> +
> +gdb_test "print symada__cS" \
> +         " = {a = 100829103}" \
> +         "print symada__cS after partial symtab expansion"
> -- 
> 2.1.4
>

Patch

From c22aef84cc86097d6d8b654b0586a3fbc1ff6af3 Mon Sep 17 00:00:00 2001
From: Joel Brobecker <brobecker@adacore.com>
Date: Fri, 9 Feb 2018 02:13:34 -0500
Subject: [PATCH] problem looking up some symbols when they have a linkage name

This patch fixes a known failure in gdb.ada/maint_with_ada.exp
(maintenance check-psymtabs). Another way to witness the same
issue is by considering the following Ada declarations...

   type Wrapper is record
      A : Integer;
   end record;
   u00045 : constant Wrapper := (A => 16#060287af#);
   pragma Export (C, u00045, "symada__cS");

... which declares a variable name "u00045" but with a linkage
name which is "symada__cS". This variable is a record with one
component, the Ada equivalent of a struct with one field in C.
Trying to print that variable's value currently yields:

    (gdb) p /x <symada__cS>
    'symada(char, signed)' has unknown type; cast it to its declared type

This indicates that GDB was only able to find the minimal symbol,
but not the full symbol. The expected output is:

    (gdb) print /x <symada__cS>
    $1 = (a => 0x60287af)

The error message gives a hint about what's happening: We processed
the symbol through gdb_demangle, which in the case of this particular
symbol name, ends up matching the C++ naming scheme. As a result,
the demangler transforms our symbol name into 'symada(char, signed)',
thus breaking Ada lookups.

This patch fixes the issue by first introducing a new language_defn
attribute called la_store_sym_names_in_linkage_form_p, which is a boolean
to be set to true for the few languages that do not want their symbols
to have their names stored in demangled form, and false otherwise.
We then use this language attribute to skip the call to gdb_demangle
for all languages whose la_store_sym_names_in_linkage_form_p is true.

In terms of the selection of languages for which the new attribute
is set to true, the selection errs on the side of preserving the
existing behavior, and only changes the behavior for the languages
where we are certain storing symbol names in demangling form is not
needed. It is conceivable that other languages might be in the same
situation, but I not knowing in detail the symbol name enconding
strategy, I decided to play it safe and let other language maintainers
potentially adjust their language if it makes sense to do so.

gdb/ChangeLog:

        PR gdb/22670
        * dwarf2read.c (dwarf2_physname): Do not return the demangled
        symbol name is the CU's language stores symbol names in linkage
        format.
        * language.h (struct language_defn)
        <la_store_sym_names_in_linkage_form_p>: New field.  Adjust
        all instances of this struct.

gdb/testsuite/ChangeLog:

        * gdb.ada/maint_with_ada.exp: Remove PR gdb/22670 setup_kfail.

        * gdb.ada/notcplusplus: New testcase.

        * gdb.base/c-linkage-name.c: New file.
        * gdb.base/c-linkage-name.exp: New testcase.

Tested on x86_64-linux.
This also passes AdaCore's internal GDB testsuite.
---
 gdb/ada-lang.c                             |  1 +
 gdb/c-lang.c                               |  4 +++
 gdb/d-lang.c                               |  1 +
 gdb/dwarf2read.c                           |  6 +++-
 gdb/f-lang.c                               |  1 +
 gdb/go-lang.c                              |  1 +
 gdb/language.c                             |  2 ++
 gdb/language.h                             | 20 +++++++++++++
 gdb/m2-lang.c                              |  1 +
 gdb/objc-lang.c                            |  1 +
 gdb/opencl-lang.c                          |  1 +
 gdb/p-lang.c                               |  1 +
 gdb/rust-lang.c                            |  1 +
 gdb/testsuite/gdb.ada/maint_with_ada.exp   |  1 -
 gdb/testsuite/gdb.ada/notcplusplus.exp     | 45 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.ada/notcplusplus/foo.adb | 21 +++++++++++++
 gdb/testsuite/gdb.ada/notcplusplus/pck.adb | 21 +++++++++++++
 gdb/testsuite/gdb.ada/notcplusplus/pck.ads | 19 ++++++++++++
 gdb/testsuite/gdb.ada/notcplusplus/ver.ads | 22 ++++++++++++++
 gdb/testsuite/gdb.base/c-linkage-name.c    | 44 ++++++++++++++++++++++++++++
 gdb/testsuite/gdb.base/c-linkage-name.exp  | 47 ++++++++++++++++++++++++++++++
 21 files changed, 259 insertions(+), 2 deletions(-)
 create mode 100644 gdb/testsuite/gdb.ada/notcplusplus.exp
 create mode 100644 gdb/testsuite/gdb.ada/notcplusplus/foo.adb
 create mode 100644 gdb/testsuite/gdb.ada/notcplusplus/pck.adb
 create mode 100644 gdb/testsuite/gdb.ada/notcplusplus/pck.ads
 create mode 100644 gdb/testsuite/gdb.ada/notcplusplus/ver.ads
 create mode 100644 gdb/testsuite/gdb.base/c-linkage-name.c
 create mode 100644 gdb/testsuite/gdb.base/c-linkage-name.exp

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 0da58d9..7f99a2e 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -14521,6 +14521,7 @@  extern const struct language_defn ada_language_defn = {
   ada_read_var_value,		/* la_read_var_value */
   NULL,                         /* Language specific skip_trampoline */
   NULL,                         /* name_of_this */
+  true,                         /* la_store_sym_names_in_linkage_form_p */
   ada_lookup_symbol_nonlocal,   /* Looking up non-local symbols.  */
   basic_lookup_transparent_type,        /* lookup_transparent_type */
   ada_la_decode,                /* Language specific symbol demangler */
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index a0b553e..658c7f7 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -853,6 +853,7 @@  extern const struct language_defn c_language_defn =
   default_read_var_value,	/* la_read_var_value */
   NULL,				/* Language specific skip_trampoline */
   NULL,				/* name_of_this */
+  true,				/* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,				/* Language specific symbol demangler */
@@ -998,6 +999,7 @@  extern const struct language_defn cplus_language_defn =
   default_read_var_value,	/* la_read_var_value */
   cplus_skip_trampoline,	/* Language specific skip_trampoline */
   "this",                       /* name_of_this */
+  false,			/* la_store_sym_names_in_linkage_form_p */
   cp_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   cp_lookup_transparent_type,   /* lookup_transparent_type */
   gdb_demangle,			/* Language specific symbol demangler */
@@ -1052,6 +1054,7 @@  extern const struct language_defn asm_language_defn =
   default_read_var_value,	/* la_read_var_value */
   NULL,				/* Language specific skip_trampoline */
   NULL,				/* name_of_this */
+  true,				/* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,				/* Language specific symbol demangler */
@@ -1106,6 +1109,7 @@  extern const struct language_defn minimal_language_defn =
   default_read_var_value,	/* la_read_var_value */
   NULL,				/* Language specific skip_trampoline */
   NULL,				/* name_of_this */
+  true,				/* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,				/* Language specific symbol demangler */
diff --git a/gdb/d-lang.c b/gdb/d-lang.c
index e0afe48..688ae98 100644
--- a/gdb/d-lang.c
+++ b/gdb/d-lang.c
@@ -229,6 +229,7 @@  extern const struct language_defn d_language_defn =
   default_read_var_value,	/* la_read_var_value */
   NULL,				/* Language specific skip_trampoline.  */
   "this",
+  false,			/* la_store_sym_names_in_linkage_form_p */
   d_lookup_symbol_nonlocal,
   basic_lookup_transparent_type,
   d_demangle,			/* Language specific symbol demangler.  */
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index d651725..b4c087f 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -11142,7 +11142,11 @@  dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
   if (mangled != NULL)
     {
 
-      if (cu->language == language_go)
+      if (language_def (cu->language)->la_store_sym_names_in_linkage_form_p)
+	{
+	  /* Do nothing (do not demangle the symbol name).  */
+	}
+      else if (cu->language == language_go)
 	{
 	  /* This is a lie, but we already lie to the caller new_symbol.
 	     new_symbol assumes we return the mangled name.
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 74f5622..81922f7 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -269,6 +269,7 @@  extern const struct language_defn f_language_defn =
   default_read_var_value,	/* la_read_var_value */
   NULL,				/* Language specific skip_trampoline */
   NULL,                    	/* name_of_this */
+  false,			/* la_store_sym_names_in_linkage_form_p */
   cp_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
 
diff --git a/gdb/go-lang.c b/gdb/go-lang.c
index 022b8de..e9cba77 100644
--- a/gdb/go-lang.c
+++ b/gdb/go-lang.c
@@ -590,6 +590,7 @@  extern const struct language_defn go_language_defn =
   default_read_var_value,	/* la_read_var_value */
   NULL,				/* Language specific skip_trampoline.  */
   NULL,				/* name_of_this */
+  false,			/* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal, 
   basic_lookup_transparent_type,
   go_demangle,			/* Language specific symbol demangler.  */
diff --git a/gdb/language.c b/gdb/language.c
index 0d8604b..22199e0 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -864,6 +864,7 @@  const struct language_defn unknown_language_defn =
   default_read_var_value,	/* la_read_var_value */
   unk_lang_trampoline,		/* Language specific skip_trampoline */
   "this",        	    	/* name_of_this */
+  true,				/* store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   unk_lang_demangle,		/* Language specific symbol demangler */
@@ -915,6 +916,7 @@  const struct language_defn auto_language_defn =
   default_read_var_value,	/* la_read_var_value */
   unk_lang_trampoline,		/* Language specific skip_trampoline */
   "this",		        /* name_of_this */
+  false,			/* store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   unk_lang_demangle,		/* Language specific symbol demangler */
diff --git a/gdb/language.h b/gdb/language.h
index 06b42ae..029de4a 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -264,6 +264,26 @@  struct language_defn
 
     const char *la_name_of_this;
 
+    /* True if the symbols names should be stored in GDB's data structures
+       for minimal/partial/full symbols using their linkage (aka mangled)
+       form; false if the symbol names should be demangled first.
+
+       Most languages implement symbol lookup by comparing the demangled
+       names, in which case it is advantageous to store that information
+       already demangled, and so would set this field to false.
+
+       On the other hand, some languages have opted for doing symbol
+       lookups by comparing mangled names instead, for reasons usually
+       specific to the language.  Those languages should set this field
+       to true.
+
+       And finally, other languages such as C or Asm do not have
+       the concept of mangled vs demangled name, so those languages
+       should set this field to true as well, to prevent any accidental
+       demangling through an unrelated language's demangler.  */
+
+    const bool la_store_sym_names_in_linkage_form_p;
+
     /* This is a function that lookup_symbol will call when it gets to
        the part of symbol lookup where C looks up static and global
        variables.  */
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index 11ccab3..6e6434b 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -377,6 +377,7 @@  extern const struct language_defn m2_language_defn =
   default_read_var_value,	/* la_read_var_value */
   NULL,				/* Language specific skip_trampoline */
   NULL,		                /* name_of_this */
+  false,			/* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,				/* Language specific symbol demangler */
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index c714ec3..4f7dc36 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -389,6 +389,7 @@  extern const struct language_defn objc_language_defn = {
   default_read_var_value,	/* la_read_var_value */
   objc_skip_trampoline, 	/* Language specific skip_trampoline */
   "self",		        /* name_of_this */
+  false,			/* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   objc_demangle,		/* Language specific symbol demangler */
diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c
index 268c3c5..9c5b90c 100644
--- a/gdb/opencl-lang.c
+++ b/gdb/opencl-lang.c
@@ -1065,6 +1065,7 @@  extern const struct language_defn opencl_language_defn =
   default_read_var_value,	/* la_read_var_value */
   NULL,				/* Language specific skip_trampoline */
   NULL,                         /* name_of_this */
+  false,			/* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,				/* Language specific symbol demangler */
diff --git a/gdb/p-lang.c b/gdb/p-lang.c
index 03db2df..3ff7f56 100644
--- a/gdb/p-lang.c
+++ b/gdb/p-lang.c
@@ -439,6 +439,7 @@  extern const struct language_defn pascal_language_defn =
   default_read_var_value,	/* la_read_var_value */
   NULL,				/* Language specific skip_trampoline */
   "this",		        /* name_of_this */
+  false,			/* la_store_sym_names_in_linkage_form_p */
   basic_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,				/* Language specific symbol demangler */
diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c
index 5ff80b2..2d7c1f7 100644
--- a/gdb/rust-lang.c
+++ b/gdb/rust-lang.c
@@ -2290,6 +2290,7 @@  extern const struct language_defn rust_language_defn =
   default_read_var_value,	/* la_read_var_value */
   NULL,				/* Language specific skip_trampoline */
   NULL,				/* name_of_this */
+  false,			/* la_store_sym_names_in_linkage_form_p */
   rust_lookup_symbol_nonlocal,	/* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   gdb_demangle,			/* Language specific symbol demangler */
diff --git a/gdb/testsuite/gdb.ada/maint_with_ada.exp b/gdb/testsuite/gdb.ada/maint_with_ada.exp
index 73da613..9ede035 100644
--- a/gdb/testsuite/gdb.ada/maint_with_ada.exp
+++ b/gdb/testsuite/gdb.ada/maint_with_ada.exp
@@ -32,7 +32,6 @@  gdb_breakpoint "adainit"
 gdb_breakpoint "Var_Arr_Typedef"
 gdb_breakpoint "Do_Nothing"
 
-setup_kfail gdb/22670 "*-*-*"
 gdb_test_no_output "maintenance check-psymtabs"
 
 gdb_test_no_output "maintenance check-symtabs"
diff --git a/gdb/testsuite/gdb.ada/notcplusplus.exp b/gdb/testsuite/gdb.ada/notcplusplus.exp
new file mode 100644
index 0000000..b2a24e8
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/notcplusplus.exp
@@ -0,0 +1,45 @@ 
+# Copyright 2018 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/>.
+
+load_lib "ada.exp"
+
+if { [skip_ada_tests] } { return -1 }
+
+standard_ada_testfile foo
+
+if {[gdb_compile_ada "${srcfile}" "${binfile}" executable {debug}] != ""} {
+    return -1
+}
+
+clean_restart ${testfile}
+
+gdb_test "print /x <symada__cS>" \
+         "= \\(a => 0x60287af\\)" \
+         "print <symada__cS> before loading symbols from ver.ads"
+
+# Force the partial symbosl from ver.ads to be expanded into full symbols.
+
+gdb_test \
+     "list ver.ads:16" \
+     [multi_line ".*" \
+                 "16\\s+package Ver is" \
+                 "17\\s+type Wrapper is record" \
+                 "18\\s+A : Integer;" \
+                 "19\\s+end record;" \
+                 "20\\s+u00045 : constant Wrapper := \\(A => 16#060287af#\\);"]
+
+gdb_test "print /x <symada__cS>" \
+         "= \\(a => 0x60287af\\)" \
+         "print <symada__cS> after loading symbols from ver.ads"
diff --git a/gdb/testsuite/gdb.ada/notcplusplus/foo.adb b/gdb/testsuite/gdb.ada/notcplusplus/foo.adb
new file mode 100644
index 0000000..89e42f9
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/notcplusplus/foo.adb
@@ -0,0 +1,21 @@ 
+--  Copyright 2018 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/>.
+
+with Pck; use Pck;
+with Ver; use Ver;
+procedure Foo is
+begin
+   Do_Nothing (u00045'Address);
+end Foo;
diff --git a/gdb/testsuite/gdb.ada/notcplusplus/pck.adb b/gdb/testsuite/gdb.ada/notcplusplus/pck.adb
new file mode 100644
index 0000000..dcfb306
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/notcplusplus/pck.adb
@@ -0,0 +1,21 @@ 
+--  Copyright 2018 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/>.
+
+package body Pck is
+   procedure Do_Nothing (A : System.Address) is
+   begin
+      null;
+   end Do_Nothing;
+end Pck;
diff --git a/gdb/testsuite/gdb.ada/notcplusplus/pck.ads b/gdb/testsuite/gdb.ada/notcplusplus/pck.ads
new file mode 100644
index 0000000..33e369e
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/notcplusplus/pck.ads
@@ -0,0 +1,19 @@ 
+--  Copyright 2018 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/>.
+
+with System;
+package Pck is
+   procedure Do_Nothing (A : System.Address);
+end Pck;
diff --git a/gdb/testsuite/gdb.ada/notcplusplus/ver.ads b/gdb/testsuite/gdb.ada/notcplusplus/ver.ads
new file mode 100644
index 0000000..8f264d0
--- /dev/null
+++ b/gdb/testsuite/gdb.ada/notcplusplus/ver.ads
@@ -0,0 +1,22 @@ 
+--  Copyright 2018 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/>.
+
+package Ver is
+   type Wrapper is record
+      A : Integer;
+   end record;
+   u00045 : constant Wrapper := (A => 16#060287af#);
+   pragma Export (C, u00045, "symada__cS");
+end Ver;
diff --git a/gdb/testsuite/gdb.base/c-linkage-name.c b/gdb/testsuite/gdb.base/c-linkage-name.c
new file mode 100644
index 0000000..925004c
--- /dev/null
+++ b/gdb/testsuite/gdb.base/c-linkage-name.c
@@ -0,0 +1,44 @@ 
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2018 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/>.  */
+
+struct wrapper
+{
+  int a;
+};
+
+/* Create a global variable whose name in the assembly code
+   (aka the "linkage name") is different from the name in
+   the source code.  The goal is to create a symbol described
+   in DWARF using a DW_AT_linkage_name attribute, with a name
+   which follows the C++ mangling.
+
+   In this particular case, we chose "symada__cS" which, if it were
+   demangled, would translate to "symada (char, signed)".  */
+struct wrapper mundane asm ("symada__cS") = {0x060287af};
+
+void
+do_something (struct wrapper *w)
+{
+  w->a++;
+}
+
+int
+main (void)
+{
+  do_something (&mundane);
+  return 0;
+}
diff --git a/gdb/testsuite/gdb.base/c-linkage-name.exp b/gdb/testsuite/gdb.base/c-linkage-name.exp
new file mode 100644
index 0000000..c80a530
--- /dev/null
+++ b/gdb/testsuite/gdb.base/c-linkage-name.exp
@@ -0,0 +1,47 @@ 
+# Copyright 2018 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/>.
+
+# This file is part of the gdb testsuite.  It is intended to test that
+# gdb can correctly print arrays with indexes for each element of the
+# array.
+
+standard_testfile .c
+
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+    untested "failed to compile"
+    return -1
+}
+
+clean_restart ${binfile}
+
+# Try to print MUNDANE, but using its linkage name.
+
+gdb_test "print symada__cS" \
+         " = {a = 100829103}" \
+         "print symada__cS before partial symtab expansion"
+
+# Force the symbols to be expanded for the unit that contains
+# our symada__cS symbol by, e.g. inserting a breakpoint on one
+# of the founction also provided by the same using.
+
+gdb_test "break main" \
+         "Breakpoint $decimal at $hex: file .*$srcfile, line $decimal\\."
+
+# Try to print MUNDANE using its linkage name again, after partial
+# symtab expansion.
+
+gdb_test "print symada__cS" \
+         " = {a = 100829103}" \
+         "print symada__cS after partial symtab expansion"
-- 
2.1.4