mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-11-16 12:34:43 +00:00
Compare commits
1 Commits
binutils-2
...
users/jema
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdeccf7331 |
@@ -1,3 +1,4 @@
|
||||
<<<<<<< HEAD:gdb/ChangeLog-2021
|
||||
2021-07-06 Tom de Vries <tdevries@suse.de>
|
||||
|
||||
* dwarf2/read.c (scan_partial_symbols): Skip top-level imports of
|
||||
@@ -576,6 +577,17 @@
|
||||
* silent-rules.mk (ECHO_CCLD, ECHO_AR, ECHO_RANLIB): New.
|
||||
|
||||
2021-06-16 Tom de Vries <tdevries@suse.de>
|
||||
=======
|
||||
2021-05-10 Jose E. Marchesi <jose.marchesi@oracle.com>
|
||||
|
||||
* configure.ac: Support --enable-poke.
|
||||
* configure: Regenerate.
|
||||
* Makefile.in (POKE_OBS): Define based on @POKE_OBS@.
|
||||
(DEPFILES): Add POKE_OBS.
|
||||
* poke.c: New file.
|
||||
|
||||
2021-05-07 Tom de Vries <tdevries@suse.de>
|
||||
>>>>>>> Integrate GNU poke in GDB:gdb/ChangeLog
|
||||
|
||||
PR symtab/26327
|
||||
* dwarf2/cu.h (dwarf2_cu::ancestor): Remove.
|
||||
|
||||
@@ -691,6 +691,9 @@ SER_HARDWIRE = @SER_HARDWIRE@
|
||||
# This is remote-sim.o if a simulator is to be linked in.
|
||||
SIM_OBS = @SIM_OBS@
|
||||
|
||||
# Object files to integrate with GNU poke.
|
||||
POKE_OBS = @POKE_OBS@
|
||||
|
||||
# Target-dependent object files.
|
||||
TARGET_OBS = @TARGET_OBS@
|
||||
|
||||
@@ -1617,7 +1620,8 @@ HFILES_WITH_SRCDIR = \
|
||||
# variables analogous to SER_HARDWIRE which get defaulted in this
|
||||
# Makefile.in
|
||||
|
||||
DEPFILES = $(TARGET_OBS) $(SER_HARDWIRE) $(NATDEPFILES) $(SIM_OBS)
|
||||
DEPFILES = $(TARGET_OBS) $(SER_HARDWIRE) $(NATDEPFILES) $(SIM_OBS) \
|
||||
$(POKE_OBS)
|
||||
|
||||
ALLDEPFILES = \
|
||||
arch/aarch32.c \
|
||||
@@ -2078,6 +2082,10 @@ install-guile:
|
||||
install-python:
|
||||
$(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(GDB_DATADIR)/python/gdb
|
||||
|
||||
install-poke:
|
||||
$(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)/$(GDB_DATADIR)/poke
|
||||
$(INSTALL) -m 644 $(srcdir)/poke/gdb.pk $(DESTDIR)/$(GDB_DATADIR)/poke
|
||||
|
||||
uninstall: force $(CONFIG_UNINSTALL)
|
||||
transformed_name=`t='$(program_transform_name)'; \
|
||||
echo gdb | sed -e $$t` ; \
|
||||
|
||||
18
gdb/NEWS
18
gdb/NEWS
@@ -885,6 +885,12 @@ GNU/Linux/OpenRISC or1k*-*-linux*
|
||||
need to focus on the command window for such key combinations to
|
||||
work.
|
||||
|
||||
* DDB now supports GNU poke, the extensible editor for structured
|
||||
binary data.
|
||||
|
||||
To build GDB with poke support, pass --with-poke to configure (this
|
||||
requires libpoke, the GNU poke library).
|
||||
|
||||
* New commands
|
||||
|
||||
set debug event-loop
|
||||
@@ -950,6 +956,18 @@ show python dont-write-bytecode
|
||||
When set to 'auto' (the default) Python will check the
|
||||
PYTHONDONTWRITEBYTECODE environment variable.
|
||||
|
||||
poke STR
|
||||
Execute a Poke statement or declaration.
|
||||
|
||||
poke-add-type EXPR
|
||||
Make Poke aware of a GDB type given an expression.
|
||||
|
||||
poke-add-types REGEXP
|
||||
Make Poke aware of GDB types based on a regexp.
|
||||
|
||||
poke-dump-types
|
||||
Dump the definition of all the GDB types known to poke.
|
||||
|
||||
* Changed commands
|
||||
|
||||
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM]
|
||||
|
||||
@@ -259,6 +259,9 @@
|
||||
/* Define to 1 if you have the `m' library (-lm). */
|
||||
#undef HAVE_LIBM
|
||||
|
||||
/* Define to 1 if you have the `poke' library (-lpoke). */
|
||||
#undef HAVE_LIBPOKE
|
||||
|
||||
/* Define to 1 if you have the <libunwind-ia64.h> header file. */
|
||||
#undef HAVE_LIBUNWIND_IA64_H
|
||||
|
||||
@@ -316,6 +319,9 @@
|
||||
/* Define to 1 if you have the `pipe2' function. */
|
||||
#undef HAVE_PIPE2
|
||||
|
||||
/* Define if building integration with GNU poke. */
|
||||
#undef HAVE_POKE
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
|
||||
100
gdb/configure
vendored
100
gdb/configure
vendored
@@ -757,6 +757,7 @@ ZSTD_LIBS
|
||||
ZSTD_CFLAGS
|
||||
zlibinc
|
||||
zlibdir
|
||||
POKE_OBS
|
||||
MIG
|
||||
WINDRES
|
||||
DLLTOOL
|
||||
@@ -874,6 +875,7 @@ infodir
|
||||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
@@ -922,6 +924,7 @@ enable_profiling
|
||||
enable_codesign
|
||||
with_pkgversion
|
||||
with_bugurl
|
||||
with_poke
|
||||
with_system_zlib
|
||||
with_zstd
|
||||
enable_rpath
|
||||
@@ -1033,6 +1036,7 @@ datadir='${datarootdir}'
|
||||
sysconfdir='${prefix}/etc'
|
||||
sharedstatedir='${prefix}/com'
|
||||
localstatedir='${prefix}/var'
|
||||
runstatedir='${localstatedir}/run'
|
||||
includedir='${prefix}/include'
|
||||
oldincludedir='/usr/include'
|
||||
docdir='${datarootdir}/doc/${PACKAGE}'
|
||||
@@ -1285,6 +1289,15 @@ do
|
||||
| -silent | --silent | --silen | --sile | --sil)
|
||||
silent=yes ;;
|
||||
|
||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||
| --run | --ru | --r)
|
||||
ac_prev=runstatedir ;;
|
||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||
| --run=* | --ru=* | --r=*)
|
||||
runstatedir=$ac_optarg ;;
|
||||
|
||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||
ac_prev=sbindir ;;
|
||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||
@@ -1422,7 +1435,7 @@ fi
|
||||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||
libdir localedir mandir
|
||||
libdir localedir mandir runstatedir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
@@ -1575,6 +1588,7 @@ Fine tuning of the installation directories:
|
||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||
@@ -1680,6 +1694,7 @@ Optional Packages:
|
||||
library
|
||||
--with-pkgversion=PKG Use PKG in the version string in place of "GDB"
|
||||
--with-bugurl=URL Direct users to URL to report a bug
|
||||
--with-poke Build GDB with poke support (default is NO)
|
||||
--with-system-zlib use installed libz
|
||||
--with-zstd support zstd compressed debug sections
|
||||
(default=auto)
|
||||
@@ -4944,7 +4959,7 @@ else
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -4990,7 +5005,7 @@ else
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -5014,7 +5029,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -5059,7 +5074,7 @@ else
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -5083,7 +5098,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -11448,7 +11463,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 11451 "configure"
|
||||
#line 11466 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -11554,7 +11569,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 11557 "configure"
|
||||
#line 11572 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@@ -19585,6 +19600,73 @@ if test "$ac_res" != no; then :
|
||||
fi
|
||||
|
||||
|
||||
# Integration with GNU poke is done through the libpoke library.
|
||||
|
||||
# Check whether --with-poke was given.
|
||||
if test "${with_poke+set}" = set; then :
|
||||
withval=$with_poke; with_poke=$withval
|
||||
else
|
||||
with_poke=no
|
||||
fi
|
||||
|
||||
if test "x$with_poke" = "xyes"; then
|
||||
# Note that we need a libpoke with support for registering foreign
|
||||
# IO devices, hence the symbol pk_register_iod.
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pk_register_iod in -lpoke" >&5
|
||||
$as_echo_n "checking for pk_register_iod in -lpoke... " >&6; }
|
||||
if ${ac_cv_lib_poke_pk_register_iod+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lpoke $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char pk_register_iod ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return pk_register_iod ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_poke_pk_register_iod=yes
|
||||
else
|
||||
ac_cv_lib_poke_pk_register_iod=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_poke_pk_register_iod" >&5
|
||||
$as_echo "$ac_cv_lib_poke_pk_register_iod" >&6; }
|
||||
if test "x$ac_cv_lib_poke_pk_register_iod" = xyes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_LIBPOKE 1
|
||||
_ACEOF
|
||||
|
||||
LIBS="-lpoke $LIBS"
|
||||
|
||||
fi
|
||||
|
||||
POKE_OBS="poke.o"
|
||||
|
||||
$as_echo "#define HAVE_POKE 1" >>confdefs.h
|
||||
|
||||
CONFIG_INSTALL="$CONFIG_INSTALL install-poke"
|
||||
else
|
||||
POKE_OBS=
|
||||
fi
|
||||
|
||||
|
||||
# Link in zlib/zstd if we can. This allows us to read compressed debug
|
||||
# sections.
|
||||
|
||||
@@ -24063,6 +24145,8 @@ main ()
|
||||
if (*(data + i) != *(data3 + i))
|
||||
return 14;
|
||||
close (fd);
|
||||
free (data);
|
||||
free (data3);
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
|
||||
@@ -506,6 +506,23 @@ AC_SEARCH_LIBS(gethostbyname, nsl)
|
||||
# Some systems (e.g. Solaris) have `socketpair' in libsocket.
|
||||
AC_SEARCH_LIBS(socketpair, socket)
|
||||
|
||||
# Integration with GNU poke is done through the libpoke library.
|
||||
AC_ARG_WITH([poke],
|
||||
AS_HELP_STRING([--with-poke],
|
||||
[Build GDB with poke support (default is NO)]),
|
||||
[with_poke=$withval], [with_poke=no])
|
||||
if test "x$with_poke" = "xyes"; then
|
||||
# Note that we need a libpoke with support for registering foreign
|
||||
# IO devices, hence the symbol pk_register_iod.
|
||||
AC_CHECK_LIB(poke, pk_register_iod)
|
||||
POKE_OBS="poke.o"
|
||||
AC_DEFINE(HAVE_POKE, 1, [Define if building integration with GNU poke.])
|
||||
CONFIG_INSTALL="$CONFIG_INSTALL install-poke"
|
||||
else
|
||||
POKE_OBS=
|
||||
fi
|
||||
AC_SUBST(POKE_OBS)
|
||||
|
||||
# Link in zlib/zstd if we can. This allows us to read compressed debug
|
||||
# sections.
|
||||
AM_ZLIB
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
<<<<<<< HEAD:gdb/doc/ChangeLog-1991-2021
|
||||
2021-07-02 Pedro Alves <pedro@palves.net>
|
||||
=======
|
||||
2021-05-10 Jose E. Marchesi <jose.marchesi@oracle.com>
|
||||
|
||||
* Makefile.in (GDB_DOC_FILES): Add poke.texi.
|
||||
* poke.texi: New file.
|
||||
* gdb.texinfo (Data): Add meny entry for Poke and @include poke.texi.
|
||||
|
||||
2021-05-07 Tom de Vries <tdevries@suse.de>
|
||||
>>>>>>> Integrate GNU poke in GDB:gdb/doc/ChangeLog
|
||||
|
||||
* gdb.texinfo (TUI): <TUI Mouse Support>: New node/section.
|
||||
|
||||
|
||||
@@ -142,6 +142,7 @@ GDB_DOC_FILES = \
|
||||
$(srcdir)/gdb.texinfo \
|
||||
$(srcdir)/guile.texi \
|
||||
$(srcdir)/python.texi \
|
||||
$(srcdir)/poke.texi \
|
||||
$(GDB_DOC_SOURCE_INCLUDES) \
|
||||
$(GDB_DOC_BUILD_INCLUDES)
|
||||
|
||||
|
||||
@@ -10617,6 +10617,7 @@ being passed the type of @var{arg} as the argument.
|
||||
* Caching Target Data:: Data caching for targets
|
||||
* Searching Memory:: Searching memory for a sequence of bytes
|
||||
* Value Sizes:: Managing memory allocated for values
|
||||
* Poke:: Poking at data using GNU poke.
|
||||
@end menu
|
||||
|
||||
@node Expressions
|
||||
@@ -14281,6 +14282,9 @@ Show the maximum size of memory, in bytes, that @value{GDBN} will
|
||||
allocate for the contents of a value.
|
||||
@end table
|
||||
|
||||
@c Poke docs live in a separate file.
|
||||
@include poke.texi
|
||||
|
||||
@node Optimized Code
|
||||
@chapter Debugging Optimized Code
|
||||
@cindex optimized code, debugging
|
||||
|
||||
371
gdb/doc/poke.texi
Normal file
371
gdb/doc/poke.texi
Normal file
@@ -0,0 +1,371 @@
|
||||
@c Copyright (C) 2022-2023 Free Software Foundation, Inc.
|
||||
@c Permission is granted to copy, distribute and/or modify this document
|
||||
@c under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||
@c any later version published by the Free Software Foundation; with the
|
||||
@c Invariant Sections being ``Free Software'' and ``Free Software Needs
|
||||
@c Free Documentation'', with the Front-Cover Texts being ``A GNU Manual,''
|
||||
@c and with the Back-Cover Texts as in (a) below.
|
||||
@c
|
||||
@c (a) The FSF's Back-Cover Text is: ``You are free to copy and modify
|
||||
@c this GNU Manual. Buying copies from GNU Press supports the FSF in
|
||||
@c developing GNU and promoting software freedom.''
|
||||
|
||||
@node Poke
|
||||
@section Poking at data using GNU @samp{poke}
|
||||
@cindex GNU poke
|
||||
@cindex poke
|
||||
|
||||
@uref{http://jemarch.net/poke.html,GNU poke} is an interactive,
|
||||
extensible editor for binary data that implements a full-fledged
|
||||
procedural, interactive domain specific language called @dfn{Poke}
|
||||
(with capital P) that is specifically designed in order to describe
|
||||
the layout of structured binary data and to operate on it.
|
||||
|
||||
@value{GDBN} integrates with GNU @samp{poke} by mean of the
|
||||
@file{libpoke} library and offers the possibility of executing Poke
|
||||
code from within the debugger, to inspect and modify data in the
|
||||
target's memory. This feature is available only if @value{GDBN} was
|
||||
configured using @option{--enable-poke}.
|
||||
|
||||
As we shall see in the sections below, @value{GDBN} uses the
|
||||
integration mechanisms provided by @file{libpoke} in order to make
|
||||
certain @value{GDBN} abstractions (such as symbols and types) visible from the
|
||||
Poke side, making the integration bidirectional.
|
||||
|
||||
Note that this section documents the integration of GNU @samp{poke}
|
||||
and @value{GDBN} and how to use it, but it doesn't describe GNU
|
||||
@samp{poke} nor the Poke language in detail. @xref{Top,,, poke, The
|
||||
GNU poke Manual}, for more information.
|
||||
|
||||
@menu
|
||||
* The @code{poke} Command:: Executing Poke from @value{GDBN}.
|
||||
* Poking the Target Memory:: Accessing the target's memory from Poke.
|
||||
* @value{GDBN} Types and Poke:: Accessing @value{GDBN} types from Poke.
|
||||
* @value{GDBN} Values and Poke:: Accessing @value{GDBN} values from Poke.
|
||||
@end menu
|
||||
|
||||
@node The @code{poke} Command
|
||||
@subsection The @code{poke} Command
|
||||
|
||||
The @code{poke} command allows to execute arbitrary Poke code from the
|
||||
@value{GDBN} prompt.
|
||||
|
||||
@table @code
|
||||
@item poke @var{src}
|
||||
@var{src} is either a Poke expression, statement or definition.
|
||||
@end table
|
||||
|
||||
For example, this executes a simple Poke expression and shows the
|
||||
result:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBP}) poke 2 + 3UL
|
||||
0x5UL
|
||||
@end smallexample
|
||||
|
||||
This declares a couple of Poke types and a variable:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBP}) type byte = uint<8>
|
||||
(@value{GDBP}) type Packet = struct @{ byte magic == 0x4a; byte sz; \
|
||||
byte[sz] payload; @}
|
||||
(@value{GDBP}) poke Packet @{ sz = 4 @}
|
||||
Packet @{
|
||||
magic=0x4aUB,
|
||||
sz=0x4UB,
|
||||
payload=[0x0UB,0x0UB,0x0UB,0x0UB]
|
||||
@}
|
||||
(@value{GDBP}) var p = Packet @{ sz = 4 @}
|
||||
(@value{GDBP}) poke p.payload
|
||||
[0x0UB,0x0UB,0x0UB,0x0UB]
|
||||
@end smallexample
|
||||
|
||||
This executes a Poke statement:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBP}) poke for (i in [1,2,3]) printf "%v\n", i
|
||||
0x00000001
|
||||
0x00000002
|
||||
0x00000003
|
||||
@end smallexample
|
||||
|
||||
This shows how the Poke incremental compiler handles and reports
|
||||
invalid input:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBP}) poke 2 + fjsdio
|
||||
<stdin>:1:5: error: undefined variable 'fjsdio'
|
||||
2 + fjsdio;
|
||||
^~~~~~
|
||||
@end smallexample
|
||||
|
||||
The standard @command{load} Poke directive loads a Poke source file
|
||||
and executes it in the incremental compiler. The list of directories
|
||||
where @command{load} looks for files is in the variable
|
||||
@code{load_path}:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBP}) poke load_path
|
||||
".:/home/jemarch/.local/share/poke:%DATADIR%/pickles:%DATADIR%"
|
||||
@end smallexample
|
||||
|
||||
This loads a file @file{foo.pk} if it is found in the load path:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBP}) poke load foo
|
||||
@end smallexample
|
||||
|
||||
Poke source files often contain definitions that conceptually apply to
|
||||
some definite domain, like some given file format or a protocol. We
|
||||
call these files @dfn{pickles}. For example, @file{elf.pk} is a
|
||||
pickle that provides facilities to poke ELF object files. The GNU
|
||||
@samp{poke} editor comes with lots of already written pickles for many
|
||||
file formats and other domains. If you happen to have GNU poke
|
||||
installed (and not just @file{libpoke}) you can also use the many
|
||||
pickles distributed with the editor. For example:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBP}) poke load elf
|
||||
(@value{GDBP}) poke Elf64_Rela @{@}
|
||||
Elf64_Rela @{
|
||||
r_offset=0x0UL#B,
|
||||
r_info=Elf64_RelInfo @{
|
||||
r_sym=0x0U,
|
||||
r_type=0x0U
|
||||
@},
|
||||
r_addend=0x0L
|
||||
@}
|
||||
@end smallexample
|
||||
|
||||
@node Poking the Target Memory
|
||||
@subsection Poking the Target Memory
|
||||
|
||||
@value{GDBN} configures @file{libpoke} to access the target's memory
|
||||
as an IO space device called @code{<gdb>}, which is automatically
|
||||
opened when the poke incremental compiler is started.
|
||||
|
||||
This means that the default IO space in the running poke will provide
|
||||
access to the virtual address space of the current @value{GDBN}
|
||||
inferior.
|
||||
|
||||
For example, suppose that a string table is at offset 0x5ff0 bytes in
|
||||
the target's memory. We could map an array of Poke strings from it by
|
||||
issuing:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBP}) poke string[3] @@ 0x5ff0#B
|
||||
["int", "long", "_pid"]
|
||||
@end smallexample
|
||||
|
||||
And we can write to the target's memory:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBP}) poke string[] @@ 0x5ff0#B = ["foo", "bar", "baz"]
|
||||
@end smallexample
|
||||
|
||||
Note that the fact the current IO space is the @value{GDBN} target memory
|
||||
doesn't mean you cannot access other IO spaces. This is how you would
|
||||
write the string table above to a file @file{strtab.out}:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBP}) poke var f = open ("strtab.out", IOS_F_WRITE | IOS_F_CREATE)
|
||||
(@value{GDBP}) poke string[] @@ f : 0#B = string[3] @@ 0x5ff0#B
|
||||
(@value{GDBP}) poke close (f)
|
||||
@end smallexample
|
||||
|
||||
If you close the default IO space you can re-open the @value{GDBN} target space
|
||||
with @code{open ("<gdb>")}.
|
||||
|
||||
@node @value{GDBN} Types and Poke
|
||||
@subsection @value{GDBN} Types and Poke
|
||||
|
||||
Maybe the strongest side of the Poke language is that it provides a
|
||||
very rich and dynamic mechanism to describe the layout of data
|
||||
structures. This is done by defining @dfn{Poke types}.
|
||||
|
||||
For example, this is the definition of a signed 13-bit integral type
|
||||
that could be used to poke immediate fields in SPARC instructions:
|
||||
|
||||
@smallexample
|
||||
type simm13 = int<13>;
|
||||
@end smallexample
|
||||
|
||||
And this is a simplified version of the structure of a 64-bit ELF file
|
||||
showing more advanced Poke capabilities like field constraints, field
|
||||
labels, absent fields, and methods:
|
||||
|
||||
@smallexample
|
||||
type Elf64_File =
|
||||
struct
|
||||
@{
|
||||
Elf64_Ehdr ehdr : ehdr.e_ident.ei-mag == [0x7fUB, 'E', 'L', 'F'];
|
||||
|
||||
Elf64_Shdr[ehdr.e_shnum] shdr @@ ehdr.e_shoff
|
||||
if ehdr.e_shnum > 0;
|
||||
|
||||
Elf64_Phdr[ehdr.e_phnum] phdr @@ ehdr.e_phoff
|
||||
if ehdr.e_phnum > 0;
|
||||
|
||||
/* Given an offset into the ELF file's section string table, return
|
||||
the string. */
|
||||
|
||||
method get_section_name = (offset<Elf_Word,B> offset) string:
|
||||
@{
|
||||
var strtab = ehdr.e_shstrndx;
|
||||
return string @@ (shdr[strtab].sh_offset + offset);
|
||||
@}
|
||||
@};
|
||||
@end smallexample
|
||||
|
||||
This is all good and well for GNU @samp{poke} as a standalone binary editor,
|
||||
but when it comes to @value{GDBN} we want to poke at data structures
|
||||
in the target memory of the debugged program. These structures are
|
||||
described by language-specific types, which @value{GDBN} abstracts as
|
||||
@value{GDBN} types, not Poke types.
|
||||
|
||||
For example, say we are debugging a C program that contains the
|
||||
following type:
|
||||
|
||||
@smallexample
|
||||
struct person
|
||||
@{
|
||||
int age;
|
||||
char *name;
|
||||
char *postal_address;
|
||||
@};
|
||||
@end smallexample
|
||||
|
||||
If we wanted to poke at a struct person from poke, we would need to
|
||||
write a Poke struct type that is equivalent to that C type. This is
|
||||
often not trivial, because the physical layout of data structures is
|
||||
almost always not well defined in programming languages.
|
||||
|
||||
Fortunately, @value{GDBN} provides a few commands to translate
|
||||
@value{GDBN} types to Poke types and inspect them.
|
||||
|
||||
@table @code
|
||||
@item poke-add-type @var{expr}
|
||||
@var{expr} is a @value{GDBN} expression that must evaluate to a type.
|
||||
|
||||
Translate a @value{GDBN} type to Poke and define it in the running
|
||||
poke incremental compiler. If the given type depends on other types
|
||||
that are not known to poke, add these as well.
|
||||
|
||||
Types for which @value{GDBN} doesn't know how to create a Poke
|
||||
equivalence are simply ignored.
|
||||
|
||||
@item poke-add-types @var{regexp}
|
||||
@var{regexp} is a regular expression.
|
||||
|
||||
Translate all known types whose name matches @var{regexp} to Poke and
|
||||
define them in the running poke incremental compiler. If the matched
|
||||
types depend on other types that are not known to poke, add these as
|
||||
well.
|
||||
|
||||
Types for which @value{GDBN} doesn't know how to create a Poke
|
||||
equivalence are simply ignored.
|
||||
|
||||
@item poke-dump-types
|
||||
Dump the Poke definition of all translated types, one definition per
|
||||
line.
|
||||
@end table
|
||||
|
||||
Using these commands, we can add a type for the @code{struct person} C
|
||||
type above like this:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBN}) poke-add-type struct person
|
||||
added type int
|
||||
added type struct_person
|
||||
@end smallexample
|
||||
|
||||
Note how two types are added: the requested @code{struct person} and
|
||||
also @code{int}, since the struct contains a field of that basic C
|
||||
type. Let's take a look to the type definitions:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBN}) poke-dump-types
|
||||
type int = int<32>;
|
||||
type struct_person = struct @{int age; offset<uint<64>,B> name @@ 8#B; \
|
||||
offset<uint<64>,B> postal_address;@};
|
||||
@end smallexample
|
||||
|
||||
If now we want to access a given variable of type @code{struct person}
|
||||
in the current target, we just use the created Poke types:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBN}) poke struct_person @@ 0xf00e#B
|
||||
struct_person @{
|
||||
age=0x28,
|
||||
name=0x5555555547b4UL#B,
|
||||
postal_address=0x5555555547c5UL#B
|
||||
@}
|
||||
(@value{GDBN}) poke string @@ (struct_person @@ 0xf00e#B).postal_address
|
||||
"Foo Street number 13"
|
||||
@end smallexample
|
||||
|
||||
If we wanted to add all the types known to @value{GDBN} to poke, we could so do
|
||||
by:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBN}) poke-add-types .*
|
||||
@end smallexample
|
||||
|
||||
The @command{poke-dump-types} is useful to generate Poke files with
|
||||
type definitions to be used in GNU @samp{poke}, like this:
|
||||
|
||||
@smallexample
|
||||
$ gdb -batch -ex poke-add-types .\* -ex poke-dump-types \
|
||||
-ex quit foo.so > foo-types.pk
|
||||
@end smallexample
|
||||
|
||||
@node @value{GDBN} Values and Poke
|
||||
@subsection @value{GDBN} Values and Poke
|
||||
|
||||
Poke variables are not the same than @value{GDBN} symbols, and live in
|
||||
a separated world of their own. However, it is possible to refer to
|
||||
GDB values by using the @code{$IDENTIFIER} notation in Poke programs.
|
||||
|
||||
Consider for example a C program with the following variable:
|
||||
|
||||
@smallexample
|
||||
short counter;
|
||||
@end smallexample
|
||||
|
||||
In @value{GDBN} we can access to the value of that variable like this:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBN}) counter
|
||||
$1 = 0
|
||||
@end smallexample
|
||||
|
||||
And from the poke side:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBN}) poke $counter
|
||||
0x0H
|
||||
@end smallexample
|
||||
|
||||
Note how the @value{GDBN} value is visible using the right type, in
|
||||
the case above a signed 16-bit integer. If we accessed a C value of a
|
||||
pointer type, like @code{char *str;}, we would get an offset with unit
|
||||
bytes instead:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBN}) poke $str
|
||||
0x0UL#B
|
||||
@end smallexample
|
||||
|
||||
Since many @value{GDBN} values are pointers, it is possible to access
|
||||
the address of a value by using the @code{$addr::IDENTIFIER} notation.
|
||||
For example, given the C @code{struct person} defined above and a
|
||||
variable @code{struct person jemarch;}:
|
||||
|
||||
@smallexample
|
||||
(@value{GDBN}) poke struct_person @@ $addr::jemarch
|
||||
struct_person @{
|
||||
age=0x28,
|
||||
name=0x5555555547b4UL#B,
|
||||
postal_address=0x5555555547c5UL#B
|
||||
@}
|
||||
@end smallexample
|
||||
789
gdb/poke.c
Normal file
789
gdb/poke.c
Normal file
@@ -0,0 +1,789 @@
|
||||
/* GDB integration with GNU poke.
|
||||
|
||||
Copyright (C) 2021-2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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 "defs.h"
|
||||
#include "command.h"
|
||||
#include "arch-utils.h"
|
||||
#include "target.h"
|
||||
#include "gdbcmd.h"
|
||||
extern "C" {
|
||||
#include <libpoke.h>
|
||||
}
|
||||
#include <ctype.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
/* Global poke incremental compiler. */
|
||||
|
||||
static pk_compiler poke_compiler;
|
||||
static bool poke_compiler_lives = false;
|
||||
|
||||
/* Global vector of the Poke code used to define types. This is
|
||||
filled in by poke_add_type and used by poke_dump_types. */
|
||||
|
||||
static std::vector<std::string> type_poke_strings;
|
||||
|
||||
/* Terminal hook that flushes the terminal. */
|
||||
|
||||
static void
|
||||
poke_term_flush (void)
|
||||
{
|
||||
/* Do nothing here. */
|
||||
}
|
||||
|
||||
/* Terminal hook that prints a fixed string. */
|
||||
|
||||
static void
|
||||
poke_puts (const char *str)
|
||||
{
|
||||
gdb_printf ("%s", str);
|
||||
}
|
||||
|
||||
/* Terminal hook that prints a formatted string. */
|
||||
|
||||
__attribute__ ((__format__ (__printf__, 1, 2)))
|
||||
static void
|
||||
poke_printf (const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *str;
|
||||
int r;
|
||||
|
||||
va_start (ap, format);
|
||||
r = vasprintf (&str, format, ap);
|
||||
if (r == -1)
|
||||
error (_("out of memory in vasprintf")); /* XXX fatal */
|
||||
va_end (ap);
|
||||
|
||||
gdb_printf ("%s", str);
|
||||
free (str);
|
||||
}
|
||||
|
||||
/* Terminal hook that indents to a given level. */
|
||||
|
||||
static void
|
||||
poke_term_indent (unsigned int lvl, unsigned int step)
|
||||
{
|
||||
gdb_printf ("\n%*s", (step * lvl), "");
|
||||
}
|
||||
|
||||
/* Terminal hook that starts a styling class. */
|
||||
|
||||
static void
|
||||
poke_term_class (const char *class_name)
|
||||
{
|
||||
/* Do nothing here. */
|
||||
}
|
||||
|
||||
/* Terminal hook that finishes a styling class. */
|
||||
|
||||
static int
|
||||
poke_term_end_class (const char *class_name)
|
||||
{
|
||||
/* Just report success. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Terminal hook that starts a terminal hyperlink. */
|
||||
|
||||
static void
|
||||
poke_term_hyperlink (const char *url, const char *id)
|
||||
{
|
||||
/* Do nothing here. */
|
||||
}
|
||||
|
||||
/* Terminal hook that finishes a terminal hyperlink. */
|
||||
|
||||
static int
|
||||
poke_term_end_hyperlink (void)
|
||||
{
|
||||
/* Just report success. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Terminal hook that returns the current terminal foreground
|
||||
color. */
|
||||
|
||||
static struct pk_color
|
||||
poke_term_get_color (void)
|
||||
{
|
||||
/* Just return the default foreground color. */
|
||||
struct pk_color dfl = {-1,-1,-1};
|
||||
return dfl;
|
||||
}
|
||||
|
||||
/* Terminal hook that returns the current terminal background
|
||||
color. */
|
||||
|
||||
static struct pk_color
|
||||
poke_term_get_bgcolor (void)
|
||||
{
|
||||
/* Just return the default background color. */
|
||||
struct pk_color dfl = {-1,-1,-1};
|
||||
return dfl;
|
||||
}
|
||||
|
||||
/* Terminal hook that sets the terminal foreground color. */
|
||||
|
||||
static void
|
||||
poke_term_set_color (struct pk_color color)
|
||||
{
|
||||
/* Do nothing. */
|
||||
}
|
||||
|
||||
/* Terminal hook that sets the terminal background color. */
|
||||
|
||||
static void
|
||||
poke_term_set_bgcolor (struct pk_color color)
|
||||
{
|
||||
/* Do nothing. */
|
||||
}
|
||||
|
||||
/* Implementation of the poke terminal interface, that uses the hooks
|
||||
defined above. */
|
||||
|
||||
static struct pk_term_if poke_term_if =
|
||||
{
|
||||
.flush_fn = poke_term_flush,
|
||||
.puts_fn = poke_puts,
|
||||
.printf_fn = poke_printf,
|
||||
.indent_fn = poke_term_indent,
|
||||
.class_fn = poke_term_class,
|
||||
.end_class_fn = poke_term_end_class,
|
||||
.hyperlink_fn = poke_term_hyperlink,
|
||||
.end_hyperlink_fn = poke_term_end_hyperlink,
|
||||
.get_color_fn = poke_term_get_color,
|
||||
.get_bgcolor_fn = poke_term_get_bgcolor,
|
||||
.set_color_fn = poke_term_set_color,
|
||||
.set_bgcolor_fn = poke_term_set_bgcolor,
|
||||
};
|
||||
|
||||
/* Foreign IO device hook that returns an unique name identifying the
|
||||
kind of device. */
|
||||
|
||||
static const char *
|
||||
iod_get_if_name (void)
|
||||
{
|
||||
return "GDB";
|
||||
}
|
||||
|
||||
/* Foreign IO device hook that recognizes whether a given IO space
|
||||
handler refer to this kind of device, and normalizes it for further
|
||||
use. */
|
||||
|
||||
static char *
|
||||
iod_handler_normalize (const char *handler, uint64_t flags, int *error)
|
||||
{
|
||||
char *new_handler = NULL;
|
||||
|
||||
if (strcmp (handler, "gdb://inferior/mem") == 0)
|
||||
new_handler = xstrdup (handler);
|
||||
if (error)
|
||||
*error = PK_IOD_OK;
|
||||
|
||||
return new_handler;
|
||||
}
|
||||
|
||||
/* Foreign IO device hook that opens a new device. */
|
||||
|
||||
static int iod_opened_p = 0;
|
||||
|
||||
static void *
|
||||
iod_open (const char *handler, uint64_t flags, int *error, void *data)
|
||||
{
|
||||
iod_opened_p = 1;
|
||||
return &iod_opened_p;
|
||||
}
|
||||
|
||||
/* Foreign IO device hook that reads data from a device. */
|
||||
|
||||
static int
|
||||
iod_pread (void *dev, void *buf, size_t count, pk_iod_off offset)
|
||||
{
|
||||
int ret = target_read_memory (offset, (gdb_byte *) buf, count);
|
||||
return ret == -1 ? PK_IOD_ERROR : PK_IOD_OK;
|
||||
}
|
||||
|
||||
/* Foreign IO device hook that writes data to a device. */
|
||||
|
||||
static int
|
||||
iod_pwrite (void *dev, const void *buf, size_t count, pk_iod_off offset)
|
||||
{
|
||||
int ret = target_write_memory (offset, (gdb_byte *) buf, count);
|
||||
return ret == -1 ? PK_IOD_ERROR : PK_IOD_OK;
|
||||
}
|
||||
|
||||
/* Foreign IO device hook that returns the flags of an IO device. */
|
||||
|
||||
static uint64_t
|
||||
iod_get_flags (void *dev)
|
||||
{
|
||||
return PK_IOS_F_READ | PK_IOS_F_WRITE;
|
||||
}
|
||||
|
||||
/* Foreign IO device hook that returns the size of an IO device, in
|
||||
bytes. */
|
||||
|
||||
static pk_iod_off
|
||||
iod_size (void *dev)
|
||||
{
|
||||
return (gdbarch_addr_bit (get_current_arch ()) == 32
|
||||
? 0xffffffff : 0xffffffffffffffff);
|
||||
}
|
||||
|
||||
/* Foreign IO device hook that flushes an IO device. */
|
||||
|
||||
static int
|
||||
iod_flush (void *dev, pk_iod_off offset)
|
||||
{
|
||||
/* Do nothing here. */
|
||||
return PK_OK;
|
||||
}
|
||||
|
||||
/* Foreign IO device hook that closes a given device. */
|
||||
|
||||
static int
|
||||
iod_close (void *dev)
|
||||
{
|
||||
iod_opened_p = 0;
|
||||
return PK_OK;
|
||||
}
|
||||
|
||||
/* Implementation of the poke foreign IO device interface, that uses
|
||||
the hooks defined above. */
|
||||
|
||||
static struct pk_iod_if iod_if =
|
||||
{
|
||||
iod_get_if_name,
|
||||
iod_handler_normalize,
|
||||
iod_open,
|
||||
iod_close,
|
||||
iod_pread,
|
||||
iod_pwrite,
|
||||
iod_get_flags,
|
||||
iod_size,
|
||||
iod_flush
|
||||
};
|
||||
|
||||
/* Handler for alien tokens. */
|
||||
|
||||
static struct pk_alien_token alien_token;
|
||||
|
||||
static struct pk_alien_token *
|
||||
poke_alien_token_handler (const char *id, char **errmsg)
|
||||
{
|
||||
/* In GDB alien poke tokens with the form $addr::FOO provide the
|
||||
address of the symbol `FOO' as an offset in bytes, i.e. it
|
||||
resolves to the GDB value &foo as a Poke offset with unit bytes
|
||||
and a magnitude whose width is the number of bits conforming an
|
||||
address in the target architecture.
|
||||
|
||||
$FOO, on the other hand, provides the value of the symbol FOO
|
||||
incarnated in a proper Poke value, provided that FOO is of a type
|
||||
that this handler knows how to handle. Otherwise the string is
|
||||
not recognized as a token. */
|
||||
|
||||
if (strncmp (id, "addr::", 6) == 0)
|
||||
{
|
||||
CORE_ADDR addr;
|
||||
|
||||
std::string expr = "&";
|
||||
expr += id + 6;
|
||||
|
||||
try
|
||||
{
|
||||
addr = parse_and_eval_address (expr.c_str ());
|
||||
}
|
||||
catch (const gdb_exception_error &except)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
alien_token.kind = PK_ALIEN_TOKEN_OFFSET;
|
||||
alien_token.value.offset.magnitude = addr;
|
||||
gdb_assert (gdbarch_addr_bit (get_current_arch ()) <= 64);
|
||||
alien_token.value.offset.width = gdbarch_addr_bit (get_current_arch ());
|
||||
alien_token.value.offset.signed_p = 0;
|
||||
alien_token.value.offset.unit = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct value *value;
|
||||
|
||||
try
|
||||
{
|
||||
value = parse_and_eval (id);
|
||||
}
|
||||
catch (const gdb_exception_error &except)
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
struct type *type = value->type ();
|
||||
|
||||
if (can_dereference (type))
|
||||
{
|
||||
alien_token.kind = PK_ALIEN_TOKEN_OFFSET;
|
||||
alien_token.value.offset.magnitude
|
||||
= value_as_address (value);
|
||||
alien_token.value.offset.width = type->length () * 8;
|
||||
alien_token.value.offset.signed_p = !type->is_unsigned ();
|
||||
alien_token.value.offset.unit = 8;
|
||||
}
|
||||
else if (is_integral_type (type))
|
||||
{
|
||||
alien_token.kind = PK_ALIEN_TOKEN_INTEGER;
|
||||
alien_token.value.integer.magnitude
|
||||
= value_as_long (value);
|
||||
alien_token.value.integer.width = type->length () * 8;
|
||||
alien_token.value.integer.signed_p
|
||||
= !type->is_unsigned ();
|
||||
}
|
||||
else
|
||||
goto error;
|
||||
}
|
||||
|
||||
*errmsg = NULL;
|
||||
return &alien_token;
|
||||
|
||||
error:
|
||||
std::string emsg = "can't access GDB variable '";
|
||||
emsg += id;
|
||||
emsg += "'";
|
||||
*errmsg = xstrdup (emsg.c_str ());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Given a string, prefix it in order to avoid collision with Poke's
|
||||
keywords. */
|
||||
|
||||
static std::string
|
||||
normalize_poke_identifier (std::string prefix, std::string str)
|
||||
{
|
||||
if (!pk_keyword_p (poke_compiler, str.c_str ()))
|
||||
str = prefix + str;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Given a GDB type name, mangle it to a valid Poke type name. */
|
||||
|
||||
static std::string
|
||||
gdb_type_name_to_poke (std::string str, struct type *type = NULL)
|
||||
{
|
||||
for (int i = 0; i < str.length (); ++i)
|
||||
if (!(str.begin()[i] == '_'
|
||||
|| (str.begin()[i] >= 'a' && str.begin()[i] <= 'z')
|
||||
|| (str.begin()[i] >= '0' && str.begin()[i] <= '9')
|
||||
|| (str.begin()[i] >= 'A' && str.begin()[i] <= 'Z')))
|
||||
str.begin()[i] = '_';
|
||||
|
||||
if (type)
|
||||
{
|
||||
/* Prepend struct and union tags with suitable prefixes. This
|
||||
is to avoid ending with recursive typedefs in C programs. */
|
||||
if (type->code () == TYPE_CODE_STRUCT)
|
||||
str = "struct_" + str;
|
||||
else if (type->code () == TYPE_CODE_UNION)
|
||||
str = "union_" + str;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Command to feed the poke compiler with the definition of some given
|
||||
GDB type. */
|
||||
|
||||
static void poke_command (const char *args, int from_tty);
|
||||
|
||||
static std::string
|
||||
poke_add_type (struct type *type)
|
||||
{
|
||||
std::string type_name;
|
||||
std::string str = "";
|
||||
|
||||
if (type != nullptr)
|
||||
{
|
||||
if (type->name ())
|
||||
type_name = type->name ();
|
||||
|
||||
/* Do not try to add a type that is already defined. */
|
||||
if (type_name != ""
|
||||
&& pk_decl_p (poke_compiler,
|
||||
gdb_type_name_to_poke (type_name, type).c_str (),
|
||||
PK_DECL_KIND_TYPE))
|
||||
return type_name;
|
||||
|
||||
switch (type->code ())
|
||||
{
|
||||
case TYPE_CODE_PTR:
|
||||
{
|
||||
str = ("offset<uint<"
|
||||
+ (std::to_string (type->length () * 8))
|
||||
+ ">,B>");
|
||||
break;
|
||||
}
|
||||
case TYPE_CODE_TYPEDEF:
|
||||
{
|
||||
struct type *target_type = type->target_type ();
|
||||
std::string target_type_code = poke_add_type (target_type);
|
||||
|
||||
if (target_type_code == "")
|
||||
goto skip;
|
||||
|
||||
if (target_type->name ())
|
||||
str += gdb_type_name_to_poke (target_type->name (), target_type);
|
||||
else
|
||||
str += target_type_code;
|
||||
break;
|
||||
}
|
||||
case TYPE_CODE_INT:
|
||||
{
|
||||
size_t type_length = type->length () * 8;
|
||||
|
||||
if (type_length > 64)
|
||||
goto skip;
|
||||
|
||||
if (type->is_unsigned ())
|
||||
str += "u";
|
||||
str += "int<";
|
||||
str += std::to_string (type_length);
|
||||
str += ">";
|
||||
break;
|
||||
}
|
||||
case TYPE_CODE_ARRAY:
|
||||
{
|
||||
struct type *target_type = type->target_type ();
|
||||
size_t target_type_length = target_type->length ();
|
||||
std::string target_type_code
|
||||
= poke_add_type (target_type);
|
||||
|
||||
if (target_type_code == "")
|
||||
goto skip;
|
||||
|
||||
/* Poke doesn't have multi-dimensional arrays. */
|
||||
if (type->is_multi_dimensional ())
|
||||
goto skip;
|
||||
|
||||
if (target_type->name ())
|
||||
str = gdb_type_name_to_poke (target_type->name (), target_type);
|
||||
else
|
||||
str = target_type_code;
|
||||
|
||||
str += "[";
|
||||
str += std::to_string (type->length () / target_type_length);
|
||||
str += "]";
|
||||
break;
|
||||
}
|
||||
case TYPE_CODE_STRUCT:
|
||||
{
|
||||
size_t natural_bitpos = 0;
|
||||
str += "struct {";
|
||||
|
||||
for (int idx = 0; idx < type->num_fields (); idx++)
|
||||
{
|
||||
std::string field_name
|
||||
= normalize_poke_identifier ("__f", type->field (idx).name ());
|
||||
struct type *field_type = type->field (idx).type ();
|
||||
size_t field_bitpos = type->field (idx).loc_bitpos ();
|
||||
|
||||
if (idx > 0)
|
||||
str += " ";
|
||||
if (field_type->name ())
|
||||
{
|
||||
if (poke_add_type (field_type) == "")
|
||||
goto skip;
|
||||
str += gdb_type_name_to_poke (field_type->name (), field_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string pstr = poke_add_type (field_type);
|
||||
if (pstr == "")
|
||||
goto skip;
|
||||
str += pstr;
|
||||
}
|
||||
str += " ";
|
||||
if (field_name != "")
|
||||
str += field_name;
|
||||
if (field_bitpos != natural_bitpos)
|
||||
str += " @ " + (field_bitpos % 8 == 0
|
||||
? std::to_string (field_bitpos / 8) + "#B"
|
||||
: std::to_string (field_bitpos) + "#b");
|
||||
str += ";";
|
||||
|
||||
natural_bitpos = field_bitpos + field_type->length () * 8;
|
||||
}
|
||||
|
||||
str += "}";
|
||||
break;
|
||||
}
|
||||
default:
|
||||
goto skip;
|
||||
break;
|
||||
}
|
||||
|
||||
if (type_name != "")
|
||||
{
|
||||
std::string poke_type_name
|
||||
= gdb_type_name_to_poke (type_name, type);
|
||||
|
||||
std::string deftype = "type ";
|
||||
deftype += poke_type_name;
|
||||
deftype += " = ";
|
||||
deftype += str;
|
||||
|
||||
type_poke_strings.push_back (deftype);
|
||||
poke_command (deftype.c_str(), 0 /* from_tty */);
|
||||
gdb_printf ("added type %s\n", poke_type_name.c_str ());
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
|
||||
skip:
|
||||
if (type_name != "")
|
||||
gdb_printf ("skipped type %s\n", type_name.c_str ());
|
||||
return "";
|
||||
}
|
||||
|
||||
/* Call the default poke exception handler. */
|
||||
|
||||
static void
|
||||
poke_handle_exception (pk_val exception)
|
||||
{
|
||||
pk_val handler = pk_decl_val (poke_compiler, "gdb_exception_handler");
|
||||
|
||||
if (handler == PK_NULL)
|
||||
error (_("Couldn't get a handler for poke gdb_exception_handler"));
|
||||
if (pk_call (poke_compiler, handler, NULL, NULL, 1, exception)
|
||||
== PK_ERROR)
|
||||
error (_("Couldn't call gdb_exception_handler in poke"));
|
||||
}
|
||||
|
||||
/* Start the poke incremental compiler. */
|
||||
|
||||
static void
|
||||
start_poke (void)
|
||||
{
|
||||
/* Note how we are creating an incremental compiler without the
|
||||
standard Poke types (int, etc) because they collide with the C
|
||||
types. */
|
||||
poke_compiler = pk_compiler_new_with_flags (&poke_term_if,
|
||||
PK_F_NOSTDTYPES);
|
||||
if (poke_compiler == NULL)
|
||||
error (_("Couldn't start the poke incremental compiler."));
|
||||
|
||||
/* Install the handler for alien tokens that recognizes GDB
|
||||
symbols. */
|
||||
pk_set_alien_token_fn (poke_compiler, poke_alien_token_handler);
|
||||
|
||||
/* Use hexadecimal output by default. */
|
||||
pk_set_obase (poke_compiler, 16);
|
||||
|
||||
/* Use `tree' printing mode by default. */
|
||||
pk_set_omode (poke_compiler, PK_PRINT_TREE);
|
||||
|
||||
/* Install our foreign IO device interface to access the target's
|
||||
memory. */
|
||||
if (pk_register_iod (poke_compiler, &iod_if) != PK_OK)
|
||||
error (_("Could not register the foreign IO device interface in poke."));
|
||||
|
||||
/* Provide access to pickles installed by poke applications, also to
|
||||
the pickles installed by GDB. */
|
||||
pk_val pk_load_path = pk_decl_val (poke_compiler, "load_path");
|
||||
std::string load_path = pk_string_str (pk_load_path);
|
||||
load_path += ":" + gdb_datadir + "/poke:%DATADIR%/pickles";
|
||||
pk_decl_set_val (poke_compiler, "load_path",
|
||||
pk_make_string (load_path.c_str ()));
|
||||
|
||||
/* Load the Poke components. */
|
||||
if (pk_load (poke_compiler, "gdb") != PK_OK)
|
||||
error (_("Could not load gdb.pk"));
|
||||
|
||||
poke_compiler_lives = true;
|
||||
}
|
||||
|
||||
/* Function to finalize the poke subsystem. This is registered with
|
||||
make_final_cleanup in _initialize_poke. */
|
||||
|
||||
static void
|
||||
poke_finalize (void *arg)
|
||||
{
|
||||
if (poke_compiler_lives)
|
||||
{
|
||||
pk_val val, exit_exception;
|
||||
if (pk_compile_statement (poke_compiler,
|
||||
"try close (get_ios); catch if E_no_ios {}",
|
||||
NULL, &val, &exit_exception) != PK_OK
|
||||
|| exit_exception != PK_NULL)
|
||||
error (_("Error while closing an IOS on exit."));
|
||||
|
||||
pk_compiler_free (poke_compiler);
|
||||
poke_compiler_lives = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Command to dump the Poke definition of known types. */
|
||||
|
||||
static void
|
||||
poke_dump_types (const char *args, int from_tty)
|
||||
{
|
||||
if (!poke_compiler_lives)
|
||||
start_poke ();
|
||||
|
||||
for (const std::string &s : type_poke_strings)
|
||||
printf ("%s;\n", s.c_str ());
|
||||
}
|
||||
|
||||
/* Commands to add GDB types to the running poke compiler. */
|
||||
|
||||
static void
|
||||
poke_add_type_command (const char *args, int from_tty)
|
||||
{
|
||||
if (!poke_compiler_lives)
|
||||
start_poke ();
|
||||
|
||||
std::string type_name = skip_spaces (args);
|
||||
type_name = gdb_type_name_to_poke (type_name);
|
||||
|
||||
expression_up expr = parse_expression (args);
|
||||
struct value *val = evaluate_type (expr.get ());
|
||||
struct type *type = val->type ();
|
||||
|
||||
poke_add_type (type);
|
||||
}
|
||||
|
||||
static void
|
||||
poke_add_types (const char *args, int from_tty)
|
||||
{
|
||||
if (!poke_compiler_lives)
|
||||
start_poke ();
|
||||
|
||||
std::string symbol_name_regexp = skip_spaces (args);
|
||||
global_symbol_searcher spec (TYPES_DOMAIN, symbol_name_regexp.c_str ());
|
||||
std::vector<symbol_search> symbols = spec.search ();
|
||||
for (const symbol_search &p : symbols)
|
||||
{
|
||||
QUIT;
|
||||
|
||||
struct symbol *sym = p.symbol;
|
||||
struct type *type = sym->type ();
|
||||
|
||||
if (type)
|
||||
poke_add_type (type);
|
||||
}
|
||||
}
|
||||
|
||||
/* Command to execute a poke statement or declaration. */
|
||||
|
||||
static void
|
||||
poke_command (const char *args, int from_tty)
|
||||
{
|
||||
if (!poke_compiler_lives)
|
||||
start_poke ();
|
||||
|
||||
int what; /* 0 -> declaration, 1 -> statement */
|
||||
const char *end;
|
||||
std::string cmd;
|
||||
pk_val exit_exception = PK_NULL;
|
||||
|
||||
#define IS_COMMAND(input, cmd) \
|
||||
(strncmp ((input), (cmd), sizeof (cmd) - 1) == 0 \
|
||||
&& ((input)[sizeof (cmd) - 1] == ' ' || (input)[sizeof (cmd) - 1] == '\t'))
|
||||
|
||||
args = skip_spaces (args);
|
||||
if (args == NULL)
|
||||
return;
|
||||
|
||||
if (IS_COMMAND (args, "fun"))
|
||||
{
|
||||
what = 0;
|
||||
cmd = args;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IS_COMMAND (args, "var")
|
||||
|| IS_COMMAND (args, "type")
|
||||
|| IS_COMMAND (args, "unit"))
|
||||
what = 0;
|
||||
else
|
||||
what = 1;
|
||||
|
||||
cmd = args;
|
||||
cmd += ';';
|
||||
}
|
||||
|
||||
pk_set_lexical_cuckolding_p (poke_compiler, 1);
|
||||
|
||||
if (what == 0)
|
||||
{
|
||||
/* Declaration. */
|
||||
if (pk_compile_buffer (poke_compiler, cmd.c_str (),
|
||||
&end, &exit_exception) != PK_OK
|
||||
|| exit_exception != PK_NULL)
|
||||
goto error;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Statement. */
|
||||
pk_val val;
|
||||
|
||||
if (pk_compile_statement (poke_compiler, cmd.c_str (), &end,
|
||||
&val, &exit_exception) != PK_OK
|
||||
|| exit_exception != PK_NULL)
|
||||
goto error;
|
||||
|
||||
if (val != PK_NULL)
|
||||
{
|
||||
pk_print_val (poke_compiler, val, &exit_exception);
|
||||
poke_puts ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
pk_set_lexical_cuckolding_p (poke_compiler, 0);
|
||||
#undef IS_COMMAND
|
||||
error:
|
||||
if (exit_exception != PK_NULL)
|
||||
poke_handle_exception (exit_exception);
|
||||
}
|
||||
|
||||
/* Initialize the poke GDB subsystem. */
|
||||
|
||||
void _initialize_poke (void);
|
||||
void
|
||||
_initialize_poke ()
|
||||
{
|
||||
add_com ("poke-add-type", class_vars, poke_add_type_command, _("\
|
||||
Make Poke aware of a GDB type given an expression.\n\
|
||||
Usage: poke-add-type EXPRESSION\n"));
|
||||
|
||||
add_com ("poke-add-types", class_vars, poke_add_types, _("\
|
||||
Make Poke aware of GDB types based on a regexp.\n\
|
||||
Usage: poke-add-types REGEXP\n"));
|
||||
|
||||
add_com ("poke-dump-types", class_vars, poke_dump_types, _("\
|
||||
Dump the definition of all the GDB types known to poke.\n\
|
||||
Usage: poke-dump-types\n"));
|
||||
|
||||
add_com ("poke", class_vars, poke_command, _("\
|
||||
Execute a Poke statement or declaration.\n\
|
||||
Usage: poke [STMT]\n"));
|
||||
|
||||
make_final_cleanup (poke_finalize, NULL);
|
||||
}
|
||||
42
gdb/poke/gdb.pk
Normal file
42
gdb/poke/gdb.pk
Normal file
@@ -0,0 +1,42 @@
|
||||
/* GDB integration with GNU poke. Poke parts.
|
||||
|
||||
Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
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/>. */
|
||||
|
||||
/* Exception handler. */
|
||||
|
||||
fun gdb_exception_handler = (Exception exception) void:
|
||||
{
|
||||
if (exception.code != EC_exit && exception.code != EC_signal)
|
||||
{
|
||||
print ("unhandled "
|
||||
+ (exception.name == "" ? "unknown" : exception.name)
|
||||
+ " exception\n");
|
||||
|
||||
if (exception.location != "" || exception.msg != "")
|
||||
{
|
||||
if (exception.location != "")
|
||||
print (exception.location + " ");
|
||||
print (exception.msg + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Open the memory of the inferior being debugged under GDB as the
|
||||
current IO space. */
|
||||
|
||||
open ("gdb://inferior/mem");
|
||||
29
gdb/testsuite/gdb.poke/poke-types.c
Normal file
29
gdb/testsuite/gdb.poke/poke-types.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/* This testcase is part of GDB, the GNU debugger.
|
||||
|
||||
Copyright 2023 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 <stdint.h>
|
||||
|
||||
int32_t i32;
|
||||
int16_t i16;
|
||||
uint64_t u64;
|
||||
char *pointer;
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
36
gdb/testsuite/gdb.poke/poke-types.exp
Normal file
36
gdb/testsuite/gdb.poke/poke-types.exp
Normal file
@@ -0,0 +1,36 @@
|
||||
# This testcase is part of GDB, the GNU debugger.
|
||||
#
|
||||
# Copyright 2023 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/>.
|
||||
|
||||
require allow_poke_tests
|
||||
|
||||
global GDB_DATA_DIRECTORY
|
||||
if ![info exists GDB_DATA_DIRECTORY] {
|
||||
set GDB_DATA_DIRECTORY [file normalize "$srcdir/.."]
|
||||
}
|
||||
|
||||
standard_testfile
|
||||
if [prepare_for_testing "failed to prepare" $testfile $srcfile] {
|
||||
return -1
|
||||
}
|
||||
|
||||
if ![runto_main] {
|
||||
return -1
|
||||
}
|
||||
|
||||
# Add all types
|
||||
gdb_test "poke-add-type int" "added type int"
|
||||
gdb_test "poke-dump-types" "type int = int<\[0-9\]*>;"
|
||||
@@ -2537,6 +2537,13 @@ proc allow_rust_tests {} {
|
||||
return 1
|
||||
}
|
||||
|
||||
# Return a 1 fo rconfigurations that support GNU poke integration.
|
||||
|
||||
proc allow_poke_tests {} {
|
||||
set output [remote_exec host $::GDB "$::INTERNAL_GDBFLAGS --configuration"]
|
||||
return [expr {[string first "--with-poke" $output] != -1}]
|
||||
}
|
||||
|
||||
# Return a 1 for configurations that support Python scripting.
|
||||
|
||||
gdb_caching_proc allow_python_tests {} {
|
||||
|
||||
10
gdb/top.c
10
gdb/top.c
@@ -1633,6 +1633,16 @@ This GDB was configured as follows:\n\
|
||||
"));
|
||||
#endif
|
||||
|
||||
#if HAVE_POKE
|
||||
gdb_printf (stream, _("\
|
||||
--with-poke\n\
|
||||
"));
|
||||
#else
|
||||
gdb_printf (stream, _("\
|
||||
--without-poke\n\
|
||||
"));
|
||||
#endif
|
||||
|
||||
#if HAVE_AMD_DBGAPI
|
||||
gdb_printf (stream, _("\
|
||||
--with-amd-dbgapi\n\
|
||||
|
||||
4
intl/aclocal.m4
vendored
4
intl/aclocal.m4
vendored
@@ -1,6 +1,6 @@
|
||||
# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
||||
19
intl/configure
vendored
19
intl/configure
vendored
@@ -696,6 +696,7 @@ infodir
|
||||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
@@ -775,6 +776,7 @@ datadir='${datarootdir}'
|
||||
sysconfdir='${prefix}/etc'
|
||||
sharedstatedir='${prefix}/com'
|
||||
localstatedir='${prefix}/var'
|
||||
runstatedir='${localstatedir}/run'
|
||||
includedir='${prefix}/include'
|
||||
oldincludedir='/usr/include'
|
||||
docdir='${datarootdir}/doc/${PACKAGE}'
|
||||
@@ -1027,6 +1029,15 @@ do
|
||||
| -silent | --silent | --silen | --sile | --sil)
|
||||
silent=yes ;;
|
||||
|
||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||
| --run | --ru | --r)
|
||||
ac_prev=runstatedir ;;
|
||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||
| --run=* | --ru=* | --r=*)
|
||||
runstatedir=$ac_optarg ;;
|
||||
|
||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||
ac_prev=sbindir ;;
|
||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||
@@ -1164,7 +1175,7 @@ fi
|
||||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||
libdir localedir mandir
|
||||
libdir localedir mandir runstatedir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
@@ -1317,6 +1328,7 @@ Fine tuning of the installation directories:
|
||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||
@@ -4656,6 +4668,8 @@ main ()
|
||||
if (*(data + i) != *(data3 + i))
|
||||
return 14;
|
||||
close (fd);
|
||||
free (data);
|
||||
free (data3);
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
@@ -6857,6 +6871,9 @@ case "${host}" in
|
||||
# sets the default TLS model and affects inlining.
|
||||
PICFLAG=-fPIC
|
||||
;;
|
||||
loongarch*-*-*)
|
||||
PICFLAG=-fpic
|
||||
;;
|
||||
mips-sgi-irix6*)
|
||||
# PIC is the default.
|
||||
;;
|
||||
|
||||
4
libiberty/aclocal.m4
vendored
4
libiberty/aclocal.m4
vendored
@@ -1,6 +1,6 @@
|
||||
# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.16.3 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
||||
26
libiberty/configure
vendored
26
libiberty/configure
vendored
@@ -684,6 +684,7 @@ infodir
|
||||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
@@ -763,6 +764,7 @@ datadir='${datarootdir}'
|
||||
sysconfdir='${prefix}/etc'
|
||||
sharedstatedir='${prefix}/com'
|
||||
localstatedir='${prefix}/var'
|
||||
runstatedir='${localstatedir}/run'
|
||||
includedir='${prefix}/include'
|
||||
oldincludedir='/usr/include'
|
||||
docdir='${datarootdir}/doc/${PACKAGE}'
|
||||
@@ -1015,6 +1017,15 @@ do
|
||||
| -silent | --silent | --silen | --sile | --sil)
|
||||
silent=yes ;;
|
||||
|
||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||
| --run | --ru | --r)
|
||||
ac_prev=runstatedir ;;
|
||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||
| --run=* | --ru=* | --r=*)
|
||||
runstatedir=$ac_optarg ;;
|
||||
|
||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||
ac_prev=sbindir ;;
|
||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||
@@ -1152,7 +1163,7 @@ fi
|
||||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||
libdir localedir mandir
|
||||
libdir localedir mandir runstatedir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
@@ -1305,6 +1316,7 @@ Fine tuning of the installation directories:
|
||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||
@@ -4430,7 +4442,7 @@ else
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -4476,7 +4488,7 @@ else
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -4500,7 +4512,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -4545,7 +4557,7 @@ else
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -4569,7 +4581,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@@ -7727,6 +7739,8 @@ main ()
|
||||
if (*(data + i) != *(data3 + i))
|
||||
return 14;
|
||||
close (fd);
|
||||
free (data);
|
||||
free (data3);
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
|
||||
Reference in New Issue
Block a user