RE: [PATCH] Enable building GDB without installed libtermcap

Bernd Edlinger
2015-02-24T18:18:50Z

Hi,

On Mon, 23 Feb 2015 16:11:38, Pedro Alves wrote:
>
> On 02/23/2015 04:05 PM, Pedro Alves wrote:
>
>>> The idea for this patch is to include a simple version of libtermcap as a fall-back
>>> for the case that the host compiler does not have any cursor library. This enables
>>> at least a non tui-enabled gdb. It works even if there is no termcap configuration
>>> file on the target. If a termcap or curses library can be found when configuring gdb,
>>> we will use the installed library instead of the included libtermcap.
>
> ...
>
>> I don't see any change to libtermcap that makes this a "simple version of libtermcap".
>> AFAICS, this is really libtermcap, minus the manual and the definitions. Parts of
>> the libtermcap patch you show look like something that really should be sent
>> to libtermcap's list, even.
>
> ...
>
>> Sorry, without a better rationale, I don't see how this makes sense. We
>> like to have _fewer_ copies of upstream projects in the repo (such as
>> e.g., readline), not more.
>
> I should have added that GDB _already_ has a very minimal termcap in
> the tree -- see gdb/windows-termcap.c. We could consider making that
> the fallback on all hosts.
>

Ok, thanks for this hint!

That is probably exactly what I need.

This makes the patch much smaller.

Maybe the name windows-termcap.c is a bit misleading,
because my target is mostly some embedded linux.

How about this:

diff --git a/gdb/configure b/gdb/configure
index 9632f9a..d44ac41 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -7253,7 +7253,7 @@ fi

if test "$ac_cv_search_tgetent" = no; then
-  as_fn_error "no termcap library found" "$LINENO" 5
+  CONFIG_OBS="$CONFIG_OBS windows-termcap.o"
fi

diff --git a/gdb/configure.ac b/gdb/configure.ac
index dfc6947..87ca668 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -621,7 +621,7 @@ esac
AC_SEARCH_LIBS(tgetent, [termcap tinfo curses ncurses])

if test "$ac_cv_search_tgetent" = no; then
-  AC_MSG_ERROR([no termcap library found])
+  CONFIG_OBS="$CONFIG_OBS windows-termcap.o"
fi

