diff --git a/gdb/c-exp.y b/gdb/c-exp.y
index bdcd51f..650ae10 100644
--- a/gdb/c-exp.y
+++ b/gdb/c-exp.y
@@ -1041,15 +1041,34 @@ variable:	name_not_typename
 			      struct bound_minimal_symbol msymbol;
 			      char *arg = copy_name ($1.stoken);
 
-			      msymbol =
-				lookup_bound_minimal_symbol (arg);
-			      if (msymbol.minsym != NULL)
-				write_exp_msymbol (pstate, msymbol);
-			      else if (!have_full_symbols () && !have_partial_symbols ())
-				error (_("No symbol table is loaded.  Use the \"file\" command."));
+			      msymbol = lookup_bound_minimal_symbol (arg);
+			      if (msymbol.minsym == NULL)
+				{
+				  if (!have_full_symbols () && !have_partial_symbols ())
+				    error (_("No symbol table is loaded.  Use the \"file\" command."));
+				  else
+				    error (_("No symbol \"%s\" in current context."),
+					   copy_name ($1.stoken));
+				}
+
+			      /* This minsym might be an alias for
+				 another function.  See if we can find
+				 the debug symbol for the target, and
+				 if so, use it instead, since it has
+				 prototype info.  This is important
+				 for example for "p *__errno_location()".  */
+			      symbol *alias_target
+				= find_function_alias_target (msymbol);
+			      if (alias_target != NULL)
+				{
+				  write_exp_elt_opcode (pstate, OP_VAR_VALUE);
+				  write_exp_elt_block
+				    (pstate, SYMBOL_BLOCK_VALUE (alias_target));
+				  write_exp_elt_sym (pstate, alias_target);
+				  write_exp_elt_opcode (pstate, OP_VAR_VALUE);
+				}
 			      else
-				error (_("No symbol \"%s\" in current context."),
-				       copy_name ($1.stoken));
+				write_exp_msymbol (pstate, msymbol);
 			    }
 			}
 	;
diff --git a/gdb/minsyms.c b/gdb/minsyms.c
index c93eaa3..69b9e40 100644
--- a/gdb/minsyms.c
+++ b/gdb/minsyms.c
@@ -52,6 +52,23 @@
 #include "cli/cli-utils.h"
 #include "symbol.h"
 
+/* See minsyms.h.  */
+
+bool
+msymbol_is_text (minimal_symbol *msymbol)
+{
+  switch (MSYMBOL_TYPE (msymbol))
+    {
+    case mst_text:
+    case mst_text_gnu_ifunc:
+    case mst_solib_trampoline:
+    case mst_file_text:
+      return true;
+    default:
+      return false;
+    }
+}
+
 /* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
    At the end, copy them all into one newly allocated location on an objfile's
    per-BFD storage obstack.  */
diff --git a/gdb/minsyms.h b/gdb/minsyms.h
index b82a22a..e763f62 100644
--- a/gdb/minsyms.h
+++ b/gdb/minsyms.h
@@ -157,6 +157,10 @@ void terminate_minimal_symbol_table (struct objfile *objfile);
 
 
 
+/* Return whether MSYMBOL is a function/method.  */
+
+bool msymbol_is_text (minimal_symbol *msymbol);
+
 /* Compute a hash code for the string argument.  */
 
 unsigned int msymbol_hash (const char *);
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 497d520..4269267 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -3827,6 +3827,25 @@ skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
     /* Don't return END_PC, which is past the end of the function.  */
     return prologue_sal.pc;
 }
+
+/* See symtab.h.  */
+
+symbol *
+find_function_alias_target (bound_minimal_symbol msymbol)
+{
+  if (!msymbol_is_text (msymbol.minsym))
+    return NULL;
+
+  CORE_ADDR addr = BMSYMBOL_VALUE_ADDRESS (msymbol);
+  symbol *sym = find_pc_function (addr);
+  if (sym != NULL
+      && SYMBOL_CLASS (sym) == LOC_BLOCK
+      && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) == addr)
+    return sym;
+
+  return NULL;
+}
+
 
 /* If P is of the form "operator[ \t]+..." where `...' is
    some legitimate operator text, return a pointer to the
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 341deca..1b48611 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -1537,6 +1537,13 @@ extern CORE_ADDR skip_prologue_using_sal (struct gdbarch *gdbarch,
 extern struct symbol *fixup_symbol_section (struct symbol *,
 					    struct objfile *);
 
+/* If MSYMBOL is an text symbol, look for a function debug symbol with
+   the same address.  Returns NULL if not found.  This is necessary in
+   case a function is an alias to some other function, because debug
+   information is only emitted for the alias target function's
+   definition, not for the alias.  */
+extern symbol *find_function_alias_target (bound_minimal_symbol msymbol);
+
 /* Symbol searching */
 /* Note: struct symbol_search, search_symbols, et.al. are declared here,
    instead of making them local to symtab.c, for gdbtk's sake.  */
diff --git a/gdb/testsuite/gdb.base/symbol-alias.c b/gdb/testsuite/gdb.base/symbol-alias.c
new file mode 100644
index 0000000..cc5d104
--- /dev/null
+++ b/gdb/testsuite/gdb.base/symbol-alias.c
@@ -0,0 +1,31 @@
+/* This test is part of GDB, the GNU debugger.
+
+   Copyright 2017 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 S
+{
+  int field1;
+  int field2;
+};
+
+extern struct S *func_alias (void);
+
+int
+main (void)
+{
+  struct S *s = func_alias ();
+  return s->field1 - s->field1;
+}
diff --git a/gdb/testsuite/gdb.base/symbol-alias.exp b/gdb/testsuite/gdb.base/symbol-alias.exp
new file mode 100644
index 0000000..dc63eb1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/symbol-alias.exp
@@ -0,0 +1,37 @@
+# Test for printing alias symbols.
+# Copyright 2017 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/>.
+
+standard_testfile symbol-alias.c symbol-alias2.c
+
+if { [prepare_for_testing "failed to prepare" ${testfile} [list $srcfile $srcfile2]] } {
+    return -1
+}
+
+if ![runto_main] then {
+    fail "can't run to main"
+    continue
+}
+
+# Functions.
+foreach f {"func" "func_alias"} {
+    gdb_test "p $f" " = {struct S \\*\\(void\\)} $hex <func>"
+    gdb_test "p *${f}()" "= {field1 = 1, field2 = 2}"
+}
+
+# Variables.
+foreach v {"g_var_s" "g_var_s_alias"} {
+    gdb_test "p $v" "= {field1 = 1, field2 = 2}"
+}
diff --git a/gdb/testsuite/gdb.base/symbol-alias2.c b/gdb/testsuite/gdb.base/symbol-alias2.c
new file mode 100644
index 0000000..aedd520
--- /dev/null
+++ b/gdb/testsuite/gdb.base/symbol-alias2.c
@@ -0,0 +1,34 @@
+/* This test is part of GDB, the GNU debugger.
+
+   Copyright 2017 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 S
+{
+  int field1;
+  int field2;
+};
+
+struct S g_var_s = { 1, 2 };
+
+static struct S *
+func (void)
+{
+  return &g_var_s;
+}
+
+struct S *func_alias (void) __attribute__ ((alias ("func")));
+
+extern struct S g_var_s_alias __attribute__ ((alias ("g_var_s")));
