1
0
mirror of https://git.FreeBSD.org/ports.git synced 2024-11-19 00:13:33 +00:00

devel/gdb: Upgrade to 14.1

- Notable upstream fixes for FreeBSD include better support for
  multiprocessing as well as support for AVX and other extended
  registers in core dumps on newer AMD CPUs.

- Use all-gdb as the build target to reduce build time.

- sim can no longer be excluded during the tarball as a couple of
  source files in GDB now use headers from sim/ unconditionally.
  Instead, use --disable-sim to skip building the simulators.

Reviewed by:	pizzamig
Sponsored by:	DARPA
Differential Revision:	https://reviews.freebsd.org/D43053
This commit is contained in:
John Baldwin 2024-01-18 14:18:23 -08:00
parent a6f331b5e1
commit af0d94a611
11 changed files with 226 additions and 342 deletions

View File

@ -1,6 +1,5 @@
PORTNAME= gdb
DISTVERSION= 13.2
PORTREVISION= 2
DISTVERSION= 14.1
CATEGORIES= devel
MASTER_SITES= GNU
@ -25,7 +24,8 @@ TEST_TARGET= check
CPE_VENDOR= gnu
GNU_CONFIGURE= yes
CONFIGURE_ENV= CONFIGURED_M4=m4 CONFIGURED_BISON=byacc
CONFIGURE_ARGS= --program-suffix=${DISTVERSION:S/.//g} \
CONFIGURE_ARGS= --program-suffix=${VER} \
--disable-sim \
--enable-targets=all --enable-64-bit-bfd \
--with-separate-debug-dir=/usr/lib/debug \
${ICONV_CONFIGURE_ARG} \
@ -33,7 +33,7 @@ CONFIGURE_ARGS= --program-suffix=${DISTVERSION:S/.//g} \
CONFIGURE_OUTSOURCE= yes
CFLAGS:= ${CFLAGS:C/ +$//} # blanks at EOL creep in sometimes
CFLAGS+= -DRL_NO_COMPAT
EXCLUDE= dejagnu expect sim texinfo intl
EXCLUDE= dejagnu expect texinfo intl
EXTRACT_AFTER_ARGS= ${EXCLUDE:S/^/--exclude /}
VER= ${DISTVERSION:S/.//g}
@ -85,6 +85,8 @@ TUI_CONFIGURE_ENABLE= tui
XXHASH_CONFIGURE_OFF= --with-xxhash=no
XXHASH_LIB_DEPENDS= libxxhash.so:devel/xxhash
ALL_TARGET= all-gdb
.include <bsd.port.pre.mk>
.if ${PORT_OPTIONS:MPYTHON}

View File

@ -1,5 +1,5 @@
TIMESTAMP = 1691332214
SHA256 (gdb-13.2.tar.xz) = fd5bebb7be1833abdb6e023c2f498a354498281df9d05523d8915babeb893f0a
SIZE (gdb-13.2.tar.xz) = 23664644
TIMESTAMP = 1702493574
SHA256 (gdb-14.1.tar.xz) = d66df51276143451fcbff464cc8723d68f1e9df45a6a2d5635a54e71643edb80
SIZE (gdb-14.1.tar.xz) = 24108624
SHA256 (bsdjhb-libcxx-gdbpy-03d0d9b_GH0.tar.gz) = 2c1563f361d4fb59b54b1b39bff5cdf609d73962758eb05a8cdfe2c22551b259
SIZE (bsdjhb-libcxx-gdbpy-03d0d9b_GH0.tar.gz) = 6052

View File

@ -1,37 +0,0 @@
commit a980a7d24b9ab416a70880182d4e6b4975967d38
Author: John Baldwin <jhb@FreeBSD.org>
Date: Fri Mar 10 12:01:40 2023 -0800
PR gdb/30214: Prefer local include paths to system include paths
Some systems may install binutils headers into a system location
(e.g. /usr/local/include on FreeBSD) which may also include headers
for other external packages used by GDB such as zlib or zstd. If a
system include path such as /usr/local/include is added before local
include paths to directories within a clone or release tarball, then
headers from the external binutils package are used which can result
in build failures if the external binutils package is out of sync with
the version of GDB being built.
To fix, sort the include paths in INTERNAL_CFLAGS_BASE to add CFLAGS
for "local" componenets before external components.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30214
Reviewed-By: Tom Tromey <tom@tromey.com>
(cherry picked from commit a2fbb6903889c8fe32f4f3b890ef4b8c565d6b84)
diff --git gdb/Makefile.in gdb/Makefile.in
index 321a58c4635..fa7c81a0fab 100644
--- gdb/Makefile.in
+++ gdb/Makefile.in
@@ -629,8 +629,8 @@ INTERNAL_CPPFLAGS = $(CPPFLAGS) @GUILE_CPPFLAGS@ @PYTHON_CPPFLAGS@ \
# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
INTERNAL_CFLAGS_BASE = \
$(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \
- $(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) $(ZLIBINC) \
- $(ZSTD_CFLAGS) $(BFD_CFLAGS) $(INCLUDE_CFLAGS) $(LIBDECNUMBER_CFLAGS) \
+ $(GDB_CFLAGS) $(OPCODES_CFLAGS) $(BFD_CFLAGS) $(INCLUDE_CFLAGS) \
+ $(READLINE_CFLAGS) $(ZLIBINC) $(ZSTD_CFLAGS) $(LIBDECNUMBER_CFLAGS) \
$(INTL_CFLAGS) $(INCGNU) $(INCSUPPORT) $(LIBBACKTRACE_INC) \
$(ENABLE_CFLAGS) $(INTERNAL_CPPFLAGS) $(SRCHIGH_CFLAGS) \
$(TOP_CFLAGS) $(PTHREAD_CFLAGS) $(DEBUGINFOD_CFLAGS)

View File

@ -1,128 +0,0 @@
commit ae61525fcf456ab395d55c45492a106d1275873a
Author: Simon Marchi <simon.marchi@efficios.com>
Date: 2023-02-23 12:35:40 -0500
gdbsupport: ignore -Wenum-constexpr-conversion in enum-flags.h
When building with clang 16, we get:
CXX gdb.o
In file included from /home/smarchi/src/binutils-gdb/gdb/gdb.c:19:
In file included from /home/smarchi/src/binutils-gdb/gdb/defs.h:65:
/home/smarchi/src/binutils-gdb/gdb/../gdbsupport/enum-flags.h:95:52: error: integer value -1 is outside the valid range of values [0, 15] for this enumeration type [-Wenum-constexpr-conversion]
integer_for_size<sizeof (T), static_cast<bool>(T (-1) < T (0))>::type
^
The error message does not make it clear in the context of which enum
flag this fails (i.e. what is T in this context), but it doesn't really
matter, we have similar warning/errors for many of them, if we let the
build go through.
clang is right that the value -1 is invalid for the enum type we cast -1
to. However, we do need this expression in order to select an integer
type with the appropriate signedness. That is, with the same signedness
as the underlying type of the enum.
I first wondered if that was really needed, if we couldn't use
std::underlying_type for that. It turns out that the comment just above
says:
/* Note that std::underlying_type<enum_type> is not what we want here,
since that returns unsigned int even when the enum decays to signed
int. */
I was surprised, because std::is_signed<std::underlying_type<enum_type>>
returns the right thing. So I tried replacing all this with
std::underlying_type, see if that would work. Doing so causes some
build failures in unittests/enum-flags-selftests.c:
CXX unittests/enum-flags-selftests.o
/home/smarchi/src/binutils-gdb/gdb/unittests/enum-flags-selftests.c:254:1: error: static assertion failed due to requirement 'gdb::is_same<selftests::enum_flags_tests::check_valid_expr254::archetype<enum_flags<s
elftests::enum_flags_tests::RE>, selftests::enum_flags_tests::RE, enum_flags<selftests::enum_flags_tests::RE2>, selftests::enum_flags_tests::RE2, enum_flags<selftests::enum_flags_tests::URE>, selftests::enum_fla
gs_tests::URE, int>, selftests::enum_flags_tests::check_valid_expr254::archetype<enum_flags<selftests::enum_flags_tests::RE>, selftests::enum_flags_tests::RE, enum_flags<selftests::enum_flags_tests::RE2>, selfte
sts::enum_flags_tests::RE2, enum_flags<selftests::enum_flags_tests::URE>, selftests::enum_flags_tests::URE, unsigned int>>::value == true':
CHECK_VALID (true, int, true ? EF () : EF2 ())
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/smarchi/src/binutils-gdb/gdb/unittests/enum-flags-selftests.c:91:3: note: expanded from macro 'CHECK_VALID'
CHECK_VALID_EXPR_6 (EF, RE, EF2, RE2, UEF, URE, VALID, EXPR_TYPE, EXPR)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/smarchi/src/binutils-gdb/gdb/../gdbsupport/valid-expr.h:105:3: note: expanded from macro 'CHECK_VALID_EXPR_6'
CHECK_VALID_EXPR_INT (ESC_PARENS (typename T1, typename T2, \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/smarchi/src/binutils-gdb/gdb/../gdbsupport/valid-expr.h:66:3: note: expanded from macro 'CHECK_VALID_EXPR_INT'
static_assert (gdb::is_detected_exact<archetype<TYPES, EXPR_TYPE>, \
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is a bit hard to decode, but basically enumerations have the
following funny property that they decay into a signed int, even if
their implicit underlying type is unsigned. This code:
enum A {};
enum B {};
int main() {
std::cout << std::is_signed<std::underlying_type<A>::type>::value
<< std::endl;
std::cout << std::is_signed<std::underlying_type<B>::type>::value
<< std::endl;
auto result = true ? A() : B();
std::cout << std::is_signed<decltype(result)>::value << std::endl;
}
produces:
0
0
1
So, the "CHECK_VALID" above checks that this property works for enum flags the
same way as it would if you were using their underlying enum types. And
somehow, changing integer_for_size to use std::underlying_type breaks that.
Since the current code does what we want, and I don't see any way of doing it
differently, ignore -Wenum-constexpr-conversion around it.
Change-Id: Ibc82ae7bbdb812102ae3f1dd099fc859dc6f3cc2
diff --git gdbsupport/enum-flags.h gdbsupport/enum-flags.h
index 700037f6126..41ac7838f06 100644
--- gdbsupport/enum-flags.h
+++ gdbsupport/enum-flags.h
@@ -91,9 +91,12 @@ template<> struct integer_for_size<8, 1> { typedef int64_t type; };
template<typename T>
struct enum_underlying_type
{
+ DIAGNOSTIC_PUSH
+ DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION
typedef typename
integer_for_size<sizeof (T), static_cast<bool>(T (-1) < T (0))>::type
type;
+ DIAGNOSTIC_POP
};
namespace enum_flags_detail
diff --git include/diagnostics.h include/diagnostics.h
index d3ff27bc008..41e6db65391 100644
--- include/diagnostics.h
+++ include/diagnostics.h
@@ -76,6 +76,11 @@
# define DIAGNOSTIC_ERROR_SWITCH \
DIAGNOSTIC_ERROR ("-Wswitch")
+# if __has_warning ("-Wenum-constexpr-conversion")
+# define DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION \
+ DIAGNOSTIC_IGNORE ("-Wenum-constexpr-conversion")
+# endif
+
#elif defined (__GNUC__) /* GCC */
# define DIAGNOSTIC_IGNORE_DEPRECATED_DECLARATIONS \
@@ -155,4 +160,8 @@
# define DIAGNOSTIC_ERROR_SWITCH
#endif
+#ifndef DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION
+# define DIAGNOSTIC_IGNORE_ENUM_CONSTEXPR_CONVERSION
+#endif
+
#endif /* DIAGNOSTICS_H */

View File

@ -1,8 +1,8 @@
diff --git gdb/Makefile.in gdb/Makefile.in
index 321a58c4635..57a45c391ef 100644
index 9c0a0bff2cd..0e62786dd31 100644
--- gdb/Makefile.in
+++ gdb/Makefile.in
@@ -696,6 +696,7 @@ TARGET_OBS = @TARGET_OBS@
@@ -704,6 +704,7 @@ ALL_AMD_DBGAPI_TARGET_OBS = \
# All target-dependent objects files that require 64-bit CORE_ADDR
# (used with --enable-targets=all --enable-64-bit-bfd).
ALL_64_TARGET_OBS = \
@ -10,7 +10,7 @@ index 321a58c4635..57a45c391ef 100644
aarch64-fbsd-tdep.o \
aarch64-linux-tdep.o \
aarch64-newlib-tdep.o \
@@ -710,6 +711,7 @@ ALL_64_TARGET_OBS = \
@@ -718,6 +719,7 @@ ALL_64_TARGET_OBS = \
amd64-darwin-tdep.o \
amd64-dicos-tdep.o \
amd64-fbsd-tdep.o \
@ -18,7 +18,7 @@ index 321a58c4635..57a45c391ef 100644
amd64-linux-tdep.o \
amd64-netbsd-tdep.o \
amd64-obsd-tdep.o \
@@ -728,18 +730,21 @@ ALL_64_TARGET_OBS = \
@@ -737,18 +739,21 @@ ALL_64_TARGET_OBS = \
ia64-vms-tdep.o \
loongarch-linux-tdep.o \
loongarch-tdep.o \
@ -40,7 +40,7 @@ index 321a58c4635..57a45c391ef 100644
sparc64-linux-tdep.o \
sparc64-netbsd-tdep.o \
sparc64-obsd-tdep.o \
@@ -764,6 +769,7 @@ ALL_TARGET_OBS = \
@@ -773,6 +778,7 @@ ALL_TARGET_OBS = \
arch/loongarch.o \
arch/ppc-linux-common.o \
arm-bsd-tdep.o \
@ -48,7 +48,7 @@ index 321a58c4635..57a45c391ef 100644
arm-fbsd-tdep.o \
arm-linux-tdep.o \
arm-netbsd-tdep.o \
@@ -781,6 +787,8 @@ ALL_TARGET_OBS = \
@@ -790,6 +796,8 @@ ALL_TARGET_OBS = \
csky-linux-tdep.o \
csky-tdep.o \
dicos-tdep.o \
@ -57,7 +57,7 @@ index 321a58c4635..57a45c391ef 100644
fbsd-tdep.o \
frv-linux-tdep.o \
frv-tdep.o \
@@ -795,6 +803,7 @@ ALL_TARGET_OBS = \
@@ -804,6 +812,7 @@ ALL_TARGET_OBS = \
i386-bsd-tdep.o \
i386-darwin-tdep.o \
i386-dicos-tdep.o \
@ -65,7 +65,7 @@ index 321a58c4635..57a45c391ef 100644
i386-fbsd-tdep.o \
i386-gnu-tdep.o \
i386-go32-tdep.o \
@@ -832,6 +841,7 @@ ALL_TARGET_OBS = \
@@ -841,6 +850,7 @@ ALL_TARGET_OBS = \
obsd-tdep.o \
or1k-linux-tdep.o \
or1k-tdep.o \
@ -73,7 +73,7 @@ index 321a58c4635..57a45c391ef 100644
ppc-fbsd-tdep.o \
ppc-linux-tdep.o \
ppc-netbsd-tdep.o \
@@ -1622,6 +1632,7 @@ ALLDEPFILES = \
@@ -1642,6 +1652,7 @@ ALLDEPFILES = \
arch/riscv.c \
arch/tic6x.c \
aarch32-tdep.c \
@ -81,7 +81,7 @@ index 321a58c4635..57a45c391ef 100644
aarch64-fbsd-nat.c \
aarch64-fbsd-tdep.c \
aarch64-linux-nat.c \
@@ -1641,6 +1652,7 @@ ALLDEPFILES = \
@@ -1662,6 +1673,7 @@ ALLDEPFILES = \
amd64-bsd-nat.c \
amd64-darwin-tdep.c \
amd64-dicos-tdep.c \
@ -89,7 +89,7 @@ index 321a58c4635..57a45c391ef 100644
amd64-fbsd-nat.c \
amd64-fbsd-tdep.c \
amd64-linux-nat.c \
@@ -1656,6 +1668,7 @@ ALLDEPFILES = \
@@ -1678,6 +1690,7 @@ ALLDEPFILES = \
arc-linux-nat.c \
arc-tdep.c \
arm-bsd-tdep.c \
@ -97,7 +97,7 @@ index 321a58c4635..57a45c391ef 100644
arm-fbsd-nat.c \
arm-fbsd-tdep.c \
arm-linux-nat.c \
@@ -1675,6 +1688,9 @@ ALLDEPFILES = \
@@ -1697,6 +1710,9 @@ ALLDEPFILES = \
csky-tdep.c \
darwin-nat.c \
dicos-tdep.c \
@ -107,7 +107,7 @@ index 321a58c4635..57a45c391ef 100644
fbsd-nat.c \
fbsd-tdep.c \
fork-child.c \
@@ -1695,6 +1711,7 @@ ALLDEPFILES = \
@@ -1717,6 +1733,7 @@ ALLDEPFILES = \
i386-darwin-nat.c \
i386-darwin-tdep.c \
i386-dicos-tdep.c \
@ -115,7 +115,7 @@ index 321a58c4635..57a45c391ef 100644
i386-fbsd-nat.c \
i386-fbsd-tdep.c \
i386-gnu-nat.c \
@@ -1735,6 +1752,7 @@ ALLDEPFILES = \
@@ -1757,6 +1774,7 @@ ALLDEPFILES = \
microblaze-linux-tdep.c \
microblaze-tdep.c \
mingw-hdep.c \
@ -123,7 +123,7 @@ index 321a58c4635..57a45c391ef 100644
mips-fbsd-nat.c \
mips-fbsd-tdep.c \
mips-linux-nat.c \
@@ -1755,6 +1773,7 @@ ALLDEPFILES = \
@@ -1777,6 +1795,7 @@ ALLDEPFILES = \
obsd-tdep.c \
or1k-linux-nat.c \
posix-hdep.c \
@ -131,7 +131,7 @@ index 321a58c4635..57a45c391ef 100644
ppc-fbsd-nat.c \
ppc-fbsd-tdep.c \
ppc-linux-nat.c \
@@ -1769,6 +1788,7 @@ ALLDEPFILES = \
@@ -1791,6 +1810,7 @@ ALLDEPFILES = \
procfs.c \
ravenscar-thread.c \
remote-sim.c \
@ -139,7 +139,7 @@ index 321a58c4635..57a45c391ef 100644
riscv-fbsd-nat.c \
riscv-fbsd-tdep.c \
riscv-linux-nat.c \
@@ -1805,6 +1825,7 @@ ALLDEPFILES = \
@@ -1828,6 +1848,7 @@ ALLDEPFILES = \
sparc-sol2-nat.c \
sparc-sol2-tdep.c \
sparc-tdep.c \
@ -147,7 +147,7 @@ index 321a58c4635..57a45c391ef 100644
sparc64-fbsd-nat.c \
sparc64-fbsd-tdep.c \
sparc64-linux-nat.c \
@@ -1891,7 +1912,7 @@ generated_files = \
@@ -1915,7 +1936,7 @@ generated_files = \
# Flags needed to compile Python code
PYTHON_CFLAGS = @PYTHON_CFLAGS@
@ -156,11 +156,11 @@ index 321a58c4635..57a45c391ef 100644
@$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=$(SUBDIRS)" subdir_do
# Rule for compiling .c files in the top-level gdb directory.
@@ -2154,6 +2175,12 @@ ifneq ($(CODESIGN_CERT),)
@@ -2178,6 +2199,12 @@ ifneq ($(CODESIGN_CERT),)
$(ECHO_SIGN) $(CODESIGN) -s $(CODESIGN_CERT) gdb$(EXEEXT)
endif
+kgdb$(EXEEXT): kgdb-main.o $(LIBGDB_OBS) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS)
+kgdb$(EXEEXT): kgdb-main.o $(LIBGDB_OBS) $(CDEPS) $(TDEPLIBS)
+ $(SILENCE) rm -f kgdb$(EXEEXT)
+ $(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \
+ -o kgdb$(EXEEXT) kgdb-main.o $(LIBGDB_OBS) \
@ -169,7 +169,7 @@ index 321a58c4635..57a45c391ef 100644
# This is useful when debugging GDB, because some Unix's don't let you run GDB
# on itself without copying the executable. So "make gdb1" will make
# gdb and put a copy in gdb1, and you can run it with "gdb gdb1".
@@ -2189,6 +2216,7 @@ clean mostlyclean: $(CONFIG_CLEAN)
@@ -2213,6 +2240,7 @@ clean mostlyclean: $(CONFIG_CLEAN)
rm -f init.c stamp-init version.c stamp-version
rm -f gdb$(EXEEXT) core make.log
rm -f gdb[0-9]$(EXEEXT)
@ -177,7 +177,7 @@ index 321a58c4635..57a45c391ef 100644
rm -f test-cp-name-parser$(EXEEXT)
rm -f xml-builtin.c stamp-xml
rm -f $(DEPDIR)/*
@@ -2608,7 +2636,7 @@ endif
@@ -2636,7 +2664,7 @@ endif
# A list of all the objects we might care about in this build, for
# dependency tracking.
@ -187,10 +187,10 @@ index 321a58c4635..57a45c391ef 100644
# All the .deps files to include.
diff --git gdb/config.in gdb/config.in
index 736e6be1c48..7df4d954db0 100644
index e17245156d8..e1be9fdbc40 100644
--- gdb/config.in
+++ gdb/config.in
@@ -223,6 +223,12 @@
@@ -229,6 +229,12 @@
/* Define to 1 if you have the `kinfo_getfile' function. */
#undef HAVE_KINFO_GETFILE
@ -204,10 +204,10 @@ index 736e6be1c48..7df4d954db0 100644
#undef HAVE_LANGINFO_CODESET
diff --git gdb/configure gdb/configure
index bdc84be9c01..607ee3618cc 100755
index 5361bf42952..9f4c500fd22 100755
--- gdb/configure
+++ gdb/configure
@@ -19476,6 +19476,126 @@ fi
@@ -19724,6 +19724,126 @@ fi
@ -335,10 +335,10 @@ index bdc84be9c01..607ee3618cc 100755
# Check whether --with-zstd was given.
if test "${with_zstd+set}" = set; then :
diff --git gdb/configure.ac gdb/configure.ac
index c81df8c4967..b3e1b3b5283 100644
index 3912b77b27f..bc960202b22 100644
--- gdb/configure.ac
+++ gdb/configure.ac
@@ -472,6 +472,16 @@ AC_SEARCH_LIBS(socketpair, socket)
@@ -516,6 +516,16 @@ AC_SEARCH_LIBS(gethostbyname, nsl)
AM_ZLIB
AC_ZSTD
@ -356,7 +356,7 @@ index c81df8c4967..b3e1b3b5283 100644
# GDB may fork/exec the iconv program to get the list of supported character
diff --git gdb/configure.nat gdb/configure.nat
index aabcdeff989..6aeee4b61fa 100644
index 1dc4206b69c..cb46e1505c7 100644
--- gdb/configure.nat
+++ gdb/configure.nat
@@ -63,7 +63,8 @@ case ${gdb_host} in
@ -370,10 +370,10 @@ index aabcdeff989..6aeee4b61fa 100644
LOADLIBES='-lkvm'
;;
diff --git gdb/configure.tgt gdb/configure.tgt
index e84e222ba0d..cd3ef37fac6 100644
index 47a674201f9..4b4b6893edf 100644
--- gdb/configure.tgt
+++ gdb/configure.tgt
@@ -115,7 +115,7 @@ esac
@@ -122,7 +122,7 @@ esac
case "${targ}" in
*-*-freebsd* | *-*-kfreebsd*-gnu)
@ -382,7 +382,7 @@ index e84e222ba0d..cd3ef37fac6 100644
*-*-netbsd* | *-*-knetbsd*-gnu)
os_obs="netbsd-tdep.o solib-svr4.o";;
*-*-openbsd*)
@@ -132,7 +132,7 @@ aarch64*-*-elf | aarch64*-*-rtems*)
@@ -139,7 +139,7 @@ aarch64*-*-elf | aarch64*-*-rtems*)
aarch64*-*-freebsd*)
# Target: FreeBSD/aarch64
@ -391,7 +391,7 @@ index e84e222ba0d..cd3ef37fac6 100644
;;
aarch64*-*-linux*)
@@ -188,7 +188,7 @@ arm*-*-linux*)
@@ -202,7 +202,7 @@ arm*-*-linux*)
;;
arm*-*-freebsd*)
# Target: FreeBSD/arm
@ -400,7 +400,7 @@ index e84e222ba0d..cd3ef37fac6 100644
;;
arm*-*-netbsd* | arm*-*-knetbsd*-gnu)
# Target: NetBSD/arm
@@ -280,7 +280,11 @@ i[34567]86-*-dicos*)
@@ -294,7 +294,11 @@ i[34567]86-*-dicos*)
;;
i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu)
# Target: FreeBSD/i386
@ -413,7 +413,7 @@ index e84e222ba0d..cd3ef37fac6 100644
;;
i[34567]86-*-netbsd* | i[34567]86-*-knetbsd*-gnu)
# Target: NetBSD/i386
@@ -420,7 +424,7 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
@@ -434,7 +438,7 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu)
;;
mips*-*-freebsd*)
# Target: MIPS running FreeBSD
@ -422,7 +422,7 @@ index e84e222ba0d..cd3ef37fac6 100644
;;
mips64*-*-openbsd*)
# Target: OpenBSD/mips64
@@ -478,7 +482,7 @@ or1k-*-* | or1knd-*-*)
@@ -492,7 +496,7 @@ or1k-*-* | or1knd-*-*)
powerpc*-*-freebsd*)
# Target: FreeBSD/powerpc
gdb_target_obs="rs6000-tdep.o ppc-sysv-tdep.o ppc64-tdep.o \
@ -431,7 +431,7 @@ index e84e222ba0d..cd3ef37fac6 100644
ravenscar-thread.o ppc-ravenscar-thread.o"
;;
@@ -527,7 +531,7 @@ s390*-*-linux*)
@@ -541,7 +545,7 @@ s390*-*-linux*)
riscv*-*-freebsd*)
# Target: FreeBSD/riscv
@ -440,7 +440,7 @@ index e84e222ba0d..cd3ef37fac6 100644
;;
riscv*-*-linux*)
@@ -592,6 +596,7 @@ sparc64-*-linux*)
@@ -606,6 +610,7 @@ sparc64-*-linux*)
sparc*-*-freebsd* | sparc*-*-kfreebsd*-gnu)
# Target: FreeBSD/sparc64
gdb_target_obs="sparc-tdep.o sparc64-tdep.o sparc64-fbsd-tdep.o \
@ -448,7 +448,7 @@ index e84e222ba0d..cd3ef37fac6 100644
ravenscar-thread.o sparc-ravenscar-thread.o"
;;
sparc-*-netbsd* | sparc-*-knetbsd*-gnu)
@@ -708,8 +713,8 @@ x86_64-*-linux*)
@@ -722,8 +727,8 @@ x86_64-*-linux*)
;;
x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu)
# Target: FreeBSD/amd64
@ -460,7 +460,7 @@ index e84e222ba0d..cd3ef37fac6 100644
x86_64-*-mingw* | x86_64-*-cygwin*)
# Target: MingW/amd64
diff --git gdb/osabi.c gdb/osabi.c
index d18802ac3a4..4f3aa6a52da 100644
index ad3dad5b849..29e8578d031 100644
--- gdb/osabi.c
+++ gdb/osabi.c
@@ -67,6 +67,7 @@ static const struct osabi_names gdb_osabi_names[] =
@ -484,10 +484,10 @@ index 35f14ec433c..1276d34d5f7 100644
GDB_OSABI_OPENBSD,
GDB_OSABI_WINCE,
diff --git gdb/regcache.c gdb/regcache.c
index 56b6d047874..47637c628a7 100644
index 91b20b7a2a2..0cfa1bae3d9 100644
--- gdb/regcache.c
+++ gdb/regcache.c
@@ -1112,6 +1112,22 @@ reg_buffer::raw_supply_zeroed (int regnum)
@@ -1123,6 +1123,22 @@ reg_buffer::raw_supply_zeroed (int regnum)
m_register_status[regnum] = REG_VALID;
}
@ -510,11 +510,91 @@ index 56b6d047874..47637c628a7 100644
/* See gdbsupport/common-regcache.h. */
void
@@ -1289,6 +1305,53 @@ regcache::collect_regset (const struct regset *regset, int regbase,
size);
}
+/* See regcache.h */
+
+int
+regcache_map_entry_size (const struct regcache_map_entry *map, gdbarch *gdbarch)
+{
+ int size = 0, count;
+
+ for (; (count = map->count) != 0; map++)
+ {
+ int regno = map->regno;
+ int slot_size = map->size;
+
+ if (slot_size == 0 && regno != REGCACHE_MAP_SKIP)
+ slot_size = register_size (gdbarch, regno);
+
+ size += count * slot_size;
+ }
+ return size;
+}
+
+/* See regcache.h */
+
+int
+regcache_map_offset (const struct regcache_map_entry *map, int regnum,
+ gdbarch *gdbarch)
+{
+ int offs = 0, count;
+
+ for (; (count = map->count) != 0; map++)
+ {
+ int regno = map->regno;
+ int slot_size = map->size;
+
+ if (slot_size == 0 && regno != REGCACHE_MAP_SKIP)
+ slot_size = register_size (gdbarch, regno);
+
+ if (regno != REGCACHE_MAP_SKIP && regnum >= regno
+ && regnum < regno + count)
+ return offs + (regno - regnum) * slot_size;
+
+ offs += count * slot_size;
+ }
+ return -1;
+}
+
+/* See regcache.h */
+
bool
regcache_map_supplies (const struct regcache_map_entry *map, int regnum,
struct gdbarch *gdbarch, size_t size)
diff --git gdb/regcache.h gdb/regcache.h
index b9ffab9950d..f32d7a3bd00 100644
index 57ddac465f0..b9f62994901 100644
--- gdb/regcache.h
+++ gdb/regcache.h
@@ -237,6 +237,8 @@ class reg_buffer : public reg_buffer_common
@@ -133,6 +133,11 @@ regcache_map_entry_size (const struct regcache_map_entry *map)
return size;
}
+/* Same as above, but accepts a gdbarch to handle entries with a
+ variable register size. */
+extern int regcache_map_entry_size (const struct regcache_map_entry *map,
+ gdbarch *gdbarch);
+
/* Transfer a set of registers (as described by REGSET) between
REGCACHE and BUF. If REGNUM == -1, transfer all registers
belonging to the regset, otherwise just the register numbered
@@ -151,6 +156,13 @@ extern void regcache_collect_regset (const struct regset *regset,
int regnum, void *buf, size_t size);
+/* Return the offset of REGNUM in a block of registers described by an
+ array of regcache_map_entries. If the register is not found,
+ returns -1. */
+
+extern int regcache_map_offset (const struct regcache_map_entry *map,
+ int regnum, gdbarch *gdbarch);
+
/* Return true if a set of registers contains the value of the
register numbered REGNUM. The size of the set of registers is
given in SIZE, and the layout of the set of registers is described
@@ -238,6 +250,8 @@ class reg_buffer : public reg_buffer_common
only LEN, without editing the rest of the register. */
void raw_supply_part (int regnum, int offset, int len, const gdb_byte *in);