AC_ARG_WITH([system-readline],
diff --git a/gdb/windows-termcap.c b/gdb/windows-termcap.c
index caafc47..b6e0d08 100644
--- a/gdb/windows-termcap.c
+++ b/gdb/windows-termcap.c
@@ -32,6 +32,8 @@ extern char* tgetstr (char *name, char **area);
extern int tputs (char *string, int nlines, int (*outfun) ());
extern char *tgoto (const char *cap, int col, int row);

+char PC, *BC, *UP;
+
/* Each of the files below is a minimal implementation of the standard
termcap function with the same name, suitable for use in a Windows
console window.  */

Thanks
Bernd.

From gdb-patches-return-120183-listarch-gdb-patches=sources.redhat.com@sourceware.org Tue Feb 24 19:07:29 2015
Return-Path: <gdb-patches-return-120183-listarch-gdb-patches=sources.redhat.com@sourceware.org>
Delivered-To: listarch-gdb-patches@sources.redhat.com
Received: (qmail 70467 invoked by alias); 24 Feb 2015 19:07:29 -0000
Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm
Precedence: bulk
List-Id: <gdb-patches.sourceware.org>
List-Subscribe: <mailto:gdb-patches-subscribe@sourceware.org>
List-Archive: <http://sourceware.org/ml/gdb-patches/>
List-Post: <mailto:gdb-patches@sourceware.org>
List-Help: <mailto:gdb-patches-help@sourceware.org>, <http://sourceware.org/ml/#faqs>
Sender: gdb-patches-owner@sourceware.org
Delivered-To: mailing list gdb-patches@sourceware.org
Received: (qmail 70429 invoked by uid 89); 24 Feb 2015 19:07:28 -0000
Authentication-Results: sourceware.org; auth=none
X-Virus-Found: No
X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,SPF_HELO_PASS,T_RP_MATCHES_RCVD autolearn=no version=3.3.2
X-HELO: mx1.redhat.com
Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 24 Feb 2015 19:07:26 +0000
Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t1OJ7Ps0027114 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits%6 verifyúIL) for <gdb-patches@sourceware.org>; Tue, 24 Feb 2015 14:07:25 -0500
Received: from host1.jankratochvil.net ([10.40.204.17]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t1OJ7LWa000985 (version=TLSv1/SSLv3 cipher®S256-SHA bits%6 verify=NO); Tue, 24 Feb 2015 14:07:24 -0500
Date: Tue, 24 Feb 2015 19:07:00 -0000
From: Jan Kratochvil <jan.kratochvil@redhat.com>
To: gdb-patches@sourceware.org
Cc: Phil Muldoon <pmuldoon@redhat.com>
Subject: [patch] compile: Fix GNU-IFUNC funcs called from injected code
Message-ID: <20150224190720.GA32497@host1.jankratochvil.net>
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="+HP7ph2BbKc20aGI"
Content-Disposition: inline
User-Agent: Mutt/1.5.23 (2014-03-12)
X-IsSubscribed: yes
X-SW-Source: 2015-02/txt/msg00696.txt.bz2

--+HP7ph2BbKc20aGI
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-length: 543

Hi,

one could not call IFUNCs (=indirect functions) from the compiled injected
code. Either it errored with:
gdb command line:1:1: error: function return type cannot be function

or it just called the IFUNC dispatcher in normal way, returning real function
implementation address instead of the function return value (and thus no
function was called).

It is a pre-requisite for Phil's later 'compile print' code which calls
memcpy() from the injected code.

No regressions on {x86_64,x86_64-m32,i686}-fedora23pre-linux-gnu.

Thanks,
Jan

--+HP7ph2BbKc20aGI
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline; filename="compile-gnu-ifunc.patch"
Content-length: 5791

gdb/ChangeLog
2015-02-24 Jan Kratochvil <jan.kratochvil@redhat.com>

* compile/compile-c-symbols.c (convert_one_symbol, convert_symbol_bmsym)
(gcc_symbol_address): Call gnu_ifunc_resolve_addr.

gdb/testsuite/ChangeLog
2015-02-24 Jan Kratochvil <jan.kratochvil@redhat.com>

* gdb.compile/compile-ifunc.c: New file.
* gdb.compile/compile-ifunc.exp: New file.

diff --git a/gdb/compile/compile-c-symbols.c b/gdb/compile/compile-c-symbols.c
index 6562f05..ba6a229 100644
--- a/gdb/compile/compile-c-symbols.c
+++ b/gdb/compile/compile-c-symbols.c
@@ -187,6 +187,8 @@ convert_one_symbol (struct compile_c_instance *context,
case LOC_BLOCK:
kind = GCC_C_SYMBOL_FUNCTION;
addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ if (is_global && TYPE_GNU_IFUNC (SYMBOL_TYPE (sym)))
+ addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr);
break;

case LOC_CONST:
@@ -365,6 +367,8 @@ convert_symbol_bmsym (struct compile_c_instance *context,
gcc_decl decl;
CORE_ADDR addr;

+ addr = MSYMBOL_VALUE_ADDRESS (objfile, msym);
+
/* Conversion copied from write_exp_msymbol. */
switch (MSYMBOL_TYPE (msym))
{
@@ -376,8 +380,11 @@ convert_symbol_bmsym (struct compile_c_instance *context,
break;

case mst_text_gnu_ifunc:
- type = objfile_type (objfile)->nodebug_text_gnu_ifunc_symbol;
+ // nodebug_text_gnu_ifunc_symbol would cause:
+ // function return type cannot be function
+ type = objfile_type (objfile)->nodebug_text_symbol;
kind = GCC_C_SYMBOL_FUNCTION;
+ addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr);
break;

case mst_data:
@@ -400,7 +407,6 @@ convert_symbol_bmsym (struct compile_c_instance *context,
}

sym_type = convert_type (context, type);
- addr = MSYMBOL_VALUE_ADDRESS (objfile, msym);
decl = C_CTX (context)->c_ops->build_decl (C_CTX (context),
MSYMBOL_NATURAL_NAME (msym),
kind, sym_type, NULL, addr,
@@ -497,6 +503,8 @@ gcc_symbol_address (void *datum, struct gcc_c_context *gcc_context,
"gcc_symbol_address \"%s\": full symbol\n",
identifier);
result = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ if (TYPE_GNU_IFUNC (SYMBOL_TYPE (sym)))
+ result = gnu_ifunc_resolve_addr (target_gdbarch (), result);
found = 1;
}
else
@@ -512,6 +520,8 @@ gcc_symbol_address (void *datum, struct gcc_c_context *gcc_context,
"symbol\n",
identifier);
result = BMSYMBOL_VALUE_ADDRESS (msym);
+ if (MSYMBOL_TYPE (msym.minsym) == mst_text_gnu_ifunc)
+ result = gnu_ifunc_resolve_addr (target_gdbarch (), result);
found = 1;
}
}
diff --git a/gdb/testsuite/gdb.compile/compile-ifunc.c b/gdb/testsuite/gdb.compile/compile-ifunc.c
new file mode 100644
index 0000000..e5cee77
--- /dev/null
+++ b/gdb/testsuite/gdb.compile/compile-ifunc.c
@@ -0,0 +1,46 @@
+/* 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/>. */
+
+#include <stdlib.h>
+
+typedef int (*final_t) (int arg);
+
+int
+final (int arg)
+{
+ return arg + 1;
+}
+
+asm (".type gnu_ifunc, %gnu_indirect_function");
+
+final_t
+gnu_ifunc (void)
+{
+ return final;
+}
+
+extern int gnu_ifunc_alias (int arg) __attribute__ ((alias ("gnu_ifunc")));
+
+static int resultvar;
+
+int
+main (void)
+{
+ if (gnu_ifunc_alias (10) != 11)
+ abort ();
+ return resultvar;
+}
diff --git a/gdb/testsuite/gdb.compile/compile-ifunc.exp b/gdb/testsuite/gdb.compile/compile-ifunc.exp
new file mode 100644
index 0000000..9e83c46
--- /dev/null
+++ b/gdb/testsuite/gdb.compile/compile-ifunc.exp
@@ -0,0 +1,54 @@
+# 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/>.
+
+standard_testfile
+
+if { [prepare_for_testing ${testfile}.exp "$testfile-nodebug" $srcfile {}] } {
+ return -1
+}
+
+if ![runto_main] {
+ return -1
+}
+
+if {[skip_compile_feature_tests]} {
+ untested "compile command not supported (could not find libcc1 shared library?)"
+ return -1
+}
+
+with_test_prefix "nodebug" {
+
+ gdb_test_no_output "compile code resultvar = gnu_ifunc (10);"
+
+ gdb_test "p resultvar" " = 11"
+
+}
+
+if { [prepare_for_testing ${testfile}.exp "$testfile-debug" $srcfile] } {
+ return -1
+}
+
+if ![runto_main] {
+ return -1
+}
+
+with_test_prefix "debug" {
+
+ # gnu_ifunc (10): error: too many arguments to function 'gnu_ifunc'
+ gdb_test_no_output "compile code resultvar = gnu_ifunc_alias (10);"
+
+ gdb_test "p resultvar" " = 11" "debug: p resultvar"
+
+}

--+HP7ph2BbKc20aGI--