View File

@ -41,36 +41,28 @@
#include "kgdb.h"
struct aarch64fbsd_info
struct aarch64_fbsd_kern_info
{
int osreldate;
LONGEST osreldate = 0;
};
/* Per-program-space data key. */
static const registry<program_space>::key<aarch64fbsd_info> aarch64fbsd_pspace_data;
static const registry<program_space>::key<aarch64_fbsd_kern_info>
aarch64_fbsd_kern_pspace_data;
static void
aarch64fbsd_pspace_data_cleanup (struct program_space *pspace, void *arg)
{
struct aarch64fbsd_info *info = (struct aarch64fbsd_info *)arg;
xfree (info);
}
/* Get the current aarch64_fbsd data. If none is found yet, add it
/* Get the current aarch64_fbsd_kern data. If none is found yet, add it
now. This function always returns a valid object. */
static struct aarch64fbsd_info *
get_aarch64fbsd_info (void)
static struct aarch64_fbsd_kern_info *
get_aarch64_fbsd_kern_info (void)
{
struct aarch64fbsd_info *info;
struct aarch64_fbsd_kern_info *info;
info = aarch64fbsd_pspace_data.get (current_program_space);
info = aarch64_fbsd_kern_pspace_data.get (current_program_space);
if (info != nullptr)
return info;
info = aarch64fbsd_pspace_data.emplace (current_program_space);
info = aarch64_fbsd_kern_pspace_data.emplace (current_program_space);
info->osreldate = parse_and_eval_long ("osreldate");
return info;
}
@ -111,14 +103,13 @@ static void
aarch64_fbsd_supply_pcb(struct regcache *regcache, CORE_ADDR pcb_addr)
{
const struct regset *pcbregset;
struct aarch64fbsd_info *info = get_aarch64fbsd_info();
struct aarch64_fbsd_kern_info *info = get_aarch64_fbsd_kern_info();
gdb_byte buf[8 * 33];
if (info->osreldate >= 1400084)
pcbregset = &aarch64_fbsd_pcbregset;
else
pcbregset = &aarch64_fbsd13_pcbregset;
if (target_read_memory (pcb_addr, buf, sizeof buf) == 0)
regcache_supply_regset (pcbregset, regcache, -1, buf,
sizeof (buf));
@ -132,8 +123,8 @@ static const struct regcache_map_entry aarch64_fbsd_trapframe_map[] =
{ 1, AARCH64_CPSR_REGNUM, 8 },
{ 1, REGCACHE_MAP_SKIP, 8 }, /* esr */
{ 1, REGCACHE_MAP_SKIP, 8 }, /* far */
{ 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */
{ 0 },
{ 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */
{ 0 }
};
/* In kernels prior to __FreeBSD_version 1400084, struct trapframe
@ -146,8 +137,8 @@ static const struct regcache_map_entry aarch64_fbsd13_trapframe_map[] =
{ 1, AARCH64_PC_REGNUM, 8 },
{ 1, AARCH64_CPSR_REGNUM, 4 },
{ 1, REGCACHE_MAP_SKIP, 4 }, /* esr */
{ 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */
{ 0 },
{ 30, AARCH64_X0_REGNUM, 8 }, /* x0 ... x29 */
{ 0 }
};
static struct trad_frame_cache *
@ -155,9 +146,9 @@ aarch64_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache)
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct aarch64fbsd_info *info = get_aarch64fbsd_info();
struct aarch64_fbsd_kern_info *info = get_aarch64_fbsd_kern_info();
struct trad_frame_cache *cache;
CORE_ADDR func, pc, sp;
CORE_ADDR func, offset, pc, sp;
const char *name;
int i, tf_size;
@ -165,29 +156,24 @@ aarch64_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache)
return ((struct trad_frame_cache *)*this_cache);
const struct regcache_map_entry *trapframe_map;
if (info->osreldate >= 1400084)
{
trapframe_map = aarch64_fbsd_trapframe_map;
}
trapframe_map = aarch64_fbsd_trapframe_map;
else
{
trapframe_map = aarch64_fbsd13_trapframe_map;
}
trapframe_map = aarch64_fbsd13_trapframe_map;
cache = trad_frame_cache_zalloc (this_frame);
*this_cache = cache;
func = get_frame_func (this_frame);
sp = get_frame_register_unsigned (this_frame, AARCH64_SP_REGNUM);
find_pc_partial_function (func, &name, NULL, NULL);
tf_size = regcache_map_entry_size (trapframe_map);
trad_frame_set_reg_regmap (cache, trapframe_map, sp, tf_size);
/* Read $PC from trap frame. */
pc = read_memory_unsigned_integer (sp + 2 * 8, 8, byte_order);
func = get_frame_func (this_frame);
find_pc_partial_function (func, &name, NULL, NULL);
offset = regcache_map_offset (trapframe_map, AARCH64_PC_REGNUM, gdbarch);
pc = read_memory_unsigned_integer (sp + offset, 8, byte_order);
if (pc == 0 && strcmp(name, "fork_trampoline") == 0)
{
@ -197,7 +183,7 @@ aarch64_fbsd_trapframe_cache (frame_info_ptr this_frame, void **this_cache)
else
{
/* Construct the frame ID using the function start. */
trad_frame_set_id (cache, frame_id_build (sp + tf_size, func));
trad_frame_set_id (cache, frame_id_build (sp, func));
}
return cache;

View File

@ -289,7 +289,7 @@ kgdb_thr_init(CORE_ADDR (*cpu_pcb_addr) (u_int))
lookup_struct_elt (proc_sym->type (), "td_oncpu",
0);
thread_off_td_oncpu = td_oncpu.offset / 8;
thread_oncpu_size = FIELD_BITSIZE(*td_oncpu.field) / 8;
thread_oncpu_size = td_oncpu.field->bitsize () / 8;
} catch (const gdb_exception_error &e2) {
proc_off_p_pid = offsetof(struct proc, p_pid);
proc_off_p_comm = offsetof(struct proc, p_comm);

View File

@ -279,7 +279,7 @@ fbsd_kvm_target_open (const char *args, int from_tty)
kvm_t *nkvm;
const char *kernel;
std::string filename;
int osreldate;
LONGEST osreldate;
bool writeable;
if (ops == NULL || ops->supply_pcb == NULL || ops->cpu_pcb_addr == NULL)
@ -343,11 +343,14 @@ fbsd_kvm_target_open (const char *args, int from_tty)
kvm = nkvm;
vmcore = std::move(filename);
current_inferior()->push_target (&fbsd_kvm_ops);
/* Pop the target automatically upon failure. */
target_unpush_up unpusher;
unpusher.reset (&fbsd_kvm_ops);
inf = current_inferior();
inf->push_target (&fbsd_kvm_ops);
if (inf->pid == 0) {
inferior_appeared(inf, 1);
inf->fake_pid_p = 1;
}
/*
* Determine the first address in KVA. Newer kernels export
@ -362,20 +365,14 @@ fbsd_kvm_target_open (const char *args, int from_tty)
kernstart = kgdb_lookup("kernbase");
}
try {
CORE_ADDR osreldatesym = kgdb_lookup("osreldate");
osreldate = read_memory_unsigned_integer(osreldatesym, 4,
gdbarch_byte_order (target_gdbarch ()));
} catch (const gdb_exception_error &e) {
error ("Failed to look up osreldate");
}
osreldate = parse_and_eval_long("osreldate");
/*
* Look up symbols needed for stoppcbs handling, but don't
* fail if they aren't present.
*/
stoppcbs = kgdb_lookup("stoppcbs");
if (osreldate > 1400088) {
if (osreldate >= 1400088) {
/* stoppcbs is now a pointer rather than an array. */
try {
stoppcbs = read_memory_typed_address(stoppcbs,
@ -408,12 +405,6 @@ fbsd_kvm_target_open (const char *args, int from_tty)
kgdb_dmesg();
inf = current_inferior();
if (inf->pid == 0) {
inferior_appeared(inf, 1);
inf->fake_pid_p = 1;
}
solib_create_inferior_hook(0);
kt = kgdb_thr_init(ops->cpu_pcb_addr);
thread_info *curthr = nullptr;
while (kt != NULL) {
@ -425,13 +416,14 @@ fbsd_kvm_target_open (const char *args, int from_tty)
}
switch_to_thread (curthr);
unpusher.release ();
post_create_inferior (from_tty);
target_fetch_registers (get_current_regcache (), -1);
reinit_frame_cache ();
print_stack_frame (get_selected_frame (NULL), 0, SRC_AND_LOC, 1);
/* Keep the target pushed. */
unpusher.release ();
}
void
@ -440,7 +432,7 @@ fbsd_kvm_target::close()
if (kvm != NULL) {
switch_to_no_thread ();
exit_inferior_silent (current_inferior ());
exit_inferior (current_inferior ());
clear_solib();
if (kvm_close(kvm) != 0)
@ -560,9 +552,7 @@ fbsd_kvm_target::xfer_partial(enum target_object object,
static void
kgdb_switch_to_thread(const char *arg, int tid)
{
struct thread_info *tp;
tp = find_thread_ptid (&fbsd_kvm_ops, fbsd_vmcore_ptid (tid));
struct thread_info *tp = fbsd_kvm_ops.find_thread (fbsd_vmcore_ptid (tid));
if (tp == NULL)
error ("invalid tid");
thread_select (arg, tp);

View File

@ -24,37 +24,15 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <errno.h>
#include <err.h>
#include <kvm.h>
#include <limits.h>
#include <paths.h>
/* libgdb stuff. */
#include <defs.h>
#include <frame.h>
#include <frame-unwind.h>
#include <inferior.h>
#include <interps.h>
#include <cli-out.h>
#include <main.h>
#include <objfiles.h>
#include "defs.h"
#include "interps.h"
#include "main.h"
#include "osabi.h"
#include "run-on-main-thread.h"
#include "serial.h"
#include <target.h>
#include <top.h>
#include <ui-file.h>
#include <bfd.h>
#include <gdbcore.h>
#include <unistd.h>
#include <err.h>
#include <paths.h>
#include "kgdb.h"
@ -66,21 +44,6 @@ static char *kernel;
static char *remote;
static char *vmcore;
/*
* TODO:
* - test remote kgdb (see if threads and klds work)
* - possibly split kthr.c out into a separate thread_stratum target that
* uses new_objfile test to push itself when a FreeBSD kernel is loaded
* (check for kernel osabi) (probably don't bother with this)
* + test alternate kgdb_lookup()
* + fix kgdb build on amd64 to include i386 cross-debug support
* - propose expanded libkvm interface that supports cross-debug and moves
* MD bits of kgdb into the library (examining PCB's and exporting a
* stable-ABI struct of registers, similarly for trapframe handling and
* stop-pcb stuff
* + use tid's as lwp IDs instead of PIDs in ptid's
*/
static void
usage(void)
{
@ -406,5 +369,6 @@ main(int argc, char *argv[])
/* Terminate argv list. */
add_arg(&args, NULL);
gdb_assert (is_main_thread ());
return (gdb_main(&args));
}

View File

@ -1,17 +0,0 @@
--- gdb/fbsd-nat.c.orig 2019-05-11 11:19:03.000000000 -0700
+++ gdb/fbsd-nat.c 2019-05-24 16:25:52.961523000 -0700
@@ -1178,6 +1178,14 @@ fbsd_nat_target::resume (ptid_t ptid, int step, enum g
/* If ptid is a specific LWP, suspend all other LWPs in the process. */
inferior *inf = find_inferior_ptid (ptid);
+#ifndef PT_LWP_EVENTS
+ /* When LWP events are not supported, a new thread might already be
+ running that has not yet reported an event when GDB wishes to
+ only run a single thread. Force an update of the thread list
+ to ensure that any such threads are suspended before the process
+ is resumed. */
+ fbsd_add_threads (ptid.pid ());
+#endif
for (thread_info *tp : inf->non_exited_threads ())
{
int request;

View File

@ -47,6 +47,50 @@ share/man/man1/gdb%%VER%%.1.gz
%%PYTHON%%%%DATADIR%%/python/gdb/command/unwinders.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/command/xmethods.py
%%PYTHON%%%%DATADIR%%/python/gdb/command/xmethods.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/__init__.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/__init__.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/breakpoint.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/breakpoint.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/bt.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/bt.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/disassemble.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/disassemble.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/evaluate.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/evaluate.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/events.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/events.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/frames.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/frames.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/io.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/io.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/launch.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/launch.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/locations.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/locations.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/memory.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/memory.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/modules.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/modules.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/next.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/next.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/pause.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/pause.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/scopes.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/scopes.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/server.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/server.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/sources.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/sources.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/startup.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/startup.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/state.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/state.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/threads.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/threads.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/typecheck.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/typecheck.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/dap/varref.py
%%PYTHON%%%%DATADIR%%/python/gdb/dap/varref.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/function/__init__.py
%%PYTHON%%%%DATADIR%%/python/gdb/function/__init__.pyc
%%PYTHON%%%%DATADIR%%/python/gdb/function/as_string.py