diff --git a/binutils/wrstabs.c b/binutils/wrstabs.c index 3d1839f131e..cae0e251695 100644 --- a/binutils/wrstabs.c +++ b/binutils/wrstabs.c @@ -1470,12 +1470,15 @@ stab_start_class_type (void *p, const char *tag, unsigned int id, bfd_boolean st vtable = (char *) xmalloc (20); sprintf (vtable, "~%%%ld", info->type_stack->index); } - else + else if (vstring) { vtable = (char *) xmalloc (strlen (vstring) + 3); sprintf (vtable, "~%%%s", vstring); free (vstring); } + else + abort (); + info->type_stack->vtable = vtable; } diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 0f495783600..220c88263ee 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -382,6 +382,7 @@ SUBDIR_PYTHON_SRCS = \ python/py-instruction.c \ python/py-lazy-string.c \ python/py-linetable.c \ + python/py-minsymbol.c \ python/py-newobjfileevent.c \ python/py-objfile.c \ python/py-param.c \ @@ -390,10 +391,12 @@ SUBDIR_PYTHON_SRCS = \ python/py-record.c \ python/py-record-btrace.c \ python/py-record-full.c \ + python/py-register.c \ python/py-signalevent.c \ python/py-stopevent.c \ python/py-symbol.c \ python/py-symtab.c \ + python/py-target.c \ python/py-threadevent.c \ python/py-type.c \ python/py-unwind.c \ @@ -1751,7 +1754,7 @@ info install-info clean-info dvi pdf install-pdf html install-html: force install: all @$(MAKE) $(FLAGS_TO_PASS) install-only -install-only: $(CONFIG_INSTALL) +install-only: install-gstack $(CONFIG_INSTALL) transformed_name=`t='$(program_transform_name)'; \ echo gdb | sed -e "$$t"` ; \ if test "x$$transformed_name" = x; then \ @@ -1800,7 +1803,25 @@ install-guile: install-python: $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(GDB_DATADIR)/python/gdb -uninstall: force $(CONFIG_UNINSTALL) +GSTACK=gstack +.PHONY: install-gstack +install-gstack: + transformed_name=`t='$(program_transform_name)'; \ + echo $(GSTACK) | sed -e "$$t"` ; \ + if test "x$$transformed_name" = x; then \ + transformed_name=$(GSTACK) ; \ + else \ + true ; \ + fi ; \ + $(SHELL) $(srcdir)/../mkinstalldirs $(DESTDIR)$(bindir) ; \ + $(INSTALL_PROGRAM) $(srcdir)/$(GSTACK).sh \ + $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) ; \ + : $(SHELL) $(srcdir)/../mkinstalldirs \ + $(DESTDIR)$(man1dir) ; \ + : $(INSTALL_DATA) $(srcdir)/gstack.1 \ + $(DESTDIR)$(man1dir)/$$transformed_name.1 + +uninstall: force uninstall-gstack $(CONFIG_UNINSTALL) transformed_name=`t='$(program_transform_name)'; \ echo gdb | sed -e $$t` ; \ if test "x$$transformed_name" = x; then \ @@ -1823,6 +1844,18 @@ uninstall: force $(CONFIG_UNINSTALL) fi @$(MAKE) DO=uninstall "DODIRS=$(SUBDIRS)" $(FLAGS_TO_PASS) subdir_do +.PHONY: uninstall-gstack +uninstall-gstack: + transformed_name=`t='$(program_transform_name)'; \ + echo $(GSTACK) | sed -e $$t` ; \ + if test "x$$transformed_name" = x; then \ + transformed_name=$(GSTACK) ; \ + else \ + true ; \ + fi ; \ + rm -f $(DESTDIR)$(bindir)/$$transformed_name$(EXEEXT) \ + $(DESTDIR)$(man1dir)/$$transformed_name.1 + # The C++ name parser can be built standalone for testing. test-cp-name-parser.o: cp-name-parser.c $(COMPILE) -DTEST_CPNAMES cp-name-parser.c @@ -2054,6 +2087,12 @@ stamp-h: $(srcdir)/config.in config.status CONFIG_LINKS= \ $(SHELL) config.status +.gdbinit: $(srcdir)/gdbinit.in config.status + CONFIG_FILES=".gdbinit:gdbinit.in" \ + CONFIG_COMMANDS= \ + CONFIG_HEADERS= \ + $(SHELL) config.status + config.status: $(srcdir)/configure configure.nat configure.tgt configure.host ../bfd/development.sh $(SHELL) config.status --recheck diff --git a/gdb/NEWS b/gdb/NEWS index 5309a8f923b..2c2e34e10ec 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -376,6 +376,8 @@ SH-5/SH64 running OpenBSD SH-5/SH64 support in sh*-*-openbsd* *** Changes in GDB 8.1 +* Fortran: Support pointers to dynamic types. + * GDB now supports dynamically creating arbitrary register groups specified in XML target descriptions. This allows for finer grain grouping of registers on systems with a large amount of registers. diff --git a/gdb/aarch64-linux-nat.c b/gdb/aarch64-linux-nat.c index 8ca96143013..41d9eaa47d0 100644 --- a/gdb/aarch64-linux-nat.c +++ b/gdb/aarch64-linux-nat.c @@ -65,14 +65,14 @@ class aarch64_linux_nat_target final : public linux_nat_target int can_use_hw_breakpoint (enum bptype, int, int) override; int insert_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override; int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override; - int region_ok_for_hw_watchpoint (CORE_ADDR, int) override; + int region_ok_for_hw_watchpoint (CORE_ADDR, LONGEST) override; int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, struct expression *) override; int remove_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, struct expression *) override; bool stopped_by_watchpoint () override; bool stopped_data_address (CORE_ADDR *) override; - bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override; + bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, LONGEST) override; int can_do_single_step () override; @@ -855,7 +855,7 @@ aarch64_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len, /* Implement the "region_ok_for_hw_watchpoint" target_ops method. */ int -aarch64_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) +aarch64_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, LONGEST len) { return aarch64_linux_region_ok_for_watchpoint (addr, len); } @@ -934,7 +934,8 @@ aarch64_linux_nat_target::stopped_by_watchpoint () bool aarch64_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr, - CORE_ADDR start, int length) + CORE_ADDR start, + LONGEST length) { return start <= addr && start + length - 1 >= addr; } diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index cb185ee337f..41379bc615a 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -3210,8 +3210,8 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) vq = aarch64_get_tdesc_vq (info.target_desc); if (vq > AARCH64_MAX_SVE_VQ) - internal_error (__FILE__, __LINE__, _("VQ out of bounds: %ld (max %d)"), - vq, AARCH64_MAX_SVE_VQ); + internal_error (__FILE__, __LINE__, _("VQ out of bounds: %s (max %d)"), + pulongest(vq), AARCH64_MAX_SVE_VQ); /* If there is already a candidate, use it. */ for (gdbarch_list *best_arch = gdbarch_list_lookup_by_info (arches, &info); diff --git a/gdb/aclocal.m4 b/gdb/aclocal.m4 index 110b416e615..a0edc50f5fc 100644 --- a/gdb/aclocal.m4 +++ b/gdb/aclocal.m4 @@ -11,7 +11,223 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant . +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES + + +# PKG_INSTALLDIR(DIRECTORY) +# ------------------------- +# Substitutes the variable pkgconfigdir as the location where a module +# should install pkg-config .pc files. By default the directory is +# $libdir/pkgconfig, but the default can be changed by passing +# DIRECTORY. The user can override through the --with-pkgconfigdir +# parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +]) dnl PKG_INSTALLDIR + + +# PKG_NOARCH_INSTALLDIR(DIRECTORY) +# ------------------------- +# Substitutes the variable noarch_pkgconfigdir as the location where a +# module should install arch-independent pkg-config .pc files. By +# default the directory is $datadir/pkgconfig, but the default can be +# changed by passing DIRECTORY. The user can override through the +# --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +]) dnl PKG_NOARCH_INSTALLDIR + + +# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# ------------------------------------------- +# Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])# PKG_CHECK_VAR + m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) + # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2017 Free Software Foundation, Inc. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index ccf8ed8039e..ead27228897 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -78,7 +78,7 @@ static struct type *desc_bounds_type (struct type *); static struct value *desc_bounds (struct value *); -static int fat_pntr_bounds_bitpos (struct type *); +static LONGEST fat_pntr_bounds_bitpos (struct type *); static int fat_pntr_bounds_bitsize (struct type *); @@ -86,13 +86,13 @@ static struct type *desc_data_target_type (struct type *); static struct value *desc_data (struct value *); -static int fat_pntr_data_bitpos (struct type *); +static LONGEST fat_pntr_data_bitpos (struct type *); static int fat_pntr_data_bitsize (struct type *); static struct value *desc_one_bound (struct value *, int, int); -static int desc_bound_bitpos (struct type *, int, int); +static LONGEST desc_bound_bitpos (struct type *, int, int); static int desc_bound_bitsize (struct type *, int, int); @@ -176,7 +176,7 @@ static struct type *static_unwrap_type (struct type *type); static struct value *unwrap_value (struct value *); -static struct type *constrained_packed_array_type (struct type *, long *); +static struct type *constrained_packed_array_type (struct type *, LONGEST *); static struct type *decode_constrained_packed_array_type (struct type *); @@ -215,14 +215,14 @@ static struct value *value_val_atr (struct type *, struct value *); static struct symbol *standard_lookup (const char *, const struct block *, domain_enum); -static struct value *ada_search_struct_field (const char *, struct value *, int, +static struct value *ada_search_struct_field (const char *, struct value *, LONGEST, struct type *); -static struct value *ada_value_primitive_field (struct value *, int, int, +static struct value *ada_value_primitive_field (struct value *, LONGEST, int, struct type *); -static int find_struct_field (const char *, struct type *, int, - struct type **, int *, int *, int *, int *); +static int find_struct_field (const char *, struct type *, LONGEST, + struct type **, LONGEST *, int *, int *, int *); static int ada_resolve_function (struct block_symbol *, int, struct value **, int, const char *, @@ -233,7 +233,7 @@ static int ada_is_direct_array_type (struct type *); static void ada_language_arch_info (struct gdbarch *, struct language_arch_info *); -static struct value *ada_index_struct_field (int, struct value *, int, +static struct value *ada_index_struct_field (LONGEST, struct value *, LONGEST, struct type *); static struct value *assign_aggregate (struct value *, struct value *, @@ -702,7 +702,7 @@ coerce_unspec_val_to_type (struct value *val, struct type *type) } static const gdb_byte * -cond_offset_host (const gdb_byte *valaddr, long offset) +cond_offset_host (const gdb_byte *valaddr, LONGEST offset) { if (valaddr == NULL) return NULL; @@ -711,7 +711,7 @@ cond_offset_host (const gdb_byte *valaddr, long offset) } static CORE_ADDR -cond_offset_target (CORE_ADDR address, long offset) +cond_offset_target (CORE_ADDR address, LONGEST offset) { if (address == 0) return 0; @@ -1753,7 +1753,7 @@ desc_bounds (struct value *arr) /* If TYPE is the type of an array-descriptor (fat pointer), the bit position of the field containing the address of the bounds data. */ -static int +static LONGEST fat_pntr_bounds_bitpos (struct type *type) { return TYPE_FIELD_BITPOS (desc_base_type (type), 1); @@ -1819,7 +1819,7 @@ desc_data (struct value *arr) /* If TYPE is the type of an array-descriptor (fat pointer), the bit position of the field containing the address of the data. */ -static int +static LONGEST fat_pntr_data_bitpos (struct type *type) { return TYPE_FIELD_BITPOS (desc_base_type (type), 0); @@ -1854,7 +1854,7 @@ desc_one_bound (struct value *bounds, int i, int which) of the Ith lower bound stored in it, if WHICH is 0, and the Ith upper bound, if WHICH is 1. The first bound is I=1. */ -static int +static LONGEST desc_bound_bitpos (struct type *type, int i, int which) { return TYPE_FIELD_BITPOS (desc_base_type (type), 2 * i + which - 2); @@ -2044,7 +2044,7 @@ ada_type_of_array (struct value *arr, int bounds) zero, and does not need to be recomputed. */ if (lo < hi) { - int array_bitsize = + LONGEST array_bitsize = (hi - lo + 1) * TYPE_FIELD_BITSIZE (elt_type, 0); TYPE_LENGTH (array_type) = (array_bitsize + 7) / 8; @@ -2204,7 +2204,7 @@ decode_packed_array_bitsize (struct type *type) the length is arbitrary. */ static struct type * -constrained_packed_array_type (struct type *type, long *elt_bits) +constrained_packed_array_type (struct type *type, LONGEST *elt_bits) { struct type *new_elt_type; struct type *new_type; @@ -2258,7 +2258,7 @@ decode_constrained_packed_array_type (struct type *type) char *name; const char *tail; struct type *shadow_type; - long bits; + LONGEST bits; if (!raw_name) raw_name = ada_type_name (desc_base_type (type)); @@ -2329,7 +2329,8 @@ decode_constrained_packed_array (struct value *arr) array with no wrapper. In order to interpret the value through the (left-justified) packed array type we just built, we must first left-justify it. */ - int bit_size, bit_pos; + int bit_size; + LONGEST bit_pos; ULONGEST mod; mod = ada_modulus (value_type (arr)) - 1; @@ -2557,7 +2558,7 @@ ada_unpack_from_contents (const gdb_byte *src, int bit_offset, int bit_size, struct value * ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr, - long offset, int bit_offset, int bit_size, + LONGEST offset, int bit_offset, int bit_size, struct type *type) { struct value *v; @@ -2627,7 +2628,7 @@ ada_value_primitive_packed_val (struct value *obj, const gdb_byte *valaddr, if (obj != NULL) { - long new_offset = offset; + LONGEST new_offset = offset; set_value_component_location (v, obj); set_value_bitpos (v, bit_offset + value_bitpos (obj)); @@ -2697,7 +2698,7 @@ ada_value_assign (struct value *toval, struct value *fromval) { int len = (value_bitpos (toval) + bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; - int from_size; + LONGEST from_size; gdb_byte *buffer = (gdb_byte *) alloca (len); struct value *val; CORE_ADDR to_addr = value_address (toval); @@ -2748,7 +2749,7 @@ value_assign_to_component (struct value *container, struct value *component, (LONGEST) (value_address (component) - value_address (container)); int bit_offset_in_container = value_bitpos (component) - value_bitpos (container); - int bits; + LONGEST bits; val = value_cast (value_type (component), val); @@ -4455,7 +4456,7 @@ ensure_lval (struct value *val) if (VALUE_LVAL (val) == not_lval || VALUE_LVAL (val) == lval_internalvar) { - int len = TYPE_LENGTH (ada_check_typedef (value_type (val))); + LONGEST len = TYPE_LENGTH (ada_check_typedef (value_type (val))); const CORE_ADDR addr = value_as_long (value_allocate_space_in_inferior (len)); @@ -4539,7 +4540,7 @@ static CORE_ADDR value_pointer (struct value *value, struct type *type) { struct gdbarch *gdbarch = get_type_arch (type); - unsigned len = TYPE_LENGTH (type); + ULONGEST len = TYPE_LENGTH (type); gdb_byte *buf = (gdb_byte *) alloca (len); CORE_ADDR addr; @@ -6653,7 +6654,7 @@ value_tag_from_contents_and_address (struct type *type, const gdb_byte *valaddr, CORE_ADDR address) { - int tag_byte_offset; + LONGEST tag_byte_offset; struct type *tag_type; if (find_struct_field ("_tag", type, 0, &tag_type, &tag_byte_offset, @@ -7144,7 +7145,7 @@ ada_in_variant (LONGEST val, struct type *type, int field_num) only in that it can handle packed values of arbitrary type. */ static struct value * -ada_value_primitive_field (struct value *arg1, int offset, int fieldno, +ada_value_primitive_field (struct value *arg1, LONGEST offset, int fieldno, struct type *arg_type) { struct type *type; @@ -7156,7 +7157,7 @@ ada_value_primitive_field (struct value *arg1, int offset, int fieldno, if (TYPE_FIELD_BITSIZE (arg_type, fieldno) != 0) { - int bit_pos = TYPE_FIELD_BITPOS (arg_type, fieldno); + LONGEST bit_pos = TYPE_FIELD_BITPOS (arg_type, fieldno); int bit_size = TYPE_FIELD_BITSIZE (arg_type, fieldno); return ada_value_primitive_packed_val (arg1, value_contents (arg1), @@ -7233,9 +7234,9 @@ ada_value_primitive_field (struct value *arg1, int offset, int fieldno, Returns 1 if found, 0 otherwise. */ static int -find_struct_field (const char *name, struct type *type, int offset, +find_struct_field (const char *name, struct type *type, LONGEST offset, struct type **field_type_p, - int *byte_offset_p, int *bit_offset_p, int *bit_size_p, + LONGEST *byte_offset_p, int *bit_offset_p, int *bit_size_p, int *index_p) { int i; @@ -7254,8 +7255,8 @@ find_struct_field (const char *name, struct type *type, int offset, for (i = 0; i < TYPE_NFIELDS (type); i += 1) { - int bit_pos = TYPE_FIELD_BITPOS (type, i); - int fld_offset = offset + bit_pos / 8; + LONGEST bit_pos = TYPE_FIELD_BITPOS (type, i); + LONGEST fld_offset = offset + bit_pos / 8; const char *t_field_name = TYPE_FIELD_NAME (type, i); if (t_field_name == NULL) @@ -7357,7 +7358,7 @@ num_visible_fields (struct type *type) long explanation in find_struct_field's function documentation. */ static struct value * -ada_search_struct_field (const char *name, struct value *arg, int offset, +ada_search_struct_field (const char *name, struct value *arg, LONGEST offset, struct type *type) { int i; @@ -7405,7 +7406,7 @@ ada_search_struct_field (const char *name, struct value *arg, int offset, int j; struct type *field_type = ada_check_typedef (TYPE_FIELD_TYPE (type, i)); - int var_offset = offset + TYPE_FIELD_BITPOS (type, i) / 8; + LONGEST var_offset = offset + TYPE_FIELD_BITPOS (type, i) / 8; for (j = 0; j < TYPE_NFIELDS (field_type); j += 1) { @@ -7437,8 +7438,8 @@ ada_search_struct_field (const char *name, struct value *arg, int offset, return NULL; } -static struct value *ada_index_struct_field_1 (int *, struct value *, - int, struct type *); +static struct value *ada_index_struct_field_1 (LONGEST *, struct value *, + LONGEST, struct type *); /* Return field #INDEX in ARG, where the index is that returned by @@ -7447,7 +7448,7 @@ static struct value *ada_index_struct_field_1 (int *, struct value *, * If found, return value, else return NULL. */ static struct value * -ada_index_struct_field (int index, struct value *arg, int offset, +ada_index_struct_field (LONGEST index, struct value *arg, LONGEST offset, struct type *type) { return ada_index_struct_field_1 (&index, arg, offset, type); @@ -7459,7 +7460,7 @@ ada_index_struct_field (int index, struct value *arg, int offset, * *INDEX_P. */ static struct value * -ada_index_struct_field_1 (int *index_p, struct value *arg, int offset, +ada_index_struct_field_1 (LONGEST *index_p, struct value *arg, LONGEST offset, struct type *type) { int i; @@ -7550,7 +7551,8 @@ ada_value_struct_elt (struct value *arg, const char *name, int no_err) v = ada_search_struct_field (name, arg, 0, t); else { - int bit_offset, bit_size, byte_offset; + int bit_offset, bit_size; + LONGEST byte_offset; struct type *field_type; CORE_ADDR address; @@ -7899,8 +7901,8 @@ ada_coerce_ref (struct value *val0) /* Return OFF rounded upward if necessary to a multiple of ALIGNMENT (a power of 2). */ -static unsigned int -align_value (unsigned int off, unsigned int alignment) +static ULONGEST +align_value (ULONGEST off, ULONGEST alignment) { return (off + alignment - 1) & ~(alignment - 1); } @@ -8290,10 +8292,9 @@ ada_template_to_fixed_record_type_1 (struct type *type, struct value *mark = value_mark (); struct value *dval; struct type *rtype; - int nfields, bit_len; + int nfields; int variant_field; - long off; - int fld_bit_len; + LONGEST off, bit_len, fld_bit_len; int f; /* Compute the number of fields in this record type that are going @@ -8370,7 +8371,7 @@ ada_template_to_fixed_record_type_1 (struct type *type, that follow this one. */ if (ada_is_aligner_type (field_type)) { - long field_offset = TYPE_FIELD_BITPOS (field_type, f); + LONGEST field_offset = TYPE_FIELD_BITPOS (field_type, f); field_valaddr = cond_offset_host (field_valaddr, field_offset); field_address = cond_offset_target (field_address, field_offset); @@ -8974,7 +8975,8 @@ to_fixed_array_type (struct type *type0, struct value *dval, type was a regular (non-packed) array type. As a result, the bitsize of the array elements needs to be set again, and the array length needs to be recomputed based on that bitsize. */ - int len = TYPE_LENGTH (result) / TYPE_LENGTH (TYPE_TARGET_TYPE (result)); + LONGEST len = (TYPE_LENGTH (result) + / TYPE_LENGTH (TYPE_TARGET_TYPE (result))); int elt_bitsize = TYPE_FIELD_BITSIZE (type0, 0); TYPE_FIELD_BITSIZE (result, 0) = TYPE_FIELD_BITSIZE (type0, 0); diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h index ee03dbd2aad..49a4e4e1686 100644 --- a/gdb/ada-lang.h +++ b/gdb/ada-lang.h @@ -173,7 +173,7 @@ extern void ada_print_type (struct type *, const char *, struct ui_file *, int, extern void ada_print_typedef (struct type *type, struct symbol *new_symbol, struct ui_file *stream); -extern void ada_val_print (struct type *, int, CORE_ADDR, +extern void ada_val_print (struct type *, LONGEST, CORE_ADDR, struct ui_file *, int, struct value *, const struct value_print_options *); @@ -188,7 +188,7 @@ extern void ada_emit_char (int, struct type *, struct ui_file *, int, int); extern void ada_printchar (int, struct type *, struct ui_file *); extern void ada_printstr (struct ui_file *, struct type *, const gdb_byte *, - unsigned int, const char *, int, + ULONGEST, const char *, int, const struct value_print_options *); struct value *ada_convert_actual (struct value *actual, @@ -263,7 +263,7 @@ extern int ada_is_constrained_packed_array_type (struct type *); extern struct value *ada_value_primitive_packed_val (struct value *, const gdb_byte *, - long, int, int, + LONGEST, int, int, struct type *); extern struct type *ada_coerce_to_simple_array_type (struct type *); diff --git a/gdb/ada-valprint.c b/gdb/ada-valprint.c index 5d7823d7204..5dd7531c9f8 100644 --- a/gdb/ada-valprint.c +++ b/gdb/ada-valprint.c @@ -34,11 +34,11 @@ #include "target-float.h" static int print_field_values (struct type *, const gdb_byte *, - int, + LONGEST, struct ui_file *, int, struct value *, const struct value_print_options *, - int, struct type *, int, + int, struct type *, LONGEST, const struct language_defn *); @@ -316,7 +316,7 @@ ada_emit_char (int c, struct type *type, struct ui_file *stream, of a character. */ static int -char_at (const gdb_byte *string, int i, int type_len, +char_at (const gdb_byte *string, LONGEST i, int type_len, enum bfd_endian byte_order) { if (type_len == 1) @@ -475,11 +475,11 @@ ada_print_scalar (struct type *type, LONGEST val, struct ui_file *stream) static void printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string, - unsigned int length, int force_ellipses, int type_len, + ULONGEST length, int force_ellipses, int type_len, const struct value_print_options *options) { enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (elttype)); - unsigned int i; + ULONGEST i; unsigned int things_printed = 0; int in_quotes = 0; int need_comma = 0; @@ -494,9 +494,9 @@ printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string, { /* Position of the character we are examining to see whether it is repeated. */ - unsigned int rep1; + ULONGEST rep1; /* Number of repetitions we have detected so far. */ - unsigned int reps; + ULONGEST reps; QUIT; @@ -527,7 +527,8 @@ printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string, ada_emit_char (char_at (string, i, type_len, byte_order), elttype, stream, '\'', type_len); fputs_filtered ("'", stream); - fprintf_filtered (stream, _(" "), reps); + fprintf_filtered (stream, _(" "), + pulongest (reps)); i = rep1 - 1; things_printed += options->repeat_count_threshold; need_comma = 1; @@ -555,7 +556,7 @@ printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string, void ada_printstr (struct ui_file *stream, struct type *type, - const gdb_byte *string, unsigned int length, + const gdb_byte *string, ULONGEST length, const char *encoding, int force_ellipses, const struct value_print_options *options) { @@ -565,12 +566,12 @@ ada_printstr (struct ui_file *stream, struct type *type, static int print_variant_part (struct type *type, int field_num, - const gdb_byte *valaddr, int offset, + const gdb_byte *valaddr, LONGEST offset, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options, int comma_needed, - struct type *outer_type, int outer_offset, + struct type *outer_type, LONGEST outer_offset, const struct language_defn *language) { struct type *var_type = TYPE_FIELD_TYPE (type, field_num); @@ -606,11 +607,11 @@ print_variant_part (struct type *type, int field_num, static int print_field_values (struct type *type, const gdb_byte *valaddr, - int offset, struct ui_file *stream, int recurse, + LONGEST offset, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options, int comma_needed, - struct type *outer_type, int outer_offset, + struct type *outer_type, LONGEST outer_offset, const struct language_defn *language) { int i, len; @@ -676,7 +677,7 @@ print_field_values (struct type *type, const gdb_byte *valaddr, else { struct value *v; - int bit_pos = TYPE_FIELD_BITPOS (type, i); + LONGEST bit_pos = TYPE_FIELD_BITPOS (type, i); int bit_size = TYPE_FIELD_BITSIZE (type, i); struct value_print_options opts; @@ -721,8 +722,8 @@ ada_val_print_string (struct type *type, const gdb_byte *valaddr, { enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); struct type *elttype = TYPE_TARGET_TYPE (type); - unsigned int eltlen; - unsigned int len; + ULONGEST eltlen; + ULONGEST len; /* We know that ELTTYPE cannot possibly be null, because we assume that we're called only when TYPE is a string-like type. @@ -741,7 +742,7 @@ ada_val_print_string (struct type *type, const gdb_byte *valaddr, elements up to it. */ if (options->stop_print_at_null) { - int temp_len; + LONGEST temp_len; /* Look for a NULL char. */ for (temp_len = 0; @@ -1114,7 +1115,7 @@ ada_val_print_ref (struct type *type, const gdb_byte *valaddr, static void ada_val_print_1 (struct type *type, - int offset, CORE_ADDR address, + LONGEST offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *original_value, const struct value_print_options *options, @@ -1198,7 +1199,7 @@ ada_val_print_1 (struct type *type, void ada_val_print (struct type *type, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options) diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index af9b9b97407..e93ff86d260 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -300,17 +300,17 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function, { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int i; - int accumulate_size = (return_method == return_method_struct) ? 8 : 0; + ssize_t accumulate_size = (return_method == return_method_struct) ? 8 : 0; struct alpha_arg { const gdb_byte *contents; - int len; - int offset; + ssize_t len; + ssize_t offset; }; struct alpha_arg *alpha_args = XALLOCAVEC (struct alpha_arg, nargs); struct alpha_arg *m_arg; gdb_byte arg_reg_buffer[ALPHA_REGISTER_SIZE * ALPHA_NUM_ARG_REGS]; - int required_arg_regs; + ssize_t required_arg_regs; CORE_ADDR func_addr = find_function_addr (function, NULL); /* The ABI places the address of the called function in T12. */ @@ -414,6 +414,13 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function, accumulate_size = 0; else accumulate_size -= sizeof(arg_reg_buffer); + + /* Check for underflow. */ + if (sp - accumulate_size > sp) + error (_("Insufficient memory in GDB host for arguments, " + "need %s bytes, but less than %s bytes available."), + plongest (accumulate_size), plongest (CORE_ADDR_MAX - sp)); + sp -= accumulate_size; /* Keep sp aligned to a multiple of 16 as the ABI requires. */ @@ -423,8 +430,8 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function, for (i = nargs; m_arg--, --i >= 0;) { const gdb_byte *contents = m_arg->contents; - int offset = m_arg->offset; - int len = m_arg->len; + ssize_t offset = m_arg->offset; + ssize_t len = m_arg->len; /* Copy the bytes destined for registers into arg_reg_buffer. */ if (offset < sizeof(arg_reg_buffer)) @@ -436,7 +443,7 @@ alpha_push_dummy_call (struct gdbarch *gdbarch, struct value *function, } else { - int tlen = sizeof(arg_reg_buffer) - offset; + ssize_t tlen = sizeof(arg_reg_buffer) - offset; memcpy (arg_reg_buffer + offset, contents, tlen); offset += tlen; contents += tlen; diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index 5475cf629f3..bd5a8aad5d4 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -291,6 +291,80 @@ amd64_linux_register_reggroup_p (struct gdbarch *gdbarch, int regnum, /* Set the program counter for process PTID to PC. */ +/* Detect the outermost frame; during unwind of + #5 0x000000305cec68c3 in clone () from /lib64/tls/libc.so.6 + avoid the additional bogus frame + #6 0x0000000000000000 in ?? + We compare if the `linux_clone_code' block is _before_ unwound PC. */ + +static const unsigned char linux_clone_code[] = +{ +/* libc/sysdeps/unix/sysv/linux/x86_64/clone.S */ +/* #ifdef RESET_PID */ +/* ... */ +/* mov $SYS_ify(getpid), %eax */ +/* 0xb8, 0x27, 0x00, 0x00, 0x00 */ +/* OR */ +/* mov $SYS_ify(getpid), %rax */ +/* 0x48, 0xc7, 0xc0, 0x27, 0x00, 0x00, 0x00 */ +/* so just: */ + 0x27, 0x00, 0x00, 0x00, +/* syscall */ + 0x0f, 0x05, +/* movl %eax, %fs:PID */ + 0x64, 0x89, 0x04, 0x25, 0x94, 0x00, 0x00, 0x00, +/* movl %eax, %fs:TID */ + 0x64, 0x89, 0x04, 0x25, 0x90, 0x00, 0x00, 0x00, +/* #endif */ +/* |* Set up arguments for the function call. *| */ +/* popq %rax |* Function to call. *| */ + 0x58, +/* popq %rdi |* Argument. *| */ + 0x5f, +/* call *%rax$ */ + 0xff, 0xd0 +}; + +#define LINUX_CLONE_LEN (sizeof linux_clone_code) + +static int +amd64_linux_clone_running (struct frame_info *this_frame) +{ + CORE_ADDR pc = get_frame_pc (this_frame); + unsigned char buf[LINUX_CLONE_LEN]; + + if (!safe_frame_unwind_memory (this_frame, pc - LINUX_CLONE_LEN, buf, + LINUX_CLONE_LEN)) + return 0; + + if (memcmp (buf, linux_clone_code, LINUX_CLONE_LEN) != 0) + return 0; + + return 1; +} + +static int +amd64_linux_outermost_frame (struct frame_info *this_frame) +{ + CORE_ADDR pc = get_frame_pc (this_frame); + const char *name; + + find_pc_partial_function (pc, &name, NULL, NULL); + + /* If we have NAME, we can optimize the search. + `clone' NAME still needs to have the code checked as its name may be + present in the user code. + `__clone' NAME should not be present in the user code but in the initial + parts of the `__clone' implementation the unwind still makes sense. + More detailed unwinding decision would be too much sensitive to possible + subtle changes in specific glibc revisions. */ + if (name == NULL || strcmp (name, "clone") == 0 + || strcmp ("__clone", name) == 0) + return (amd64_linux_clone_running (this_frame) != 0); + + return 0; +} + static void amd64_linux_write_pc (struct regcache *regcache, CORE_ADDR pc) { @@ -1808,6 +1882,8 @@ amd64_linux_init_abi_common(struct gdbarch_info info, struct gdbarch *gdbarch) tdep->xsave_xcr0_offset = I386_LINUX_XSAVE_XCR0_OFFSET; + tdep->outermost_frame_p = amd64_linux_outermost_frame; + /* Add the %orig_rax register used for syscall restarting. */ set_gdbarch_write_pc (gdbarch, amd64_linux_write_pc); diff --git a/gdb/amd64-nat.c b/gdb/amd64-nat.c index 3dcac73d88a..42a3ce17769 100644 --- a/gdb/amd64-nat.c +++ b/gdb/amd64-nat.c @@ -135,9 +135,9 @@ amd64_collect_native_gregset (const struct regcache *regcache, { num_regs = amd64_native_gregset32_num_regs; - /* Make sure %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and + /* Make sure %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp and %eip get zero-extended to 64 bits. */ - for (i = 0; i <= I386_EIP_REGNUM; i++) + for (i = I386_ECX_REGNUM; i <= I386_EIP_REGNUM; i++) { if (regnum == -1 || regnum == i) memset (regs + amd64_native_gregset_reg_offset (gdbarch, i), 0, 8); @@ -163,4 +163,20 @@ amd64_collect_native_gregset (const struct regcache *regcache, regcache->raw_collect (i, regs + offset); } } + + if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 32) + { + /* Sign-extend %eax as during return from a syscall it is being checked + for -ERESTART* values -512 being above 0xfffffffffffffe00; tested by + interrupt.exp. */ + + i = I386_EAX_REGNUM; + + if (regnum == -1 || regnum == i) + { + void *ptr = regs + amd64_native_gregset_reg_offset (gdbarch, i); + + *(int64_t *) ptr = *(int32_t *) ptr; + } + } } diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index d4c96de5716..9c60e8c2316 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -754,7 +754,7 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function, gdb_byte *readbuf, const gdb_byte *writebuf) { enum amd64_reg_class theclass[2]; - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); static int integer_regnum[] = { AMD64_RAX_REGNUM, AMD64_RDX_REGNUM }; static int sse_regnum[] = { AMD64_XMM0_REGNUM, AMD64_XMM1_REGNUM }; int integer_reg = 0; @@ -871,10 +871,10 @@ amd64_return_value (struct gdbarch *gdbarch, struct value *function, gdb_assert (regnum != -1); if (readbuf) - regcache->raw_read_part (regnum, offset, std::min (len, 8), + regcache->raw_read_part (regnum, offset, std::min (len, (LONGEST) 8), readbuf + i * 8); if (writebuf) - regcache->raw_write_part (regnum, offset, std::min (len, 8), + regcache->raw_write_part (regnum, offset, std::min (len, (LONGEST) 8), writebuf + i * 8); } @@ -905,8 +905,8 @@ amd64_push_arguments (struct regcache *regcache, int nargs, struct value **args, }; struct value **stack_args = XALLOCAVEC (struct value *, nargs); int num_stack_args = 0; - int num_elements = 0; - int element = 0; + LONGEST num_elements = 0; + LONGEST element = 0; int integer_reg = 0; int sse_reg = 0; int i; @@ -918,7 +918,7 @@ if (return_method == return_method_struct) for (i = 0; i < nargs; i++) { struct type *type = value_type (args[i]); - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); enum amd64_reg_class theclass[2]; int needed_integer_regs = 0; int needed_sse_regs = 0; @@ -982,7 +982,7 @@ if (return_method == return_method_struct) gdb_assert (regnum != -1); memset (buf, 0, sizeof buf); - memcpy (buf, valbuf + j * 8, std::min (len, 8)); + memcpy (buf, valbuf + j * 8, std::min (len, (LONGEST) 8)); regcache->raw_write_part (regnum, offset, 8, buf); } } @@ -2622,6 +2622,7 @@ amd64_frame_unwind_stop_reason (struct frame_info *this_frame, { struct amd64_frame_cache *cache = amd64_frame_cache (this_frame, this_cache); + struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame)); if (!cache->base_p) return UNWIND_UNAVAILABLE; @@ -2630,6 +2631,10 @@ amd64_frame_unwind_stop_reason (struct frame_info *this_frame, if (cache->base == 0) return UNWIND_OUTERMOST; + /* Detect OS dependent outermost frames; such as `clone'. */ + if (tdep->outermost_frame_p && tdep->outermost_frame_p (this_frame)) + return UNWIND_OUTERMOST; + return UNWIND_NO_REASON; } @@ -2763,6 +2768,7 @@ amd64_sigtramp_frame_this_id (struct frame_info *this_frame, { struct amd64_frame_cache *cache = amd64_sigtramp_frame_cache (this_frame, this_cache); + struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame)); if (!cache->base_p) (*this_id) = frame_id_build_unavailable_stack (get_frame_pc (this_frame)); @@ -2771,6 +2777,11 @@ amd64_sigtramp_frame_this_id (struct frame_info *this_frame, /* This marks the outermost frame. */ return; } + else if (tdep->outermost_frame_p && tdep->outermost_frame_p (this_frame)) + { + /* Detect OS dependent outermost frames; such as `clone'. */ + return; + } else (*this_id) = frame_id_build (cache->base + 16, get_frame_pc (this_frame)); } diff --git a/gdb/amd64-windows-tdep.c b/gdb/amd64-windows-tdep.c index 922da9e48bc..22660129520 100644 --- a/gdb/amd64-windows-tdep.c +++ b/gdb/amd64-windows-tdep.c @@ -291,7 +291,7 @@ amd64_windows_return_value (struct gdbarch *gdbarch, struct value *function, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); int regnum = -1; /* See if our value is returned through a register. If it is, then diff --git a/gdb/annotate.c b/gdb/annotate.c index 97cb4c8855d..fa9b27dc2d0 100644 --- a/gdb/annotate.c +++ b/gdb/annotate.c @@ -531,21 +531,21 @@ annotate_frame_end (void) } void -annotate_array_section_begin (int idx, struct type *elttype) +annotate_array_section_begin (LONGEST idx, struct type *elttype) { if (annotation_level == 2) { - printf_filtered (("\n\032\032array-section-begin %d "), idx); + printf_filtered (("\n\032\032array-section-begin %s "), plongest (idx)); print_value_flags (elttype); printf_filtered (("\n")); } } void -annotate_elt_rep (unsigned int repcount) +annotate_elt_rep (ULONGEST repcount) { if (annotation_level == 2) - printf_filtered (("\n\032\032elt-rep %u\n"), repcount); + printf_filtered (("\n\032\032elt-rep %s\n"), pulongest (repcount)); } void diff --git a/gdb/annotate.h b/gdb/annotate.h index 4a9e1b58f28..4d5efb61795 100644 --- a/gdb/annotate.h +++ b/gdb/annotate.h @@ -105,8 +105,8 @@ extern void annotate_frame_source_end (void); extern void annotate_frame_where (void); extern void annotate_frame_end (void); -extern void annotate_array_section_begin (int, struct type *); -extern void annotate_elt_rep (unsigned int); +extern void annotate_array_section_begin (LONGEST, struct type *); +extern void annotate_elt_rep (ULONGEST); extern void annotate_elt_rep_end (void); extern void annotate_elt (void); extern void annotate_array_section_end (void); diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c index 43f5834b383..e7eebe874f9 100644 --- a/gdb/arch-utils.c +++ b/gdb/arch-utils.c @@ -227,7 +227,7 @@ legacy_virtual_frame_pointer (struct gdbarch *gdbarch, const struct floatformat ** default_floatformat_for_type (struct gdbarch *gdbarch, - const char *name, int len) + const char *name, LONGEST len) { const struct floatformat **format = NULL; diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h index 155cf5cfe30..3bc936133d8 100644 --- a/gdb/arch-utils.h +++ b/gdb/arch-utils.h @@ -131,7 +131,7 @@ extern gdbarch_virtual_frame_pointer_ftype legacy_virtual_frame_pointer; /* Default implementation of gdbarch_floatformat_for_type. */ extern const struct floatformat ** default_floatformat_for_type (struct gdbarch *gdbarch, - const char *name, int len); + const char *name, LONGEST len); extern CORE_ADDR generic_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc); diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c index 52668da9fcf..d40167806f6 100644 --- a/gdb/arm-linux-nat.c +++ b/gdb/arm-linux-nat.c @@ -81,7 +81,7 @@ class arm_linux_nat_target final : public linux_nat_target int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override; - int region_ok_for_hw_watchpoint (CORE_ADDR, int) override; + int region_ok_for_hw_watchpoint (CORE_ADDR, LONGEST) override; int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, struct expression *) override; @@ -92,7 +92,7 @@ class arm_linux_nat_target final : public linux_nat_target bool stopped_data_address (CORE_ADDR *) override; - bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override; + bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, LONGEST) override; const struct target_desc *read_description () override; @@ -1088,7 +1088,7 @@ arm_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch, /* Are we able to use a hardware watchpoint for the LEN bytes starting at ADDR? */ int -arm_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) +arm_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, LONGEST len) { const struct arm_linux_hwbp_cap *cap = arm_linux_get_hwbp_cap (); CORE_ADDR max_wp_length, aligned_addr; @@ -1195,7 +1195,7 @@ arm_linux_nat_target::stopped_by_watchpoint () bool arm_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr, CORE_ADDR start, - int length) + LONGEST length) { return start <= addr && start + length - 1 >= addr; } diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 599f785b349..e18f643199f 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -3440,7 +3440,7 @@ arm_vfp_cprc_reg_char (enum arm_vfp_cprc_base_type b) array). Vector types are not currently supported, matching the generic AAPCS support. */ -static int +static LONGEST arm_vfp_cprc_sub_candidate (struct type *t, enum arm_vfp_cprc_base_type *base_type) { @@ -3523,7 +3523,7 @@ arm_vfp_cprc_sub_candidate (struct type *t, } else { - int count; + LONGEST count; unsigned unitlen; count = arm_vfp_cprc_sub_candidate (TYPE_TARGET_TYPE (t), @@ -3546,12 +3546,12 @@ arm_vfp_cprc_sub_candidate (struct type *t, case TYPE_CODE_STRUCT: { - int count = 0; + LONGEST count = 0; unsigned unitlen; int i; for (i = 0; i < TYPE_NFIELDS (t); i++) { - int sub_count = 0; + LONGEST sub_count = 0; if (!field_is_static (&TYPE_FIELD (t, i))) sub_count = arm_vfp_cprc_sub_candidate (TYPE_FIELD_TYPE (t, i), @@ -3575,13 +3575,15 @@ arm_vfp_cprc_sub_candidate (struct type *t, case TYPE_CODE_UNION: { - int count = 0; + LONGEST count = 0; unsigned unitlen; int i; for (i = 0; i < TYPE_NFIELDS (t); i++) { - int sub_count = arm_vfp_cprc_sub_candidate (TYPE_FIELD_TYPE (t, i), - base_type); + LONGEST sub_count; + + sub_count = arm_vfp_cprc_sub_candidate (TYPE_FIELD_TYPE (t, i), + base_type); if (sub_count == -1) return -1; count = (count > sub_count ? count : sub_count); @@ -3617,7 +3619,7 @@ arm_vfp_call_candidate (struct type *t, enum arm_vfp_cprc_base_type *base_type, int *count) { enum arm_vfp_cprc_base_type b = VFP_CPRC_UNKNOWN; - int c = arm_vfp_cprc_sub_candidate (t, &b); + LONGEST c = arm_vfp_cprc_sub_candidate (t, &b); if (c <= 0 || c > 4) return 0; *base_type = b; @@ -3699,7 +3701,7 @@ arm_push_dummy_call (struct gdbarch *gdbarch, struct value *function, for (argnum = 0; argnum < nargs; argnum++) { - int len; + LONGEST len; struct type *arg_type; struct type *target_type; enum type_code typecode; diff --git a/gdb/avr-tdep.c b/gdb/avr-tdep.c index 6d11ee1618c..cd0759d131b 100644 --- a/gdb/avr-tdep.c +++ b/gdb/avr-tdep.c @@ -1192,13 +1192,13 @@ avr_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) struct stack_item { - int len; + ssize_t len; struct stack_item *prev; gdb_byte *data; }; static struct stack_item * -push_stack_item (struct stack_item *prev, const bfd_byte *contents, int len) +push_stack_item (struct stack_item *prev, const bfd_byte *contents, ssize_t len) { struct stack_item *si; si = XNEW (struct stack_item); @@ -1287,12 +1287,12 @@ avr_push_dummy_call (struct gdbarch *gdbarch, struct value *function, for (i = 0; i < nargs; i++) { - int last_regnum; - int j; + ssize_t last_regnum; + ssize_t j; struct value *arg = args[i]; struct type *type = check_typedef (value_type (arg)); const bfd_byte *contents = value_contents (arg); - int len = TYPE_LENGTH (type); + ssize_t len = TYPE_LENGTH (type); /* Calculate the potential last register needed. E.g. For length 2, registers regnum and regnum-1 (say 25 and 24) diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c index 778e89515b6..1677dd26cf9 100644 --- a/gdb/ax-gdb.c +++ b/gdb/ax-gdb.c @@ -82,12 +82,12 @@ static void gen_traced_pop (struct agent_expr *, struct axs_value *); static void gen_sign_extend (struct agent_expr *, struct type *); static void gen_extend (struct agent_expr *, struct type *); static void gen_fetch (struct agent_expr *, struct type *); -static void gen_left_shift (struct agent_expr *, int); +static void gen_left_shift (struct agent_expr *, LONGEST); static void gen_frame_args_address (struct agent_expr *); static void gen_frame_locals_address (struct agent_expr *); -static void gen_offset (struct agent_expr *ax, int offset); +static void gen_offset (struct agent_expr *ax, LONGEST offset); static void gen_sym_offset (struct agent_expr *, struct symbol *); static void gen_var_ref (struct agent_expr *ax, struct axs_value *value, struct symbol *var); @@ -132,13 +132,13 @@ static void gen_complement (struct agent_expr *ax, struct axs_value *value); static void gen_deref (struct axs_value *); static void gen_address_of (struct axs_value *); static void gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value, - struct type *type, int start, int end); + struct type *type, LONGEST start, LONGEST end); static void gen_primitive_field (struct agent_expr *ax, struct axs_value *value, - int offset, int fieldno, struct type *type); + LONGEST offset, int fieldno, struct type *type); static int gen_struct_ref_recursive (struct agent_expr *ax, struct axs_value *value, - const char *field, int offset, + const char *field, LONGEST offset, struct type *type); static void gen_struct_ref (struct agent_expr *ax, struct axs_value *value, @@ -529,7 +529,7 @@ gen_fetch (struct agent_expr *ax, struct type *type) right shift it by -DISTANCE bits if DISTANCE < 0. This generates unsigned (logical) right shifts. */ static void -gen_left_shift (struct agent_expr *ax, int distance) +gen_left_shift (struct agent_expr *ax, LONGEST distance) { if (distance > 0) { @@ -583,7 +583,7 @@ gen_frame_locals_address (struct agent_expr *ax) programming in ML, it would be clearer why these are the same thing. */ static void -gen_offset (struct agent_expr *ax, int offset) +gen_offset (struct agent_expr *ax, LONGEST offset) { /* It would suffice to simply push the offset and add it, but this makes it easier to read positive and negative offsets in the @@ -1254,7 +1254,7 @@ gen_address_of (struct axs_value *value) structure. */ static void gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value, - struct type *type, int start, int end) + struct type *type, LONGEST start, LONGEST end) { /* Note that ops[i] fetches 8 << i bits. */ static enum agent_op ops[] @@ -1289,13 +1289,13 @@ gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value, /* The first and one-after-last bits in the field, but rounded down and up to byte boundaries. */ - int bound_start = (start / TARGET_CHAR_BIT) * TARGET_CHAR_BIT; - int bound_end = (((end + TARGET_CHAR_BIT - 1) - / TARGET_CHAR_BIT) - * TARGET_CHAR_BIT); + LONGEST bound_start = (start / TARGET_CHAR_BIT) * TARGET_CHAR_BIT; + LONGEST bound_end = (((end + TARGET_CHAR_BIT - 1) + / TARGET_CHAR_BIT) + * TARGET_CHAR_BIT); /* current bit offset within the structure */ - int offset; + LONGEST offset; /* The index in ops of the opcode we're considering. */ int op; @@ -1413,7 +1413,7 @@ gen_bitfield_ref (struct agent_expr *ax, struct axs_value *value, static void gen_primitive_field (struct agent_expr *ax, struct axs_value *value, - int offset, int fieldno, struct type *type) + LONGEST offset, int fieldno, struct type *type) { /* Is this a bitfield? */ if (TYPE_FIELD_PACKED (type, fieldno)) @@ -1437,7 +1437,7 @@ gen_primitive_field (struct agent_expr *ax, struct axs_value *value, static int gen_struct_ref_recursive (struct agent_expr *ax, struct axs_value *value, - const char *field, int offset, struct type *type) + const char *field, LONGEST offset, struct type *type) { int i, rslt; int nbases = TYPE_N_BASECLASSES (type); diff --git a/gdb/ax-general.c b/gdb/ax-general.c index f956dfc2f53..7adfc1a66a3 100644 --- a/gdb/ax-general.c +++ b/gdb/ax-general.c @@ -177,7 +177,7 @@ ax_zero_ext (struct agent_expr *x, int n) /* Append a trace_quick instruction to EXPR, to record N bytes. */ void -ax_trace_quick (struct agent_expr *x, int n) +ax_trace_quick (struct agent_expr *x, LONGEST n) { /* N must fit in a byte. */ if (n < 0 || n > 255) diff --git a/gdb/ax.h b/gdb/ax.h index d16098b8c9c..2e3c9a110e9 100644 --- a/gdb/ax.h +++ b/gdb/ax.h @@ -193,7 +193,7 @@ extern void ax_ext (struct agent_expr *EXPR, int N); extern void ax_zero_ext (struct agent_expr *EXPR, int N); /* Append a trace_quick instruction to EXPR, to record N bytes. */ -extern void ax_trace_quick (struct agent_expr *EXPR, int N); +extern void ax_trace_quick (struct agent_expr *EXPR, LONGEST N); /* Append a goto op to EXPR. OP is the actual op (must be aop_goto or aop_if_goto). We assume we don't know the target offset yet, diff --git a/gdb/bfin-tdep.c b/gdb/bfin-tdep.c index 9d3e8ebce16..dc565db214c 100644 --- a/gdb/bfin-tdep.c +++ b/gdb/bfin-tdep.c @@ -504,7 +504,7 @@ bfin_push_dummy_call (struct gdbarch *gdbarch, enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int i; long reg_r0, reg_r1, reg_r2; - int total_len = 0; + ssize_t total_len = 0; for (i = nargs - 1; i >= 0; i--) { @@ -526,7 +526,7 @@ bfin_push_dummy_call (struct gdbarch *gdbarch, { struct type *value_type = value_enclosing_type (args[i]); struct type *arg_type = check_typedef (value_type); - int container_len = (TYPE_LENGTH (arg_type) + 3) & ~3; + ssize_t container_len = (TYPE_LENGTH (arg_type) + 3) & ~3; sp -= container_len; write_memory (sp, value_contents (args[i]), container_len); diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 3047ef3827d..1e937565bff 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -2057,9 +2057,9 @@ should_be_inserted (struct bp_location *bl) { fprintf_unfiltered (gdb_stdlog, "infrun: stepping past non-steppable watchpoint. " - "skipping watchpoint at %s:%d\n", + "skipping watchpoint at %s:%s\n", paddress (bl->gdbarch, bl->address), - bl->length); + plongest (bl->length)); } return 0; } @@ -6796,7 +6796,7 @@ breakpoint_address_match (const address_space *aspace1, CORE_ADDR addr1, static int breakpoint_address_match_range (const address_space *aspace1, CORE_ADDR addr1, - int len1, const address_space *aspace2, + LONGEST len1, const address_space *aspace2, CORE_ADDR addr2) { return ((gdbarch_has_global_breakpoints (target_gdbarch ()) @@ -8776,7 +8776,7 @@ init_breakpoint_sal (struct breakpoint *b, struct gdbarch *gdbarch, int enabled, int internal, unsigned flags, int display_canonical) { - int i; + int i ATTRIBUTE_UNUSED; if (type == bp_hardware_breakpoint) { @@ -10861,7 +10861,7 @@ can_use_hardware_watchpoint (const std::vector &vals) && TYPE_CODE (vtype) != TYPE_CODE_ARRAY)) { CORE_ADDR vaddr = value_address (v); - int len; + LONGEST len; int num_regs; len = (target_exact_watchpoints @@ -11931,6 +11931,8 @@ update_global_location_list (enum ugll_insert_mode insert_mode) traps we can no longer explain. */ old_loc->events_till_retirement = 3 * (thread_count () + 1); + /* Red Hat Bug 590623. */ + old_loc->events_till_retirement *= 10; old_loc->owner = NULL; moribund_locations.push_back (old_loc); @@ -14269,7 +14271,7 @@ enable_breakpoint_disp (struct breakpoint *bpt, enum bpdisp disposition, if (bpt->type == bp_hardware_breakpoint) { - int i; + int i ATTRIBUTE_UNUSED; i = hw_breakpoint_used_count (); target_resources_ok = target_can_use_hardware_watchpoint (bp_hardware_breakpoint, @@ -15437,6 +15439,50 @@ static struct cmd_list_element *enablebreaklist = NULL; cmd_list_element *commands_cmd_element = nullptr; +void +breakpoints_relocate (struct objfile *objfile, struct section_offsets *delta) +{ + struct bp_location *bl, **blp_tmp; + int changed = 0; + + gdb_assert (objfile->separate_debug_objfile_backlink == NULL); + + ALL_BP_LOCATIONS (bl, blp_tmp) + { + struct obj_section *osect; + + /* BL->SECTION can be correctly NULL for breakpoints with multiple + locations expanded through symtab. */ + + ALL_OBJFILE_OSECTIONS (objfile, osect) + { + CORE_ADDR relocated_address; + CORE_ADDR delta_offset; + + delta_offset = ANOFFSET (delta, osect->the_bfd_section->index); + if (delta_offset == 0) + continue; + relocated_address = bl->address + delta_offset; + + if (obj_section_addr (osect) <= relocated_address + && relocated_address < obj_section_endaddr (osect)) + { + if (bl->inserted) + remove_breakpoint (bl); + + bl->address += delta_offset; + bl->requested_address += delta_offset; + + changed = 1; + } + } + } + + if (changed) + qsort (bp_locations, bp_locations_count, sizeof (*bp_locations), + bp_locations_compare); +} + void _initialize_breakpoint (void) { diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index a91e3e334cf..f90432912bc 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -252,7 +252,7 @@ struct bp_target_info /* If this is a ranged breakpoint, then this field contains the length of the range that will be watched for execution. */ - int length; + LONGEST length; /* If the breakpoint lives in memory and reading that memory would give back the breakpoint, instead of the original contents, then @@ -417,7 +417,7 @@ class bp_location /* For hardware watchpoints, the size of the memory region being watched. For hardware ranged breakpoints, the size of the breakpoint range. */ - int length = 0; + LONGEST length = 0; /* Type of hardware watchpoint. */ target_hw_bp_type watchpoint_type {}; @@ -1664,6 +1664,9 @@ extern const char *ep_parse_optional_if_clause (const char **arg); UIOUT iff debugging multiple threads. */ extern void maybe_print_thread_hit_breakpoint (struct ui_out *uiout); +extern void breakpoints_relocate (struct objfile *objfile, + struct section_offsets *delta); + /* Print the specified breakpoint. */ extern void print_breakpoint (breakpoint *bp); diff --git a/gdb/build-id.c b/gdb/build-id.c index 27f29cd0442..5b598c819ad 100644 --- a/gdb/build-id.c +++ b/gdb/build-id.c @@ -26,11 +26,68 @@ #include "objfiles.h" #include "filenames.h" #include "gdbcore.h" +#include "libbfd.h" +#include "gdbcore.h" +#include "gdbcmd.h" +#include "observable.h" +#include "elf/external.h" +#include "elf/internal.h" +#include "elf/common.h" +#include "elf-bfd.h" +#include +#include "elf/external.h" +#include "inferior.h" + +#define BUILD_ID_VERBOSE_NONE 0 +#define BUILD_ID_VERBOSE_FILENAMES 1 +#define BUILD_ID_VERBOSE_BINARY_PARSE 2 +static int build_id_verbose = BUILD_ID_VERBOSE_FILENAMES; +static void +show_build_id_verbose (struct ui_file *file, int from_tty, + struct cmd_list_element *c, const char *value) +{ + fprintf_filtered (file, _("Verbosity level of the build-id locator is %s.\n"), + value); +} +/* Locate NT_GNU_BUILD_ID and return its matching debug filename. + FIXME: NOTE decoding should be unified with the BFD core notes decoding. */ + +static struct bfd_build_id * +build_id_buf_get (bfd *templ, gdb_byte *buf, bfd_size_type size) +{ + bfd_byte *p; + + p = buf; + while (p < buf + size) + { + /* FIXME: bad alignment assumption. */ + Elf_External_Note *xnp = (Elf_External_Note *) p; + size_t namesz = H_GET_32 (templ, xnp->namesz); + size_t descsz = H_GET_32 (templ, xnp->descsz); + bfd_byte *descdata = (gdb_byte *) xnp->name + BFD_ALIGN (namesz, 4); + + if (H_GET_32 (templ, xnp->type) == NT_GNU_BUILD_ID + && namesz == sizeof "GNU" + && memcmp (xnp->name, "GNU", sizeof "GNU") == 0) + { + gdb_byte *data = (gdb_byte *) descdata; + struct bfd_build_id *retval; + + retval = (struct bfd_build_id *) xmalloc (sizeof *retval - 1 + descsz); + retval->size = descsz; + memcpy (retval->data, data, descsz); + + return retval; + } + p = descdata + BFD_ALIGN (descsz, 4); + } + return NULL; +} /* See build-id.h. */ const struct bfd_build_id * -build_id_bfd_get (bfd *abfd) +build_id_bfd_shdr_get (bfd *abfd) { if (!bfd_check_format (abfd, bfd_object)) return NULL; @@ -42,6 +99,348 @@ build_id_bfd_get (bfd *abfd) return NULL; } +/* Core files may have missing (corrupt) SHDR but PDHR is correct there. + bfd_elf_bfd_from_remote_memory () has too much overhead by + allocating/reading all the available ELF PT_LOADs. */ + +static struct bfd_build_id * +build_id_phdr_get (bfd *templ, bfd_vma loadbase, unsigned e_phnum, + Elf_Internal_Phdr *i_phdr) +{ + int i; + struct bfd_build_id *retval = NULL; + + for (i = 0; i < e_phnum; i++) + if (i_phdr[i].p_type == PT_NOTE && i_phdr[i].p_filesz > 0) + { + Elf_Internal_Phdr *hdr = &i_phdr[i]; + gdb_byte *buf; + int err; + + buf = (gdb_byte *) xmalloc (hdr->p_filesz); + err = target_read_memory (loadbase + i_phdr[i].p_vaddr, buf, + hdr->p_filesz); + if (err == 0) + retval = build_id_buf_get (templ, buf, hdr->p_filesz); + else + retval = NULL; + xfree (buf); + if (retval != NULL) + break; + } + return retval; +} + +/* First we validate the file by reading in the ELF header and checking + the magic number. */ + +static inline bfd_boolean +elf_file_p (Elf64_External_Ehdr *x_ehdrp64) +{ + gdb_assert (sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr)); + gdb_assert (offsetof (Elf64_External_Ehdr, e_ident) + == offsetof (Elf32_External_Ehdr, e_ident)); + gdb_assert (sizeof (((Elf64_External_Ehdr *) 0)->e_ident) + == sizeof (((Elf32_External_Ehdr *) 0)->e_ident)); + + return ((x_ehdrp64->e_ident[EI_MAG0] == ELFMAG0) + && (x_ehdrp64->e_ident[EI_MAG1] == ELFMAG1) + && (x_ehdrp64->e_ident[EI_MAG2] == ELFMAG2) + && (x_ehdrp64->e_ident[EI_MAG3] == ELFMAG3)); +} + +/* Translate an ELF file header in external format into an ELF file header in + internal format. */ + +#define H_GET_WORD(bfd, ptr) (is64 ? H_GET_64 (bfd, (ptr)) \ + : H_GET_32 (bfd, (ptr))) +#define H_GET_SIGNED_WORD(bfd, ptr) (is64 ? H_GET_S64 (bfd, (ptr)) \ + : H_GET_S32 (bfd, (ptr))) + +static void +elf_swap_ehdr_in (bfd *abfd, + const Elf64_External_Ehdr *src64, + Elf_Internal_Ehdr *dst) +{ + int is64 = bfd_get_arch_size (abfd) == 64; +#define SRC(field) (is64 ? src64->field \ + : ((const Elf32_External_Ehdr *) src64)->field) + + int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; + memcpy (dst->e_ident, SRC (e_ident), EI_NIDENT); + dst->e_type = H_GET_16 (abfd, SRC (e_type)); + dst->e_machine = H_GET_16 (abfd, SRC (e_machine)); + dst->e_version = H_GET_32 (abfd, SRC (e_version)); + if (signed_vma) + dst->e_entry = H_GET_SIGNED_WORD (abfd, SRC (e_entry)); + else + dst->e_entry = H_GET_WORD (abfd, SRC (e_entry)); + dst->e_phoff = H_GET_WORD (abfd, SRC (e_phoff)); + dst->e_shoff = H_GET_WORD (abfd, SRC (e_shoff)); + dst->e_flags = H_GET_32 (abfd, SRC (e_flags)); + dst->e_ehsize = H_GET_16 (abfd, SRC (e_ehsize)); + dst->e_phentsize = H_GET_16 (abfd, SRC (e_phentsize)); + dst->e_phnum = H_GET_16 (abfd, SRC (e_phnum)); + dst->e_shentsize = H_GET_16 (abfd, SRC (e_shentsize)); + dst->e_shnum = H_GET_16 (abfd, SRC (e_shnum)); + dst->e_shstrndx = H_GET_16 (abfd, SRC (e_shstrndx)); + +#undef SRC +} + +/* Translate an ELF program header table entry in external format into an + ELF program header table entry in internal format. */ + +static void +elf_swap_phdr_in (bfd *abfd, + const Elf64_External_Phdr *src64, + Elf_Internal_Phdr *dst) +{ + int is64 = bfd_get_arch_size (abfd) == 64; +#define SRC(field) (is64 ? src64->field \ + : ((const Elf32_External_Phdr *) src64)->field) + + int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma; + + dst->p_type = H_GET_32 (abfd, SRC (p_type)); + dst->p_flags = H_GET_32 (abfd, SRC (p_flags)); + dst->p_offset = H_GET_WORD (abfd, SRC (p_offset)); + if (signed_vma) + { + dst->p_vaddr = H_GET_SIGNED_WORD (abfd, SRC (p_vaddr)); + dst->p_paddr = H_GET_SIGNED_WORD (abfd, SRC (p_paddr)); + } + else + { + dst->p_vaddr = H_GET_WORD (abfd, SRC (p_vaddr)); + dst->p_paddr = H_GET_WORD (abfd, SRC (p_paddr)); + } + dst->p_filesz = H_GET_WORD (abfd, SRC (p_filesz)); + dst->p_memsz = H_GET_WORD (abfd, SRC (p_memsz)); + dst->p_align = H_GET_WORD (abfd, SRC (p_align)); + +#undef SRC +} + +#undef H_GET_SIGNED_WORD +#undef H_GET_WORD + +static Elf_Internal_Phdr * +elf_get_phdr (bfd *templ, bfd_vma ehdr_vma, unsigned *e_phnum_pointer, + bfd_vma *loadbase_pointer) +{ + /* sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr) */ + Elf64_External_Ehdr x_ehdr64; /* Elf file header, external form */ + Elf_Internal_Ehdr i_ehdr; /* Elf file header, internal form */ + bfd_size_type x_phdrs_size; + gdb_byte *x_phdrs_ptr; + Elf_Internal_Phdr *i_phdrs; + int err; + unsigned int i; + bfd_vma loadbase; + int loadbase_set; + + gdb_assert (templ != NULL); + gdb_assert (sizeof (Elf64_External_Ehdr) >= sizeof (Elf32_External_Ehdr)); + + /* Read in the ELF header in external format. */ + err = target_read_memory (ehdr_vma, (bfd_byte *) &x_ehdr64, sizeof x_ehdr64); + if (err) + { + if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) + warning (_("build-id: Error reading ELF header at address 0x%lx"), + (unsigned long) ehdr_vma); + return NULL; + } + + /* Now check to see if we have a valid ELF file, and one that BFD can + make use of. The magic number must match, the address size ('class') + and byte-swapping must match our XVEC entry. */ + + if (! elf_file_p (&x_ehdr64) + || x_ehdr64.e_ident[EI_VERSION] != EV_CURRENT + || !((bfd_get_arch_size (templ) == 64 + && x_ehdr64.e_ident[EI_CLASS] == ELFCLASS64) + || (bfd_get_arch_size (templ) == 32 + && x_ehdr64.e_ident[EI_CLASS] == ELFCLASS32))) + { + if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) + warning (_("build-id: Unrecognized ELF header at address 0x%lx"), + (unsigned long) ehdr_vma); + return NULL; + } + + /* Check that file's byte order matches xvec's */ + switch (x_ehdr64.e_ident[EI_DATA]) + { + case ELFDATA2MSB: /* Big-endian */ + if (! bfd_header_big_endian (templ)) + { + if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) + warning (_("build-id: Unrecognized " + "big-endian ELF header at address 0x%lx"), + (unsigned long) ehdr_vma); + return NULL; + } + break; + case ELFDATA2LSB: /* Little-endian */ + if (! bfd_header_little_endian (templ)) + { + if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) + warning (_("build-id: Unrecognized " + "little-endian ELF header at address 0x%lx"), + (unsigned long) ehdr_vma); + return NULL; + } + break; + case ELFDATANONE: /* No data encoding specified */ + default: /* Unknown data encoding specified */ + if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) + warning (_("build-id: Unrecognized " + "ELF header endianity at address 0x%lx"), + (unsigned long) ehdr_vma); + return NULL; + } + + elf_swap_ehdr_in (templ, &x_ehdr64, &i_ehdr); + + /* The file header tells where to find the program headers. + These are what we use to actually choose what to read. */ + + if (i_ehdr.e_phentsize != (bfd_get_arch_size (templ) == 64 + ? sizeof (Elf64_External_Phdr) + : sizeof (Elf32_External_Phdr)) + || i_ehdr.e_phnum == 0) + { + if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) + warning (_("build-id: Invalid ELF program headers from the ELF header " + "at address 0x%lx"), (unsigned long) ehdr_vma); + return NULL; + } + + x_phdrs_size = (bfd_get_arch_size (templ) == 64 ? sizeof (Elf64_External_Phdr) + : sizeof (Elf32_External_Phdr)); + + i_phdrs = (Elf_Internal_Phdr *) xmalloc (i_ehdr.e_phnum * (sizeof *i_phdrs + x_phdrs_size)); + x_phdrs_ptr = (gdb_byte *) &i_phdrs[i_ehdr.e_phnum]; + err = target_read_memory (ehdr_vma + i_ehdr.e_phoff, (bfd_byte *) x_phdrs_ptr, + i_ehdr.e_phnum * x_phdrs_size); + if (err) + { + free (i_phdrs); + if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) + warning (_("build-id: Error reading " + "ELF program headers at address 0x%lx"), + (unsigned long) (ehdr_vma + i_ehdr.e_phoff)); + return NULL; + } + + loadbase = ehdr_vma; + loadbase_set = 0; + for (i = 0; i < i_ehdr.e_phnum; ++i) + { + elf_swap_phdr_in (templ, (Elf64_External_Phdr *) + (x_phdrs_ptr + i * x_phdrs_size), &i_phdrs[i]); + /* IA-64 vDSO may have two mappings for one segment, where one mapping + is executable only, and one is read only. We must not use the + executable one (PF_R is the first one, PF_X the second one). */ + if (i_phdrs[i].p_type == PT_LOAD && (i_phdrs[i].p_flags & PF_R)) + { + /* Only the first PT_LOAD segment indicates the file bias. + Next segments may have P_VADDR arbitrarily higher. + If the first segment has P_VADDR zero any next segment must not + confuse us, the first one sets LOADBASE certainly enough. */ + if (!loadbase_set && i_phdrs[i].p_offset == 0) + { + loadbase = ehdr_vma - i_phdrs[i].p_vaddr; + loadbase_set = 1; + } + } + } + + if (build_id_verbose >= BUILD_ID_VERBOSE_BINARY_PARSE) + warning (_("build-id: Found ELF header at address 0x%lx, loadbase 0x%lx"), + (unsigned long) ehdr_vma, (unsigned long) loadbase); + + *e_phnum_pointer = i_ehdr.e_phnum; + *loadbase_pointer = loadbase; + return i_phdrs; +} + +/* BUILD_ID_ADDR_GET gets ADDR located somewhere in the object. + Find the first section before ADDR containing an ELF header. + We rely on the fact the sections from multiple files do not mix. + FIXME: We should check ADDR is contained _inside_ the section with possibly + missing content (P_FILESZ < P_MEMSZ). These omitted sections are currently + hidden by _BFD_ELF_MAKE_SECTION_FROM_PHDR. */ + +static CORE_ADDR build_id_addr; +struct build_id_addr_sect + { + struct build_id_addr_sect *next; + asection *sect; + }; +static struct build_id_addr_sect *build_id_addr_sect; + +static void build_id_addr_candidate (bfd *abfd, asection *sect, void *obj) +{ + if (build_id_addr >= bfd_section_vma (abfd, sect)) + { + struct build_id_addr_sect *candidate; + + candidate = (struct build_id_addr_sect *) xmalloc (sizeof *candidate); + candidate->next = build_id_addr_sect; + build_id_addr_sect = candidate; + candidate->sect = sect; + } +} + +struct bfd_build_id * +build_id_addr_get (CORE_ADDR addr) +{ + struct build_id_addr_sect *candidate; + struct bfd_build_id *retval = NULL; + Elf_Internal_Phdr *i_phdr = NULL; + bfd_vma loadbase = 0; + unsigned e_phnum = 0; + + if (core_bfd == NULL) + return NULL; + + build_id_addr = addr; + gdb_assert (build_id_addr_sect == NULL); + bfd_map_over_sections (core_bfd, build_id_addr_candidate, NULL); + + /* Sections are sorted in the high-to-low VMAs order. + Stop the search on the first ELF header we find. + Do not continue the search even if it does not contain NT_GNU_BUILD_ID. */ + + for (candidate = build_id_addr_sect; candidate != NULL; + candidate = candidate->next) + { + i_phdr = elf_get_phdr (core_bfd, + bfd_section_vma (core_bfd, candidate->sect), + &e_phnum, &loadbase); + if (i_phdr != NULL) + break; + } + + if (i_phdr != NULL) + { + retval = build_id_phdr_get (core_bfd, loadbase, e_phnum, i_phdr); + xfree (i_phdr); + } + + while (build_id_addr_sect != NULL) + { + candidate = build_id_addr_sect; + build_id_addr_sect = candidate->next; + xfree (candidate); + } + + return retval; +} + /* See build-id.h. */ int @@ -50,7 +449,7 @@ build_id_verify (bfd *abfd, size_t check_len, const bfd_byte *check) const struct bfd_build_id *found; int retval = 0; - found = build_id_bfd_get (abfd); + found = build_id_bfd_shdr_get (abfd); if (found == NULL) warning (_("File \"%s\" has no build-id, file skipped"), @@ -117,11 +516,49 @@ build_id_to_debug_bfd_1 (const std::string &link, size_t build_id_len, return debug_bfd; } +static char * +link_resolve (const char *symlink, int level) +{ + char buf[PATH_MAX + 1], *target, *retval; + ssize_t got; + + if (level > 10) + return xstrdup (symlink); + + got = readlink (symlink, buf, sizeof (buf)); + if (got < 0 || got >= sizeof (buf)) + return xstrdup (symlink); + buf[got] = '\0'; + + if (IS_ABSOLUTE_PATH (buf)) + target = xstrdup (buf); + else + { + const std::string dir (ldirname (symlink)); + + target = xstrprintf ("%s" +#ifndef HAVE_DOS_BASED_FILE_SYSTEM + "/" +#else /* HAVE_DOS_BASED_FILE_SYSTEM */ + "\\" +#endif /* HAVE_DOS_BASED_FILE_SYSTEM */ + "%s", dir.c_str(), buf); + } + + retval = link_resolve (target, level + 1); + xfree (target); + return retval; +} + /* See build-id.h. */ gdb_bfd_ref_ptr -build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) +build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id, + char **link_return, int add_debug_suffix) { + std::string link, link_all; + gdb_bfd_ref_ptr abfd; + /* Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will cause "/.build-id/..." lookups. */ @@ -132,25 +569,28 @@ build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) { const gdb_byte *data = build_id; size_t size = build_id_len; + gdb::unique_xmalloc_ptr filename; + unsigned seqno; + struct stat statbuf_trash; + std::string link0; /* Compute where the file named after the build-id would be. If debugdir is "/usr/lib/debug" and the build-id is abcdef, this will give "/usr/lib/debug/.build-id/ab/cdef.debug". */ - std::string link = debugdir.get (); + link = debugdir.get (); link += "/.build-id/"; if (size > 0) { size--; - string_appendf (link, "%02x/", (unsigned) *data++); + string_appendf (link, "%02x", (unsigned) *data++); } - + if (size > 0) + link += "/"; while (size-- > 0) string_appendf (link, "%02x", (unsigned) *data++); - link += ".debug"; - gdb_bfd_ref_ptr debug_bfd = build_id_to_debug_bfd_1 (link, build_id_len, build_id); if (debug_bfd != NULL) @@ -170,27 +610,689 @@ build_id_to_debug_bfd (size_t build_id_len, const bfd_byte *build_id) if (debug_bfd != NULL) return debug_bfd; } + + if (separate_debug_file_debug) + printf_unfiltered (_(" Trying %s\n"), link.c_str ()); + + for (seqno = 0;; seqno++) + { + if (seqno) + { + /* There can be multiple build-id symlinks pointing to real files + with the same build-id (such as hard links). Some of the real + files may not be installed. */ + + string_appendf (link, ".%u", seqno); + } + + if (add_debug_suffix) + link += ".debug"; + + if (!seqno) + { + /* If none of the real files is found report as missing file + always the non-.%u-suffixed file. */ + link0 = link; + } + + /* `access' automatically dereferences LINK. */ + if (lstat (link.c_str (), &statbuf_trash) != 0) + { + /* Stop increasing SEQNO. */ + break; + } + + filename.reset(lrealpath (link.c_str ())); + if (filename == NULL) + continue; + + /* We expect to be silent on the non-existing files. */ + abfd = gdb_bfd_open (filename.get(), gnutarget, -1); + + if (abfd == NULL) + { + filename = NULL; + continue; + } + + if (build_id_verify (abfd.get(), build_id_len, build_id)) + break; + + abfd.reset (nullptr); + + filename.reset (nullptr); + } + + if (filename != NULL) + { + /* LINK_ALL is not used below in this non-NULL FILENAME case. */ + break; + } + + /* If the symlink has target request to install the target. + BASE-debuginfo.rpm contains the symlink but BASE.rpm may be missing. + https://bugzilla.redhat.com/show_bug.cgi?id=981154 */ + std::string link0_resolved (link_resolve (link0.c_str (), 0)); + + if (link_all.empty ()) + link_all = link0_resolved; + else + { + /* Use whitespace instead of DIRNAME_SEPARATOR to be compatible with + its possible use as an argument for installation command. */ + link_all += " " + link0_resolved; + } + } + + if (link_return != NULL) + { + if (abfd != NULL) + { + *link_return = xstrdup (link.c_str ()); + return abfd; + } + else + { + *link_return = xstrdup (link_all.c_str ()); + } } return {}; } +char * +build_id_to_filename (const struct bfd_build_id *build_id, char **link_return) +{ + gdb_bfd_ref_ptr abfd; + char *result; + + abfd = build_id_to_debug_bfd (build_id->size, build_id->data, link_return, 0); + if (abfd == NULL) + return NULL; + + result = xstrdup (bfd_get_filename (abfd)); + abfd.reset (nullptr); + return result; +} + +#ifdef HAVE_LIBRPM + +#include +#include +#include +#include +#ifdef DLOPEN_LIBRPM +#include +#endif + +/* Workarodun https://bugzilla.redhat.com/show_bug.cgi?id=643031 + librpm must not exit() an application on SIGINT + + Enable or disable a signal handler. SIGNUM: signal to enable (or disable + if negative). HANDLER: sa_sigaction handler (or NULL to use + rpmsqHandler()). Returns: no. of refs, -1 on error. */ +extern int rpmsqEnable (int signum, /* rpmsqAction_t handler */ void *handler); +int +rpmsqEnable (int signum, /* rpmsqAction_t handler */ void *handler) +{ + return 0; +} + +/* This MISSING_RPM_HASH tracker is used to collect all the missing rpm files + and avoid their duplicities during a single inferior run. */ + +static struct htab *missing_rpm_hash; + +/* This MISSING_RPM_LIST tracker is used to collect and print as a single line + all the rpms right before the nearest GDB prompt. It gets cleared after + each such print (it is questionable if we should clear it after the print). + */ + +struct missing_rpm + { + struct missing_rpm *next; + char rpm[1]; + }; +static struct missing_rpm *missing_rpm_list; +static int missing_rpm_list_entries; + +/* Returns the count of newly added rpms. */ + +static int +#ifndef GDB_INDEX_VERIFY_VENDOR +missing_rpm_enlist (const char *filename) +#else +missing_rpm_enlist_1 (const char *filename, int verify_vendor) +#endif +{ + static int rpm_init_done = 0; + rpmts ts; + rpmdbMatchIterator mi; + int count = 0; + +#ifdef DLOPEN_LIBRPM + /* Duplicate here the declarations to verify they match. The same sanity + check is present also in `configure.ac'. */ + extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg); + static char *(*headerFormat_p) (Header h, const char * fmt, errmsg_t *errmsg); + extern int rpmReadConfigFiles(const char * file, const char * target); + static int (*rpmReadConfigFiles_p) (const char * file, const char * target); + extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); + static rpmdbMatchIterator (*rpmdbFreeIterator_p) (rpmdbMatchIterator mi); + extern Header rpmdbNextIterator(rpmdbMatchIterator mi); + static Header (*rpmdbNextIterator_p) (rpmdbMatchIterator mi); + extern rpmts rpmtsCreate(void); + static rpmts (*rpmtsCreate_p) (void); + extern rpmts rpmtsFree(rpmts ts); + static rpmts (*rpmtsFree_p) (rpmts ts); + extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag, + const void * keyp, size_t keylen); + static rpmdbMatchIterator (*rpmtsInitIterator_p) (const rpmts ts, + rpmTag rpmtag, + const void *keyp, + size_t keylen); +#else /* !DLOPEN_LIBRPM */ +# define headerFormat_p headerFormat +# define rpmReadConfigFiles_p rpmReadConfigFiles +# define rpmdbFreeIterator_p rpmdbFreeIterator +# define rpmdbNextIterator_p rpmdbNextIterator +# define rpmtsCreate_p rpmtsCreate +# define rpmtsFree_p rpmtsFree +# define rpmtsInitIterator_p rpmtsInitIterator +#endif /* !DLOPEN_LIBRPM */ + + gdb_assert (filename != NULL); + + if (strcmp (filename, BUILD_ID_MAIN_EXECUTABLE_FILENAME) == 0) + return 0; + + if (is_target_filename (filename)) + return 0; + + if (filename[0] != '/') + { + warning (_("Ignoring non-absolute filename: <%s>"), filename); + return 0; + } + + if (!rpm_init_done) + { + static int init_tried; + + /* Already failed the initialization before? */ + if (init_tried) + return 0; + init_tried = 1; + +#ifdef DLOPEN_LIBRPM + { + void *h; + + h = dlopen (DLOPEN_LIBRPM, RTLD_LAZY); + if (!h) + { + warning (_("Unable to open \"%s\" (%s), " + "missing debuginfos notifications will not be displayed"), + DLOPEN_LIBRPM, dlerror ()); + return 0; + } + + if (!((headerFormat_p = (char *(*) (Header h, const char * fmt, errmsg_t *errmsg)) dlsym (h, "headerFormat")) + && (rpmReadConfigFiles_p = (int (*) (const char * file, const char * target)) dlsym (h, "rpmReadConfigFiles")) + && (rpmdbFreeIterator_p = (rpmdbMatchIterator (*) (rpmdbMatchIterator mi)) dlsym (h, "rpmdbFreeIterator")) + && (rpmdbNextIterator_p = (Header (*) (rpmdbMatchIterator mi)) dlsym (h, "rpmdbNextIterator")) + && (rpmtsCreate_p = (rpmts (*) (void)) dlsym (h, "rpmtsCreate")) + && (rpmtsFree_p = (rpmts (*) (rpmts ts)) dlsym (h, "rpmtsFree")) + && (rpmtsInitIterator_p = (rpmdbMatchIterator (*) (const rpmts ts, rpmTag rpmtag, const void *keyp, size_t keylen)) dlsym (h, "rpmtsInitIterator")))) + { + warning (_("Opened library \"%s\" is incompatible (%s), " + "missing debuginfos notifications will not be displayed"), + DLOPEN_LIBRPM, dlerror ()); + if (dlclose (h)) + warning (_("Error closing library \"%s\": %s\n"), DLOPEN_LIBRPM, + dlerror ()); + return 0; + } + } +#endif /* DLOPEN_LIBRPM */ + + if (rpmReadConfigFiles_p (NULL, NULL) != 0) + { + warning (_("Error reading the rpm configuration files")); + return 0; + } + + rpm_init_done = 1; + } + + ts = rpmtsCreate_p (); + + mi = rpmtsInitIterator_p (ts, RPMTAG_BASENAMES, filename, 0); + if (mi != NULL) + { +#ifndef GDB_INDEX_VERIFY_VENDOR + for (;;) +#else + if (!verify_vendor) for (;;) +#endif + { + Header h; + char *debuginfo, **slot, *s, *s2; + errmsg_t err; + size_t srcrpmlen = sizeof (".src.rpm") - 1; + size_t debuginfolen = sizeof ("-debuginfo") - 1; + rpmdbMatchIterator mi_debuginfo; + + h = rpmdbNextIterator_p (mi); + if (h == NULL) + break; + + /* The allocated memory gets utilized below for MISSING_RPM_HASH. */ + debuginfo = headerFormat_p (h, + "%{name}-debuginfo-%{version}-%{release}.%{arch}", + &err); + if (!debuginfo) + { + warning (_("Error querying the rpm file `%s': %s"), filename, + err); + continue; + } + + /* Verify the debuginfo file is not already installed. */ + /* RPMDBI_PACKAGES requires keylen == sizeof (int). */ + /* RPMDBI_LABEL is an interface for NVR-based dbiFindByLabel(). */ + mi_debuginfo = rpmtsInitIterator_p (ts, (rpmTag) RPMDBI_LABEL, debuginfo, 0); + if (mi_debuginfo) + { + xfree (debuginfo); + rpmdbFreeIterator_p (mi_debuginfo); + count = 0; + break; + } + + /* Base package name for `debuginfo-install'. We do not use the + `yum' command directly as the line + yum --enablerepo='*debug*' install NAME-debuginfo.ARCH + would be more complicated than just: + debuginfo-install NAME-VERSION-RELEASE.ARCH + Do not supply the rpm base name (derived from .src.rpm name) as + debuginfo-install is unable to install the debuginfo package if + the base name PKG binary rpm is not installed while for example + PKG-libs would be installed (RH Bug 467901). + FUTURE: After multiple debuginfo versions simultaneously installed + get supported the support for the VERSION-RELEASE tags handling + may need an update. */ + + if (missing_rpm_hash == NULL) + { + /* DEL_F is passed NULL as MISSING_RPM_LIST's HTAB_DELETE + should not deallocate the entries. */ + + missing_rpm_hash = htab_create_alloc (64, htab_hash_string, + (int (*) (const void *, const void *)) streq, + NULL, xcalloc, xfree); + } + slot = (char **) htab_find_slot (missing_rpm_hash, debuginfo, INSERT); + /* XCALLOC never returns NULL. */ + gdb_assert (slot != NULL); + if (*slot == NULL) + { + struct missing_rpm *missing_rpm; + + *slot = debuginfo; + + missing_rpm = (struct missing_rpm *) xmalloc (sizeof (*missing_rpm) + strlen (debuginfo)); + strcpy (missing_rpm->rpm, debuginfo); + missing_rpm->next = missing_rpm_list; + missing_rpm_list = missing_rpm; + missing_rpm_list_entries++; + } + else + xfree (debuginfo); + count++; + } +#ifdef GDB_INDEX_VERIFY_VENDOR + else /* verify_vendor */ + { + int vendor_pass = 0, vendor_fail = 0; + + for (;;) + { + Header h; + errmsg_t err; + char *vendor; + + h = rpmdbNextIterator_p (mi); + if (h == NULL) + break; + + vendor = headerFormat_p (h, "%{vendor}", &err); + if (!vendor) + { + warning (_("Error querying the rpm file `%s': %s"), filename, + err); + continue; + } + if (strcmp (vendor, "Red Hat, Inc.") == 0) + vendor_pass = 1; + else + vendor_fail = 1; + xfree (vendor); + } + count = vendor_pass != 0 && vendor_fail == 0; + } +#endif + + rpmdbFreeIterator_p (mi); + } + + rpmtsFree_p (ts); + + return count; +} + +static int +#ifdef GDB_INDEX_VERIFY_VENDOR +missing_rpm_enlist (const char *filename) +{ + return missing_rpm_enlist_1 (filename, 0); +} + +extern int rpm_verify_vendor (const char *filename); +int +rpm_verify_vendor (const char *filename) +{ + return missing_rpm_enlist_1 (filename, 1); +} + +static int +#endif +missing_rpm_list_compar (const char *const *ap, const char *const *bp) +{ + return strcoll (*ap, *bp); +} + +/* It returns a NULL-terminated array of strings needing to be FREEd. It may + also return only NULL. */ + +static void +missing_rpm_list_print (void) +{ + char **array, **array_iter; + struct missing_rpm *list_iter; + struct cleanup *cleanups; + + if (missing_rpm_list_entries == 0) + return; + + array = (char **) xmalloc (sizeof (*array) * missing_rpm_list_entries); + gdb::unique_xmalloc_ptr array_holder(array); + + array_iter = array; + for (list_iter = missing_rpm_list; list_iter != NULL; + list_iter = list_iter->next) + { + *array_iter++ = list_iter->rpm; + } + gdb_assert (array_iter == array + missing_rpm_list_entries); + + qsort (array, missing_rpm_list_entries, sizeof (*array), + (int (*) (const void *, const void *)) missing_rpm_list_compar); + + printf_unfiltered (_("Missing separate debuginfos, use: %s"), + "zypper install"); + for (array_iter = array; array_iter < array + missing_rpm_list_entries; + array_iter++) + { + putchar_unfiltered (' '); + puts_unfiltered (*array_iter); + } + putchar_unfiltered ('\n'); + + while (missing_rpm_list != NULL) + { + list_iter = missing_rpm_list; + missing_rpm_list = list_iter->next; + xfree (list_iter); + } + missing_rpm_list_entries = 0; +} + +static void +missing_rpm_change (void) +{ + debug_flush_missing (); + + gdb_assert (missing_rpm_list == NULL); + if (missing_rpm_hash != NULL) + { + htab_delete (missing_rpm_hash); + missing_rpm_hash = NULL; + } +} + +enum missing_exec + { + /* Init state. EXEC_BFD also still could be NULL. */ + MISSING_EXEC_NOT_TRIED, + /* We saw a non-NULL EXEC_BFD but RPM has no info about it. */ + MISSING_EXEC_NOT_FOUND, + /* We found EXEC_BFD by RPM and we either have its symbols (either embedded + or separate) or the main executable's RPM is now contained in + MISSING_RPM_HASH. */ + MISSING_EXEC_ENLISTED + }; +static enum missing_exec missing_exec = MISSING_EXEC_NOT_TRIED; + +#endif /* HAVE_LIBRPM */ + +void +debug_flush_missing (void) +{ +#ifdef HAVE_LIBRPM + missing_rpm_list_print (); +#endif +} + +/* This MISSING_FILEPAIR_HASH tracker is used only for the duplicite messages + yum --enablerepo='*debug*' install ... + avoidance. */ + +struct missing_filepair + { + char *binary; + char *debug; + char data[1]; + }; + +static struct htab *missing_filepair_hash; +static struct obstack missing_filepair_obstack; + +static void * +missing_filepair_xcalloc (size_t nmemb, size_t nmemb_size) +{ + void *retval; + size_t size = nmemb * nmemb_size; + + retval = obstack_alloc (&missing_filepair_obstack, size); + memset (retval, 0, size); + return retval; +} + +static hashval_t +missing_filepair_hash_func (const struct missing_filepair *elem) +{ + hashval_t retval = 0; + + retval ^= htab_hash_string (elem->binary); + if (elem->debug != NULL) + retval ^= htab_hash_string (elem->debug); + + return retval; +} + +static int +missing_filepair_eq (const struct missing_filepair *elem1, + const struct missing_filepair *elem2) +{ + return strcmp (elem1->binary, elem2->binary) == 0 + && ((elem1->debug == NULL) == (elem2->debug == NULL)) + && (elem1->debug == NULL || strcmp (elem1->debug, elem2->debug) == 0); +} + +static void +missing_filepair_change (void) +{ + if (missing_filepair_hash != NULL) + { + obstack_free (&missing_filepair_obstack, NULL); + /* All their memory came just from missing_filepair_OBSTACK. */ + missing_filepair_hash = NULL; + } +#ifdef HAVE_LIBRPM + missing_exec = MISSING_EXEC_NOT_TRIED; +#endif +} + +static void +debug_print_executable_changed (void) +{ +#ifdef HAVE_LIBRPM + missing_rpm_change (); +#endif + missing_filepair_change (); +} + +/* Notify user the file BINARY with (possibly NULL) associated separate debug + information file DEBUG is missing. DEBUG may or may not be the build-id + file such as would be: + /usr/lib/debug/.build-id/dd/b1d2ce632721c47bb9e8679f369e2295ce71be.debug + */ + +void +debug_print_missing (const char *binary, const char *debug) +{ + size_t binary_len0 = strlen (binary) + 1; + size_t debug_len0 = debug ? strlen (debug) + 1 : 0; + struct missing_filepair missing_filepair_find; + struct missing_filepair *missing_filepair; + struct missing_filepair **slot; + + if (build_id_verbose < BUILD_ID_VERBOSE_FILENAMES) + return; + + if (missing_filepair_hash == NULL) + { + obstack_init (&missing_filepair_obstack); + missing_filepair_hash = htab_create_alloc (64, + (hashval_t (*) (const void *)) missing_filepair_hash_func, + (int (*) (const void *, const void *)) missing_filepair_eq, NULL, + missing_filepair_xcalloc, NULL); + } + + /* Use MISSING_FILEPAIR_FIND first instead of calling obstack_alloc with + obstack_free in the case of a (rare) match. The problem is ALLOC_F for + MISSING_FILEPAIR_HASH allocates from MISSING_FILEPAIR_OBSTACK maintenance + structures for MISSING_FILEPAIR_HASH. Calling obstack_free would possibly + not to free only MISSING_FILEPAIR but also some such structures (allocated + during the htab_find_slot call). */ + + missing_filepair_find.binary = (char *) binary; + missing_filepair_find.debug = (char *) debug; + slot = (struct missing_filepair **) htab_find_slot (missing_filepair_hash, + &missing_filepair_find, + INSERT); + + /* While it may be still printed duplicitely with the missing debuginfo file + * it is due to once printing about the binary file build-id link and once + * about the .debug file build-id link as both the build-id symlinks are + * located in the debuginfo package. */ + + if (*slot != NULL) + return; + + missing_filepair = (struct missing_filepair *) obstack_alloc (&missing_filepair_obstack, + sizeof (*missing_filepair) - 1 + + binary_len0 + debug_len0); + missing_filepair->binary = missing_filepair->data; + memcpy (missing_filepair->binary, binary, binary_len0); + if (debug != NULL) + { + missing_filepair->debug = missing_filepair->binary + binary_len0; + memcpy (missing_filepair->debug, debug, debug_len0); + } + else + missing_filepair->debug = NULL; + + *slot = missing_filepair; + +#ifdef HAVE_LIBRPM + if (missing_exec == MISSING_EXEC_NOT_TRIED) + { + char *execfilename; + + execfilename = get_exec_file (0); + if (execfilename != NULL) + { + if (missing_rpm_enlist (execfilename) == 0) + missing_exec = MISSING_EXEC_NOT_FOUND; + else + missing_exec = MISSING_EXEC_ENLISTED; + } + } + if (missing_exec != MISSING_EXEC_ENLISTED) + if ((binary[0] == 0 || missing_rpm_enlist (binary) == 0) + && (debug == NULL || missing_rpm_enlist (debug) == 0)) +#endif /* HAVE_LIBRPM */ + { + /* We do not collect and flush these messages as each such message + already requires its own separate lines. */ + + fprintf_unfiltered (gdb_stdlog, + _("Missing separate debuginfo for %s\n"), binary); + if (debug != NULL) + { + const char *p = strrchr (debug, '/'); + fprintf_unfiltered (gdb_stdlog, _("Try: %s%.2s%.38s\"\n"), + "zypper install -C \"debuginfo(build-id)=", + p - 2, p + 1); + } + } +} + /* See build-id.h. */ std::string -find_separate_debug_file_by_buildid (struct objfile *objfile) +find_separate_debug_file_by_buildid (struct objfile *objfile, + gdb::unique_xmalloc_ptr *build_id_filename_return) { const struct bfd_build_id *build_id; - build_id = build_id_bfd_get (objfile->obfd); + if (build_id_filename_return) + *build_id_filename_return = NULL; + + build_id = build_id_bfd_shdr_get (objfile->obfd); if (build_id != NULL) { if (separate_debug_file_debug) printf_unfiltered (_("\nLooking for separate debug info (build-id) for " "%s\n"), objfile_name (objfile)); + char *build_id_filename_cstr = NULL; gdb_bfd_ref_ptr abfd (build_id_to_debug_bfd (build_id->size, - build_id->data)); + build_id->data, + (!build_id_filename_return ? NULL : &build_id_filename_cstr), 1)); + if (build_id_filename_return) + { + if (!build_id_filename_cstr) + gdb_assert (!*build_id_filename_return); + else + { + *build_id_filename_return = gdb::unique_xmalloc_ptr (build_id_filename_cstr); + build_id_filename_cstr = NULL; + } + } + /* Prevent looping on a stripped .debug file. */ if (abfd != NULL && filename_cmp (bfd_get_filename (abfd.get ()), @@ -203,3 +1305,21 @@ find_separate_debug_file_by_buildid (struct objfile *objfile) return std::string (); } + +extern void _initialize_build_id (void); + +void +_initialize_build_id (void) +{ + add_setshow_zinteger_cmd ("build-id-verbose", no_class, &build_id_verbose, + _("\ +Set debugging level of the build-id locator."), _("\ +Show debugging level of the build-id locator."), _("\ +Level 1 (default) enables printing the missing debug filenames,\n\ +level 2 also prints the parsing of binaries to find the identificators."), + NULL, + show_build_id_verbose, + &setlist, &showlist); + + gdb::observers::executable_changed.attach (debug_print_executable_changed); +} diff --git a/gdb/build-id.h b/gdb/build-id.h index b8b033e62aa..4ab705ad57a 100644 --- a/gdb/build-id.h +++ b/gdb/build-id.h @@ -23,9 +23,10 @@ #include "gdb_bfd.h" #include "common/rsp-low.h" -/* Locate NT_GNU_BUILD_ID from ABFD and return its content. */ +/* Separate debuginfo files have corrupted PHDR but SHDR is correct there. + Locate NT_GNU_BUILD_ID from ABFD and return its content. */ -extern const struct bfd_build_id *build_id_bfd_get (bfd *abfd); +extern const struct bfd_build_id *build_id_bfd_shdr_get (bfd *abfd); /* Return true if ABFD has NT_GNU_BUILD_ID matching the CHECK value. Otherwise, issue a warning and return false. */ @@ -39,14 +40,19 @@ extern int build_id_verify (bfd *abfd, the caller. */ extern gdb_bfd_ref_ptr build_id_to_debug_bfd (size_t build_id_len, - const bfd_byte *build_id); + const bfd_byte *build_id, + char **link_return, + int add_debug_suffix); + +extern char *build_id_to_filename (const struct bfd_build_id *build_id, + char **link_return); /* Find the separate debug file for OBJFILE, by using the build-id associated with OBJFILE's BFD. If successful, returns the file name for the separate debug file, otherwise, return an empty string. */ -extern std::string find_separate_debug_file_by_buildid - (struct objfile *objfile); +extern std::string find_separate_debug_file_by_buildid (struct objfile *objfile, + gdb::unique_xmalloc_ptr *build_id_filename_return); /* Return an hex-string representation of BUILD_ID. */ diff --git a/gdb/c-lang.c b/gdb/c-lang.c index 33506f1d1ed..e650375fd02 100644 --- a/gdb/c-lang.c +++ b/gdb/c-lang.c @@ -185,7 +185,7 @@ c_printchar (int c, struct type *type, struct ui_file *stream) void c_printstr (struct ui_file *stream, struct type *type, - const gdb_byte *string, unsigned int length, + const gdb_byte *string, ULONGEST length, const char *user_encoding, int force_ellipses, const struct value_print_options *options) { @@ -664,7 +664,7 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp, } else { - int i; + LONGEST i; /* Write the terminating character. */ for (i = 0; i < TYPE_LENGTH (type); ++i) @@ -673,7 +673,7 @@ evaluate_subexp_c (struct type *expect_type, struct expression *exp, if (satisfy_expected) { LONGEST low_bound, high_bound; - int element_size = TYPE_LENGTH (type); + LONGEST element_size = TYPE_LENGTH (type); if (get_discrete_bounds (TYPE_INDEX_TYPE (expect_type), &low_bound, &high_bound) < 0) diff --git a/gdb/c-lang.h b/gdb/c-lang.h index e7b6d5ef737..33a4bb94ef6 100644 --- a/gdb/c-lang.h +++ b/gdb/c-lang.h @@ -82,7 +82,7 @@ extern void c_print_typedef (struct type *, struct ui_file *); extern void c_val_print (struct type *, - int, CORE_ADDR, + LONGEST, CORE_ADDR, struct ui_file *, int, struct value *, const struct value_print_options *); @@ -102,7 +102,7 @@ extern void c_printchar (int, struct type *, struct ui_file *); extern void c_printstr (struct ui_file * stream, struct type *elttype, const gdb_byte *string, - unsigned int length, + ULONGEST length, const char *user_encoding, int force_ellipses, const struct value_print_options *options); diff --git a/gdb/c-valprint.c b/gdb/c-valprint.c index c4306f1488f..91df0e6b778 100644 --- a/gdb/c-valprint.c +++ b/gdb/c-valprint.c @@ -246,7 +246,7 @@ c_val_print_array (struct type *type, const gdb_byte *valaddr, if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0) { LONGEST low_bound, high_bound; - int eltlen, len; + LONGEST eltlen, len; struct gdbarch *gdbarch = get_type_arch (type); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); unsigned int i = 0; /* Number of characters printed. */ @@ -320,8 +320,8 @@ c_val_print_array (struct type *type, const gdb_byte *valaddr, if (cp_is_vtbl_ptr_type (elttype)) { i = 1; - fprintf_filtered (stream, _("%d vtable entries"), - len - 1); + fprintf_filtered (stream, _("%s vtable entries"), + plongest (len - 1)); } else { @@ -398,7 +398,7 @@ c_val_print_struct (struct type *type, const gdb_byte *valaddr, -fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */ struct gdbarch *gdbarch = get_type_arch (type); - int offset = (embedded_offset + LONGEST offset = (embedded_offset + TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8); struct type *field_type = TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET); @@ -497,7 +497,7 @@ c_val_print_memberptr (struct type *type, const gdb_byte *valaddr, void c_val_print (struct type *type, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *original_value, const struct value_print_options *options) @@ -651,6 +651,28 @@ c_value_print (struct value *val, struct ui_file *stream, else { /* normal case */ + if (TYPE_CODE (type) == TYPE_CODE_PTR + && 1 == is_dynamic_type (type)) + { + CORE_ADDR addr; + if (NULL != TYPE_DATA_LOCATION (TYPE_TARGET_TYPE (type))) + addr = value_address (val); + else + addr = value_as_address (val); + + /* We resolve the target-type only when the + pointer is associated. */ + if ((addr != 0) + && (0 == type_not_associated (type))) + TYPE_TARGET_TYPE (type) = + resolve_dynamic_type (TYPE_TARGET_TYPE (type), + NULL, addr); + } + else + { + /* Do nothing. References are already resolved from the beginning, + only pointers are resolved when we actual need the target. */ + } fprintf_filtered (stream, "("); type_print (value_type (val), "", stream, -1); fprintf_filtered (stream, ") "); diff --git a/gdb/coffread.c b/gdb/coffread.c index 4354741ab64..c735b979990 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -720,7 +720,8 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) /* Try to add separate debug file if no symbols table found. */ if (!objfile_has_partial_symbols (objfile)) { - std::string debugfile = find_separate_debug_file_by_buildid (objfile); + std::string debugfile = find_separate_debug_file_by_buildid (objfile, + NULL); if (debugfile.empty ()) debugfile = find_separate_debug_file_by_debuglink (objfile); diff --git a/gdb/common/common-exceptions.h b/gdb/common/common-exceptions.h index 3f47caec775..b045a364cea 100644 --- a/gdb/common/common-exceptions.h +++ b/gdb/common/common-exceptions.h @@ -106,6 +106,9 @@ enum errors { "_ERROR" is appended to the name. */ MAX_COMPLETIONS_REACHED_ERROR, + /* Attempt to load a core file as executable. */ + IS_CORE_ERROR, + /* Add more errors here. */ NR_ERRORS }; diff --git a/gdb/common/common-utils.c b/gdb/common/common-utils.c index 74ca93810c7..9beb4e35b96 100644 --- a/gdb/common/common-utils.c +++ b/gdb/common/common-utils.c @@ -91,6 +91,9 @@ xcalloc (size_t number, size_t size) void * xzalloc (size_t size) { + /* HACK: Round up to 8 bytes, fixes a problem with buffers of long double on + 32 bit (12 bytes) when filled from a 64 bit gdb (16 bytes). Ugh. */ + size = (size + 7) & ~(size_t)7; return xcalloc (1, size); } diff --git a/gdb/config.in b/gdb/config.in index c0291fbd9c5..a229ad02a37 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -33,6 +33,9 @@ /* Define to BFD's default target vector. */ #undef DEFAULT_BFD_VEC +/* librpm version specific library name to dlopen. */ +#undef DLOPEN_LIBRPM + /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef ENABLE_NLS @@ -255,6 +258,12 @@ /* Define if Python 2.7 is being used. */ #undef HAVE_LIBPYTHON2_7 +/* Define if librpm library is being used. */ +#undef HAVE_LIBRPM + +/* Define to 1 if you have the `selinux' library (-lselinux). */ +#undef HAVE_LIBSELINUX + /* Define to 1 if you have the header file. */ #undef HAVE_LIBUNWIND_IA64_H @@ -378,6 +387,9 @@ /* Define to 1 if you have the `scm_new_smob' function. */ #undef HAVE_SCM_NEW_SMOB +/* Define to 1 if you have the header file. */ +#undef HAVE_SELINUX_SELINUX_H + /* Define to 1 if you have the `setlocale' function. */ #undef HAVE_SETLOCALE diff --git a/gdb/config/i386/nm-linux.h b/gdb/config/i386/nm-linux.h new file mode 100644 index 00000000000..38e94baab1c --- /dev/null +++ b/gdb/config/i386/nm-linux.h @@ -0,0 +1,28 @@ +/* Native support for GNU/Linux i386. + + Copyright 2010 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 . */ + +#ifndef NM_LINUX_H +#define NM_LINUX_H + +#include "config/nm-linux.h" + +/* Red Hat backward compatibility with gdb-6.8. */ +#define target_can_use_hardware_watchpoint(type, cnt, ot) 1 + +#endif /* NM_LINUX64_H */ diff --git a/gdb/config/i386/nm-linux64.h b/gdb/config/i386/nm-linux64.h new file mode 100644 index 00000000000..212daba4774 --- /dev/null +++ b/gdb/config/i386/nm-linux64.h @@ -0,0 +1,28 @@ +/* Native support for GNU/Linux amd64. + + Copyright 2010 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 . */ + +#ifndef NM_LINUX64_H +#define NM_LINUX64_H + +#include "config/nm-linux.h" + +/* Red Hat backward compatibility with gdb-6.8. */ +#define target_can_use_hardware_watchpoint(type, cnt, ot) 1 + +#endif /* NM_LINUX64_H */ diff --git a/gdb/configure b/gdb/configure index f2d271e23a2..8b4b4ac16da 100755 --- a/gdb/configure +++ b/gdb/configure @@ -751,6 +751,11 @@ CODESIGN_CERT HAVE_NATIVE_GCORE_TARGET TARGET_OBS subdirs +RPM_LIBS +RPM_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG GDB_DATADIR DEBUGDIR MAKEINFO_EXTRA_FLAGS @@ -855,6 +860,7 @@ with_gdb_datadir with_relocated_sources with_auto_load_dir with_auto_load_safe_path +with_rpm enable_targets enable_64_bit_bfd enable_gdbmi @@ -914,6 +920,11 @@ CCC CPP MAKEINFO MAKEINFOFLAGS +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +RPM_CFLAGS +RPM_LIBS YACC YFLAGS XMKMF' @@ -1585,6 +1596,8 @@ Optional Packages: [--with-auto-load-dir] --without-auto-load-safe-path do not restrict auto-loaded files locations + --with-rpm query rpm database for missing debuginfos (yes/no, + def. auto=librpm.so) --with-libunwind-ia64 use libunwind frame unwinding for ia64 targets --with-curses use the curses library instead of the termcap library @@ -1642,6 +1655,13 @@ Some influential environment variables: MAKEINFO Parent configure detects if it is of sufficient version. MAKEINFOFLAGS Parameters for MAKEINFO. + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + RPM_CFLAGS C compiler flags for RPM, overriding pkg-config + RPM_LIBS linker flags for RPM, overriding pkg-config YACC The `Yet Another Compiler Compiler' implementation to use. Defaults to the first program found out of: `bison -y', `byacc', `yacc'. @@ -6623,6 +6643,494 @@ _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_auto_load_safe_path" >&5 $as_echo "$with_auto_load_safe_path" >&6; } +# Integration with rpm library to support missing debuginfo suggestions. +# --without-rpm: Disable any rpm support. +# --with-rpm=libname.so: Try to dynamically open `libname.so' during runtime. +# Even with runtime missing `libname.so' GDB will still other run correctly. +# Missing `libname.so' during ./configure will abort the configuration. +# --with-rpm=librpm.so: Like `--with-rpm=libname.so' but try to find specific +# minor version first such as `librpm-4.6.so' as minor version differences +# mean API+ABI incompatibility. If the specific match versioned library name +# could not be found still open dynamically at least `librpm.so'. +# --with-rpm: Like `--with-rpm=librpm.so' but if any of its detection fails try +# to find librpm for compilation-time linking by pkg-config. GDB binary will +# be probably linked with the version specific library (as `librpm-4.6.so'). +# Failure to find librpm by pkg-config will abort the configuration. +# (default) --with-rpm=auto: Like `--with-rpm=librpm.so' but if even pkg-config +# cannot find librpm use to the rpmless compilation (like `--without-rpm'). + + +# Check whether --with-rpm was given. +if test "${with_rpm+set}" = set; then : + withval=$with_rpm; +else + with_rpm="auto" +fi + + + + +if test "x$with_rpm" != "xno"; then + if test "x$with_rpm" = "xyes"; then + LIBRPM="librpm.so" + RPM_REQUIRE=true + DLOPEN_REQUIRE=false + elif test "x$with_rpm" = "xauto"; then + LIBRPM="librpm.so" + RPM_REQUIRE=false + DLOPEN_REQUIRE=false + else + LIBRPM="$with_rpm" + RPM_REQUIRE=true + DLOPEN_REQUIRE=true + fi + LIBRPM_STRING='"'"$LIBRPM"'"' + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking specific librpm version" >&5 +$as_echo_n "checking specific librpm version... " >&6; } + HAVE_DLOPEN_LIBRPM=false + save_LIBS="$LIBS" + LIBS="$LIBS -ldl" + if test "$cross_compiling" = yes; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error "cannot run test program while cross compiling +See \`config.log' for more details." "$LINENO" 5; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include +#include +#include + +int +main () +{ + + void *h; + const char *const *rpmverp; + FILE *f; + + f = fopen ("conftest.out", "w"); + if (!f) + { + fprintf (stderr, "Cannot write \"%s\": %s\n", "conftest.out", + strerror (errno)); + return 1; + } + h = dlopen ($LIBRPM_STRING, RTLD_LAZY); + if (!h) + { + fprintf (stderr, "dlopen (\"%s\"): %s\n", $LIBRPM_STRING, dlerror ()); + return 1; + } + rpmverp = dlsym (h, "RPMVERSION"); + if (!rpmverp) + { + fprintf (stderr, "dlsym (\"RPMVERSION\"): %s\n", dlerror ()); + return 1; + } + fprintf (stderr, "RPMVERSION is: \""); + fprintf (stderr, "%s\"\n", *rpmverp); + + /* Try to find the specific librpm version only for "librpm.so" as we do + not know how to assemble the version string otherwise. */ + + if (strcmp ("librpm.so", $LIBRPM_STRING) != 0) + { + fprintf (f, "%s\n", $LIBRPM_STRING); + return 0; + } + else + { + char *h2_name; + void *h2; + int major, minor; + + if (sscanf (*rpmverp, "%d.%d", &major, &minor) != 2) + { + fprintf (stderr, "Unable to parse RPMVERSION.\n"); + fprintf (f, "%s\n", $LIBRPM_STRING); + return 0; + } + /* Avoid the square brackets by malloc. */ + h2_name = malloc (64); + sprintf (h2_name, "librpm-%d.%d.so", major, minor); + h2 = dlopen (h2_name, RTLD_LAZY); + if (!h2) + { + fprintf (stderr, "dlopen (\"%s\"): %s\n", h2_name, dlerror ()); + fprintf (f, "%s\n", $LIBRPM_STRING); + return 0; + } + if (h2 != h) + { + fprintf (stderr, "dlopen of \"%s\" and \"%s\" are different.\n", + $LIBRPM_STRING, h2_name); + fprintf (f, "%s\n", $LIBRPM_STRING); + return 0; + } + /* Found the valid .so name with a specific version. */ + fprintf (f, "%s\n", h2_name); + return 0; + } + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + + DLOPEN_LIBRPM="`cat conftest.out`" + if test "x$DLOPEN_LIBRPM" != "x"; then + HAVE_DLOPEN_LIBRPM=true + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLOPEN_LIBRPM" >&5 +$as_echo "$DLOPEN_LIBRPM" >&6; } + fi + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + rm -f conftest.out + + + + if $HAVE_DLOPEN_LIBRPM; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking rpm library API compatibility" >&5 +$as_echo_n "checking rpm library API compatibility... " >&6; } + # The compilation requires -Werror to verify anything. + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Duplicate here the declarations to verify they match "elfread.c". */ +#include +#include +#include +#include +extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg); +extern int rpmReadConfigFiles(const char * file, const char * target); +extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); +extern Header rpmdbNextIterator(rpmdbMatchIterator mi); +extern rpmts rpmtsCreate(void); +extern rpmts rpmtsFree(rpmts ts); +extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag, + const void * keyp, size_t keylen); + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + LIBRPM_COMPAT=true + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +else + + LIBRPM_COMPAT=false + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$save_CFLAGS" + + if ! $LIBRPM_COMPAT; then + HAVE_DLOPEN_LIBRPM=false + fi + fi + + if $HAVE_DLOPEN_LIBRPM; then + DLOPEN_LIBRPM_STRING='"'"$DLOPEN_LIBRPM"'"' + +cat >>confdefs.h <<_ACEOF +#define DLOPEN_LIBRPM $DLOPEN_LIBRPM_STRING +_ACEOF + + +$as_echo "#define HAVE_LIBRPM 1" >>confdefs.h + + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + LIBS="$save_LIBS" + if $DLOPEN_REQUIRE; then + as_fn_error "Specific name $LIBRPM was requested but it could not be opened." "$LINENO" 5 + fi + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_PKG_CONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for RPM" >&5 +$as_echo_n "checking for RPM... " >&6; } + +if test -n "$RPM_CFLAGS"; then + pkg_cv_RPM_CFLAGS="$RPM_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"rpm\""; } >&5 + ($PKG_CONFIG --exists --print-errors "rpm") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_RPM_CFLAGS=`$PKG_CONFIG --cflags "rpm" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$RPM_LIBS"; then + pkg_cv_RPM_LIBS="$RPM_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"rpm\""; } >&5 + ($PKG_CONFIG --exists --print-errors "rpm") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_RPM_LIBS=`$PKG_CONFIG --libs "rpm" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + RPM_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "rpm" 2>&1` + else + RPM_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "rpm" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$RPM_PKG_ERRORS" >&5 + + HAVE_LIBRPM=false +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + HAVE_LIBRPM=false +else + RPM_CFLAGS=$pkg_cv_RPM_CFLAGS + RPM_LIBS=$pkg_cv_RPM_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + HAVE_LIBRPM=true +fi + + if $HAVE_LIBRPM; then + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking rpm library API compatibility" >&5 +$as_echo_n "checking rpm library API compatibility... " >&6; } + # The compilation requires -Werror to verify anything. + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Duplicate here the declarations to verify they match "elfread.c". */ +#include +#include +#include +#include +extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg); +extern int rpmReadConfigFiles(const char * file, const char * target); +extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); +extern Header rpmdbNextIterator(rpmdbMatchIterator mi); +extern rpmts rpmtsCreate(void); +extern rpmts rpmtsFree(rpmts ts); +extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag, + const void * keyp, size_t keylen); + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + LIBRPM_COMPAT=true + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +else + + LIBRPM_COMPAT=false + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + CFLAGS="$save_CFLAGS" + + if ! $LIBRPM_COMPAT; then + HAVE_LIBRPM=false + RPM_PKG_ERRORS="Found $LIBRPM API is incompatibile with this GDB" + fi + fi + + if $HAVE_LIBRPM; then + +$as_echo "#define HAVE_LIBRPM 1" >>confdefs.h + + CFLAGS="$CFLAGS $RPM_CFLAGS" + LIBS="$LIBS $RPM_LIBS" + else + if $RPM_REQUIRE; then + as_fn_error "$RPM_PKG_ERRORS" "$LINENO" 5 + else + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $RPM_PKG_ERRORS" >&5 +$as_echo "$as_me: WARNING: $RPM_PKG_ERRORS" >&2;} + fi + fi + fi +fi + subdirs="$subdirs testsuite" @@ -8907,6 +9415,7 @@ if test x"$prefer_curses" = xyes; then # search /usr/local/include, if ncurses is installed in /usr/local. A # default installation of ncurses on alpha*-dec-osf* will lead to such # a situation. + # Fedora: Force libncursesw over libncurses to match the includes. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing waddstr" >&5 $as_echo_n "checking for library containing waddstr... " >&6; } if ${ac_cv_search_waddstr+:} false; then : @@ -8931,7 +9440,7 @@ return waddstr (); return 0; } _ACEOF -for ac_lib in '' ncursesw ncurses cursesX curses; do +for ac_lib in '' ncursesw; do if test -z "$ac_lib"; then ac_res="none required" else @@ -9005,6 +9514,7 @@ case $host_os in esac # These are the libraries checked by Readline. +# Fedora: Force libncursesw over libncurses to match the includes. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tgetent" >&5 $as_echo_n "checking for library containing tgetent... " >&6; } if ${ac_cv_search_tgetent+:} false; then : @@ -9029,7 +9539,7 @@ return tgetent (); return 0; } _ACEOF -for ac_lib in '' termcap tinfow tinfo curses ncursesw ncurses; do +for ac_lib in '' termcap tinfow tinfo ncursesw; do if test -z "$ac_lib"; then ac_res="none required" else @@ -9194,10 +9704,12 @@ _ACEOF -if test "x${ac_cv_sizeof_unsigned_long}" = "x8"; then - TARGET_PTR="unsigned long" -elif test "x${ac_cv_sizeof_unsigned_long_long}" = "x8"; then +# Try to keep TARGET_PTR the same across archs so that jit-reader.h file +# content is the same for multilib distributions. +if test "x${ac_cv_sizeof_unsigned_long_long}" = "x8"; then TARGET_PTR="unsigned long long" +elif test "x${ac_cv_sizeof_unsigned_long}" = "x8"; then + TARGET_PTR="unsigned long" elif test "x${ac_cv_sizeof_unsigned___int128}" = "x16"; then TARGET_PTR="unsigned __int128" else @@ -11517,7 +12029,7 @@ else #include #ifndef PERF_ATTR_SIZE_VER5 -# error +// error // PERF_ATTR_SIZE_VER5_BUNDLE is not available here - Fedora+RHEL #endif _ACEOF @@ -15282,6 +15794,64 @@ cat >>confdefs.h <<_ACEOF _ACEOF +for ac_header in selinux/selinux.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default" +if test "x$ac_cv_header_selinux_selinux_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SELINUX_SELINUX_H 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for security_get_boolean_active in -lselinux" >&5 +$as_echo_n "checking for security_get_boolean_active in -lselinux... " >&6; } +if test "${ac_cv_lib_selinux_security_get_boolean_active+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lselinux $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 security_get_boolean_active (); +int +main () +{ +return security_get_boolean_active (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_selinux_security_get_boolean_active=yes +else + ac_cv_lib_selinux_security_get_boolean_active=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_selinux_security_get_boolean_active" >&5 +$as_echo "$ac_cv_lib_selinux_security_get_boolean_active" >&6; } +if test "x$ac_cv_lib_selinux_security_get_boolean_active" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSELINUX 1 +_ACEOF + + LIBS="-lselinux $LIBS" + +fi + + # Support for --with-sysroot is a copy of GDB_AC_WITH_DIR, # except that the argument to --with-sysroot is optional. diff --git a/gdb/configure.ac b/gdb/configure.ac index 8ddd0fda61c..5f3ebebd848 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -166,6 +166,199 @@ AC_DEFINE_DIR(AUTO_LOAD_SAFE_PATH, escape_dir, [Directories safe to hold auto-loaded files.]) AC_MSG_RESULT([$with_auto_load_safe_path]) +# Integration with rpm library to support missing debuginfo suggestions. +# --without-rpm: Disable any rpm support. +# --with-rpm=libname.so: Try to dynamically open `libname.so' during runtime. +# Even with runtime missing `libname.so' GDB will still other run correctly. +# Missing `libname.so' during ./configure will abort the configuration. +# --with-rpm=librpm.so: Like `--with-rpm=libname.so' but try to find specific +# minor version first such as `librpm-4.6.so' as minor version differences +# mean API+ABI incompatibility. If the specific match versioned library name +# could not be found still open dynamically at least `librpm.so'. +# --with-rpm: Like `--with-rpm=librpm.so' but if any of its detection fails try +# to find librpm for compilation-time linking by pkg-config. GDB binary will +# be probably linked with the version specific library (as `librpm-4.6.so'). +# Failure to find librpm by pkg-config will abort the configuration. +# (default) --with-rpm=auto: Like `--with-rpm=librpm.so' but if even pkg-config +# cannot find librpm use to the rpmless compilation (like `--without-rpm'). + +AC_ARG_WITH([rpm], + [AS_HELP_STRING([--with-rpm], + [query rpm database for missing debuginfos (yes/no, def. auto=librpm.so)])], [], [with_rpm="auto"]) + +m4_pattern_allow([^AC_MSG_ERROR$]) +m4_pattern_allow([^AC_MSG_WARN$]) +if test "x$with_rpm" != "xno"; then + if test "x$with_rpm" = "xyes"; then + LIBRPM="librpm.so" + RPM_REQUIRE=true + DLOPEN_REQUIRE=false + elif test "x$with_rpm" = "xauto"; then + LIBRPM="librpm.so" + RPM_REQUIRE=false + DLOPEN_REQUIRE=false + else + LIBRPM="$with_rpm" + RPM_REQUIRE=true + DLOPEN_REQUIRE=true + fi + LIBRPM_STRING='"'"$LIBRPM"'"' + + AC_MSG_CHECKING([specific librpm version]) + HAVE_DLOPEN_LIBRPM=false + save_LIBS="$LIBS" + LIBS="$LIBS -ldl" + AC_RUN_IFELSE(AC_LANG_PROGRAM([[ +#include +#include +#include + ]], [[ + void *h; + const char *const *rpmverp; + FILE *f; + + f = fopen ("conftest.out", "w"); + if (!f) + { + fprintf (stderr, "Cannot write \"%s\": %s\n", "conftest.out", + strerror (errno)); + return 1; + } + h = dlopen ($LIBRPM_STRING, RTLD_LAZY); + if (!h) + { + fprintf (stderr, "dlopen (\"%s\"): %s\n", $LIBRPM_STRING, dlerror ()); + return 1; + } + rpmverp = dlsym (h, "RPMVERSION"); + if (!rpmverp) + { + fprintf (stderr, "dlsym (\"RPMVERSION\"): %s\n", dlerror ()); + return 1; + } + fprintf (stderr, "RPMVERSION is: \""); + fprintf (stderr, "%s\"\n", *rpmverp); + + /* Try to find the specific librpm version only for "librpm.so" as we do + not know how to assemble the version string otherwise. */ + + if (strcmp ("librpm.so", $LIBRPM_STRING) != 0) + { + fprintf (f, "%s\n", $LIBRPM_STRING); + return 0; + } + else + { + char *h2_name; + void *h2; + int major, minor; + + if (sscanf (*rpmverp, "%d.%d", &major, &minor) != 2) + { + fprintf (stderr, "Unable to parse RPMVERSION.\n"); + fprintf (f, "%s\n", $LIBRPM_STRING); + return 0; + } + /* Avoid the square brackets by malloc. */ + h2_name = malloc (64); + sprintf (h2_name, "librpm-%d.%d.so", major, minor); + h2 = dlopen (h2_name, RTLD_LAZY); + if (!h2) + { + fprintf (stderr, "dlopen (\"%s\"): %s\n", h2_name, dlerror ()); + fprintf (f, "%s\n", $LIBRPM_STRING); + return 0; + } + if (h2 != h) + { + fprintf (stderr, "dlopen of \"%s\" and \"%s\" are different.\n", + $LIBRPM_STRING, h2_name); + fprintf (f, "%s\n", $LIBRPM_STRING); + return 0; + } + /* Found the valid .so name with a specific version. */ + fprintf (f, "%s\n", h2_name); + return 0; + } + ]]), [ + DLOPEN_LIBRPM="`cat conftest.out`" + if test "x$DLOPEN_LIBRPM" != "x"; then + HAVE_DLOPEN_LIBRPM=true + AC_MSG_RESULT($DLOPEN_LIBRPM) + fi + ]) + rm -f conftest.out + + m4_define([CHECK_LIBRPM_COMPAT], [ + AC_MSG_CHECKING([rpm library API compatibility]) + # The compilation requires -Werror to verify anything. + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[ +/* Duplicate here the declarations to verify they match "elfread.c". */ +#include +#include +#include +#include +extern char * headerFormat(Header h, const char * fmt, errmsg_t * errmsg); +extern int rpmReadConfigFiles(const char * file, const char * target); +extern rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi); +extern Header rpmdbNextIterator(rpmdbMatchIterator mi); +extern rpmts rpmtsCreate(void); +extern rpmts rpmtsFree(rpmts ts); +extern rpmdbMatchIterator rpmtsInitIterator(const rpmts ts, rpmTag rpmtag, + const void * keyp, size_t keylen); + ]]), [ + LIBRPM_COMPAT=true + AC_MSG_RESULT(yes) + ], [ + LIBRPM_COMPAT=false + AC_MSG_RESULT(no) + ]) + CFLAGS="$save_CFLAGS" + ]) + + if $HAVE_DLOPEN_LIBRPM; then + CHECK_LIBRPM_COMPAT + if ! $LIBRPM_COMPAT; then + HAVE_DLOPEN_LIBRPM=false + fi + fi + + if $HAVE_DLOPEN_LIBRPM; then + DLOPEN_LIBRPM_STRING='"'"$DLOPEN_LIBRPM"'"' + AC_DEFINE_UNQUOTED(DLOPEN_LIBRPM, $DLOPEN_LIBRPM_STRING, [librpm version specific library name to dlopen.]) + AC_DEFINE(HAVE_LIBRPM, 1, [Define if librpm library is being used.]) + else + AC_MSG_RESULT(no) + LIBS="$save_LIBS" + if $DLOPEN_REQUIRE; then + AC_MSG_ERROR([Specific name $LIBRPM was requested but it could not be opened.]) + fi + PKG_CHECK_MODULES(RPM, rpm, [HAVE_LIBRPM=true], [HAVE_LIBRPM=false]) + + if $HAVE_LIBRPM; then + CHECK_LIBRPM_COMPAT + if ! $LIBRPM_COMPAT; then + HAVE_LIBRPM=false + RPM_PKG_ERRORS="Found $LIBRPM API is incompatibile with this GDB" + fi + fi + + if $HAVE_LIBRPM; then + AC_DEFINE(HAVE_LIBRPM, 1, [Define if librpm library is being used.]) + CFLAGS="$CFLAGS $RPM_CFLAGS" + LIBS="$LIBS $RPM_LIBS" + else + if $RPM_REQUIRE; then + AC_MSG_ERROR($RPM_PKG_ERRORS) + else + AC_MSG_WARN($RPM_PKG_ERRORS) + fi + fi + fi +fi + AC_CONFIG_SUBDIRS(testsuite) # Check whether to support alternative target configurations @@ -550,7 +743,8 @@ if test x"$prefer_curses" = xyes; then # search /usr/local/include, if ncurses is installed in /usr/local. A # default installation of ncurses on alpha*-dec-osf* will lead to such # a situation. - AC_SEARCH_LIBS(waddstr, [ncursesw ncurses cursesX curses]) + # Fedora: Force libncursesw over libncurses to match the includes. + AC_SEARCH_LIBS(waddstr, [ncursesw]) if test "$ac_cv_search_waddstr" != no; then curses_found=yes @@ -592,7 +786,8 @@ case $host_os in esac # These are the libraries checked by Readline. -AC_SEARCH_LIBS(tgetent, [termcap tinfow tinfo curses ncursesw ncurses]) +# Fedora: Force libncursesw over libncurses to match the includes. +AC_SEARCH_LIBS(tgetent, [termcap tinfow tinfo ncursesw ]) if test "$ac_cv_search_tgetent" = no; then CONFIG_OBS="$CONFIG_OBS stub-termcap.o" @@ -627,10 +822,12 @@ AC_CHECK_SIZEOF(unsigned long long) AC_CHECK_SIZEOF(unsigned long) AC_CHECK_SIZEOF(unsigned __int128) -if test "x${ac_cv_sizeof_unsigned_long}" = "x8"; then - TARGET_PTR="unsigned long" -elif test "x${ac_cv_sizeof_unsigned_long_long}" = "x8"; then +# Try to keep TARGET_PTR the same across archs so that jit-reader.h file +# content is the same for multilib distributions. +if test "x${ac_cv_sizeof_unsigned_long_long}" = "x8"; then TARGET_PTR="unsigned long long" +elif test "x${ac_cv_sizeof_unsigned_long}" = "x8"; then + TARGET_PTR="unsigned long" elif test "x${ac_cv_sizeof_unsigned___int128}" = "x16"; then TARGET_PTR="unsigned __int128" else @@ -1272,7 +1469,7 @@ else AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ #include #ifndef PERF_ATTR_SIZE_VER5 -# error +// error // PERF_ATTR_SIZE_VER5_BUNDLE is not available here - Fedora+RHEL #endif ]])], [perf_event=yes], [perf_event=no]) if test "$perf_event" != yes; then @@ -1827,6 +2024,10 @@ case $host_os in esac AC_DEFINE_UNQUOTED(GDBINIT,"$gdbinit",[The .gdbinit filename.]) +dnl Check security_get_boolean_active availability. +AC_CHECK_HEADERS(selinux/selinux.h) +AC_CHECK_LIB(selinux, security_get_boolean_active) + dnl Handle optional features that can be enabled. # Support for --with-sysroot is a copy of GDB_AC_WITH_DIR, diff --git a/gdb/configure.nat b/gdb/configure.nat index 64ee101d836..f02fdef3644 100644 --- a/gdb/configure.nat +++ b/gdb/configure.nat @@ -245,6 +245,7 @@ case ${gdb_host} in ;; i386) # Host: Intel 386 running GNU/Linux. + NAT_FILE="${srcdir}/config/${gdb_host_cpu}/nm-linux.h" NATDEPFILES="${NATDEPFILES} x86-nat.o nat/x86-dregs.o \ i386-linux-nat.o x86-linux-nat.o nat/linux-btrace.o \ nat/x86-linux.o nat/x86-linux-dregs.o" @@ -301,6 +302,7 @@ case ${gdb_host} in case ${gdb_host_cpu} in i386) # Host: GNU/Linux x86-64 + NAT_FILE="${srcdir}/config/${gdb_host_cpu}/nm-linux64.h" NATDEPFILES="${NATDEPFILES} x86-nat.o nat/x86-dregs.o \ amd64-nat.o amd64-linux-nat.o x86-linux-nat.o \ nat/linux-btrace.o \ diff --git a/gdb/contrib/gdb-add-index.sh b/gdb/contrib/gdb-add-index.sh index efaad1dce71..c85e2e9403d 100755 --- a/gdb/contrib/gdb-add-index.sh +++ b/gdb/contrib/gdb-add-index.sh @@ -21,6 +21,11 @@ GDB=${GDB:=gdb} OBJCOPY=${OBJCOPY:=objcopy} +GDB2=/usr/libexec/gdb +if test -x $GDB2 && ! which $GDB &>/dev/null; then + GDB=$GDB2 +fi + myname="${0##*/}" dwarf5="" diff --git a/gdb/corelow.c b/gdb/corelow.c index 3ce612d31b4..29448129d09 100644 --- a/gdb/corelow.c +++ b/gdb/corelow.c @@ -43,6 +43,10 @@ #include "gdb_bfd.h" #include "completer.h" #include "common/filestuff.h" +#include "auxv.h" +#include "elf/common.h" +#include "gdbcmd.h" +#include "build-id.h" #ifndef O_LARGEFILE #define O_LARGEFILE 0 @@ -320,6 +324,49 @@ add_to_thread_list (bfd *abfd, asection *asect, void *reg_sect_arg) inferior_ptid = ptid; /* Yes, make it current. */ } +static int build_id_core_loads = 1; + +static void +build_id_locate_exec (int from_tty) +{ + CORE_ADDR at_entry; + gdb::unique_xmalloc_ptr build_id; + char *build_id_filename; + gdb::unique_xmalloc_ptr execfilename, build_id_filename_ptr; + + if (exec_bfd != NULL || symfile_objfile != NULL) + return; + + if (target_auxv_search (current_top_target (), AT_ENTRY, &at_entry) <= 0) + return; + + build_id.reset(build_id_addr_get (at_entry)); + if (build_id == NULL) + return; + + /* SYMFILE_OBJFILE should refer to the main executable (not only to its + separate debug info file). gcc44+ keeps .eh_frame only in the main + executable without its duplicate .debug_frame in the separate debug info + file - such .eh_frame would not be found if SYMFILE_OBJFILE would refer + directly to the separate debug info file. */ + + execfilename.reset(build_id_to_filename (build_id.get(), &build_id_filename)); + build_id_filename_ptr.reset(build_id_filename); + + if (execfilename != NULL) + { + exec_file_attach (execfilename.get(), from_tty); + symbol_file_add_main (execfilename.get(), + symfile_add_flag (!from_tty ? 0 : SYMFILE_VERBOSE)); + if (symfile_objfile != NULL) + symfile_objfile->flags |= OBJF_BUILD_ID_CORE_LOADED; + } + else + debug_print_missing (BUILD_ID_MAIN_EXECUTABLE_FILENAME, build_id_filename); + + /* No automatic SOLIB_ADD as the libraries would get read twice. */ +} + /* Issue a message saying we have no core to debug, if FROM_TTY. */ static void @@ -455,6 +502,14 @@ core_target_open (const char *arg, int from_tty) switch_to_thread (thread); } + /* Find the build_id identifiers. If it gets executed after + POST_CREATE_INFERIOR we would clash with asking to discard the already + loaded VDSO symbols. If it gets executed before bfd_map_over_sections + INFERIOR_PTID is still not set and libthread_db initialization crashes on + PID == 0 in ps_pglobal_lookup. */ + if (build_id_core_loads != 0) + build_id_locate_exec (from_tty); + post_create_inferior (target, from_tty); /* Now go through the target stack looking for threads since there @@ -1059,4 +1114,11 @@ void _initialize_corelow (void) { add_target (core_target_info, core_target_open, filename_completer); + + add_setshow_boolean_cmd ("build-id-core-loads", class_files, + &build_id_core_loads, _("\ +Set whether CORE-FILE loads the build-id associated files automatically."), _("\ +Show whether CORE-FILE loads the build-id associated files automatically."), + NULL, NULL, NULL, + &setlist, &showlist); } diff --git a/gdb/cp-abi.c b/gdb/cp-abi.c index d95b1404dce..bc56a1a03e9 100644 --- a/gdb/cp-abi.c +++ b/gdb/cp-abi.c @@ -64,12 +64,12 @@ is_operator_name (const char *name) return (*current_cp_abi.is_operator_name) (name); } -int +LONGEST baseclass_offset (struct type *type, int index, const gdb_byte *valaddr, LONGEST embedded_offset, CORE_ADDR address, const struct value *val) { - int res = 0; + LONGEST res = 0; gdb_assert (current_cp_abi.baseclass_offset != NULL); @@ -95,7 +95,7 @@ baseclass_offset (struct type *type, int index, const gdb_byte *valaddr, struct value * value_virtual_fn_field (struct value **arg1p, struct fn_field *f, int j, - struct type *type, int offset) + struct type *type, LONGEST offset) { if ((current_cp_abi.virtual_fn_field) == NULL) return NULL; diff --git a/gdb/cp-abi.h b/gdb/cp-abi.h index 3cbf19cd511..3e96f4d2d3e 100644 --- a/gdb/cp-abi.h +++ b/gdb/cp-abi.h @@ -108,7 +108,7 @@ extern struct value *value_virtual_fn_field (struct value **valuep, struct fn_field *f, int j, struct type *type, - int offset); + LONGEST offset); /* Try to find the run-time type of VALUE, using C++ run-time type @@ -144,11 +144,11 @@ extern struct type *value_rtti_type (struct value *value, contents of VAL. The result is the offset of the baseclass value relative to (the address of)(ARG) + OFFSET. */ -extern int baseclass_offset (struct type *type, - int index, const gdb_byte *valaddr, - LONGEST embedded_offset, - CORE_ADDR address, - const struct value *val); +extern LONGEST baseclass_offset (struct type *type, + int index, const gdb_byte *valaddr, + LONGEST embedded_offset, + CORE_ADDR address, + const struct value *val); /* Describe the target of a pointer to method. CONTENTS is the byte pattern representing the pointer to method. TYPE is the pointer to @@ -226,12 +226,12 @@ struct cp_abi_ops struct value *(*virtual_fn_field) (struct value **arg1p, struct fn_field * f, int j, struct type * type, - int offset); + LONGEST offset); struct type *(*rtti_type) (struct value *v, int *full, LONGEST *top, int *using_enc); - int (*baseclass_offset) (struct type *type, int index, - const bfd_byte *valaddr, LONGEST embedded_offset, - CORE_ADDR address, const struct value *val); + LONGEST (*baseclass_offset) (struct type *type, int index, + const bfd_byte *valaddr, LONGEST embedded_offset, + CORE_ADDR address, const struct value *val); void (*print_method_ptr) (const gdb_byte *contents, struct type *type, struct ui_file *stream); diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c index e883179dfad..c36482ac60d 100644 --- a/gdb/cp-valprint.c +++ b/gdb/cp-valprint.c @@ -318,11 +318,14 @@ cp_print_value_fields (struct type *type, struct type *real_type, } else if (field_is_static (&TYPE_FIELD (type, i))) { - struct value *v = NULL; try { + struct value *v = NULL; v = value_static_field (type, i); + cp_print_static_field (TYPE_FIELD_TYPE (type, i), + v, stream, recurse + 1, + options); } catch (const gdb_exception_error &ex) @@ -331,14 +334,10 @@ cp_print_value_fields (struct type *type, struct type *real_type, _(""), ex.what ()); } - - cp_print_static_field (TYPE_FIELD_TYPE (type, i), - v, stream, recurse + 1, - options); } else if (i == vptr_fieldno && type == vptr_basetype) { - int i_offset = offset + TYPE_FIELD_BITPOS (type, i) / 8; + LONGEST i_offset = offset + TYPE_FIELD_BITPOS (type, i) / 8; struct type *i_type = TYPE_FIELD_TYPE (type, i); if (valprint_check_validity (stream, i_type, i_offset, val)) @@ -531,6 +530,7 @@ cp_print_value (struct type *type, struct type *real_type, if ((boffset + offset) < 0 || (boffset + offset) >= TYPE_LENGTH (real_type)) { + ulongest_fits_host_or_error (TYPE_LENGTH (baseclass)); gdb::byte_vector buf (TYPE_LENGTH (baseclass)); if (target_read_memory (address + boffset, buf.data (), diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c index 8eda05806f8..1d59d541828 100644 --- a/gdb/cris-tdep.c +++ b/gdb/cris-tdep.c @@ -657,13 +657,13 @@ static CORE_ADDR crisv32_scan_prologue (CORE_ADDR pc, struct stack_item { - int len; + ssize_t len; struct stack_item *prev; gdb_byte *data; }; static struct stack_item * -push_stack_item (struct stack_item *prev, const gdb_byte *contents, int len) +push_stack_item (struct stack_item *prev, const gdb_byte *contents, ssize_t len) { struct stack_item *si = XNEW (struct stack_item); si->data = (gdb_byte *) xmalloc (len); @@ -814,13 +814,13 @@ cris_push_dummy_call (struct gdbarch *gdbarch, struct value *function, for (argnum = 0; argnum < nargs; argnum++) { - int len; + ssize_t len; const gdb_byte *val; - int reg_demand; - int i; + ssize_t reg_demand; + ssize_t i; - len = TYPE_LENGTH (value_type (args[argnum])); val = value_contents (args[argnum]); + len = TYPE_LENGTH (value_type (args[argnum])); /* How may registers worth of storage do we need for this argument? */ reg_demand = (len / 4) + (len % 4 != 0 ? 1 : 0); diff --git a/gdb/d-lang.h b/gdb/d-lang.h index 956c1923a69..ecadf73416b 100644 --- a/gdb/d-lang.h +++ b/gdb/d-lang.h @@ -79,7 +79,7 @@ extern struct block_symbol d_lookup_nested_symbol (struct type *, const char *, /* Defined in d-valprint.c */ extern void d_val_print (struct type *type, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options); diff --git a/gdb/d-valprint.c b/gdb/d-valprint.c index 54652364a8f..68174a843dd 100644 --- a/gdb/d-valprint.c +++ b/gdb/d-valprint.c @@ -73,7 +73,7 @@ dynamic_array_type (struct type *type, /* Implements the la_val_print routine for language D. */ void -d_val_print (struct type *type, int embedded_offset, +d_val_print (struct type *type, LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options) diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in index 88147125ccd..47e54c46868 100644 --- a/gdb/data-directory/Makefile.in +++ b/gdb/data-directory/Makefile.in @@ -71,6 +71,8 @@ PYTHON_FILE_LIST = \ gdb/__init__.py \ gdb/FrameDecorator.py \ gdb/FrameIterator.py \ + gdb/FrameWrapper.py \ + gdb/backtrace.py \ gdb/frames.py \ gdb/printing.py \ gdb/prompt.py \ @@ -78,7 +80,9 @@ PYTHON_FILE_LIST = \ gdb/unwinder.py \ gdb/xmethod.py \ gdb/command/__init__.py \ + gdb/command/ignore_errors.py \ gdb/command/explore.py \ + gdb/command/backtrace.py \ gdb/command/frame_filters.py \ gdb/command/pretty_printers.py \ gdb/command/prompt.py \ @@ -89,6 +93,8 @@ PYTHON_FILE_LIST = \ gdb/function/as_string.py \ gdb/function/caller_is.py \ gdb/function/strfns.py \ + gdb/function/caller_is.py \ + gdb/function/in_scope.py \ gdb/printer/__init__.py \ gdb/printer/bound_registers.py diff --git a/gdb/defs.h b/gdb/defs.h index a44e186907d..05e04b14733 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -168,6 +168,10 @@ extern void default_quit_handler (void); /* Flag that function quit should call quit_force. */ extern volatile int sync_quit_force_run; +#ifdef NEED_DETACH_SIGSTOP +extern int quit_flag_cleanup; +#endif + extern void quit (void); /* Helper for the QUIT macro. */ @@ -669,4 +673,6 @@ DEF_ENUM_FLAGS_TYPE (enum user_selected_what_flag, user_selected_what); #include "utils.h" +extern void ulongest_fits_host_or_error (ULONGEST num); + #endif /* #ifndef DEFS_H */ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index f410d026b82..c039d2b0568 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -1251,6 +1251,16 @@ for remote debugging. Run using @var{device} for your program's standard input and output. @c FIXME: kingdon thinks there is more to -tty. Investigate. +@item -P +@cindex @code{-P} +@itemx --python +@cindex @code{--python} +Change interpretation of command line so that the argument immediately +following this switch is taken to be the name of a Python script file. +This option stops option processing; subsequent options are passed to +Python as @code{sys.argv}. This option is only available if Python +scripting support was enabled when @value{GDBN} was configured. + @c resolve the situation of these eventually @item -tui @cindex @code{--tui} @@ -19967,6 +19977,27 @@ information files. @end table +You can also adjust the current verbosity of the @dfn{build id} locating. + +@table @code + +@kindex set build-id-verbose +@item set build-id-verbose 0 +No additional messages are printed. + +@item set build-id-verbose 1 +Missing separate debug filenames are printed. + +@item set build-id-verbose 2 +Missing separate debug filenames are printed and also all the parsing of the +binaries to find their @dfn{build id} content is printed. + +@kindex show build-id-verbose +@item show build-id-verbose +Show the current verbosity value for the @dfn{build id} content locating. + +@end table + @cindex @code{.gnu_debuglink} sections @cindex debug link sections A debug link is a special section of the executable file named diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi index 36947de30b0..515f8b9a58a 100644 --- a/gdb/doc/python.texi +++ b/gdb/doc/python.texi @@ -90,8 +90,6 @@ containing @code{end}. For example: @smallexample (@value{GDBP}) python -Type python script -End with a line saying just "end". >print 23 >end 23 @@ -158,7 +156,9 @@ optional arguments while skipping others. Example: * Frames In Python:: Accessing inferior stack frames from Python. * Blocks In Python:: Accessing blocks from Python. * Symbols In Python:: Python representation of symbols. +* Minimal Symbols In Python:: Python representation of minimal symbols. * Symbol Tables In Python:: Python representation of symbol tables. +* Registers in Python:: Python representation of CPU registers. * Line Tables In Python:: Python representation of line tables. * Breakpoints In Python:: Manipulating breakpoints using Python. * Finish Breakpoints in Python:: Setting Breakpoints on function return @@ -234,6 +234,14 @@ returned as a string. The default is @code{False}, in which case the return value is @code{None}. If @var{to_string} is @code{True}, the @value{GDBN} virtual terminal will be temporarily set to unlimited width and height, and its pagination will be disabled; @pxref{Screen Size}. + +The @var{release_gil} flag specifies whether @value{GDBN} ought to +release the Python GIL before executing the command. This is useful +in multi-threaded Python programs where by default the Python +interpreter will acquire the GIL and lock other threads from +executing. After the command has completed executing in @value{GDBN} +the Python GIL is reacquired. This flag must be a boolean value. If +omitted, it defaults to @code{False}. @end defun @findex gdb.breakpoints @@ -579,8 +587,9 @@ for its internal bookkeeping of the inferior's values, and for fetching values when necessary. Inferior values that are simple scalars can be used directly in -Python expressions that are valid for the value's data type. Here's -an example for an integer or floating-point value @code{some_val}: +Python expressions that are valid for the value's data type. Signedness +is be preserved from the value. Here's an example for an integer or +floating-point value @code{some_val}: @smallexample bar = some_val + 2 @@ -601,6 +610,14 @@ as follows: val3 = val1 + val2 @end smallexample +@noindent +In C-like languages, one can convert the target address of pointer types +for use in Python as unsigned long values as follows: + +@smallexample +val = long(some_val) +@end smallexample + @noindent The result of the operation @code{val3} is also a @code{gdb.Value} object corresponding to the value returned by the overloaded @code{+} @@ -2969,6 +2986,13 @@ as a whole. Some platforms can have multiple architectures in a single address space, so this may not match the architecture of a particular frame (@pxref{Frames In Python}). @end defun +@findex Inferior.new_thread +@defun Inferior.new_thread (ptid-tuple [, info]) +This method creates a new thread object within @value{GDBN} and assigns it +the ptid contained in ptid-tuple. Optionally, the caller can provide an +object that will be associated with the thread and made available via the +@code{gdb.InferiorThread.info} attribute. +@end defun @findex Inferior.read_memory @defun Inferior.read_memory (address, length) @@ -3312,6 +3336,19 @@ The inferior this thread belongs to. This attribute is represented as a @code{gdb.Inferior} object. This attribute is not writable. @end defvar +@defvar InferiorThread.registers +Return a dictionary of registers associated with this thread. The dictionary +is not writable but the values of the registers it contains may be writable +depending on the target. Writing to the register values will update them +similar to using the @code{set $register} @value{GDBN} command. +@end defvar + +@defvar InferiorThread.info +If the thread was created via a @code{gdb.InferiorThread.new_thread} call, +the @code{info} attribute will contain the object passed to it during +thread creation. This attribute is not writable. +@end defvar + A @code{gdb.InferiorThread} object has the following methods: @defun InferiorThread.is_valid () @@ -4784,8 +4821,9 @@ arguments. @var{name} is the name of the symbol. It must be a string. The optional @var{block} argument restricts the search to symbols visible in that @var{block}. The @var{block} argument must be a -@code{gdb.Block} object. If omitted, the block for the current frame -is used. The optional @var{domain} argument restricts +@code{gdb.Block} object or @code{None}. If omitted, the block for the +current frame is used. If @code{None}, no block will be used to resolve +the symbol. The optional @var{domain} argument restricts the search to the domain type. The @var{domain} argument must be a domain constant defined in the @code{gdb} module and described later in this chapter. @@ -5001,6 +5039,183 @@ The value's address is a symbol. This is only used for Fortran common blocks. @end vtable +@node Minimal Symbols In Python +@subsubsection Python representation of Minimal Symbols. + +@cindex minsymbols in python +@tindex gdb.MinSymbol + +@value{GDBN} represents every variable, function and type as an +entry in a symbol table. @xref{Symbols, ,Examining the Symbol Table}. +Typical symbols like functions, variables, etc are represented by +gdb.Symbol objects in Python. Some symbols are defined with less +information associated with them, like linker script variables +or assembly labels. Python represents these minimal symbols in @value{GDBN} +with the @code{gdb.MinSymbol} object. + +The following minimal symbol-related functions are available in the @code{gdb} +module: + +@findex gdb.lookup_minimal_symbol +@defun gdb.lookup_minimal_symbol (name @r{[}, sfile@r{]}, objfile@r{[}) +This function searches for a minimal symbol by name. +The search scope can be restricted by the sfile and objfile arguments. + +@var{name} is the name of the minimal symbol. It must be a string. +The optional @var{sfile} argument restricts the search to the source file +in which the minimal symbol was defined. +The @var{sfile} argument must be a string. The optional @var{objfile} +restricts the search to the objfile that contains the minimal symbol. The @var{objfile} argument must be a @code{gdb.Objfile} object. + +The result is a @code{gdb.MinSymbol} object or @code{None} if the symbol +is not found. +@end defun + +A @code{gdb.MinSymbol} object has the following attributes: + +@defvar MinSymbol.name +The name of the symbol as a string. This attribute is not writable. +@end defvar + +@defvar MinSymbol.linkage_name +The name of the symbol, as used by the linker (i.e., may be mangled). +This attribute is not writable. +@end defvar + +@defvar MinSymbol.print_name +The name of the symbol in a form suitable for output. This is either +@code{name} or @code{linkage_name}, depending on whether the user +asked @value{GDBN} to display demangled or mangled names. +@end defvar + +@defvar MinSymbol.filename +The file name of the source file where the minimal symbol is defined. This +value may represent filenames used internally by the compiler rather +than a viewable/editable source file. +@end defvar + +@defvar MinSymbol.section +The name of the binary section containing this minimal symbol. +@end defvar + +@defvar MinSymbol.is_code +@code{True} if the minimal symbol is a function or a method. +@end defvar + +@defvar MinSymbol.is_data +@code{True} if the symbol is a variable or other data. +@end defvar + +A @code{gdb.MinSymbol} object has the following methods: + +@defun MinSymbol.is_valid () +Returns @code{True} if the @code{gdb.MinSymbol} object is valid, +@code{False} if not. A @code{gdb.MinSymbol} object can become invalid if +the symbol it refers to does not exist in @value{GDBN} any longer. +All other @code{gdb.MinSymbol} methods will throw an exception if it is +invalid at the time the method is called. +@end defun + +@defun MinSymbol.value () +Compute the value of the minimal symbol, as a @code{gdb.Value}. The value +returned represents the address of the minimal symbol. Since minimal symbols +represent objects without rich type information, the @code{gdb.Type} +associated with the @code{gdb.Value} objects will be limited to whether +the minimal symbol describes executable code or data. +@end defun + +The available types for @code{gdb.MinSymbol} are represented +as constants in the @code{gdb} module. They are distinctly separate from the +types represented by the @code{gdb.Type} object. + +@vtable @code +@vindex MINSYMBOL_TYPE_UNKNOWN +@item gdb.MINSYMBOL_TYPE_UNKNOWN +This is used when the type has not been discovered or none of the +following types apply. This usually indicates an error either +in the symbol information or in @value{GDBN}'s handling of symbols. + +@vindex MINSYMBOL_TYPE_TEXT +@item gdb.MINSYMBOL_TYPE_TEXT +This type represents executable code. + +@vindex MINSYMBOL_TYPE_TEXT_GNU_IFUNC +@item gdb.MINSYMBOL_TYPE_TEXT_GNU_IFUNC +This type represents executable code that returns the address +of executable code. + +@vindex MINSYMBOL_TYPE_SLOT_GOT_PLT +@item gdb.MINSYMBOL_TYPE_SLOT_GOT_PLT +This type represents GOT for .plt sections. + +@vindex MINSYMBOL_TYPE_DATA +@item gdb.MINSYMBOL_TYPE_DATA +This type represents generally initialized (nonzero) data. + +@vindex MINSYMBOL_TYPE_BSS +@item gdb.MINSYMBOL_TYPE_BSS +This type represents generally uninitialized (zeroed) data. + +@vindex MINSYMBOL_TYPE_ABS +@item gdb.MINSYMBOL_TYPE_ABS +This type represents generally absolute (non-relocatable) data. + +@vindex MINSYMBOL_TYPE_SOLIB_TRAMPOLINE +@item gdb.MINSYMBOL_TYPE_SOLIB_TRAMPOLINE +This type represents the start address of a shared library trampoline entry. + +@vindex MINSYMBOL_TYPE_FILE_TEXT +@item gdb.MINSYMBOL_TYPE_FILE_TEXT +This type represents the static version of gdb.MINSYMBOL_TYPE_TEXT. + +@vindex MINSYMBOL_TYPE_FILE_DATA +@item gdb.MINSYMBOL_TYPE_FILE_DATA +This type represents the static version of gdb.MINSYMBOL_TYPE_DATA. + +@vindex MINSYMBOL_TYPE_FILE_BSS +@item gdb.MINSYMBOL_TYPE_FILE_BSS +This type represents the static version of gdb.MINSYMBOL_TYPE_BSS. +@end vtable + +@node Registers in Python +@subsubsection Python representation of CPU registers + +@cindex registers in python +@tindex gdb.Register + +@value{GDBN} represents CPU registers associated with threads as a @code{gdb.Register} object in Python. + +A @code{gdb.Register} object has the following attributes: + +@defvar Register.name +The architecture-defined name for the register. This attribute is not writable. +@end defvar + +@defvar Register.value +The value that this register contains. This attribute is writable. The value +assigned to the register must be of sufficient size and compatible with the +@code{Register.type} or a TypeError exception will be raised. Integers, longs, +bytearray objects, and @code{gdb.Value} objects are accepted. @value{GDBN} +will attempt to automatically cast a supplied @code{gdb.Value} object to the +register type. Providing None marks the register as containing and +undefined value. +@end defvar + +@defvar Register.size +The size of the register in bytes. Most general purpose registers will +have a size that matches the size of a long integer on the target +architecture. Special-purpose registers can have arbitary lengths. This +attribute is not writable. +@end defvar + +@defvar Register.regnum +The architecture-dependent register number. This attribute is not writable. +@end defvar + +@defvar Register.type +The type that this register represents. This attribute is not writable. +@end defvar + @node Symbol Tables In Python @subsubsection Symbol table representation in Python diff --git a/gdb/dwarf-index-cache.c b/gdb/dwarf-index-cache.c index 9513891a45f..9bbcdeff4e1 100644 --- a/gdb/dwarf-index-cache.c +++ b/gdb/dwarf-index-cache.c @@ -93,7 +93,7 @@ index_cache::store (struct dwarf2_per_objfile *dwarf2_per_objfile) if (!enabled ()) return; - const bfd_build_id *build_id = build_id_bfd_get (obj->obfd); + const bfd_build_id *build_id = build_id_bfd_shdr_get (obj->obfd); if (build_id == nullptr) { if (debug_index_cache) diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 2b8aeee83ad..c2d81d4bc50 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -42,6 +42,7 @@ #include #include #include +#include #include "common/underlying.h" #include "common/byte-vector.h" @@ -1622,7 +1623,7 @@ rw_pieced_value (struct value *v, struct value *from) for (; i < c->pieces.size () && offset < max_offset; i++) { struct dwarf_expr_piece *p = &c->pieces[i]; - size_t this_size_bits, this_size; + ULONGEST this_size_bits, this_size; this_size_bits = p->size - bits_to_skip; if (this_size_bits > max_offset - offset) @@ -1869,7 +1870,7 @@ write_pieced_value (struct value *to, struct value *from) static int check_pieced_synthetic_pointer (const struct value *value, LONGEST bit_offset, - int bit_length) + LONGEST bit_length) { struct piece_closure *c = (struct piece_closure *) value_computed_closure (value); @@ -1882,7 +1883,7 @@ check_pieced_synthetic_pointer (const struct value *value, LONGEST bit_offset, for (i = 0; i < c->pieces.size () && bit_length > 0; i++) { struct dwarf_expr_piece *p = &c->pieces[i]; - size_t this_size_bits = p->size; + ULONGEST this_size_bits = p->size; if (bit_offset > 0) { @@ -1986,8 +1987,8 @@ indirect_pieced_value (struct value *value) = (struct piece_closure *) value_computed_closure (value); struct type *type; struct frame_info *frame; - int i, bit_length; - LONGEST bit_offset; + int i; + LONGEST bit_length, bit_offset; struct dwarf_expr_piece *piece = NULL; LONGEST byte_offset; enum bfd_endian byte_order; @@ -2004,7 +2005,7 @@ indirect_pieced_value (struct value *value) for (i = 0; i < c->pieces.size () && bit_length > 0; i++) { struct dwarf_expr_piece *p = &c->pieces[i]; - size_t this_size_bits = p->size; + ULONGEST this_size_bits = p->size; if (bit_offset > 0) { @@ -2156,6 +2157,20 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, ctx.per_cu = per_cu; ctx.obj_address = 0; +frame_id old_frame_id (get_frame_id (deprecated_safe_get_selected_frame ())); +class RestoreCall { +private: + const std::function func; +public: + RestoreCall(std::function func_):func(func_) {} + ~RestoreCall() { func(); } +} restore_frame([=]() { + frame_info *old_frame (frame_find_by_id (old_frame_id)); + if (old_frame != NULL) + select_frame (old_frame); +}); +if (frame != NULL) select_frame (frame); + scoped_value_mark free_values; ctx.gdbarch = get_objfile_arch (objfile); @@ -2278,9 +2293,9 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, case DWARF_VALUE_STACK: { struct value *value = ctx.fetch (0); - size_t n = TYPE_LENGTH (value_type (value)); - size_t len = TYPE_LENGTH (subobj_type); - size_t max = TYPE_LENGTH (type); + ULONGEST n = TYPE_LENGTH (value_type (value)); + ULONGEST len = TYPE_LENGTH (subobj_type); + ULONGEST max = TYPE_LENGTH (type); struct gdbarch *objfile_gdbarch = get_objfile_arch (objfile); if (subobj_byte_offset + len > max) @@ -2425,11 +2440,14 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton, /* See dwarf2loc.h. */ int -dwarf2_evaluate_property (const struct dynamic_prop *prop, +dwarf2_evaluate_property_signed (const struct dynamic_prop *prop, struct frame_info *frame, struct property_addr_info *addr_stack, - CORE_ADDR *value) + CORE_ADDR *value, + int is_signed) { + int rc = 0; + if (prop == NULL) return 0; @@ -2453,7 +2471,7 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop, *value = value_as_address (val); } - return 1; + rc = 1; } } break; @@ -2475,7 +2493,7 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop, if (!value_optimized_out (val)) { *value = value_as_address (val); - return 1; + rc = 1; } } } @@ -2483,8 +2501,8 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop, case PROP_CONST: *value = prop->data.const_val; - return 1; - + rc = 1; + break; case PROP_ADDR_OFFSET: { struct dwarf2_property_baton *baton @@ -2505,11 +2523,38 @@ dwarf2_evaluate_property (const struct dynamic_prop *prop, val = value_at (baton->offset_info.type, pinfo->addr + baton->offset_info.offset); *value = value_as_address (val); - return 1; + rc = 1; } + break; } - return 0; + if (rc == 1 && is_signed == 1) + { + /* If we have a valid return candidate and it's value is signed, + we have to sign-extend the value because CORE_ADDR on 64bit machine has + 8 bytes but address size of an 32bit application is 4 bytes. */ + struct gdbarch * gdbarch = target_gdbarch (); + const int addr_bit = gdbarch_addr_bit (gdbarch); + const CORE_ADDR neg_mask = ((~0) << (addr_bit - 1)); + + /* Check if signed bit is set and sign-extend values. */ + if (*value & (neg_mask)) + *value |= (neg_mask ); + } + return rc; +} + +int +dwarf2_evaluate_property (const struct dynamic_prop *prop, + struct frame_info *frame, + struct property_addr_info *addr_stack, + CORE_ADDR *value) +{ + return dwarf2_evaluate_property_signed (prop, + frame, + addr_stack, + value, + 0); } /* See dwarf2loc.h. */ diff --git a/gdb/dwarf2loc.h b/gdb/dwarf2loc.h index 955e6f1b48a..705e659c5ff 100644 --- a/gdb/dwarf2loc.h +++ b/gdb/dwarf2loc.h @@ -143,6 +143,12 @@ int dwarf2_evaluate_property (const struct dynamic_prop *prop, struct property_addr_info *addr_stack, CORE_ADDR *value); +int dwarf2_evaluate_property_signed (const struct dynamic_prop *prop, + struct frame_info *frame, + struct property_addr_info *addr_stack, + CORE_ADDR *value, + int is_signed); + /* A helper for the compiler interface that compiles a single dynamic property to C code. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 0873028e438..2cf33fefe63 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -1832,7 +1832,8 @@ static void read_signatured_type (struct signatured_type *); static int attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, struct dwarf2_cu *cu, - struct dynamic_prop *prop); + struct dynamic_prop *prop, const gdb_byte *additional_data, + int additional_data_size); /* memory allocation interface */ @@ -2063,11 +2064,11 @@ dwarf2_complex_location_expr_complaint (void) } static void -dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2, - int arg3) +dwarf2_const_value_length_mismatch_complaint (const char *arg1, LONGEST arg2, + LONGEST arg3) { - complaint (_("const value length mismatch for '%s', got %d, expected %d"), - arg1, arg2, arg3); + complaint (_("const value length mismatch for '%s', got %s, expected %s"), + arg1, plongest (arg2), plongest (arg3)); } static void @@ -2725,7 +2726,7 @@ dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile) } if (dwz_bfd == NULL) - dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid); + dwz_bfd = build_id_to_debug_bfd (buildid_len, buildid, NULL, 1); if (dwz_bfd == NULL) error (_("could not find '.gnu_debugaltlink' file for %s"), @@ -3278,7 +3279,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile, const uint8_t offset_size = dwarf5_is_dwarf64 ? 8 : 4; if (addr + entry_length > section->buffer + section->size) { - warning (_("Section .debug_aranges in %s entry at offset %zu " + warning (_("Section .debug_aranges in %s entry at offset %td " "length %s exceeds section length %s, " "ignoring .debug_aranges."), objfile_name (objfile), entry_addr - section->buffer, @@ -3292,7 +3293,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile, addr += 2; if (version != 2) { - warning (_("Section .debug_aranges in %s entry at offset %zu " + warning (_("Section .debug_aranges in %s entry at offset %tu " "has unsupported version %d, ignoring .debug_aranges."), objfile_name (objfile), entry_addr - section->buffer, version); @@ -3306,7 +3307,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile, = debug_info_offset_to_per_cu.find (sect_offset (debug_info_offset)); if (per_cu_it == debug_info_offset_to_per_cu.cend ()) { - warning (_("Section .debug_aranges in %s entry at offset %zu " + warning (_("Section .debug_aranges in %s entry at offset %tu " "debug_info_offset %s does not exists, " "ignoring .debug_aranges."), objfile_name (objfile), entry_addr - section->buffer, @@ -3318,7 +3319,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile, const uint8_t address_size = *addr++; if (address_size < 1 || address_size > 8) { - warning (_("Section .debug_aranges in %s entry at offset %zu " + warning (_("Section .debug_aranges in %s entry at offset %tu " "address_size %u is invalid, ignoring .debug_aranges."), objfile_name (objfile), entry_addr - section->buffer, address_size); @@ -3328,7 +3329,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile, const uint8_t segment_selector_size = *addr++; if (segment_selector_size != 0) { - warning (_("Section .debug_aranges in %s entry at offset %zu " + warning (_("Section .debug_aranges in %s entry at offset %tu " "segment_selector_size %u is not supported, " "ignoring .debug_aranges."), objfile_name (objfile), entry_addr - section->buffer, @@ -3344,7 +3345,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile, padding > 0; padding--) if (*addr++ != 0) { - warning (_("Section .debug_aranges in %s entry at offset %zu " + warning (_("Section .debug_aranges in %s entry at offset %tu " "padding is not zero, ignoring .debug_aranges."), objfile_name (objfile), entry_addr - section->buffer); return; @@ -3354,7 +3355,7 @@ create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile, { if (addr + 2 * address_size > entry_end) { - warning (_("Section .debug_aranges in %s entry at offset %zu " + warning (_("Section .debug_aranges in %s entry at offset %tu " "address list is not properly terminated, " "ignoring .debug_aranges."), objfile_name (objfile), entry_addr - section->buffer); @@ -3499,6 +3500,16 @@ read_gdb_index_from_buffer (struct objfile *objfile, "set use-deprecated-index-sections on". */ if (version < 6 && !deprecated_ok) { +#ifdef GDB_INDEX_VERIFY_VENDOR + extern int rpm_verify_vendor (const char *filename); + + /* Red Hat Developer Toolset exception. */ + if (rpm_verify_vendor (filename)) + {} + else + { + +#endif static int warning_printed = 0; if (!warning_printed) { @@ -3510,6 +3521,10 @@ to use the section anyway."), warning_printed = 1; } return 0; +#ifdef GDB_INDEX_VERIFY_VENDOR + + } +#endif } /* Version 7 indices generated by gold refer to the CU for a symbol instead of the TU (for symbols coming from TUs), @@ -5569,7 +5584,7 @@ read_debug_names_from_section (struct objfile *objfile, if (addr != abbrev_table_start + abbrev_table_size) { warning (_("Section .debug_names in %s has abbreviation_table " - "of size %zu vs. written as %u, ignoring .debug_names."), + "of size %tu vs. written as %u, ignoring .debug_names."), filename, addr - abbrev_table_start, abbrev_table_size); return false; } @@ -6235,7 +6250,7 @@ get_gdb_index_contents_from_section (objfile *obj, T *section_owner) static gdb::array_view get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_objfile *dwarf2_obj) { - const bfd_build_id *build_id = build_id_bfd_get (obj->obfd); + const bfd_build_id *build_id = build_id_bfd_shdr_get (obj->obfd); if (build_id == nullptr) return {}; @@ -6248,7 +6263,7 @@ get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_objfile *dwarf2_obj) static gdb::array_view get_gdb_index_contents_from_cache_dwz (objfile *obj, dwz_file *dwz) { - const bfd_build_id *build_id = build_id_bfd_get (dwz->dwz_bfd.get ()); + const bfd_build_id *build_id = build_id_bfd_shdr_get (dwz->dwz_bfd.get ()); if (build_id == nullptr) return {}; @@ -10585,6 +10600,13 @@ class process_die_scope static void process_die (struct die_info *die, struct dwarf2_cu *cu) { + if (die->in_process) + { + complaint (_("DIE at 0x%s attempted to be processed twice"), + sect_offset_str (die->sect_off)); + return; + } + process_die_scope scope (die, cu); switch (die->tag) @@ -13755,7 +13777,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu) { newobj->static_link = XOBNEW (&objfile->objfile_obstack, struct dynamic_prop); - attr_to_dynamic_prop (attr, die, cu, newobj->static_link); + attr_to_dynamic_prop (attr, die, cu, newobj->static_link, NULL, 0); } cu->list_in_scope = cu->get_builder ()->get_local_symbols (); @@ -15101,8 +15123,8 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, object, and then subtract off the number of bits of the field itself. The result is the bit offset of the LSB of the field. */ - int anonymous_size; - int bit_offset = DW_UNSND (attr); + LONGEST anonymous_size; + LONGEST bit_offset = DW_UNSND (attr); attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) @@ -16416,6 +16438,8 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu) xrealloc (fields, (num_fields + DW_FIELD_ALLOC_CHUNK) * sizeof (struct field)); + memset (fields + num_fields, 0, + DW_FIELD_ALLOC_CHUNK * sizeof(struct field)); } FIELD_NAME (fields[num_fields]) = SYMBOL_LINKAGE_NAME (sym); @@ -16493,7 +16517,8 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) byte_stride_prop = (struct dynamic_prop *) alloca (sizeof (struct dynamic_prop)); - stride_ok = attr_to_dynamic_prop (attr, die, cu, byte_stride_prop); + stride_ok = attr_to_dynamic_prop (attr, die, cu, byte_stride_prop, + NULL, 0); if (!stride_ok) { complaint (_("unable to read array DW_AT_byte_stride " @@ -17254,29 +17279,90 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu) struct gdbarch *gdbarch = get_objfile_arch (objfile); struct type *type, *range_type, *index_type, *char_type; struct attribute *attr; - unsigned int length; + unsigned int length = UINT_MAX; + index_type = objfile_type (objfile)->builtin_int; + range_type = create_static_range_type (NULL, index_type, 1, length); + + /* If DW_AT_string_length is defined, the length is stored in memory. */ attr = dwarf2_attr (die, DW_AT_string_length, cu); if (attr) { - length = DW_UNSND (attr); + if (attr_form_is_block (attr)) + { + struct attribute *byte_size, *bit_size; + struct dynamic_prop high; + + byte_size = dwarf2_attr (die, DW_AT_byte_size, cu); + bit_size = dwarf2_attr (die, DW_AT_bit_size, cu); + + /* DW_AT_byte_size should never occur in combination with + DW_AT_bit_size. */ + if (byte_size != NULL && bit_size != NULL) + complaint (_("DW_AT_byte_size AND " + "DW_AT_bit_size found together at the same time.")); + + /* If DW_AT_string_length AND DW_AT_byte_size exist together, + DW_AT_byte_size describes the number of bytes that should be read + from the length memory location. */ + if (byte_size != NULL) + { + /* Build new dwarf2_locexpr_baton structure with additions to the + data attribute, to reflect DWARF specialities to get address + sizes. */ + const gdb_byte append_ops[] = + { + /* DW_OP_deref_size: size of an address on the target machine + (bytes), where the size will be specified by the next + operand. */ + DW_OP_deref_size, + /* Operand for DW_OP_deref_size. */ + (gdb_byte)DW_UNSND(byte_size) }; + + if (!attr_to_dynamic_prop (attr, die, cu, &high, append_ops, + ARRAY_SIZE(append_ops))) + complaint (_("Could not parse DW_AT_byte_size")); + } + else if (bit_size != NULL) + complaint (_("DW_AT_string_length AND " + "DW_AT_bit_size found but not supported yet.")); + /* If DW_AT_string_length WITHOUT DW_AT_byte_size exist, the default + is the address size of the target machine. */ + else + { + const gdb_byte append_ops[] = + { DW_OP_deref }; + + if (!attr_to_dynamic_prop (attr, die, cu, &high, append_ops, + ARRAY_SIZE(append_ops))) + complaint (_("Could not parse DW_AT_string_length")); + } + + TYPE_RANGE_DATA (range_type)->high = high; + } + else + { + TYPE_HIGH_BOUND (range_type) = DW_UNSND(attr); + TYPE_HIGH_BOUND_KIND (range_type) = PROP_CONST; + } } else { - /* Check for the DW_AT_byte_size attribute. */ + /* Check for the DW_AT_byte_size attribute, which represents the length + in this case. */ attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) - { - length = DW_UNSND (attr); - } + { + TYPE_HIGH_BOUND (range_type) = DW_UNSND(attr); + TYPE_HIGH_BOUND_KIND (range_type) = PROP_CONST; + } else - { - length = 1; - } + { + TYPE_HIGH_BOUND (range_type) = 1; + TYPE_HIGH_BOUND_KIND (range_type) = PROP_CONST; + } } - index_type = objfile_type (objfile)->builtin_int; - range_type = create_static_range_type (NULL, index_type, 1, length); char_type = language_string_char_type (cu->language_defn, gdbarch); type = create_string_type (NULL, char_type, range_type); @@ -17688,7 +17774,8 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu) static int attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, - struct dwarf2_cu *cu, struct dynamic_prop *prop) + struct dwarf2_cu *cu, struct dynamic_prop *prop, + const gdb_byte *additional_data, int additional_data_size) { struct dwarf2_property_baton *baton; struct obstack *obstack @@ -17699,14 +17786,33 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, if (attr_form_is_block (attr)) { - baton = XOBNEW (obstack, struct dwarf2_property_baton); + baton = XOBNEW(obstack, struct dwarf2_property_baton); baton->referenced_type = NULL; baton->locexpr.per_cu = cu->per_cu; - baton->locexpr.size = DW_BLOCK (attr)->size; - baton->locexpr.data = DW_BLOCK (attr)->data; + + if (additional_data != NULL && additional_data_size > 0) + { + gdb_byte *data; + + data = (gdb_byte *) obstack_alloc( + &cu->per_cu->dwarf2_per_objfile->objfile->objfile_obstack, + DW_BLOCK (attr)->size + additional_data_size); + memcpy (data, DW_BLOCK (attr)->data, DW_BLOCK (attr)->size); + memcpy (data + DW_BLOCK (attr)->size, additional_data, + additional_data_size); + + baton->locexpr.data = data; + baton->locexpr.size = DW_BLOCK (attr)->size + additional_data_size; + } + else + { + baton->locexpr.data = DW_BLOCK (attr)->data; + baton->locexpr.size = DW_BLOCK (attr)->size; + } + prop->data.baton = baton; prop->kind = PROP_LOCEXPR; - gdb_assert (prop->data.baton != NULL); + gdb_assert(prop->data.baton != NULL); } else if (attr_form_is_ref (attr)) { @@ -17739,8 +17845,28 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die, baton = XOBNEW (obstack, struct dwarf2_property_baton); baton->referenced_type = die_type (target_die, target_cu); baton->locexpr.per_cu = cu->per_cu; - baton->locexpr.size = DW_BLOCK (target_attr)->size; - baton->locexpr.data = DW_BLOCK (target_attr)->data; + + if (additional_data != NULL && additional_data_size > 0) + { + gdb_byte *data; + + data = (gdb_byte *) obstack_alloc (&cu->per_cu->dwarf2_per_objfile->objfile->objfile_obstack, + DW_BLOCK (target_attr)->size + additional_data_size); + memcpy (data, DW_BLOCK (target_attr)->data, + DW_BLOCK (target_attr)->size); + memcpy (data + DW_BLOCK (target_attr)->size, + additional_data, additional_data_size); + + baton->locexpr.data = data; + baton->locexpr.size = (DW_BLOCK (target_attr)->size + + additional_data_size); + } + else + { + baton->locexpr.data = DW_BLOCK (target_attr)->data; + baton->locexpr.size = DW_BLOCK (target_attr)->size; + } + prop->data.baton = baton; prop->kind = PROP_LOCEXPR; gdb_assert (prop->data.baton != NULL); @@ -17794,7 +17920,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) struct type *base_type, *orig_base_type; struct type *range_type; struct attribute *attr; - struct dynamic_prop low, high; + struct dynamic_prop low, high, stride; int low_default_is_valid; int high_bound_is_count = 0; const char *name; @@ -17814,7 +17940,9 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) low.kind = PROP_CONST; high.kind = PROP_CONST; + stride.kind = PROP_CONST; high.data.const_val = 0; + stride.data.const_val = 0; /* Set LOW_DEFAULT_IS_VALID if current language and DWARF version allow omitting DW_AT_lower_bound. */ @@ -17847,9 +17975,17 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) break; } + attr = dwarf2_attr (die, DW_AT_byte_stride, cu); + if (attr) + if (!attr_to_dynamic_prop (attr, die, cu, &stride, NULL, 0)) + complaint (_("Missing DW_AT_byte_stride " + "- DIE at 0x%s [in module %s]"), + sect_offset_str (die->sect_off), + objfile_name (cu->per_cu->dwarf2_per_objfile->objfile)); + attr = dwarf2_attr (die, DW_AT_lower_bound, cu); if (attr) - attr_to_dynamic_prop (attr, die, cu, &low); + attr_to_dynamic_prop (attr, die, cu, &low, NULL, 0); else if (!low_default_is_valid) complaint (_("Missing DW_AT_lower_bound " "- DIE at %s [in module %s]"), @@ -17858,10 +17994,10 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) struct attribute *attr_ub, *attr_count; attr = attr_ub = dwarf2_attr (die, DW_AT_upper_bound, cu); - if (!attr_to_dynamic_prop (attr, die, cu, &high)) + if (!attr_to_dynamic_prop (attr, die, cu, &high, NULL, 0)) { attr = attr_count = dwarf2_attr (die, DW_AT_count, cu); - if (attr_to_dynamic_prop (attr, die, cu, &high)) + if (attr_to_dynamic_prop (attr, die, cu, &high, NULL, 0)) { /* If bounds are constant do the final calculation here. */ if (low.kind == PROP_CONST && high.kind == PROP_CONST) @@ -17939,7 +18075,7 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) && !TYPE_UNSIGNED (base_type) && (high.data.const_val & negative_mask)) high.data.const_val |= negative_mask; - range_type = create_range_type (NULL, orig_base_type, &low, &high); + range_type = create_range_type (NULL, orig_base_type, &low, &high, &stride); if (high_bound_is_count) TYPE_RANGE_DATA (range_type)->flag_upper_bound_is_count = 1; @@ -21440,6 +21576,26 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu, /* Cache this symbol's name and the name's demangled form (if any). */ SYMBOL_SET_LANGUAGE (sym, cu->language, &objfile->objfile_obstack); linkagename = dwarf2_physname (name, die, cu); + + /* Workaround for: + * invalid IFUNC DW_AT_linkage_name: memmove strstr time + * http://sourceware.org/bugzilla/show_bug.cgi?id=14166 */ + if (strcmp (linkagename, "strstr") == 0 + && strstr (objfile_name (objfile), "/libc") != NULL) + { + struct objfile *objfile_msym; + struct bound_minimal_symbol bmsym; + + if (objfile->separate_debug_objfile_backlink) + objfile_msym = objfile->separate_debug_objfile_backlink; + else + objfile_msym = objfile; + bmsym = lookup_minimal_symbol ("strstr", NULL, objfile_msym); + if (bmsym.minsym != NULL + && MSYMBOL_TYPE (bmsym.minsym) == mst_text_gnu_ifunc) + linkagename = "__strstr"; + } + SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), 0, objfile); /* Fortran does not have mangling standard and the mangling does differ @@ -25446,7 +25602,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) attr = dwarf2_attr (die, DW_AT_allocated, cu); if (attr_form_is_block (attr)) { - if (attr_to_dynamic_prop (attr, die, cu, &prop)) + if (attr_to_dynamic_prop (attr, die, cu, &prop, NULL, 0)) add_dyn_prop (DYN_PROP_ALLOCATED, prop, type); } else if (attr != NULL) @@ -25460,7 +25616,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) attr = dwarf2_attr (die, DW_AT_associated, cu); if (attr_form_is_block (attr)) { - if (attr_to_dynamic_prop (attr, die, cu, &prop)) + if (attr_to_dynamic_prop (attr, die, cu, &prop, NULL, 0)) add_dyn_prop (DYN_PROP_ASSOCIATED, prop, type); } else if (attr != NULL) @@ -25472,7 +25628,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) /* Read DW_AT_data_location and set in type. */ attr = dwarf2_attr (die, DW_AT_data_location, cu); - if (attr_to_dynamic_prop (attr, die, cu, &prop)) + if (attr_to_dynamic_prop (attr, die, cu, &prop, NULL, 0)) add_dyn_prop (DYN_PROP_DATA_LOCATION, prop, type); if (dwarf2_per_objfile->die_type_hash == NULL) diff --git a/gdb/elfread.c b/gdb/elfread.c index 55a16bb2f8e..1cf941614da 100644 --- a/gdb/elfread.c +++ b/gdb/elfread.c @@ -1287,7 +1287,9 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) && objfile->separate_debug_objfile == NULL && objfile->separate_debug_objfile_backlink == NULL) { - std::string debugfile = find_separate_debug_file_by_buildid (objfile); + gdb::unique_xmalloc_ptr build_id_filename; + std::string debugfile + = find_separate_debug_file_by_buildid (objfile, &build_id_filename); if (debugfile.empty ()) debugfile = find_separate_debug_file_by_debuglink (objfile); @@ -1299,6 +1301,10 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags) symbol_file_add_separate (debug_bfd.get (), debugfile.c_str (), symfile_flags, objfile); } + /* Check if any separate debug info has been extracted out. */ + else if (bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink") + != NULL) + debug_print_missing (objfile_name (objfile), build_id_filename.get ()); } } diff --git a/gdb/eval.c b/gdb/eval.c index aed89e5f85a..cbe5dec6c46 100644 --- a/gdb/eval.c +++ b/gdb/eval.c @@ -293,7 +293,8 @@ evaluate_struct_tuple (struct value *struct_val, while (--nargs >= 0) { struct value *val = NULL; - int bitpos, bitsize; + LONGEST bitpos; + int bitsize; bfd_byte *addr; fieldno++; @@ -354,7 +355,7 @@ init_array_element (struct value *array, struct value *element, enum noside noside, LONGEST low_bound, LONGEST high_bound) { LONGEST index; - int element_size = TYPE_LENGTH (value_type (element)); + LONGEST element_size = TYPE_LENGTH (value_type (element)); if (exp->elts[*pos].opcode == BINOP_COMMA) { @@ -375,29 +376,335 @@ init_array_element (struct value *array, struct value *element, return index; } +static void +skip_undetermined_arglist (int nargs, struct expression *exp, int *pos, + enum noside noside); + +/* Evaluates any operation on Fortran arrays or strings with at least + one user provided parameter. Expects the input ARRAY to be either + an array, or a string. Evaluates EXP by incrementing POS, and + writes the content from the elt stack into a local struct. NARGS + specifies number of literal or range arguments the user provided. + NARGS must be the same number as ARRAY has dimensions. */ + static struct value * -value_f90_subarray (struct value *array, - struct expression *exp, int *pos, enum noside noside) +value_f90_subarray (struct value *array, struct expression *exp, + int *pos, int nargs, enum noside noside) { - int pc = (*pos) + 1; - LONGEST low_bound, high_bound; - struct type *range = check_typedef (TYPE_INDEX_TYPE (value_type (array))); - enum range_type range_type - = (enum range_type) longest_to_int (exp->elts[pc].longconst); - - *pos += 3; - - if (range_type == LOW_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT) - low_bound = TYPE_LOW_BOUND (range); - else - low_bound = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside)); + int i, dim_count = 0; + struct value *new_array = array; + struct type *array_type = check_typedef (value_type (new_array)); + struct type *elt_type; + + typedef struct + { + enum range_type f90_range_type; + LONGEST low, high, stride; + } subscript_range; + + typedef enum subscript_kind + { + SUBSCRIPT_RANGE, /* e.g. "(lowbound:highbound)" */ + SUBSCRIPT_INDEX /* e.g. "(literal)" */ + } kind; + + /* Local struct to hold user data for Fortran subarray dimensions. */ + struct subscript_store + { + /* For every dimension, we are either working on a range or an index + expression, so we store this info separately for later. */ + enum subscript_kind kind; + + /* We also store either the lower and upper bound info, or the index + number. Before evaluation of the input values, we do not know if we are + actually working on a range of ranges, or an index in a range. So as a + first step we store all input in a union. The array calculation itself + deals with this later on. */ + union element_range + { + subscript_range range; + LONGEST number; + } U; + } *subscript_array; + + /* Check if the number of arguments provided by the user matches + the number of dimension of the array. A string has only one + dimension. */ + if (nargs != calc_f77_array_dims (value_type (new_array))) + error (_("Wrong number of subscripts")); + + subscript_array = (struct subscript_store*) alloca (sizeof (*subscript_array) * nargs); + + /* Parse the user input into the SUBSCRIPT_ARRAY to store it. We need + to evaluate it first, as the input is from left-to-right. The + array is stored from right-to-left. So we have to use the user + input in reverse order. Later on, we need the input information to + re-calculate the output array. For multi-dimensional arrays, we + can be dealing with any possible combination of ranges and indices + for every dimension. */ + for (i = 0; i < nargs; i++) + { + struct subscript_store *index = &subscript_array[i]; + + /* The user input is a range, with or without lower and upper bound. + E.g.: "p arry(2:5)", "p arry( :5)", "p arry( : )", etc. */ + if (exp->elts[*pos].opcode == OP_RANGE) + { + int pc = (*pos) + 1; + subscript_range *range; + + index->kind = SUBSCRIPT_RANGE; + range = &index->U.range; + + *pos += 3; + range->f90_range_type = (enum range_type) exp->elts[pc].longconst; + + /* If a lower bound was provided by the user, the bit has been + set and we can assign the value from the elt stack. Same for + upper bound. */ + if ((range->f90_range_type & SUBARRAY_LOW_BOUND) + == SUBARRAY_LOW_BOUND) + range->low = value_as_long (evaluate_subexp (NULL_TYPE, exp, + pos, noside)); + if ((range->f90_range_type & SUBARRAY_HIGH_BOUND) + == SUBARRAY_HIGH_BOUND) + range->high = value_as_long (evaluate_subexp (NULL_TYPE, exp, + pos, noside)); + + /* Assign the user's stride value if provided. */ + if ((range->f90_range_type & SUBARRAY_STRIDE) == SUBARRAY_STRIDE) + range->stride = value_as_long (evaluate_subexp (NULL_TYPE, exp, + pos, noside)); + + /* Assign the default stride value '1'. */ + else + range->stride = 1; - if (range_type == HIGH_BOUND_DEFAULT || range_type == BOTH_BOUND_DEFAULT) - high_bound = TYPE_HIGH_BOUND (range); - else - high_bound = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside)); + /* Check the provided stride value is illegal, aka '0'. */ + if (range->stride == 0) + error (_("Stride must not be 0")); + } + /* User input is an index. E.g.: "p arry(5)". */ + else + { + struct value *val; + + if (noside == EVAL_SKIP) + { + skip_undetermined_arglist (nargs, exp, pos, noside); + /* Return the dummy value with the correct type. */ + return array; + } + + index->kind = SUBSCRIPT_INDEX; + + /* Evaluate each subscript; it must be a legal integer in F77. This + ensures the validity of the provided index. */ + val = evaluate_subexp_with_coercion (exp, pos, noside); + index->U.number = value_as_long (val); + } + + } + + /* Traverse the array from right to left and set the high and low bounds + for later use. */ + for (i = nargs - 1; i >= 0; i--) + { + struct subscript_store *index = &subscript_array[i]; + struct type *index_type = TYPE_INDEX_TYPE (array_type); + + switch (index->kind) + { + case SUBSCRIPT_RANGE: + { + + /* When we hit the first range specified by the user, we must + treat any subsequent user entry as a range. We simply + increment DIM_COUNT which tells us how many times we are + calling VALUE_SLICE_1. */ + subscript_range *range = &index->U.range; + + /* If no lower bound was provided by the user, we take the + default boundary. Same for the high bound. */ + if ((range->f90_range_type & SUBARRAY_LOW_BOUND) == 0) + range->low = TYPE_LOW_BOUND (index_type); + + if ((range->f90_range_type & SUBARRAY_HIGH_BOUND) == 0) + range->high = TYPE_HIGH_BOUND (index_type); + + /* Both user provided low and high bound have to be inside the + array bounds. Throw an error if not. */ + if (range->low < TYPE_LOW_BOUND (index_type) + || range->low > TYPE_HIGH_BOUND (index_type) + || range->high < TYPE_LOW_BOUND (index_type) + || range->high > TYPE_HIGH_BOUND (index_type)) + error (_("provided bound(s) outside array bound(s)")); + + /* For a negative stride the lower boundary must be larger than the + upper boundary. + For a positive stride the lower boundary must be smaller than the + upper boundary. */ + if ((range->stride < 0 && range->low < range->high) + || (range->stride > 0 && range->low > range->high)) + error (_("Wrong value provided for stride and boundaries")); + + } + break; + + case SUBSCRIPT_INDEX: + break; + + } + + array_type = TYPE_TARGET_TYPE (array_type); + } + + /* Reset ARRAY_TYPE before slicing.*/ + array_type = check_typedef (value_type (new_array)); + + /* Traverse the array from right to left and evaluate each corresponding + user input. VALUE_SUBSCRIPT is called for every index, until a range + expression is evaluated. After a range expression has been evaluated, + every subsequent expression is also treated as a range. */ + for (i = nargs - 1; i >= 0; i--) + { + struct subscript_store *index = &subscript_array[i]; + struct type *index_type = TYPE_INDEX_TYPE (array_type); + + switch (index->kind) + { + case SUBSCRIPT_RANGE: + { + + /* When we hit the first range specified by the user, we must + treat any subsequent user entry as a range. We simply + increment DIM_COUNT which tells us how many times we are + calling VALUE_SLICE_1. */ + subscript_range *range = &index->U.range; + + /* DIM_COUNT counts every user argument that is treated as a range. + This is necessary for expressions like 'print array(7, 8:9). + Here the first argument is a literal, but must be treated as a + range argument to allow the correct output representation. */ + dim_count++; + + new_array + = value_slice_1 (new_array, range->low, + range->high - range->low + 1, + range->stride, dim_count); + } + break; + + case SUBSCRIPT_INDEX: + { + /* DIM_COUNT only stays '0' when no range argument was processed + before, starting from the last dimension. This way we can + reduce the number of dimensions from the result array. + However, if a range has been processed before an index, we + treat the index like a range with equal low- and high bounds + to get the value offset right. */ + if (dim_count == 0) + new_array + = value_subscripted_rvalue (new_array, index->U.number, + f77_get_lowerbound (value_type + (new_array))); + else + { + dim_count++; + + /* We might end up here, because we have to treat the provided + index like a range. But now VALUE_SUBSCRIPTED_RVALUE + cannot do the range checks for us. So we have to make sure + ourselves that the user provided index is inside the + array bounds. Throw an error if not. */ + if (index->U.number < TYPE_LOW_BOUND (index_type) + && index->U.number > TYPE_HIGH_BOUND (index_type)) + error (_("provided bound(s) outside array bound(s)")); + + if (index->U.number > TYPE_LOW_BOUND (index_type) + && index->U.number > TYPE_HIGH_BOUND (index_type)) + error (_("provided bound(s) outside array bound(s)")); + + new_array = value_slice_1 (new_array, + index->U.number, + 1, /* COUNT is '1' element */ + 1, /* STRIDE set to '1' */ + dim_count); + } + + } + break; + } + array_type = TYPE_TARGET_TYPE (array_type); + } + + /* With DIM_COUNT > 1 we currently have a one dimensional array, but expect + an array of arrays, depending on how many ranges have been provided by + the user. So we need to rebuild the array dimensions for printing it + correctly. + Starting from right to left in the user input, after we hit the first + range argument every subsequent argument is also treated as a range. + E.g.: + "p ary(3, 7, 2:15)" in Fortran has only 1 dimension, but we calculated 3 + ranges. + "p ary(3, 7:12, 4)" in Fortran has only 1 dimension, but we calculated 2 + ranges. + "p ary(2:4, 5, 7)" in Fortran has only 1 dimension, and we calculated 1 + range. */ + if (dim_count > 1) + { + struct value *v = NULL; + + elt_type = TYPE_TARGET_TYPE (value_type (new_array)); + + /* Every SUBSCRIPT_RANGE in the user input signifies an actual range in + the output array. So we traverse the SUBSCRIPT_ARRAY again, looking + for a range entry. When we find one, we use the range info to create + an additional range_type to set the correct bounds and dimensions for + the output array. In addition, we may have a stride value that is not + '1', forcing us to adjust the number of elements in a range, according + to the stride value. */ + for (i = 0; i < nargs; i++) + { + struct subscript_store *index = &subscript_array[i]; + + if (index->kind == SUBSCRIPT_RANGE) + { + struct type *range_type, *interim_array_type; + + int new_length; + + /* The length of a sub-dimension with all elements between the + bounds plus the start element itself. It may be modified by + a user provided stride value. */ + new_length = index->U.range.high - index->U.range.low; + + new_length /= index->U.range.stride; + + range_type + = create_static_range_type (NULL, + elt_type, + index->U.range.low, + index->U.range.low + new_length); - return value_slice (array, low_bound, high_bound - low_bound + 1); + interim_array_type = create_array_type (NULL, + elt_type, + range_type); + + TYPE_CODE (interim_array_type) + = TYPE_CODE (value_type (new_array)); + + v = allocate_value (interim_array_type); + + elt_type = value_type (v); + } + + } + value_contents_copy (v, 0, new_array, 0, TYPE_LENGTH (elt_type)); + return v; + } + + return new_array; } @@ -502,11 +809,11 @@ binop_promote (const struct language_defn *language, struct gdbarch *gdbarch, /* FIXME: Also mixed integral/booleans, with result an integer. */ { const struct builtin_type *builtin = builtin_type (gdbarch); - unsigned int promoted_len1 = TYPE_LENGTH (type1); - unsigned int promoted_len2 = TYPE_LENGTH (type2); + ULONGEST promoted_len1 = TYPE_LENGTH (type1); + ULONGEST promoted_len2 = TYPE_LENGTH (type2); int is_unsigned1 = TYPE_UNSIGNED (type1); int is_unsigned2 = TYPE_UNSIGNED (type2); - unsigned int result_len; + ULONGEST result_len; int unsigned_operation; /* Determine type length and signedness after promotion for @@ -1267,7 +1574,7 @@ evaluate_subexp_standard (struct type *expect_type, struct value **argvec; int code; int ix; - long mem_offset; + LONGEST mem_offset; struct type **arg_types; pc = (*pos)++; @@ -1452,7 +1759,7 @@ evaluate_subexp_standard (struct type *expect_type, struct type *range_type = TYPE_INDEX_TYPE (type); struct type *element_type = TYPE_TARGET_TYPE (type); struct value *array = allocate_value (expect_type); - int element_size = TYPE_LENGTH (check_typedef (element_type)); + LONGEST element_size = TYPE_LENGTH (check_typedef (element_type)); LONGEST low_bound, high_bound, index; if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0) @@ -1945,33 +2252,8 @@ evaluate_subexp_standard (struct type *expect_type, switch (code) { case TYPE_CODE_ARRAY: - if (exp->elts[*pos].opcode == OP_RANGE) - return value_f90_subarray (arg1, exp, pos, noside); - else - { - if (noside == EVAL_SKIP) - { - skip_undetermined_arglist (nargs, exp, pos, noside); - /* Return the dummy value with the correct type. */ - return arg1; - } - goto multi_f77_subscript; - } - case TYPE_CODE_STRING: - if (exp->elts[*pos].opcode == OP_RANGE) - return value_f90_subarray (arg1, exp, pos, noside); - else - { - if (noside == EVAL_SKIP) - { - skip_undetermined_arglist (nargs, exp, pos, noside); - /* Return the dummy value with the correct type. */ - return arg1; - } - arg2 = evaluate_subexp_with_coercion (exp, pos, noside); - return value_subscript (arg1, value_as_long (arg2)); - } + return value_f90_subarray (arg1, exp, pos, nargs, noside); case TYPE_CODE_PTR: case TYPE_CODE_FUNC: @@ -2384,49 +2666,6 @@ evaluate_subexp_standard (struct type *expect_type, } return (arg1); - multi_f77_subscript: - { - LONGEST subscript_array[MAX_FORTRAN_DIMS]; - int ndimensions = 1, i; - struct value *array = arg1; - - if (nargs > MAX_FORTRAN_DIMS) - error (_("Too many subscripts for F77 (%d Max)"), MAX_FORTRAN_DIMS); - - ndimensions = calc_f77_array_dims (type); - - if (nargs != ndimensions) - error (_("Wrong number of subscripts")); - - gdb_assert (nargs > 0); - - /* Now that we know we have a legal array subscript expression - let us actually find out where this element exists in the array. */ - - /* Take array indices left to right. */ - for (i = 0; i < nargs; i++) - { - /* Evaluate each subscript; it must be a legal integer in F77. */ - arg2 = evaluate_subexp_with_coercion (exp, pos, noside); - - /* Fill in the subscript array. */ - - subscript_array[i] = value_as_long (arg2); - } - - /* Internal type of array is arranged right to left. */ - for (i = nargs; i > 0; i--) - { - struct type *array_type = check_typedef (value_type (array)); - LONGEST index = subscript_array[i - 1]; - - array = value_subscripted_rvalue (array, index, - f77_get_lowerbound (array_type)); - } - - return array; - } - case BINOP_LOGICAL_AND: arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside); if (noside == EVAL_SKIP) @@ -3346,6 +3585,9 @@ calc_f77_array_dims (struct type *array_type) int ndimen = 1; struct type *tmp_type; + if (TYPE_CODE (array_type) == TYPE_CODE_STRING) + return 1; + if ((TYPE_CODE (array_type) != TYPE_CODE_ARRAY)) error (_("Can't get dimensions for a non-array type")); diff --git a/gdb/event-top.c b/gdb/event-top.c index cd54eb5a2c5..2dbd0cee594 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -40,6 +40,7 @@ #include "common/buffer.h" #include "ser-event.h" #include "gdb_select.h" +#include "symfile.h" /* readline include files. */ #include "readline/readline.h" @@ -358,6 +359,8 @@ display_gdb_prompt (const char *new_prompt) /* Reset the nesting depth used when trace-commands is set. */ reset_command_nest_depth (); + debug_flush_missing (); + /* Do not call the python hook on an explicit prompt change as passed to this function, as this forms a secondary/local prompt, IE, displayed but not set. */ @@ -769,7 +772,10 @@ command_line_handler (gdb::unique_xmalloc_ptr &&rl) command_handler (cmd); if (ui->prompt_state != PROMPTED) - display_gdb_prompt (0); + { + debug_flush_missing (); + display_gdb_prompt (0); + } } } @@ -1170,6 +1176,13 @@ gdb_setup_readline (int editing) { struct ui *ui = current_ui; +#ifdef NEED_RL_STATE_FEDORA_GDB + /* 6.2 regression: no longed asks for --more-- + gdb.base/readline-ask.exp + https://bugzilla.redhat.com/show_bug.cgi?id=701131 */ + RL_SETSTATE (RL_STATE_FEDORA_GDB); +#endif + /* This function is a noop for the sync case. The assumption is that the sync setup is ALL done in gdb_init, and we would only mess it up here. The sync stuff should really go away over diff --git a/gdb/exec.c b/gdb/exec.c index b0eb9ff02a3..f765d163504 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -36,6 +36,7 @@ #include "gdb_bfd.h" #include "gcore.h" #include "source.h" +#include "exceptions.h" #include #include "readline/readline.h" @@ -345,12 +346,27 @@ exec_file_attach (const char *filename, int from_tty) if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching)) { + int is_core; + + /* If the user accidentally did "gdb core", print a useful + error message. Check it only after bfd_object has been checked as + a valid executable may get recognized for example also as + "trad-core". */ + is_core = bfd_check_format (exec_bfd, bfd_core); + /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); - error (_("\"%s\": not in executable format: %s"), - scratch_pathname, - gdb_bfd_errmsg (bfd_get_error (), matching).c_str ()); + + if (is_core != 0) + throw_error (IS_CORE_ERROR, + _("\"%s\" is a core file.\n" + "Please specify an executable to debug."), + scratch_pathname); + else + error (_("\"%s\": not in executable format: %s"), + scratch_pathname, + gdb_bfd_errmsg (bfd_get_error (), matching).c_str ()); } if (build_section_table (exec_bfd, §ions, §ions_end)) diff --git a/gdb/expprint.c b/gdb/expprint.c index a22499f4833..14508cc371b 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -578,17 +578,14 @@ print_subexp_standard (struct expression *exp, int *pos, longest_to_int (exp->elts[pc + 1].longconst); *pos += 2; - if (range_type == NONE_BOUND_DEFAULT_EXCLUSIVE - || range_type == LOW_BOUND_DEFAULT_EXCLUSIVE) + if ((range_type & SUBARRAY_HIGH_BOUND_EXCLUSIVE) + == SUBARRAY_HIGH_BOUND_EXCLUSIVE) fputs_filtered ("EXCLUSIVE_", stream); fputs_filtered ("RANGE(", stream); - if (range_type == HIGH_BOUND_DEFAULT - || range_type == NONE_BOUND_DEFAULT - || range_type == NONE_BOUND_DEFAULT_EXCLUSIVE) + if ((range_type & SUBARRAY_LOW_BOUND) == SUBARRAY_LOW_BOUND) print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); fputs_filtered ("..", stream); - if (range_type == LOW_BOUND_DEFAULT - || range_type == NONE_BOUND_DEFAULT) + if ((range_type & SUBARRAY_HIGH_BOUND) == SUBARRAY_HIGH_BOUND) print_subexp (exp, pos, stream, PREC_ABOVE_COMMA); fputs_filtered (")", stream); return; @@ -1106,22 +1103,24 @@ dump_subexp_body_standard (struct expression *exp, switch (range_type) { - case BOTH_BOUND_DEFAULT: + case SUBARRAY_NONE_BOUND: fputs_filtered ("Range '..'", stream); break; - case LOW_BOUND_DEFAULT: + case SUBARRAY_HIGH_BOUND: fputs_filtered ("Range '..EXP'", stream); break; - case LOW_BOUND_DEFAULT_EXCLUSIVE: - fputs_filtered ("ExclusiveRange '..EXP'", stream); - break; - case HIGH_BOUND_DEFAULT: + case SUBARRAY_LOW_BOUND: fputs_filtered ("Range 'EXP..'", stream); break; - case NONE_BOUND_DEFAULT: + case (SUBARRAY_LOW_BOUND + | SUBARRAY_HIGH_BOUND + | SUBARRAY_HIGH_BOUND_EXCLUSIVE): + fputs_filtered ("ExclusiveRange '..EXP'", stream); + break; + case (SUBARRAY_LOW_BOUND | SUBARRAY_HIGH_BOUND): fputs_filtered ("Range 'EXP..EXP'", stream); break; - case NONE_BOUND_DEFAULT_EXCLUSIVE: + case (SUBARRAY_HIGH_BOUND | SUBARRAY_HIGH_BOUND_EXCLUSIVE): fputs_filtered ("ExclusiveRange 'EXP..EXP'", stream); break; default: @@ -1129,11 +1128,9 @@ dump_subexp_body_standard (struct expression *exp, break; } - if (range_type == HIGH_BOUND_DEFAULT - || range_type == NONE_BOUND_DEFAULT) + if ((range_type & SUBARRAY_LOW_BOUND) == SUBARRAY_LOW_BOUND) elt = dump_subexp (exp, stream, elt); - if (range_type == LOW_BOUND_DEFAULT - || range_type == NONE_BOUND_DEFAULT) + if ((range_type & SUBARRAY_HIGH_BOUND) == SUBARRAY_HIGH_BOUND) elt = dump_subexp (exp, stream, elt); } break; diff --git a/gdb/expression.h b/gdb/expression.h index 10e5f3e788e..56b7dd62fa1 100644 --- a/gdb/expression.h +++ b/gdb/expression.h @@ -164,28 +164,27 @@ extern void dump_raw_expression (struct expression *, struct ui_file *, const char *); extern void dump_prefix_expression (struct expression *, struct ui_file *); -/* In an OP_RANGE expression, either bound could be empty, indicating - that its value is by default that of the corresponding bound of the - array or string. Also, the upper end of the range can be exclusive - or inclusive. So we have six sorts of subrange. This enumeration - type is to identify this. */ +/* In an OP_RANGE expression, either bound can be provided by the + user, or not. In addition to this, the user can also specify a + stride value to indicated only certain elements of the array. + Also, the upper end of the range can be exclusive or inclusive. + This enumeration type is to identify this. */ enum range_type -{ - /* Neither the low nor the high bound was given -- so this refers to - the entire available range. */ - BOTH_BOUND_DEFAULT, - /* The low bound was not given and the high bound is inclusive. */ - LOW_BOUND_DEFAULT, - /* The high bound was not given and the low bound in inclusive. */ - HIGH_BOUND_DEFAULT, - /* Both bounds were given and both are inclusive. */ - NONE_BOUND_DEFAULT, - /* The low bound was not given and the high bound is exclusive. */ - NONE_BOUND_DEFAULT_EXCLUSIVE, - /* Both bounds were given. The low bound is inclusive and the high - bound is exclusive. */ - LOW_BOUND_DEFAULT_EXCLUSIVE, -}; + { + SUBARRAY_NONE_BOUND = 0x0, /* "( : )" */ + SUBARRAY_LOW_BOUND = 0x1, /* "(low:)" */ + SUBARRAY_HIGH_BOUND = 0x2, /* "(:high)" */ + SUBARRAY_STRIDE = 0x4, /* "(::stride)" */ + /* The low bound was not given and the high bound is exclusive. + In this case we always use (SUBARRAY_HIGH_BOUND | + SUBARRAY_HIGH_BOUND_EXCLUSIVE). */ + SUBARRAY_HIGH_BOUND_EXCLUSIVE = 0x8, + /* Both bounds were given. The low bound is inclusive and the high + bound is exclusive. In this case, we use (SUBARRAY_LOW_BOUND | + SUBARRAY_HIGH_BOUND | SUBARRAY_HIGH_BOUND_EXCLUSIVE). */ + // SUBARRAY_LOW_BOUND_EXCLUSIVE = (SUBARRAY_LOW_BOUND + // | SUBARRAY_HIGH_BOUND_EXCLUSIVE), + }; #endif /* !defined (EXPRESSION_H) */ diff --git a/gdb/extension.c b/gdb/extension.c index 8637bc53f2e..40bf6349efc 100644 --- a/gdb/extension.c +++ b/gdb/extension.c @@ -820,6 +820,11 @@ check_quit_flag (void) int i, result = 0; const struct extension_language_defn *extlang; +#ifdef NEED_DETACH_SIGSTOP + if (quit_flag_cleanup) + return 0; +#endif + ALL_ENABLED_EXTENSION_LANGUAGES (i, extlang) { if (extlang->ops->check_quit_flag != NULL) diff --git a/gdb/f-exp.y b/gdb/f-exp.y index 9ee5316470f..c223faa814c 100644 --- a/gdb/f-exp.y +++ b/gdb/f-exp.y @@ -276,31 +276,63 @@ arglist : subrange arglist : arglist ',' exp %prec ABOVE_COMMA { pstate->arglist_len++; } + | arglist ',' subrange %prec ABOVE_COMMA + { pstate->arglist_len++; } ; /* There are four sorts of subrange types in F90. */ subrange: exp ':' exp %prec ABOVE_COMMA - { write_exp_elt_opcode (pstate, OP_RANGE); - write_exp_elt_longcst (pstate, NONE_BOUND_DEFAULT); + { write_exp_elt_opcode (pstate, OP_RANGE); + write_exp_elt_longcst (pstate, + SUBARRAY_LOW_BOUND | SUBARRAY_HIGH_BOUND); write_exp_elt_opcode (pstate, OP_RANGE); } ; subrange: exp ':' %prec ABOVE_COMMA { write_exp_elt_opcode (pstate, OP_RANGE); - write_exp_elt_longcst (pstate, HIGH_BOUND_DEFAULT); + write_exp_elt_longcst (pstate, SUBARRAY_LOW_BOUND); write_exp_elt_opcode (pstate, OP_RANGE); } ; subrange: ':' exp %prec ABOVE_COMMA { write_exp_elt_opcode (pstate, OP_RANGE); - write_exp_elt_longcst (pstate, LOW_BOUND_DEFAULT); + write_exp_elt_longcst (pstate, SUBARRAY_HIGH_BOUND); write_exp_elt_opcode (pstate, OP_RANGE); } ; subrange: ':' %prec ABOVE_COMMA { write_exp_elt_opcode (pstate, OP_RANGE); - write_exp_elt_longcst (pstate, BOTH_BOUND_DEFAULT); + write_exp_elt_longcst (pstate, SUBARRAY_NONE_BOUND); + write_exp_elt_opcode (pstate, OP_RANGE); } + ; + +/* Each subrange type can have a stride argument. */ +subrange: exp ':' exp ':' exp %prec ABOVE_COMMA + { write_exp_elt_opcode (pstate, OP_RANGE); + write_exp_elt_longcst (pstate, SUBARRAY_LOW_BOUND + | SUBARRAY_HIGH_BOUND + | SUBARRAY_STRIDE); + write_exp_elt_opcode (pstate, OP_RANGE); } + ; + +subrange: exp ':' ':' exp %prec ABOVE_COMMA + { write_exp_elt_opcode (pstate, OP_RANGE); + write_exp_elt_longcst (pstate, SUBARRAY_LOW_BOUND + | SUBARRAY_STRIDE); + write_exp_elt_opcode (pstate, OP_RANGE); } + ; + +subrange: ':' exp ':' exp %prec ABOVE_COMMA + { write_exp_elt_opcode (pstate, OP_RANGE); + write_exp_elt_longcst (pstate, SUBARRAY_HIGH_BOUND + | SUBARRAY_STRIDE); + write_exp_elt_opcode (pstate, OP_RANGE); } + ; + +subrange: ':' ':' exp %prec ABOVE_COMMA + { write_exp_elt_opcode (pstate, OP_RANGE); + write_exp_elt_longcst (pstate, SUBARRAY_STRIDE); write_exp_elt_opcode (pstate, OP_RANGE); } ; diff --git a/gdb/f-lang.c b/gdb/f-lang.c index f3a806e7a6f..63c86bd8eb8 100644 --- a/gdb/f-lang.c +++ b/gdb/f-lang.c @@ -104,7 +104,7 @@ f_printchar (int c, struct type *type, struct ui_file *stream) static void f_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string, - unsigned int length, const char *encoding, int force_ellipses, + ULONGEST length, const char *encoding, int force_ellipses, const struct value_print_options *options) { const char *type_encoding = f_get_encoding (type); diff --git a/gdb/f-lang.h b/gdb/f-lang.h index 1ba529d76c5..b0560e36d15 100644 --- a/gdb/f-lang.h +++ b/gdb/f-lang.h @@ -31,7 +31,7 @@ extern int f_parse (struct parser_state *); extern void f_print_type (struct type *, const char *, struct ui_file *, int, int, const struct type_print_options *); -extern void f_val_print (struct type *, int, CORE_ADDR, +extern void f_val_print (struct type *, LONGEST, CORE_ADDR, struct ui_file *, int, struct value *, const struct value_print_options *); diff --git a/gdb/f-typeprint.c b/gdb/f-typeprint.c index a0e34b3058d..c4b04551b08 100644 --- a/gdb/f-typeprint.c +++ b/gdb/f-typeprint.c @@ -37,7 +37,7 @@ static void f_type_print_args (struct type *, struct ui_file *); #endif static void f_type_print_varspec_suffix (struct type *, struct ui_file *, int, - int, int, int); + int, int, int, int); void f_type_print_varspec_prefix (struct type *, struct ui_file *, int, int); @@ -53,18 +53,6 @@ f_print_type (struct type *type, const char *varstring, struct ui_file *stream, { enum type_code code; - if (type_not_associated (type)) - { - val_print_not_associated (stream); - return; - } - - if (type_not_allocated (type)) - { - val_print_not_allocated (stream); - return; - } - f_type_print_base (type, stream, show, level); code = TYPE_CODE (type); if ((varstring != NULL && *varstring != '\0') @@ -89,7 +77,7 @@ f_print_type (struct type *type, const char *varstring, struct ui_file *stream, demangled_args = (*varstring != '\0' && varstring[strlen (varstring) - 1] == ')'); - f_type_print_varspec_suffix (type, stream, show, 0, demangled_args, 0); + f_type_print_varspec_suffix (type, stream, show, 0, demangled_args, 0, 0); } } @@ -159,7 +147,7 @@ f_type_print_varspec_prefix (struct type *type, struct ui_file *stream, static void f_type_print_varspec_suffix (struct type *type, struct ui_file *stream, int show, int passed_a_ptr, int demangled_args, - int arrayprint_recurse_level) + int arrayprint_recurse_level, int print_rank_only) { /* No static variables are permitted as an error call may occur during execution of this function. */ @@ -181,14 +169,33 @@ f_type_print_varspec_suffix (struct type *type, struct ui_file *stream, fprintf_filtered (stream, "("); if (type_not_associated (type)) - val_print_not_associated (stream); + print_rank_only = 1; else if (type_not_allocated (type)) - val_print_not_allocated (stream); + print_rank_only = 1; + else if ((TYPE_ASSOCIATED_PROP (type) + && PROP_CONST != TYPE_DYN_PROP_KIND (TYPE_ASSOCIATED_PROP (type))) + || (TYPE_ALLOCATED_PROP (type) + && PROP_CONST != TYPE_DYN_PROP_KIND (TYPE_ALLOCATED_PROP (type))) + || (TYPE_DATA_LOCATION (type) + && PROP_CONST != TYPE_DYN_PROP_KIND (TYPE_DATA_LOCATION (type)))) + /* This case exist when we ptype a typename which has the + dynamic properties but cannot be resolved as there is + no object. */ + print_rank_only = 1; + + if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY) + f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, + 0, 0, arrayprint_recurse_level, + print_rank_only); + + if (print_rank_only == 1) + fprintf_filtered (stream, ":"); else { if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_ARRAY) f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, - 0, 0, arrayprint_recurse_level); + 0, 0, arrayprint_recurse_level, + print_rank_only); LONGEST lower_bound = f77_get_lowerbound (type); @@ -209,7 +216,8 @@ f_type_print_varspec_suffix (struct type *type, struct ui_file *stream, if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_ARRAY) f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, - 0, 0, arrayprint_recurse_level); + 0, 0, arrayprint_recurse_level, + print_rank_only); } if (arrayprint_recurse_level == 1) fprintf_filtered (stream, ")"); @@ -221,13 +229,14 @@ f_type_print_varspec_suffix (struct type *type, struct ui_file *stream, case TYPE_CODE_PTR: case TYPE_CODE_REF: f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1, 0, - arrayprint_recurse_level); + arrayprint_recurse_level, 0); fprintf_filtered (stream, ")"); break; case TYPE_CODE_FUNC: f_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, - passed_a_ptr, 0, arrayprint_recurse_level); + passed_a_ptr, 0, arrayprint_recurse_level, + 0); if (passed_a_ptr) fprintf_filtered (stream, ")"); @@ -388,7 +397,7 @@ f_type_print_base (struct type *type, struct ui_file *stream, int show, fputs_filtered (" :: ", stream); fputs_filtered (TYPE_FIELD_NAME (type, index), stream); f_type_print_varspec_suffix (TYPE_FIELD_TYPE (type, index), - stream, show - 1, 0, 0, 0); + stream, show - 1, 0, 0, 0, 0); fputs_filtered ("\n", stream); } fprintfi_filtered (level, stream, "End Type "); diff --git a/gdb/f-valprint.c b/gdb/f-valprint.c index 37b0ed5176d..874d7512456 100644 --- a/gdb/f-valprint.c +++ b/gdb/f-valprint.c @@ -36,7 +36,7 @@ static void f77_get_dynamic_length_of_aggregate (struct type *); -int f77_array_offset_tbl[MAX_FORTRAN_DIMS + 1][2]; +LONGEST f77_array_offset_tbl[MAX_FORTRAN_DIMS + 1][2]; /* Array which holds offsets to be applied to get a row's elements for a given array. Array also holds the size of each subarray. */ @@ -71,8 +71,8 @@ f77_get_upperbound (struct type *type) static void f77_get_dynamic_length_of_aggregate (struct type *type) { - int upper_bound = -1; - int lower_bound = 1; + LONGEST upper_bound = -1; + LONGEST lower_bound = 1; /* Recursively go all the way down into a possibly multi-dimensional F77 array and get the bounds. For simple arrays, this is pretty @@ -104,7 +104,7 @@ f77_get_dynamic_length_of_aggregate (struct type *type) static void f77_print_array_1 (int nss, int ndimensions, struct type *type, const gdb_byte *valaddr, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options, @@ -113,14 +113,20 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type, struct type *range_type = TYPE_INDEX_TYPE (check_typedef (type)); CORE_ADDR addr = address + embedded_offset; LONGEST lowerbound, upperbound; - int i; + LONGEST i; get_discrete_bounds (range_type, &lowerbound, &upperbound); if (nss != ndimensions) { - size_t dim_size = TYPE_LENGTH (TYPE_TARGET_TYPE (type)); + size_t dim_size; size_t offs = 0; + LONGEST byte_stride = abs (TYPE_BYTE_STRIDE (range_type)); + + if (byte_stride) + dim_size = byte_stride; + else + dim_size = TYPE_LENGTH (TYPE_TARGET_TYPE (type)); for (i = lowerbound; (i < upperbound + 1 && (*elts) < options->print_max); @@ -169,7 +175,7 @@ f77_print_array_1 (int nss, int ndimensions, struct type *type, static void f77_print_array (struct type *type, const gdb_byte *valaddr, - int embedded_offset, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, @@ -208,7 +214,7 @@ static const struct generic_val_print_decorations f_decorations = function; they are identical. */ void -f_val_print (struct type *type, int embedded_offset, +f_val_print (struct type *type, LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *original_value, const struct value_print_options *options) @@ -307,8 +313,22 @@ f_val_print (struct type *type, int embedded_offset, original_value, &opts, 0, stream); } else - val_print_scalar_formatted (type, embedded_offset, - original_value, options, 0, stream); + { + val_print_scalar_formatted (type, embedded_offset, + original_value, options, 0, stream); + /* C and C++ has no single byte int type, char is used instead. + Since we don't know whether the value is really intended to + be used as an integer or a character, print the character + equivalent as well. */ + if (TYPE_LENGTH (type) == 1) + { + LONGEST c; + + fputs_filtered (" ", stream); + c = unpack_long (type, valaddr + embedded_offset); + LA_PRINT_CHAR ((unsigned char) c, type, stream); + } + } break; case TYPE_CODE_STRUCT: diff --git a/gdb/findvar.c b/gdb/findvar.c index e89ee37ffc7..0d1c86ef079 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -821,7 +821,7 @@ struct value * default_value_from_register (struct gdbarch *gdbarch, struct type *type, int regnum, struct frame_id frame_id) { - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); struct value *value = allocate_value (type); struct frame_info *frame; @@ -865,7 +865,7 @@ read_frame_register_value (struct value *value, struct frame_info *frame) LONGEST offset = 0; LONGEST reg_offset = value_offset (value); int regnum = VALUE_REGNUM (value); - int len = type_length_units (check_typedef (value_type (value))); + LONGEST len = type_length_units (check_typedef (value_type (value))); gdb_assert (VALUE_LVAL (value) == lval_register); @@ -880,7 +880,7 @@ read_frame_register_value (struct value *value, struct frame_info *frame) while (len > 0) { struct value *regval = get_frame_register_value (frame, regnum); - int reg_len = type_length_units (value_type (regval)) - reg_offset; + LONGEST reg_len = type_length_units (value_type (regval)) - reg_offset; /* If the register length is larger than the number of bytes remaining to copy, then only copy the appropriate bytes. */ diff --git a/gdb/frame.c b/gdb/frame.c index f4303d13cc1..066aba5cb2e 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -1392,7 +1392,7 @@ deprecated_frame_register_read (struct frame_info *frame, int regnum, int get_frame_register_bytes (struct frame_info *frame, int regnum, - CORE_ADDR offset, int len, gdb_byte *myaddr, + CORE_ADDR offset, LONGEST len, gdb_byte *myaddr, int *optimizedp, int *unavailablep) { struct gdbarch *gdbarch = get_frame_arch (frame); @@ -1421,7 +1421,7 @@ get_frame_register_bytes (struct frame_info *frame, int regnum, } if (len > maxsize) error (_("Bad debug information detected: " - "Attempt to read %d bytes from registers."), len); + "Attempt to read %s bytes from registers."), plongest (len)); /* Copy the data. */ while (len > 0) diff --git a/gdb/frame.h b/gdb/frame.h index 0a0baf46a0c..d1d74050c19 100644 --- a/gdb/frame.h +++ b/gdb/frame.h @@ -620,7 +620,7 @@ extern void put_frame_register (struct frame_info *frame, int regnum, contents are optimized out or unavailable, set *OPTIMIZEDP, *UNAVAILABLEP accordingly. */ extern int get_frame_register_bytes (struct frame_info *frame, int regnum, - CORE_ADDR offset, int len, + CORE_ADDR offset, LONGEST len, gdb_byte *myaddr, int *optimizedp, int *unavailablep); diff --git a/gdb/gdb-gdb.gdb.in b/gdb/gdb-gdb.gdb.in index 05a38b2670b..9801fdff673 100644 --- a/gdb/gdb-gdb.gdb.in +++ b/gdb/gdb-gdb.gdb.in @@ -1,5 +1,15 @@ echo Setting up the environment for debugging gdb.\n +# Set up the Python library and "require" command. +python +from os.path import abspath +gdb.datadir = abspath ('@srcdir@/python/lib') +gdb.pythonlibdir = gdb.datadir +gdb.__path__ = [gdb.datadir + '/gdb'] +sys.path.insert(0, gdb.datadir) +end +source @srcdir@/python/lib/gdb/__init__.py + if !$gdb_init_done set variable $gdb_init_done = 1 diff --git a/gdb/gdb.c b/gdb/gdb.c index 09c05779025..c266df70849 100644 --- a/gdb/gdb.c +++ b/gdb/gdb.c @@ -20,11 +20,19 @@ #include "main.h" #include "interps.h" +#ifdef PERF_ATTR_SIZE_VER5_BUNDLE +extern "C" void __libipt_init(void); +#endif + int main (int argc, char **argv) { struct captured_main_args args; +#ifdef PERF_ATTR_SIZE_VER5_BUNDLE + __libipt_init(); +#endif + memset (&args, 0, sizeof args); args.argc = argc; args.argv = argv; diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index 5c6bbef551d..4487dd04c02 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -24,12 +24,14 @@ #include "hashtab.h" #include "common/filestuff.h" #include "common/vec.h" +#ifndef __sparc__ #ifdef HAVE_MMAP #include #ifndef MAP_FAILED #define MAP_FAILED ((void *) -1) #endif #endif +#endif #include "target.h" #include "gdb/fileio.h" #include "inferior.h" @@ -484,6 +486,7 @@ free_one_bfd_section (bfd *abfd, asection *sectp, void *ignore) if (sect != NULL && sect->data != NULL) { +#ifndef __sparc__ #ifdef HAVE_MMAP if (sect->map_addr != NULL) { @@ -493,6 +496,7 @@ free_one_bfd_section (bfd *abfd, asection *sectp, void *ignore) gdb_assert (res == 0); } else +#endif #endif xfree (sect->data); } @@ -659,6 +663,7 @@ gdb_bfd_map_section (asection *sectp, bfd_size_type *size) if (descriptor->data != NULL) goto done; +#ifndef __sparc__ #ifdef HAVE_MMAP if (!bfd_is_section_compressed (abfd, sectp)) { @@ -693,6 +698,7 @@ gdb_bfd_map_section (asection *sectp, bfd_size_type *size) } } #endif /* HAVE_MMAP */ +#endif /* Handle compressed sections, or ordinary uncompressed sections in the no-mmap case. */ diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index a0c169d74d4..d6b19c4f2fc 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -1803,7 +1803,7 @@ set_gdbarch_wchar_signed (struct gdbarch *gdbarch, } const struct floatformat ** -gdbarch_floatformat_for_type (struct gdbarch *gdbarch, const char *name, int length) +gdbarch_floatformat_for_type (struct gdbarch *gdbarch, const char *name, LONGEST length) { gdb_assert (gdbarch != NULL); gdb_assert (gdbarch->floatformat_for_type != NULL); diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 7ebd365a31e..9628e6e299b 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -218,8 +218,8 @@ extern void set_gdbarch_wchar_signed (struct gdbarch *gdbarch, int wchar_signed) NAME, if non-NULL, is the type name, which may be used to distinguish different target formats of the same length. */ -typedef const struct floatformat ** (gdbarch_floatformat_for_type_ftype) (struct gdbarch *gdbarch, const char *name, int length); -extern const struct floatformat ** gdbarch_floatformat_for_type (struct gdbarch *gdbarch, const char *name, int length); +typedef const struct floatformat ** (gdbarch_floatformat_for_type_ftype) (struct gdbarch *gdbarch, const char *name, LONGEST length); +extern const struct floatformat ** gdbarch_floatformat_for_type (struct gdbarch *gdbarch, const char *name, LONGEST length); extern void set_gdbarch_floatformat_for_type (struct gdbarch *gdbarch, gdbarch_floatformat_for_type_ftype *floatformat_for_type); /* For most targets, a pointer on the target and its representation as an diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 59493d8c215..8b9fbace4d6 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -385,7 +385,7 @@ v;int;wchar_signed;;;1;-1;1 # Returns the floating-point format to be used for values of length LENGTH. # NAME, if non-NULL, is the type name, which may be used to distinguish # different target formats of the same length. -m;const struct floatformat **;floatformat_for_type;const char *name, int length;name, length;0;default_floatformat_for_type;;0 +m;const struct floatformat **;floatformat_for_type;const char *name, LONGEST length;name, length;0;default_floatformat_for_type;;0 # For most targets, a pointer on the target and its representation as an # address in GDB have the same size and "look the same". For such a diff --git a/gdb/gdbinit b/gdb/gdbinit new file mode 100644 index 00000000000..9b71451bbf1 --- /dev/null +++ b/gdb/gdbinit @@ -0,0 +1,5 @@ +set auto-load safe-path / +file /media/build//x86_64/linux-4.12-xfs-review-default/vmlinux +source target.py +target kdumpfile /var/crash/2019-04-17-17:05/vmcore +print &modules == modules.next diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in index 05537df81e3..ddd84ae38ea 100644 --- a/gdb/gdbserver/config.in +++ b/gdb/gdbserver/config.in @@ -126,6 +126,9 @@ /* Define to 1 if you have the `mcheck' library (-lmcheck). */ #undef HAVE_LIBMCHECK +/* Define to 1 if you have the `selinux' library (-lselinux). */ +#undef HAVE_LIBSELINUX + /* Define if the target supports branch tracing. */ #undef HAVE_LINUX_BTRACE @@ -202,6 +205,9 @@ /* Define to 1 if you have the `pwrite' function. */ #undef HAVE_PWRITE +/* Define to 1 if you have the header file. */ +#undef HAVE_SELINUX_SELINUX_H + /* Define to 1 if you have the `setns' function. */ #undef HAVE_SETNS diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure index 1ddbd6b27e0..e8a25c52701 100755 --- a/gdb/gdbserver/configure +++ b/gdb/gdbserver/configure @@ -8589,6 +8589,64 @@ if $want_ipa ; then fi fi +for ac_header in selinux/selinux.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "selinux/selinux.h" "ac_cv_header_selinux_selinux_h" "$ac_includes_default" +if test "x$ac_cv_header_selinux_selinux_h" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_SELINUX_SELINUX_H 1 +_ACEOF + +fi + +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for security_get_boolean_active in -lselinux" >&5 +$as_echo_n "checking for security_get_boolean_active in -lselinux... " >&6; } +if test "${ac_cv_lib_selinux_security_get_boolean_active+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lselinux $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 security_get_boolean_active (); +int +main () +{ +return security_get_boolean_active (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_selinux_security_get_boolean_active=yes +else + ac_cv_lib_selinux_security_get_boolean_active=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_selinux_security_get_boolean_active" >&5 +$as_echo "$ac_cv_lib_selinux_security_get_boolean_active" >&6; } +if test "x$ac_cv_lib_selinux_security_get_boolean_active" = x""yes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSELINUX 1 +_ACEOF + + LIBS="-lselinux $LIBS" + +fi + + diff --git a/gdb/gdbserver/configure.ac b/gdb/gdbserver/configure.ac index 98b22535775..23e495b518c 100644 --- a/gdb/gdbserver/configure.ac +++ b/gdb/gdbserver/configure.ac @@ -478,6 +478,10 @@ if $want_ipa ; then fi fi +dnl Check security_get_boolean_active availability. +AC_CHECK_HEADERS(selinux/selinux.h) +AC_CHECK_LIB(selinux, security_get_boolean_active) + AC_SUBST(GDBSERVER_DEPFILES) AC_SUBST(GDBSERVER_LIBS) AC_SUBST(srv_xmlbuiltin) diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 168f4b2abc2..d81d99011bf 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -971,7 +971,16 @@ linux_ptrace_fun () { if (ptrace (PTRACE_TRACEME, 0, (PTRACE_TYPE_ARG3) 0, (PTRACE_TYPE_ARG4) 0) < 0) - trace_start_error_with_name ("ptrace"); + { + int save_errno = errno; + + std::string msg (linux_ptrace_create_warnings ()); + + msg += _("Cannot trace created process"); + + errno = save_errno; + trace_start_error_with_name (msg.c_str ()); + } if (setpgid (0, 0) < 0) trace_start_error_with_name ("setpgid"); diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 683238d03d2..0f4bdf93332 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -900,7 +900,8 @@ operator== (const range_bounds &l, const range_bounds &r) return (FIELD_EQ (low) && FIELD_EQ (high) && FIELD_EQ (flag_upper_bound_is_count) - && FIELD_EQ (flag_bound_evaluated)); + && (FIELD_EQ (flag_bound_evaluated) || + l.high.kind == PROP_UNDEFINED)); #undef FIELD_EQ } @@ -911,7 +912,8 @@ operator== (const range_bounds &l, const range_bounds &r) struct type * create_range_type (struct type *result_type, struct type *index_type, const struct dynamic_prop *low_bound, - const struct dynamic_prop *high_bound) + const struct dynamic_prop *high_bound, + const struct dynamic_prop *stride) { if (result_type == NULL) result_type = alloc_type_copy (index_type); @@ -926,6 +928,7 @@ create_range_type (struct type *result_type, struct type *index_type, TYPE_ZALLOC (result_type, sizeof (struct range_bounds)); TYPE_RANGE_DATA (result_type)->low = *low_bound; TYPE_RANGE_DATA (result_type)->high = *high_bound; + TYPE_RANGE_DATA (result_type)->stride = *stride; if (low_bound->kind == PROP_CONST && low_bound->data.const_val >= 0) TYPE_UNSIGNED (result_type) = 1; @@ -954,7 +957,7 @@ struct type * create_static_range_type (struct type *result_type, struct type *index_type, LONGEST low_bound, LONGEST high_bound) { - struct dynamic_prop low, high; + struct dynamic_prop low, high, stride; low.kind = PROP_CONST; low.data.const_val = low_bound; @@ -962,7 +965,11 @@ create_static_range_type (struct type *result_type, struct type *index_type, high.kind = PROP_CONST; high.data.const_val = high_bound; - result_type = create_range_type (result_type, index_type, &low, &high); + stride.kind = PROP_CONST; + stride.data.const_val = 0; + + result_type = create_range_type (result_type, index_type, + &low, &high, &stride); return result_type; } @@ -1180,16 +1187,20 @@ create_array_type_with_stride (struct type *result_type, && (!type_not_associated (result_type) && !type_not_allocated (result_type))) { - LONGEST low_bound, high_bound; + LONGEST low_bound, high_bound, byte_stride; if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0) low_bound = high_bound = 0; element_type = check_typedef (element_type); + byte_stride = abs (TYPE_BYTE_STRIDE (range_type)); + /* Be careful when setting the array length. Ada arrays can be empty arrays with the high_bound being smaller than the low_bound. In such cases, the array length should be zero. */ if (high_bound < low_bound) TYPE_LENGTH (result_type) = 0; + else if (byte_stride > 0) + TYPE_LENGTH (result_type) = byte_stride * (high_bound - low_bound + 1); else if (bit_stride > 0) TYPE_LENGTH (result_type) = (bit_stride * (high_bound - low_bound + 1) + 7) / 8; @@ -1887,7 +1898,8 @@ is_dynamic_type_internal (struct type *type, int top_level) type = check_typedef (type); /* We only want to recognize references at the outermost level. */ - if (top_level && TYPE_CODE (type) == TYPE_CODE_REF) + if (top_level && + (TYPE_CODE (type) == TYPE_CODE_REF || TYPE_CODE (type) == TYPE_CODE_PTR)) type = check_typedef (TYPE_TARGET_TYPE (type)); /* Types that have a dynamic TYPE_DATA_LOCATION are considered @@ -1921,6 +1933,7 @@ is_dynamic_type_internal (struct type *type, int top_level) } case TYPE_CODE_ARRAY: + case TYPE_CODE_STRING: { gdb_assert (TYPE_NFIELDS (type) == 1); @@ -1974,12 +1987,12 @@ resolve_dynamic_range (struct type *dyn_range_type, CORE_ADDR value; struct type *static_range_type, *static_target_type; const struct dynamic_prop *prop; - struct dynamic_prop low_bound, high_bound; + struct dynamic_prop low_bound, high_bound, stride; gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE); prop = &TYPE_RANGE_DATA (dyn_range_type)->low; - if (dwarf2_evaluate_property (prop, NULL, addr_stack, &value)) + if (dwarf2_evaluate_property_signed (prop, NULL, addr_stack, &value, 1)) { low_bound.kind = PROP_CONST; low_bound.data.const_val = value; @@ -1991,7 +2004,7 @@ resolve_dynamic_range (struct type *dyn_range_type, } prop = &TYPE_RANGE_DATA (dyn_range_type)->high; - if (dwarf2_evaluate_property (prop, NULL, addr_stack, &value)) + if (dwarf2_evaluate_property_signed (prop, NULL, addr_stack, &value, 1)) { high_bound.kind = PROP_CONST; high_bound.data.const_val = value; @@ -2006,12 +2019,20 @@ resolve_dynamic_range (struct type *dyn_range_type, high_bound.data.const_val = 0; } + prop = &TYPE_RANGE_DATA (dyn_range_type)->stride; + if (dwarf2_evaluate_property_signed (prop, NULL, addr_stack, &value, 1)) + { + stride.kind = PROP_CONST; + stride.data.const_val = value; + } + static_target_type = resolve_dynamic_type_internal (TYPE_TARGET_TYPE (dyn_range_type), addr_stack, 0); static_range_type = create_range_type (copy_type (dyn_range_type), static_target_type, - &low_bound, &high_bound); + &low_bound, &high_bound, &stride); + TYPE_RANGE_DATA (static_range_type)->flag_bound_evaluated = 1; return static_range_type; } @@ -2031,7 +2052,8 @@ resolve_dynamic_array (struct type *type, struct dynamic_prop *prop; unsigned int bit_stride = 0; - gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY); + gdb_assert (TYPE_CODE (type) == TYPE_CODE_ARRAY + || TYPE_CODE (type) == TYPE_CODE_STRING); type = copy_type (type); @@ -2056,11 +2078,15 @@ resolve_dynamic_array (struct type *type, ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type)); - if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY) + if (ary_dim != NULL && (TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY + || TYPE_CODE (ary_dim) == TYPE_CODE_STRING)) elt_type = resolve_dynamic_array (ary_dim, addr_stack); else elt_type = TYPE_TARGET_TYPE (type); + if (TYPE_CODE (type) == TYPE_CODE_STRING) + return create_string_type (type, elt_type, range_type); + prop = get_dyn_prop (DYN_PROP_BYTE_STRIDE, type); if (prop != NULL) { @@ -2215,6 +2241,28 @@ resolve_dynamic_struct (struct type *type, return resolved_type; } +/* Worker for pointer types. */ + +static struct type * +resolve_dynamic_pointer (struct type *type, + struct property_addr_info *addr_stack) +{ + struct dynamic_prop *prop; + CORE_ADDR value; + + type = copy_type (type); + + /* Resolve associated property. */ + prop = TYPE_ASSOCIATED_PROP (type); + if (prop != NULL && dwarf2_evaluate_property (prop, NULL, addr_stack, &value)) + { + TYPE_DYN_PROP_ADDR (prop) = value; + TYPE_DYN_PROP_KIND (prop) = PROP_CONST; + } + + return type; +} + /* Worker for resolved_dynamic_type. */ static struct type * @@ -2263,7 +2311,12 @@ resolve_dynamic_type_internal (struct type *type, break; } + case TYPE_CODE_PTR: + resolved_type = resolve_dynamic_pointer (type, addr_stack); + break; + case TYPE_CODE_ARRAY: + case TYPE_CODE_STRING: resolved_type = resolve_dynamic_array (type, addr_stack); break; @@ -2820,7 +2873,7 @@ floatformat_from_type (const struct type *type) least as long as OBJFILE. */ struct type * -init_type (struct objfile *objfile, enum type_code code, int bit, +init_type (struct objfile *objfile, enum type_code code, LONGEST bit, const char *name) { struct type *type; @@ -3277,8 +3330,8 @@ is_public_ancestor (struct type *base, struct type *dclass) static int is_unique_ancestor_worker (struct type *base, struct type *dclass, - int *offset, - const gdb_byte *valaddr, int embedded_offset, + LONGEST *offset, + const gdb_byte *valaddr, LONGEST embedded_offset, CORE_ADDR address, struct value *val) { int i, count = 0; @@ -3289,7 +3342,7 @@ is_unique_ancestor_worker (struct type *base, struct type *dclass, for (i = 0; i < TYPE_N_BASECLASSES (dclass) && count < 2; ++i) { struct type *iter; - int this_offset; + LONGEST this_offset; iter = check_typedef (TYPE_BASECLASS (dclass, i)); @@ -3330,7 +3383,7 @@ is_unique_ancestor_worker (struct type *base, struct type *dclass, int is_unique_ancestor (struct type *base, struct value *val) { - int offset = -1; + LONGEST offset = -1; return is_unique_ancestor_worker (base, value_type (val), &offset, value_contents_for_printing (val), @@ -3600,6 +3653,9 @@ static bool check_types_equal (struct type *type1, struct type *type2, std::vector *worklist) { + if (type1 == type2) + return 1; + type1 = check_typedef (type1); type2 = check_typedef (type2); @@ -5035,7 +5091,7 @@ copy_type (const struct type *type) struct type * arch_type (struct gdbarch *gdbarch, - enum type_code code, int bit, const char *name) + enum type_code code, LONGEST bit, const char *name) { struct type *type; diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h index 2125ed991d0..df6f61e154f 100644 --- a/gdb/gdbtypes.h +++ b/gdb/gdbtypes.h @@ -507,6 +507,7 @@ enum field_loc_kind { FIELD_LOC_KIND_BITPOS, /**< bitpos */ FIELD_LOC_KIND_ENUMVAL, /**< enumval */ + /* This address is unrelocated by the objfile's ANOFFSET. */ FIELD_LOC_KIND_PHYSADDR, /**< physaddr */ FIELD_LOC_KIND_PHYSNAME, /**< physname */ FIELD_LOC_KIND_DWARF_BLOCK /**< dwarf_block */ @@ -558,6 +559,7 @@ union field_location field. Otherwise, physname is the mangled label of the static field. */ + /* This address is unrelocated by the objfile's ANOFFSET. */ CORE_ADDR physaddr; const char *physname; @@ -614,6 +616,10 @@ struct range_bounds struct dynamic_prop high; + /* * Stride of range. */ + + struct dynamic_prop stride; + /* True if HIGH range bound contains the number of elements in the subrange. This affects how the final hight bound is computed. */ @@ -778,7 +784,6 @@ struct main_type /* * Union member used for range types. */ struct range_bounds *bounds; - } flds_bnds; /* * Slot to point to additional language-specific fields of this @@ -1327,6 +1332,15 @@ extern bool set_type_align (struct type *, ULONGEST); TYPE_RANGE_DATA(range_type)->high.kind #define TYPE_LOW_BOUND_KIND(range_type) \ TYPE_RANGE_DATA(range_type)->low.kind +#define TYPE_BYTE_STRIDE(range_type) \ + TYPE_RANGE_DATA(range_type)->stride.data.const_val +#define TYPE_BYTE_STRIDE_BLOCK(range_type) \ + TYPE_RANGE_DATA(range_type)->stride.data.locexpr +#define TYPE_BYTE_STRIDE_LOCLIST(range_type) \ + TYPE_RANGE_DATA(range_type)->stride.data.loclist +#define TYPE_BYTE_STRIDE_KIND(range_type) \ + TYPE_RANGE_DATA(range_type)->stride.kind + /* Property accessors for the type data location. */ #define TYPE_DATA_LOCATION(thistype) \ @@ -1361,6 +1375,9 @@ extern bool set_type_align (struct type *, ULONGEST); TYPE_HIGH_BOUND_UNDEFINED(TYPE_INDEX_TYPE(arraytype)) #define TYPE_ARRAY_LOWER_BOUND_IS_UNDEFINED(arraytype) \ TYPE_LOW_BOUND_UNDEFINED(TYPE_INDEX_TYPE(arraytype)) +#define TYPE_ARRAY_STRIDE_IS_UNDEFINED(arraytype) \ + (TYPE_BYTE_STRIDE(TYPE_INDEX_TYPE(arraytype)) == 0) + #define TYPE_ARRAY_UPPER_BOUND_VALUE(arraytype) \ (TYPE_HIGH_BOUND(TYPE_INDEX_TYPE((arraytype)))) @@ -1421,6 +1438,7 @@ extern void set_type_vptr_basetype (struct type *, struct type *); #define FIELD_ENUMVAL_LVAL(thisfld) ((thisfld).loc.enumval) #define FIELD_ENUMVAL(thisfld) (FIELD_ENUMVAL_LVAL (thisfld) + 0) #define FIELD_STATIC_PHYSNAME(thisfld) ((thisfld).loc.physname) +/* This address is unrelocated by the objfile's ANOFFSET. */ #define FIELD_STATIC_PHYSADDR(thisfld) ((thisfld).loc.physaddr) #define FIELD_DWARF_BLOCK(thisfld) ((thisfld).loc.dwarf_block) #define SET_FIELD_BITPOS(thisfld, bitpos) \ @@ -1432,6 +1450,7 @@ extern void set_type_vptr_basetype (struct type *, struct type *); #define SET_FIELD_PHYSNAME(thisfld, name) \ (FIELD_LOC_KIND (thisfld) = FIELD_LOC_KIND_PHYSNAME, \ FIELD_STATIC_PHYSNAME (thisfld) = (name)) +/* This address is unrelocated by the objfile's ANOFFSET. */ #define SET_FIELD_PHYSADDR(thisfld, addr) \ (FIELD_LOC_KIND (thisfld) = FIELD_LOC_KIND_PHYSADDR, \ FIELD_STATIC_PHYSADDR (thisfld) = (addr)) @@ -1448,6 +1467,7 @@ extern void set_type_vptr_basetype (struct type *, struct type *); #define TYPE_FIELD_BITPOS(thistype, n) FIELD_BITPOS (TYPE_FIELD (thistype, n)) #define TYPE_FIELD_ENUMVAL(thistype, n) FIELD_ENUMVAL (TYPE_FIELD (thistype, n)) #define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) FIELD_STATIC_PHYSNAME (TYPE_FIELD (thistype, n)) +/* This address is unrelocated by the objfile's ANOFFSET. */ #define TYPE_FIELD_STATIC_PHYSADDR(thistype, n) FIELD_STATIC_PHYSADDR (TYPE_FIELD (thistype, n)) #define TYPE_FIELD_DWARF_BLOCK(thistype, n) FIELD_DWARF_BLOCK (TYPE_FIELD (thistype, n)) #define TYPE_FIELD_ARTIFICIAL(thistype, n) FIELD_ARTIFICIAL(TYPE_FIELD(thistype,n)) @@ -1767,7 +1787,7 @@ extern unsigned int type_length_units (struct type *type); /* * Helper function to construct objfile-owned types. */ -extern struct type *init_type (struct objfile *, enum type_code, int, +extern struct type *init_type (struct objfile *, enum type_code, LONGEST, const char *); extern struct type *init_integer_type (struct objfile *, int, int, const char *); @@ -1784,7 +1804,7 @@ extern struct type *init_pointer_type (struct objfile *, int, const char *, struct type *); /* Helper functions to construct architecture-owned types. */ -extern struct type *arch_type (struct gdbarch *, enum type_code, int, +extern struct type *arch_type (struct gdbarch *, enum type_code, LONGEST, const char *); extern struct type *arch_integer_type (struct gdbarch *, int, int, const char *); @@ -1934,6 +1954,7 @@ extern struct type *create_array_type_with_stride struct dynamic_prop *, unsigned int); extern struct type *create_range_type (struct type *, struct type *, + const struct dynamic_prop *, const struct dynamic_prop *, const struct dynamic_prop *); diff --git a/gdb/gnu-v2-abi.c b/gdb/gnu-v2-abi.c index 30405684dd8..a284517a4a5 100644 --- a/gdb/gnu-v2-abi.c +++ b/gdb/gnu-v2-abi.c @@ -82,7 +82,7 @@ gnuv2_is_operator_name (const char *name) TYPE is the type in which F is located. */ static struct value * gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j, - struct type * type, int offset) + struct type *type, LONGEST offset) { struct value *arg1 = *arg1p; struct type *type1 = check_typedef (value_type (arg1)); @@ -338,7 +338,7 @@ vb_match (struct type *type, int index, struct type *basetype) target). The result is the offset of the baseclass value relative to (the address of)(ARG) + OFFSET. */ -static int +static LONGEST gnuv2_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr, LONGEST embedded_offset, CORE_ADDR address, const struct value *val) @@ -358,8 +358,7 @@ gnuv2_baseclass_offset (struct type *type, int index, if (vb_match (type, i, basetype)) { struct type *field_type; - LONGEST field_offset; - int field_length; + LONGEST field_offset, field_length; CORE_ADDR addr; field_type = check_typedef (TYPE_FIELD_TYPE (type, i)); @@ -383,7 +382,7 @@ gnuv2_baseclass_offset (struct type *type, int index, /* Don't go through baseclass_offset, as that wraps exceptions, thus, inner exceptions would be wrapped more than once. */ - int boffset = + LONGEST boffset = gnuv2_baseclass_offset (type, i, valaddr, embedded_offset, address, val); diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c index 6407c9beb82..d9894fd55f8 100644 --- a/gdb/gnu-v3-abi.c +++ b/gdb/gnu-v3-abi.c @@ -109,7 +109,7 @@ build_gdb_vtable_type (struct gdbarch *arch) { struct type *t; struct field *field_list, *field; - int offset; + LONGEST offset; struct type *void_ptr_type = builtin_type (arch)->builtin_data_ptr; @@ -185,7 +185,7 @@ vtable_ptrdiff_type (struct gdbarch *gdbarch) /* Return the offset from the start of the imaginary `struct gdb_gnu_v3_abi_vtable' object to the vtable's "address point" (i.e., where objects' virtual table pointers point). */ -static int +static LONGEST vtable_address_point_offset (struct gdbarch *gdbarch) { struct type *vtable_type @@ -409,7 +409,7 @@ gnuv3_get_virtual_fn (struct gdbarch *gdbarch, struct value *container, static struct value * gnuv3_virtual_fn_field (struct value **value_p, struct fn_field *f, int j, - struct type *vfn_base, int offset) + struct type *vfn_base, LONGEST offset) { struct type *values_type = check_typedef (value_type (*value_p)); struct gdbarch *gdbarch; @@ -439,7 +439,7 @@ gnuv3_virtual_fn_field (struct value **value_p, -1 is returned on error. */ -static int +static LONGEST gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr, LONGEST embedded_offset, CORE_ADDR address, const struct value *val) @@ -448,7 +448,7 @@ gnuv3_baseclass_offset (struct type *type, int index, struct type *ptr_type; struct value *vtable; struct value *vbase_array; - long int cur_base_offset, base_offset; + LONGEST cur_base_offset, base_offset; /* Determine architecture. */ gdbarch = get_type_arch (type); @@ -471,7 +471,7 @@ gnuv3_baseclass_offset (struct type *type, int index, cur_base_offset = cur_base_offset + vtable_address_point_offset (gdbarch); if ((- cur_base_offset) % TYPE_LENGTH (ptr_type) != 0) error (_("Misaligned vbase offset.")); - cur_base_offset = cur_base_offset / ((int) TYPE_LENGTH (ptr_type)); + cur_base_offset = cur_base_offset / ((LONGEST) TYPE_LENGTH (ptr_type)); vtable = gnuv3_get_vtable (gdbarch, type, address + embedded_offset); gdb_assert (vtable != NULL); @@ -515,7 +515,7 @@ gnuv3_find_method_in (struct type *domain, CORE_ADDR voffset, we're out of luck. */ for (i = 0; i < TYPE_N_BASECLASSES (domain); i++) { - int pos; + LONGEST pos; struct type *basetype; if (BASETYPE_VIA_VIRTUAL (domain, i)) diff --git a/gdb/go-lang.h b/gdb/go-lang.h index 18748b0acbe..a3bd47b9977 100644 --- a/gdb/go-lang.h +++ b/gdb/go-lang.h @@ -83,7 +83,7 @@ extern void go_print_type (struct type *type, const char *varstring, /* Defined in go-valprint.c. */ extern void go_val_print (struct type *type, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options); diff --git a/gdb/go-valprint.c b/gdb/go-valprint.c index eda40f8ed8b..51eecf9ac13 100644 --- a/gdb/go-valprint.c +++ b/gdb/go-valprint.c @@ -86,7 +86,7 @@ print_go_string (struct type *type, /* Implements the la_val_print routine for language Go. */ void -go_val_print (struct type *type, int embedded_offset, +go_val_print (struct type *type, LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options) diff --git a/gdb/gstack.sh b/gdb/gstack.sh new file mode 100644 index 00000000000..f7f07248f77 --- /dev/null +++ b/gdb/gstack.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +if test $# -ne 1; then + echo "Usage: `basename $0 .sh` " 1>&2 + exit 1 +fi + +if test ! -r /proc/$1; then + echo "Process $1 not found." 1>&2 + exit 1 +fi + +# GDB doesn't allow "thread apply all bt" when the process isn't +# threaded; need to peek at the process to determine if that or the +# simpler "bt" should be used. + +backtrace="bt" +if test -d /proc/$1/task ; then + # Newer kernel; has a task/ directory. + if test `/bin/ls /proc/$1/task | /usr/bin/wc -l` -gt 1 2>/dev/null ; then + backtrace="thread apply all bt" + fi +elif test -f /proc/$1/maps ; then + # Older kernel; go by it loading libpthread. + if /bin/grep -e libpthread /proc/$1/maps > /dev/null 2>&1 ; then + backtrace="thread apply all bt" + fi +fi + +GDB=${GDB:-gdb} + +# Run GDB, strip out unwanted noise. +# --readnever is no longer used since .gdb_index is now in use. +$GDB --quiet -nx $GDBARGS /proc/$1/exe $1 <&1 | +set width 0 +set height 0 +set pagination no +$backtrace +EOF +/bin/sed -n \ + -e 's/^\((gdb) \)*//' \ + -e '/^#/p' \ + -e '/^Thread/p' diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c index b41a0b6c260..a74c96b2a84 100644 --- a/gdb/h8300-tdep.c +++ b/gdb/h8300-tdep.c @@ -619,7 +619,7 @@ h8300_push_dummy_call (struct gdbarch *gdbarch, struct value *function, CORE_ADDR struct_addr) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - int stack_alloc = 0, stack_offset = 0; + LONGEST stack_alloc = 0, stack_offset = 0; int wordsize = BINWORD (gdbarch); int reg = E_ARG0_REGNUM; int argument; @@ -645,11 +645,11 @@ h8300_push_dummy_call (struct gdbarch *gdbarch, struct value *function, for (argument = 0; argument < nargs; argument++) { struct type *type = value_type (args[argument]); - int len = TYPE_LENGTH (type); + ssize_t len = TYPE_LENGTH (type); char *contents = (char *) value_contents (args[argument]); /* Pad the argument appropriately. */ - int padded_len = align_up (len, wordsize); + ssize_t padded_len = align_up (len, wordsize); /* Use std::vector here to get zero initialization. */ std::vector padded (padded_len); @@ -678,7 +678,7 @@ h8300_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Heavens to Betsy --- it's really going in registers! Note that on the h8/300s, there are gaps between the registers in the register file. */ - int offset; + ssize_t offset; for (offset = 0; offset < padded_len; offset += wordsize) { diff --git a/gdb/hppa-tdep.c b/gdb/hppa-tdep.c index d2b3336cfc7..592af90f0ad 100644 --- a/gdb/hppa-tdep.c +++ b/gdb/hppa-tdep.c @@ -985,7 +985,7 @@ hppa64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, { struct value *arg = args[i]; struct type *type = value_type (arg); - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); const bfd_byte *valbuf; bfd_byte fptrbuf[8]; int regnum; @@ -1178,7 +1178,7 @@ hppa64_return_value (struct gdbarch *gdbarch, struct value *function, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); int regnum, offset; if (len > 16) diff --git a/gdb/i386-darwin-tdep.c b/gdb/i386-darwin-tdep.c index 22653d36606..e738a27e5dc 100644 --- a/gdb/i386-darwin-tdep.c +++ b/gdb/i386-darwin-tdep.c @@ -167,7 +167,7 @@ i386_darwin_push_dummy_call (struct gdbarch *gdbarch, struct value *function, for (write_pass = 0; write_pass < 2; write_pass++) { - int args_space = 0; + LONGEST args_space = 0; int num_m128 = 0; if (return_method == return_method_struct) diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c index 54d9dd873b8..982be926387 100644 --- a/gdb/i386-tdep.c +++ b/gdb/i386-tdep.c @@ -2676,7 +2676,7 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function, gdb_byte buf[4]; int i; int write_pass; - int args_space = 0; + LONGEST args_space = 0; /* BND registers can be in arbitrary values at the moment of the inferior call. This can cause boundary violations that are not @@ -2691,7 +2691,7 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function, for (write_pass = 0; write_pass < 2; write_pass++) { - int args_space_used = 0; + LONGEST args_space_used = 0; if (return_method == return_method_struct) { @@ -2708,7 +2708,7 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function, for (i = 0; i < nargs; i++) { - int len = TYPE_LENGTH (value_enclosing_type (args[i])); + LONGEST len = TYPE_LENGTH (value_enclosing_type (args[i])); if (write_pass) { @@ -2915,7 +2915,7 @@ i386_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum type_code code = TYPE_CODE (type); - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION @@ -3701,7 +3701,7 @@ static int i386_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type) { - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); /* Values may be spread across multiple registers. Most debugging formats aren't expressive enough to specify the locations, so @@ -3734,7 +3734,7 @@ i386_register_to_value (struct frame_info *frame, int regnum, int *optimizedp, int *unavailablep) { struct gdbarch *gdbarch = get_frame_arch (frame); - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); if (i386_fp_regnum_p (gdbarch, regnum)) return i387_register_to_value (frame, regnum, type, to, @@ -3770,7 +3770,7 @@ static void i386_value_to_register (struct frame_info *frame, int regnum, struct type *type, const gdb_byte *from) { - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); if (i386_fp_regnum_p (get_frame_arch (frame), regnum)) { @@ -8153,7 +8153,7 @@ i386_fast_tracepoint_valid_at (struct gdbarch *gdbarch, CORE_ADDR addr, const struct floatformat ** i386_floatformat_for_type (struct gdbarch *gdbarch, - const char *name, int len) + const char *name, LONGEST len) { if (len == 128 && name) if (strcmp (name, "__float128") == 0 @@ -8417,6 +8417,9 @@ i386_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->xsave_xcr0_offset = -1; + /* Unwinding stops on i386 automatically. */ + tdep->outermost_frame_p = NULL; + tdep->record_regmap = i386_record_regmap; set_gdbarch_type_align (gdbarch, i386_type_align); diff --git a/gdb/i386-tdep.h b/gdb/i386-tdep.h index c0d494824cc..eda49279fed 100644 --- a/gdb/i386-tdep.h +++ b/gdb/i386-tdep.h @@ -255,6 +255,9 @@ struct gdbarch_tdep /* Regsets. */ const struct regset *fpregset; + + /* Detect OS dependent outermost frames; such as `clone'. */ + int (*outermost_frame_p) (struct frame_info *this_frame); }; /* Floating-point registers. */ diff --git a/gdb/infrun.c b/gdb/infrun.c index 37713b24fee..90623f0891d 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -610,6 +610,13 @@ holding the child stopped. Try \"set detach-on-fork\" or \ target_pid_to_str (process_ptid).c_str ()); } +#ifdef NEED_DETACH_SIGSTOP + /* We should check PID_WAS_STOPPED and detach it stopped accordingly. + In this point of code it cannot be 1 as we would not get FORK + executed without CONTINUE first which resets PID_WAS_STOPPED. + We would have to first TARGET_STOP and WAITPID it as with running + inferior PTRACE_DETACH, SIGSTOP will ignore the signal. */ +#endif target_detach (parent_inf, 0); } @@ -755,6 +762,9 @@ follow_fork (void) } else { + /* Possibly referenced PARENT is no longer valid. */ + reinit_frame_cache (); + /* This pending follow fork event is now handled, one way or another. The previous selected thread may be gone from the lists by now, but if it is still around, need @@ -2068,7 +2078,7 @@ static const char *const scheduler_enums[] = { schedlock_replay, NULL }; -static const char *scheduler_mode = schedlock_replay; +static const char *scheduler_mode = schedlock_step; static void show_scheduler_mode (struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value) @@ -6448,6 +6458,16 @@ process_event_stop_test (struct execution_control_state *ecs) if (ecs->event_thread->control.step_over_calls == STEP_OVER_ALL) { + struct symbol *stop_fn = find_pc_function (stop_pc); + struct minimal_symbol *stopf = lookup_minimal_symbol_by_pc (stop_pc).minsym; + + if ((stop_fn == NULL + || strstr (SYMBOL_LINKAGE_NAME (stop_fn), ".omp_fn.") == NULL) + /* gcc-4.7.2-9.fc19.x86_64 uses a new format. */ + && (stopf == NULL + || strstr (MSYMBOL_LINKAGE_NAME (stopf), "._omp_fn.") == NULL)) +{ /* ".omp_fn." */ + /* We're doing a "next". Normal (forward) execution: set a breakpoint at the @@ -6481,6 +6501,7 @@ process_event_stop_test (struct execution_control_state *ecs) keep_going (ecs); return; +} /* ".omp_fn." */ } /* If we are in a function call trampoline (a stub between the diff --git a/gdb/iq2000-tdep.c b/gdb/iq2000-tdep.c index c37f763a2f2..a9d514c864a 100644 --- a/gdb/iq2000-tdep.c +++ b/gdb/iq2000-tdep.c @@ -652,8 +652,9 @@ iq2000_push_dummy_call (struct gdbarch *gdbarch, struct value *function, const bfd_byte *val; bfd_byte buf[4]; struct type *type; - int i, argreg, typelen, slacklen; - int stackspace = 0; + int i, argreg, slacklen; + LONGEST typelen; + LONGEST stackspace = 0; /* Used to copy struct arguments into the stack. */ CORE_ADDR struct_ptr; diff --git a/gdb/language.c b/gdb/language.c index 954e4c200f0..5bfe0dc2a02 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -764,7 +764,7 @@ unk_lang_printchar (int c, struct type *type, struct ui_file *stream) static void unk_lang_printstr (struct ui_file *stream, struct type *type, - const gdb_byte *string, unsigned int length, + const gdb_byte *string, ULONGEST length, const char *encoding, int force_ellipses, const struct value_print_options *options) { @@ -783,7 +783,7 @@ unk_lang_print_type (struct type *type, const char *varstring, static void unk_lang_val_print (struct type *type, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options) diff --git a/gdb/language.h b/gdb/language.h index 3e0bc9d0d46..e4b2f00d4de 100644 --- a/gdb/language.h +++ b/gdb/language.h @@ -188,7 +188,7 @@ struct language_defn struct ui_file * stream); void (*la_printstr) (struct ui_file * stream, struct type *elttype, - const gdb_byte *string, unsigned int length, + const gdb_byte *string, ULONGEST length, const char *encoding, int force_ellipses, const struct value_print_options *); @@ -226,7 +226,7 @@ struct language_defn printing. */ void (*la_val_print) (struct type *type, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options); diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 65165a2d46b..d294a127b29 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -192,6 +192,12 @@ struct linux_nat_target *linux_target; /* Does the current host support PTRACE_GETREGSET? */ enum tribool have_ptrace_getregset = TRIBOOL_UNKNOWN; +#ifdef NEED_DETACH_SIGSTOP +/* PID of the inferior stopped by SIGSTOP before attaching (or zero). */ +static pid_t pid_was_stopped; + +#endif + static unsigned int debug_linux_nat; static void show_debug_linux_nat (struct ui_file *file, int from_tty, @@ -1036,6 +1042,9 @@ linux_nat_post_attach_wait (ptid_t ptid, int *signalled) if (debug_linux_nat) fprintf_unfiltered (gdb_stdlog, "LNPAW: Attaching to a stopped process\n"); +#ifdef NEED_DETACH_SIGSTOP + pid_was_stopped = ptid.pid (); +#endif /* The process is definitely stopped. It is in a job control stop, unless the kernel predates the TASK_STOPPED / @@ -1098,7 +1107,16 @@ linux_nat_target::create_inferior (const char *exec_file, /* Make sure we report all signals during startup. */ pass_signals ({}); - inf_ptrace_target::create_inferior (exec_file, allargs, env, from_tty); + try + { + inf_ptrace_target::create_inferior (exec_file, allargs, env, from_tty); + } + catch (const gdb_exception_error &ex) + { + std::string result = linux_ptrace_create_warnings (); + + throw_error (ex.error, "%s%s", result.c_str (), ex.what ()); + } } /* Callback for linux_proc_attach_tgid_threads. Attach to PTID if not @@ -1358,6 +1376,25 @@ get_detach_signal (struct lwp_info *lp) return gdb_signal_to_host (signo); } +#ifdef NEED_DETACH_SIGSTOP + /* Workaround RHEL-5 kernel which has unreliable PTRACE_DETACH, SIGSTOP (that + many TIDs are left unstopped). See RH Bug 496732. */ + if (lp->ptid.pid () == pid_was_stopped) + { + int err; + + errno = 0; + err = kill_lwp (lp->ptid.lwp (), SIGSTOP); + if (debug_linux_nat) + { + fprintf_unfiltered (gdb_stdlog, + "SC: lwp kill %d %s\n", + err, + errno ? safe_strerror (errno) : "ERRNO-OK"); + } + } + +#endif return 0; } @@ -1506,6 +1543,10 @@ linux_nat_target::detach (inferior *inf, int from_tty) detach_one_lwp (main_lwp, &signo); detach_success (inf); + +#ifdef NEED_DETACH_SIGSTOP + pid_was_stopped = 0; +#endif } } @@ -1763,6 +1804,16 @@ linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo) return; } +#ifdef NEED_DETACH_SIGSTOP + /* At this point, we are going to resume the inferior and if we + have attached to a stopped process, we no longer should leave + it as stopped if the user detaches. PTID variable has PID set to LWP + while we need to check the real PID here. */ + + if (!step && lp && pid_was_stopped == lp->ptid.pid ()) + pid_was_stopped = 0; + +#endif if (resume_many) iterate_over_lwps (ptid, [=] (struct lwp_info *info) { @@ -3764,6 +3815,10 @@ linux_nat_target::mourn_inferior () /* Let the arch-specific native code know this process is gone. */ linux_target->low_forget_process (pid); +#ifdef NEED_DETACH_SIGSTOP + + pid_was_stopped = 0; +#endif } /* Convert a native/host siginfo object, into/from the siginfo in the diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c index b4eb2628571..657af0cd30a 100644 --- a/gdb/m2-lang.c +++ b/gdb/m2-lang.c @@ -103,10 +103,10 @@ m2_printchar (int c, struct type *type, struct ui_file *stream) static void m2_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string, - unsigned int length, const char *encoding, int force_ellipses, + ULONGEST length, const char *encoding, int force_ellipses, const struct value_print_options *options) { - unsigned int i; + ULONGEST i; unsigned int things_printed = 0; int in_quotes = 0; int need_comma = 0; @@ -121,9 +121,9 @@ m2_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string, { /* Position of the character we are examining to see whether it is repeated. */ - unsigned int rep1; + ULONGEST rep1; /* Number of repetitions we have detected so far. */ - unsigned int reps; + ULONGEST reps; QUIT; @@ -149,7 +149,7 @@ m2_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string, in_quotes = 0; } m2_printchar (string[i], type, stream); - fprintf_filtered (stream, " ", reps); + fprintf_filtered (stream, " ", pulongest (reps)); i = rep1 - 1; things_printed += options->repeat_count_threshold; need_comma = 1; diff --git a/gdb/m2-lang.h b/gdb/m2-lang.h index 96058bb4f48..a0e03892b15 100644 --- a/gdb/m2-lang.h +++ b/gdb/m2-lang.h @@ -35,7 +35,7 @@ extern void m2_print_typedef (struct type *, struct symbol *, extern int m2_is_long_set (struct type *type); extern int m2_is_unbounded_array (struct type *type); -extern void m2_val_print (struct type *, int, CORE_ADDR, +extern void m2_val_print (struct type *, LONGEST, CORE_ADDR, struct ui_file *, int, struct value *, const struct value_print_options *); diff --git a/gdb/m2-valprint.c b/gdb/m2-valprint.c index 74f89ee45fb..1f33a42ee5f 100644 --- a/gdb/m2-valprint.c +++ b/gdb/m2-valprint.c @@ -35,7 +35,7 @@ static int print_unpacked_pointer (struct type *type, struct ui_file *stream); static void m2_print_array_contents (struct type *type, const gdb_byte *valaddr, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options, @@ -67,7 +67,7 @@ get_long_set_bounds (struct type *type, LONGEST *low, LONGEST *high) static void m2_print_long_set (struct type *type, const gdb_byte *valaddr, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream) { int empty_set = 1; @@ -158,7 +158,7 @@ m2_print_long_set (struct type *type, const gdb_byte *valaddr, static void m2_print_unbounded_array (struct type *type, const gdb_byte *valaddr, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value_print_options *options) { @@ -260,7 +260,7 @@ print_variable_at_address (struct type *type, static void m2_print_array_contents (struct type *type, const gdb_byte *valaddr, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options, @@ -308,12 +308,12 @@ static const struct generic_val_print_decorations m2_decorations = function; they are identical. */ void -m2_val_print (struct type *type, int embedded_offset, +m2_val_print (struct type *type, LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *original_value, const struct value_print_options *options) { - unsigned len; + ULONGEST len; struct type *elttype; CORE_ADDR addr; const gdb_byte *valaddr = value_contents_for_printing (original_value); @@ -339,7 +339,7 @@ m2_val_print (struct type *type, int embedded_offset, elements up to it. */ if (options->stop_print_at_null) { - unsigned int temp_len; + ULONGEST temp_len; /* Look for a NULL char. */ for (temp_len = 0; @@ -414,7 +414,7 @@ m2_val_print (struct type *type, int embedded_offset, { struct type *range = elttype; LONGEST low_bound, high_bound; - int i; + LONGEST i; int need_comma = 0; fputs_filtered ("{", stream); diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c index 18acdb6990c..332abf5dfd3 100644 --- a/gdb/m32r-tdep.c +++ b/gdb/m32r-tdep.c @@ -671,7 +671,7 @@ m32r_push_dummy_call (struct gdbarch *gdbarch, struct value *function, CORE_ADDR regval; gdb_byte *val; gdb_byte valbuf[M32R_ARG_REGISTER_SIZE]; - int len; + LONGEST len; /* First force sp to a 4-byte alignment. */ sp = sp & ~3; diff --git a/gdb/m68k-tdep.c b/gdb/m68k-tdep.c index fb18cadfc7f..6718b151631 100644 --- a/gdb/m68k-tdep.c +++ b/gdb/m68k-tdep.c @@ -372,7 +372,7 @@ m68k_reg_struct_return_p (struct gdbarch *gdbarch, struct type *type) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum type_code code = TYPE_CODE (type); - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); gdb_assert (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION || code == TYPE_CODE_COMPLEX); @@ -505,9 +505,9 @@ m68k_push_dummy_call (struct gdbarch *gdbarch, struct value *function, for (i = nargs - 1; i >= 0; i--) { struct type *value_type = value_enclosing_type (args[i]); - int len = TYPE_LENGTH (value_type); - int container_len = (len + 3) & ~3; - int offset; + LONGEST len = TYPE_LENGTH (value_type); + LONGEST container_len = (len + 3) & ~3; + LONGEST offset; /* Non-scalars bigger than 4 bytes are left aligned, others are right aligned. */ diff --git a/gdb/main.c b/gdb/main.c index e67efc7bcdf..0563c2d59fd 100644 --- a/gdb/main.c +++ b/gdb/main.c @@ -33,6 +33,7 @@ #include "interps.h" #include "main.h" +#include "python/python.h" #include "source.h" #include "cli/cli-cmds.h" #include "objfiles.h" @@ -439,8 +440,36 @@ struct cmdarg char *string; }; +/* Call exec_file_attach. If it detected FILENAME is a core file call + core_file_command. Print the original exec_file_attach error only if + core_file_command failed to find a matching executable. */ + +static void +exec_or_core_file_attach (const char *filename, int from_tty) +{ + gdb_assert (exec_bfd == NULL); + + try + { + exec_file_attach (filename, from_tty); + } + catch (const gdb_exception &e) + { + if (e.error == IS_CORE_ERROR) + { + core_file_command ((char *) filename, from_tty); + + /* Iff the core file found its executable suppress the error message + from exec_file_attach. */ + if (exec_bfd != NULL) + return; + } + throw_exception (e); + } +} + static void -captured_main_1 (struct captured_main_args *context) +captured_main_1 (struct captured_main_args *context, int &python_script) { int argc = context->argc; char **argv = context->argv; @@ -660,10 +689,14 @@ captured_main_1 (struct captured_main_args *context) {"args", no_argument, &set_args, 1}, {"l", required_argument, 0, 'l'}, {"return-child-result", no_argument, &return_child_result, 1}, +#if HAVE_PYTHON + {"python", no_argument, 0, 'P'}, + {"P", no_argument, 0, 'P'}, +#endif {0, no_argument, 0, 0} }; - while (1) + while (!python_script) { int option_index; @@ -681,6 +714,9 @@ captured_main_1 (struct captured_main_args *context) case 0: /* Long option that just sets a flag. */ break; + case 'P': + python_script = 1; + break; case OPT_SE: symarg = optarg; execarg = optarg; @@ -860,7 +896,31 @@ captured_main_1 (struct captured_main_args *context) /* Now that gdb_init has created the initial inferior, we're in position to set args for that inferior. */ - if (set_args) + if (python_script) + { + /* The first argument is a python script to evaluate, and + subsequent arguments are passed to the script for + processing there. */ + if (optind >= argc) + { + fprintf_unfiltered (gdb_stderr, + _("%s: Python script file name required\n"), + argv[0]); + exit (1); + } + + /* FIXME: should handle inferior I/O intelligently here. + E.g., should be possible to run gdb in pipeline and have + Python (and gdb) output go to stderr or file; and if a + prompt is needed, open the tty. */ + quiet = 1; + /* FIXME: should read .gdbinit if, and only if, a prompt is + requested by the script. Though... maybe this is not + ideal? */ + /* FIXME: likewise, reading in history. */ + inhibit_gdbinit = 1; + } + else if (set_args) { /* The remaining options are the command-line options for the inferior. The first one is the sym/exec file, and the rest @@ -884,6 +944,8 @@ captured_main_1 (struct captured_main_args *context) { symarg = argv[optind]; execarg = argv[optind]; + if (optind + 1 == argc && corearg == NULL) + corearg = argv[optind]; optind++; } @@ -1034,12 +1096,23 @@ captured_main_1 (struct captured_main_args *context) && symarg != NULL && strcmp (execarg, symarg) == 0) { + catch_command_errors_const_ftype *func; + + /* Call exec_or_core_file_attach only if the file was specified as + a command line argument (and not an a command line option). */ + if (corearg != NULL && strcmp (corearg, execarg) == 0) + { + func = exec_or_core_file_attach; + corearg = NULL; + } + else + func = exec_file_attach; + /* The exec file and the symbol-file are the same. If we can't open it, better only print one error message. catch_command_errors returns non-zero on success! */ - ret = catch_command_errors (exec_file_attach, execarg, - !batch_flag); - if (ret != 0) + ret = catch_command_errors (func, execarg, !batch_flag); + if (ret != 0 && core_bfd == NULL) ret = catch_command_errors (symbol_file_add_main_adapter, symarg, !batch_flag); } @@ -1076,7 +1149,9 @@ captured_main_1 (struct captured_main_args *context) { ret = catch_command_errors (attach_command, pid_or_core_arg, !batch_flag); - if (ret == 0) + /* attach_command could succeed partially and core_file_command + core_file_command would try to kill it. */ + if (ret == 0 && !have_inferiors ()) ret = catch_command_errors (core_file_command, pid_or_core_arg, !batch_flag); @@ -1143,7 +1218,8 @@ captured_main_1 (struct captured_main_args *context) /* Read in the old history after all the command files have been read. */ - init_history (); + if (!python_script) + init_history (); if (batch_flag) { @@ -1159,22 +1235,35 @@ static void captured_main (void *data) { struct captured_main_args *context = (struct captured_main_args *) data; + int python_script = 0; - captured_main_1 (context); + captured_main_1 (context, python_script); - /* NOTE: cagney/1999-11-07: There is probably no reason for not - moving this loop and the code found in captured_command_loop() - into the command_loop() proper. The main thing holding back that - change - SET_TOP_LEVEL() - has been eliminated. */ - while (1) +#if HAVE_PYTHON + if (python_script) { - try - { - captured_command_loop (); - } - catch (const gdb_exception &ex) + extern int pagination_enabled; + pagination_enabled = 0; + run_python_script (context->argc - optind, &context->argv[optind]); + return; + } + else +#endif + { + /* NOTE: cagney/1999-11-07: There is probably no reason for not + moving this loop and the code found in captured_command_loop() + into the command_loop() proper. The main thing holding back that + change - SET_TOP_LEVEL() - has been eliminated. */ + while (1) { - exception_print (gdb_stderr, ex); + try + { + captured_command_loop (); + } + catch (const gdb_exception &ex) + { + exception_print (gdb_stderr, ex); + } } } /* No exit -- exit is through quit_command. */ @@ -1217,6 +1306,12 @@ print_gdb_help (struct ui_file *stream) fputs_unfiltered (_("\ This is the GNU debugger. Usage:\n\n\ gdb [options] [executable-file [core-file or process-id]]\n\ + gdb [options] --args executable-file [inferior-arguments ...]\n"), stream); +#if HAVE_PYTHON + fputs_unfiltered (_("\ + gdb [options] [--python|-P] script-file [script-arguments ...]\n"), stream); +#endif + fputs_unfiltered (_("\n\ gdb [options] --args executable-file [inferior-arguments ...]\n\n\ "), stream); fputs_unfiltered (_("\ @@ -1262,6 +1357,13 @@ Output and user interface control:\n\n\ #endif fputs_unfiltered (_("\ --dbx DBX compatibility mode.\n\ +"), stream); +#if HAVE_PYTHON + fputs_unfiltered (_("\ + --python, -P Following argument is Python script file; remaining\n\ + arguments are passed to script.\n"), stream); +#endif + fputs_unfiltered (_("\ -q, --quiet, --silent\n\ Do not print version number on startup.\n\n\ "), stream); diff --git a/gdb/memrange.c b/gdb/memrange.c index 0f999815c54..9e0dc576210 100644 --- a/gdb/memrange.c +++ b/gdb/memrange.c @@ -22,8 +22,8 @@ #include int -mem_ranges_overlap (CORE_ADDR start1, int len1, - CORE_ADDR start2, int len2) +mem_ranges_overlap (CORE_ADDR start1, LONGEST len1, + CORE_ADDR start2, LONGEST len2) { ULONGEST h, l; diff --git a/gdb/memrange.h b/gdb/memrange.h index d751d3cf230..0afe0c8f8b4 100644 --- a/gdb/memrange.h +++ b/gdb/memrange.h @@ -28,7 +28,7 @@ struct mem_range { mem_range () = default; - mem_range (CORE_ADDR start_, int length_) + mem_range (CORE_ADDR start_, LONGEST length_) : start (start_), length (length_) {} @@ -47,14 +47,14 @@ struct mem_range CORE_ADDR start; /* Length of the range. */ - int length; + LONGEST length; }; /* Returns true if the ranges defined by [start1, start1+len1) and [start2, start2+len2) overlap. */ -extern int mem_ranges_overlap (CORE_ADDR start1, int len1, - CORE_ADDR start2, int len2); +extern int mem_ranges_overlap (CORE_ADDR start1, LONGEST len1, + CORE_ADDR start2, LONGEST len2); /* Returns true if ADDR is in RANGE. */ diff --git a/gdb/mep-tdep.c b/gdb/mep-tdep.c index 3288291a461..dbd7e1f7d4e 100644 --- a/gdb/mep-tdep.c +++ b/gdb/mep-tdep.c @@ -2238,7 +2238,7 @@ push_large_arguments (CORE_ADDR sp, int argc, struct value **argv, for (i = 0; i < argc; i++) { - unsigned arg_len = TYPE_LENGTH (value_type (argv[i])); + ULONGEST arg_len = TYPE_LENGTH (value_type (argv[i])); if (arg_len > MEP_GPR_SIZE) { diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c index e68ed1e4da9..fc8750829fb 100644 --- a/gdb/mips-linux-nat.c +++ b/gdb/mips-linux-nat.c @@ -610,7 +610,7 @@ mips_linux_nat_target::stopped_data_address (CORE_ADDR *paddr) the specified region can be covered by the watch registers. */ int -mips_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) +mips_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, LONGEST len) { struct pt_watch_regs dummy_regs; int i; diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index f3361388225..b38ffa22710 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -489,7 +489,7 @@ static void mips_xfer_register (struct gdbarch *gdbarch, struct regcache *regcache, int reg_num, int length, enum bfd_endian endian, gdb_byte *in, - const gdb_byte *out, int buf_offset) + const gdb_byte *out, LONGEST buf_offset) { int reg_offset = 0; @@ -512,8 +512,8 @@ mips_xfer_register (struct gdbarch *gdbarch, struct regcache *regcache, } if (mips_debug) fprintf_unfiltered (gdb_stderr, - "xfer $%d, reg offset %d, buf offset %d, length %d, ", - reg_num, reg_offset, buf_offset, length); + "xfer $%d, reg offset %d, buf offset %s, length %d, ", + reg_num, reg_offset, plongest (buf_offset), length); if (mips_debug && out != NULL) { int i; @@ -4563,13 +4563,13 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, gdb_byte ref_valbuf[MAX_MIPS_ABI_REGSIZE]; struct value *arg = args[argnum]; struct type *arg_type = check_typedef (value_type (arg)); - int len = TYPE_LENGTH (arg_type); + LONGEST len = TYPE_LENGTH (arg_type); enum type_code typecode = TYPE_CODE (arg_type); if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_eabi_push_dummy_call: %d len=%d type=%d", - argnum + 1, len, (int) typecode); + "mips_eabi_push_dummy_call: %d len=%s type=%d", + argnum + 1, plongest (len), (int) typecode); /* The EABI passes structures that do not fit in a register by reference. */ @@ -4839,7 +4839,7 @@ mips_eabi_return_value (struct gdbarch *gdbarch, struct value *function, static int mips_n32n64_fp_arg_chunk_p (struct gdbarch *gdbarch, struct type *arg_type, - int offset) + LONGEST offset) { int i; @@ -4854,7 +4854,7 @@ mips_n32n64_fp_arg_chunk_p (struct gdbarch *gdbarch, struct type *arg_type, for (i = 0; i < TYPE_NFIELDS (arg_type); i++) { - int pos; + LONGEST pos; struct type *field_type; /* We're only looking at normal fields. */ @@ -4897,7 +4897,7 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, int argreg; int float_argreg; int argnum; - int arg_space = 0; + LONGEST arg_space = 0; int stack_offset = 0; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = find_function_addr (function, NULL); @@ -5249,11 +5249,11 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, struct value *function, : MIPS_V0_REGNUM); field < TYPE_NFIELDS (type); field++, regnum += 2) { - int offset = (FIELD_BITPOS (TYPE_FIELDS (type)[field]) - / TARGET_CHAR_BIT); + LONGEST offset = (FIELD_BITPOS (TYPE_FIELDS (type)[field]) + / TARGET_CHAR_BIT); if (mips_debug) - fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", - offset); + fprintf_unfiltered (gdb_stderr, "Return float struct+%s\n", + plongest (offset)); if (TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)) == 16) { /* A 16-byte long double field goes in two consecutive @@ -5295,8 +5295,8 @@ mips_n32n64_return_value (struct gdbarch *gdbarch, struct value *function, if (offset + xfer > TYPE_LENGTH (type)) xfer = TYPE_LENGTH (type) - offset; if (mips_debug) - fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n", - offset, xfer, regnum); + fprintf_unfiltered (gdb_stderr, "Return struct+%s:%d in $%d\n", + plongest (offset), xfer, regnum); mips_xfer_register (gdbarch, regcache, gdbarch_num_regs (gdbarch) + regnum, xfer, BFD_ENDIAN_UNKNOWN, readbuf, writebuf, @@ -5355,7 +5355,7 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, int argreg; int float_argreg; int argnum; - int arg_space = 0; + LONGEST arg_space = 0; int stack_offset = 0; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = find_function_addr (function, NULL); @@ -5420,13 +5420,13 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, const gdb_byte *val; struct value *arg = args[argnum]; struct type *arg_type = check_typedef (value_type (arg)); - int len = TYPE_LENGTH (arg_type); + LONGEST len = TYPE_LENGTH (arg_type); enum type_code typecode = TYPE_CODE (arg_type); if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_o32_push_dummy_call: %d len=%d type=%d", - argnum + 1, len, (int) typecode); + "mips_o32_push_dummy_call: %d len=%s type=%d", + argnum + 1, plongest (len), (int) typecode); val = value_contents (arg); @@ -5880,8 +5880,8 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, int argreg; int float_argreg; int argnum; - int arg_space = 0; - int stack_offset = 0; + LONGEST arg_space = 0; + LONGEST stack_offset = 0; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = find_function_addr (function, NULL); @@ -5942,13 +5942,13 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, const gdb_byte *val; struct value *arg = args[argnum]; struct type *arg_type = check_typedef (value_type (arg)); - int len = TYPE_LENGTH (arg_type); + LONGEST len = TYPE_LENGTH (arg_type); enum type_code typecode = TYPE_CODE (arg_type); if (mips_debug) fprintf_unfiltered (gdb_stdlog, - "mips_o64_push_dummy_call: %d len=%d type=%d", - argnum + 1, len, (int) typecode); + "mips_o64_push_dummy_call: %d len=%s type=%d", + argnum + 1, plongest (len), (int) typecode); val = value_contents (arg); diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c index 583827e447d..f1b617f365e 100644 --- a/gdb/mn10300-tdep.c +++ b/gdb/mn10300-tdep.c @@ -1197,7 +1197,7 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch, enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); const int push_size = register_size (gdbarch, E_PC_REGNUM); int regs_used; - int len, arg_len; + LONGEST len, arg_len; int stack_offset = 0; int argnum; const gdb_byte *val; diff --git a/gdb/nat/aarch64-linux-hw-point.c b/gdb/nat/aarch64-linux-hw-point.c index 1efec9a268c..2afe4176d88 100644 --- a/gdb/nat/aarch64-linux-hw-point.c +++ b/gdb/nat/aarch64-linux-hw-point.c @@ -137,7 +137,7 @@ aarch64_point_encode_ctrl_reg (enum target_hw_bp_type type, int offset, int len) Return 0 for any non-compliant ADDR and/or LEN; return 1 otherwise. */ static int -aarch64_point_is_aligned (int is_watchpoint, CORE_ADDR addr, int len) +aarch64_point_is_aligned (int is_watchpoint, CORE_ADDR addr, LONGEST len) { unsigned int alignment = 0; @@ -212,9 +212,10 @@ aarch64_point_is_aligned (int is_watchpoint, CORE_ADDR addr, int len) an address within the latter. */ static void -aarch64_align_watchpoint (CORE_ADDR addr, int len, CORE_ADDR *aligned_addr_p, +aarch64_align_watchpoint (CORE_ADDR addr, LONGEST len, + CORE_ADDR *aligned_addr_p, int *aligned_offset_p, int *aligned_len_p, - CORE_ADDR *next_addr_p, int *next_len_p, + CORE_ADDR *next_addr_p, LONGEST *next_len_p, CORE_ADDR *next_addr_orig_p) { int aligned_len; @@ -602,7 +603,7 @@ aarch64_handle_aligned_watchpoint (enum target_hw_bp_type type, static int aarch64_handle_unaligned_watchpoint (enum target_hw_bp_type type, - CORE_ADDR addr, int len, int is_insert, + CORE_ADDR addr, LONGEST len, int is_insert, struct aarch64_debug_reg_state *state) { CORE_ADDR addr_orig = addr; @@ -632,12 +633,12 @@ aarch64_handle_unaligned_watchpoint (enum target_hw_bp_type type, " " "addr_orig: %s\n" " " - "next_addr: %s, next_len: %d\n" + "next_addr: %s, next_len: %s\n" " " "addr_orig_next: %s\n", is_insert, core_addr_to_string_nz (aligned_addr), aligned_len, core_addr_to_string_nz (addr_orig), - core_addr_to_string_nz (addr), len, + core_addr_to_string_nz (addr), plongest (len), core_addr_to_string_nz (addr_orig_next)); addr_orig = addr_orig_next; @@ -651,7 +652,7 @@ aarch64_handle_unaligned_watchpoint (enum target_hw_bp_type type, int aarch64_handle_watchpoint (enum target_hw_bp_type type, CORE_ADDR addr, - int len, int is_insert, + LONGEST len, int is_insert, struct aarch64_debug_reg_state *state) { if (aarch64_point_is_aligned (1 /* is_watchpoint */ , addr, len)) @@ -733,14 +734,14 @@ aarch64_linux_any_set_debug_regs_state (aarch64_debug_reg_state *state, void aarch64_show_debug_reg_state (struct aarch64_debug_reg_state *state, const char *func, CORE_ADDR addr, - int len, enum target_hw_bp_type type) + LONGEST len, enum target_hw_bp_type type) { int i; debug_printf ("%s", func); if (addr || len) - debug_printf (" (addr=0x%08lx, len=%d, type=%s)", - (unsigned long) addr, len, + debug_printf (" (addr=0x%08lx, len=%s, type=%s)", + (unsigned long) addr, plongest (len), type == hw_write ? "hw-write-watchpoint" : (type == hw_read ? "hw-read-watchpoint" : (type == hw_access ? "hw-access-watchpoint" @@ -823,7 +824,7 @@ aarch64_linux_get_debug_reg_capacity (int tid) ADDR and whose length is LEN in bytes. */ int -aarch64_linux_region_ok_for_watchpoint (CORE_ADDR addr, int len) +aarch64_linux_region_ok_for_watchpoint (CORE_ADDR addr, LONGEST len) { CORE_ADDR aligned_addr; diff --git a/gdb/nat/aarch64-linux-hw-point.h b/gdb/nat/aarch64-linux-hw-point.h index 5d9c2a1c80b..96d85ad7bfb 100644 --- a/gdb/nat/aarch64-linux-hw-point.h +++ b/gdb/nat/aarch64-linux-hw-point.h @@ -176,7 +176,7 @@ int aarch64_handle_breakpoint (enum target_hw_bp_type type, CORE_ADDR addr, int len, int is_insert, struct aarch64_debug_reg_state *state); int aarch64_handle_watchpoint (enum target_hw_bp_type type, CORE_ADDR addr, - int len, int is_insert, + LONGEST len, int is_insert, struct aarch64_debug_reg_state *state); void aarch64_linux_set_debug_regs (struct aarch64_debug_reg_state *state, @@ -189,12 +189,12 @@ bool aarch64_linux_any_set_debug_regs_state (aarch64_debug_reg_state *state, void aarch64_show_debug_reg_state (struct aarch64_debug_reg_state *state, const char *func, CORE_ADDR addr, - int len, enum target_hw_bp_type type); + LONGEST len, enum target_hw_bp_type type); void aarch64_linux_get_debug_reg_capacity (int tid); struct aarch64_debug_reg_state *aarch64_get_debug_reg_state (pid_t pid); -int aarch64_linux_region_ok_for_watchpoint (CORE_ADDR addr, int len); +int aarch64_linux_region_ok_for_watchpoint (CORE_ADDR addr, LONGEST len); #endif /* NAT_AARCH64_LINUX_HW_POINT_H */ diff --git a/gdb/nat/linux-btrace.h b/gdb/nat/linux-btrace.h index df7b0d27c7e..cca04d1aa62 100644 --- a/gdb/nat/linux-btrace.h +++ b/gdb/nat/linux-btrace.h @@ -28,6 +28,177 @@ # include #endif +#ifdef PERF_ATTR_SIZE_VER5_BUNDLE +#ifndef HAVE_LINUX_PERF_EVENT_H +# error "PERF_ATTR_SIZE_VER5_BUNDLE && !HAVE_LINUX_PERF_EVENT_H" +#endif +#ifndef PERF_ATTR_SIZE_VER5 +#define PERF_ATTR_SIZE_VER5 +#define perf_event_mmap_page perf_event_mmap_page_bundle +// kernel-headers-3.10.0-493.el7.x86_64/usr/include/linux/perf_event.h +/* + * Structure of the page that can be mapped via mmap + */ +struct perf_event_mmap_page { + __u32 version; /* version number of this structure */ + __u32 compat_version; /* lowest version this is compat with */ + + /* + * Bits needed to read the hw events in user-space. + * + * u32 seq, time_mult, time_shift, index, width; + * u64 count, enabled, running; + * u64 cyc, time_offset; + * s64 pmc = 0; + * + * do { + * seq = pc->lock; + * barrier() + * + * enabled = pc->time_enabled; + * running = pc->time_running; + * + * if (pc->cap_usr_time && enabled != running) { + * cyc = rdtsc(); + * time_offset = pc->time_offset; + * time_mult = pc->time_mult; + * time_shift = pc->time_shift; + * } + * + * index = pc->index; + * count = pc->offset; + * if (pc->cap_user_rdpmc && index) { + * width = pc->pmc_width; + * pmc = rdpmc(index - 1); + * } + * + * barrier(); + * } while (pc->lock != seq); + * + * NOTE: for obvious reason this only works on self-monitoring + * processes. + */ + __u32 lock; /* seqlock for synchronization */ + __u32 index; /* hardware event identifier */ + __s64 offset; /* add to hardware event value */ + __u64 time_enabled; /* time event active */ + __u64 time_running; /* time event on cpu */ + union { + __u64 capabilities; + struct { + __u64 cap_bit0 : 1, /* Always 0, deprecated, see commit 860f085b74e9 */ + cap_bit0_is_deprecated : 1, /* Always 1, signals that bit 0 is zero */ + + cap_user_rdpmc : 1, /* The RDPMC instruction can be used to read counts */ + cap_user_time : 1, /* The time_* fields are used */ + cap_user_time_zero : 1, /* The time_zero field is used */ + cap_____res : 59; + }; + }; + + /* + * If cap_user_rdpmc this field provides the bit-width of the value + * read using the rdpmc() or equivalent instruction. This can be used + * to sign extend the result like: + * + * pmc <<= 64 - width; + * pmc >>= 64 - width; // signed shift right + * count += pmc; + */ + __u16 pmc_width; + + /* + * If cap_usr_time the below fields can be used to compute the time + * delta since time_enabled (in ns) using rdtsc or similar. + * + * u64 quot, rem; + * u64 delta; + * + * quot = (cyc >> time_shift); + * rem = cyc & (((u64)1 << time_shift) - 1); + * delta = time_offset + quot * time_mult + + * ((rem * time_mult) >> time_shift); + * + * Where time_offset,time_mult,time_shift and cyc are read in the + * seqcount loop described above. This delta can then be added to + * enabled and possible running (if index), improving the scaling: + * + * enabled += delta; + * if (index) + * running += delta; + * + * quot = count / running; + * rem = count % running; + * count = quot * enabled + (rem * enabled) / running; + */ + __u16 time_shift; + __u32 time_mult; + __u64 time_offset; + /* + * If cap_usr_time_zero, the hardware clock (e.g. TSC) can be calculated + * from sample timestamps. + * + * time = timestamp - time_zero; + * quot = time / time_mult; + * rem = time % time_mult; + * cyc = (quot << time_shift) + (rem << time_shift) / time_mult; + * + * And vice versa: + * + * quot = cyc >> time_shift; + * rem = cyc & (((u64)1 << time_shift) - 1); + * timestamp = time_zero + quot * time_mult + + * ((rem * time_mult) >> time_shift); + */ + __u64 time_zero; + __u32 size; /* Header size up to __reserved[] fields. */ + + /* + * Hole for extension of the self monitor capabilities + */ + + __u8 __reserved[118*8+4]; /* align to 1k. */ + + /* + * Control data for the mmap() data buffer. + * + * User-space reading the @data_head value should issue an smp_rmb(), + * after reading this value. + * + * When the mapping is PROT_WRITE the @data_tail value should be + * written by userspace to reflect the last read data, after issueing + * an smp_mb() to separate the data read from the ->data_tail store. + * In this case the kernel will not over-write unread data. + * + * See perf_output_put_handle() for the data ordering. + * + * data_{offset,size} indicate the location and size of the perf record + * buffer within the mmapped area. + */ + __u64 data_head; /* head in the data section */ + __u64 data_tail; /* user-space written tail */ + __u64 data_offset; /* where the buffer starts */ + __u64 data_size; /* data buffer size */ + + /* + * AUX area is defined by aux_{offset,size} fields that should be set + * by the userspace, so that + * + * aux_offset >= data_offset + data_size + * + * prior to mmap()ing it. Size of the mmap()ed area should be aux_size. + * + * Ring buffer pointers aux_{head,tail} have the same semantics as + * data_{head,tail} and same ordering rules apply. + */ + __u64 aux_head; + __u64 aux_tail; + __u64 aux_offset; + __u64 aux_size; +}; +#endif // PERF_ATTR_SIZE_VER5 +#endif // PERF_ATTR_SIZE_VER5_BUNDLE + struct target_ops; #if HAVE_LINUX_PERF_EVENT_H diff --git a/gdb/nat/linux-ptrace.c b/gdb/nat/linux-ptrace.c index 40919f77d72..e59083ed128 100644 --- a/gdb/nat/linux-ptrace.c +++ b/gdb/nat/linux-ptrace.c @@ -25,6 +25,10 @@ #include #endif +#ifdef HAVE_SELINUX_SELINUX_H +# include +#endif /* HAVE_SELINUX_SELINUX_H */ + /* Stores the ptrace options supported by the running kernel. A value of -1 means we did not check for features yet. A value of 0 means there are no supported features. */ @@ -50,6 +54,8 @@ linux_ptrace_attach_fail_reason (pid_t pid) "terminated"), (int) pid); + result += linux_ptrace_create_warnings (); + return result; } @@ -586,6 +592,25 @@ linux_ptrace_init_warnings (void) linux_ptrace_test_ret_to_nx (); } +/* Print all possible reasons we could fail to create a traced process. */ + +std::string +linux_ptrace_create_warnings () +{ + std::string result; + +#ifdef HAVE_LIBSELINUX + /* -1 is returned for errors, 0 if it has no effect, 1 if PTRACE_ATTACH is + forbidden. */ + if (security_get_boolean_active ("deny_ptrace") == 1) + string_appendf (result, + _("the SELinux boolean 'deny_ptrace' is enabled, " + "you can disable this process attach protection by: " + "(gdb) shell sudo setsebool deny_ptrace=0\n")); +#endif /* HAVE_LIBSELINUX */ + return result; +} + /* Extract extended ptrace event from wait status. */ int diff --git a/gdb/nat/linux-ptrace.h b/gdb/nat/linux-ptrace.h index cfb12178a42..8ebe580a6d2 100644 --- a/gdb/nat/linux-ptrace.h +++ b/gdb/nat/linux-ptrace.h @@ -184,6 +184,7 @@ extern std::string linux_ptrace_attach_fail_reason (pid_t pid); extern std::string linux_ptrace_attach_fail_reason_string (ptid_t ptid, int err); extern void linux_ptrace_init_warnings (void); +extern std::string linux_ptrace_create_warnings (); extern void linux_check_ptrace_features (void); extern void linux_enable_event_reporting (pid_t pid, int attached); extern void linux_disable_event_reporting (pid_t pid); diff --git a/gdb/nat/x86-dregs.c b/gdb/nat/x86-dregs.c index fb35178965d..b8c489c131a 100644 --- a/gdb/nat/x86-dregs.c +++ b/gdb/nat/x86-dregs.c @@ -380,7 +380,7 @@ x86_remove_aligned_watchpoint (struct x86_debug_reg_state *state, static int x86_handle_nonaligned_watchpoint (struct x86_debug_reg_state *state, - x86_wp_op_t what, CORE_ADDR addr, int len, + x86_wp_op_t what, CORE_ADDR addr, LONGEST len, enum target_hw_bp_type type) { int retval = 0; @@ -548,7 +548,7 @@ x86_dr_remove_watchpoint (struct x86_debug_reg_state *state, int x86_dr_region_ok_for_watchpoint (struct x86_debug_reg_state *state, - CORE_ADDR addr, int len) + CORE_ADDR addr, LONGEST len) { int nregs; diff --git a/gdb/nat/x86-dregs.h b/gdb/nat/x86-dregs.h index e8a2e0099e8..4cdf79fc098 100644 --- a/gdb/nat/x86-dregs.h +++ b/gdb/nat/x86-dregs.h @@ -117,7 +117,7 @@ extern int x86_dr_remove_watchpoint (struct x86_debug_reg_state *state, /* Return non-zero if we can watch a memory region that starts at address ADDR and whose length is LEN bytes. */ extern int x86_dr_region_ok_for_watchpoint (struct x86_debug_reg_state *state, - CORE_ADDR addr, int len); + CORE_ADDR addr, LONGEST len); /* If the inferior has some break/watchpoint that triggered, set the address associated with that break/watchpoint and return true. diff --git a/gdb/objfiles.c b/gdb/objfiles.c index e055365d37e..71a4e6cf23b 100644 --- a/gdb/objfiles.c +++ b/gdb/objfiles.c @@ -849,6 +849,11 @@ objfile_relocate1 (struct objfile *objfile, obj_section_addr (s)); } + /* Final call of breakpoint_re_set can keep breakpoint locations disabled if + their addresses match. */ + if (objfile->separate_debug_objfile_backlink == NULL) + breakpoints_relocate (objfile, delta); + /* Data changed. */ return 1; } diff --git a/gdb/objfiles.h b/gdb/objfiles.h index 168f7fc275b..f52e1db130e 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -618,6 +618,10 @@ struct objfile htab_t static_links {}; }; +/* This file was loaded according to the BUILD_ID_CORE_LOADS rules. */ + +#define OBJF_BUILD_ID_CORE_LOADED static_cast(1 << 12) + /* Declarations for functions defined in objfiles.c */ extern struct gdbarch *get_objfile_arch (const struct objfile *); diff --git a/gdb/opencl-lang.c b/gdb/opencl-lang.c index c1ea66eea39..b124a6f11f8 100644 --- a/gdb/opencl-lang.c +++ b/gdb/opencl-lang.c @@ -76,11 +76,11 @@ builtin_opencl_type (struct gdbarch *gdbarch) static struct type * lookup_opencl_vector_type (struct gdbarch *gdbarch, enum type_code code, - unsigned int el_length, unsigned int flag_unsigned, + ULONGEST el_length, unsigned int flag_unsigned, int n) { int i; - unsigned int length; + ULONGEST length; struct type *type = NULL; struct type **types = builtin_opencl_type (gdbarch); @@ -172,7 +172,7 @@ lval_func_read (struct value *v) struct type *eltype = TYPE_TARGET_TYPE (check_typedef (value_type (c->val))); LONGEST offset = value_offset (v); LONGEST elsize = TYPE_LENGTH (eltype); - int n, i, j = 0; + LONGEST n, i, j = 0; LONGEST lowb = 0; LONGEST highb = 0; @@ -201,7 +201,7 @@ lval_func_write (struct value *v, struct value *fromval) struct type *eltype = TYPE_TARGET_TYPE (check_typedef (value_type (c->val))); LONGEST offset = value_offset (v); LONGEST elsize = TYPE_LENGTH (eltype); - int n, i, j = 0; + LONGEST n, i, j = 0; LONGEST lowb = 0; LONGEST highb = 0; @@ -241,17 +241,17 @@ lval_func_write (struct value *v, struct value *fromval) static int lval_func_check_synthetic_pointer (const struct value *v, - LONGEST offset, int length) + LONGEST offset, LONGEST length) { struct lval_closure *c = (struct lval_closure *) value_computed_closure (v); /* Size of the target type in bits. */ - int elsize = + LONGEST elsize = TYPE_LENGTH (TYPE_TARGET_TYPE (check_typedef (value_type (c->val)))) * 8; - int startrest = offset % elsize; - int start = offset / elsize; - int endrest = (offset + length) % elsize; - int end = (offset + length) / elsize; - int i; + LONGEST startrest = offset % elsize; + LONGEST start = offset / elsize; + LONGEST endrest = (offset + length) % elsize; + LONGEST end = (offset + length) / elsize; + LONGEST i; if (endrest) end++; @@ -261,8 +261,8 @@ lval_func_check_synthetic_pointer (const struct value *v, for (i = start; i < end; i++) { - int comp_offset = (i == start) ? startrest : 0; - int comp_length = (i == end) ? endrest : elsize; + LONGEST comp_offset = (i == start) ? startrest : 0; + LONGEST comp_length = (i == end) ? endrest : elsize; if (!value_bits_synthetic_pointer (c->val, c->indices[i] * elsize + comp_offset, diff --git a/gdb/p-lang.c b/gdb/p-lang.c index 9340861761b..873c7024fc7 100644 --- a/gdb/p-lang.c +++ b/gdb/p-lang.c @@ -93,8 +93,8 @@ pascal_main_name (void) are not multiple of TARGET_CHAR_BIT then the results are wrong but this does not happen for Free Pascal nor for GPC. */ int -is_pascal_string_type (struct type *type,int *length_pos, - int *length_size, int *string_pos, +is_pascal_string_type (struct type *type, LONGEST *length_pos, + LONGEST *length_size, LONGEST *string_pos, struct type **char_type, const char **arrayname) { @@ -214,12 +214,12 @@ pascal_printchar (int c, struct type *type, struct ui_file *stream) void pascal_printstr (struct ui_file *stream, struct type *type, - const gdb_byte *string, unsigned int length, + const gdb_byte *string, ULONGEST length, const char *encoding, int force_ellipses, const struct value_print_options *options) { enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); - unsigned int i; + ULONGEST i; unsigned int things_printed = 0; int in_quotes = 0; int need_comma = 0; @@ -247,9 +247,9 @@ pascal_printstr (struct ui_file *stream, struct type *type, { /* Position of the character we are examining to see whether it is repeated. */ - unsigned int rep1; + ULONGEST rep1; /* Number of repetitions we have detected so far. */ - unsigned int reps; + ULONGEST reps; unsigned long int current_char; QUIT; @@ -281,7 +281,7 @@ pascal_printstr (struct ui_file *stream, struct type *type, in_quotes = 0; } pascal_printchar (current_char, type, stream); - fprintf_filtered (stream, " ", reps); + fprintf_filtered (stream, " ", pulongest (reps)); i = rep1 - 1; things_printed += options->repeat_count_threshold; need_comma = 1; diff --git a/gdb/p-lang.h b/gdb/p-lang.h index 7d1d285bd94..8ce518c2122 100644 --- a/gdb/p-lang.h +++ b/gdb/p-lang.h @@ -37,7 +37,7 @@ extern void pascal_print_type (struct type *, const char *, struct ui_file *, extern void pascal_print_typedef (struct type *, struct symbol *, struct ui_file *); -extern void pascal_val_print (struct type *, int, +extern void pascal_val_print (struct type *, LONGEST, CORE_ADDR, struct ui_file *, int, struct value *, const struct value_print_options *); @@ -51,13 +51,13 @@ extern void pascal_type_print_method_args (const char *, const char *, /* These are in p-lang.c: */ extern int - is_pascal_string_type (struct type *, int *, int *, int *, + is_pascal_string_type (struct type *, LONGEST *, LONGEST *, LONGEST *, struct type **, const char **); extern void pascal_printchar (int, struct type *, struct ui_file *); extern void pascal_printstr (struct ui_file *, struct type *, const gdb_byte *, - unsigned int, const char *, int, + ULONGEST, const char *, int, const struct value_print_options *); extern struct type **const pascal_builtin_types[]; diff --git a/gdb/p-valprint.c b/gdb/p-valprint.c index 62679ac4445..238cb942bb2 100644 --- a/gdb/p-valprint.c +++ b/gdb/p-valprint.c @@ -60,7 +60,7 @@ static const struct generic_val_print_decorations p_decorations = void pascal_val_print (struct type *type, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *original_value, const struct value_print_options *options) @@ -70,8 +70,8 @@ pascal_val_print (struct type *type, unsigned int i = 0; /* Number of characters printed */ unsigned len; struct type *elttype; - unsigned eltlen; - int length_pos, length_size, string_pos; + ULONGEST eltlen; + LONGEST length_pos, length_size, string_pos; struct type *char_type; CORE_ADDR addr; int want_space = 0; @@ -771,6 +771,7 @@ pascal_object_print_value (struct type *type, const gdb_byte *valaddr, if (boffset < 0 || boffset >= TYPE_LENGTH (type)) { + ulongest_fits_host_or_error (TYPE_LENGTH (baseclass)); buf.resize (TYPE_LENGTH (baseclass)); base_valaddr = buf.data (); diff --git a/gdb/parse.c b/gdb/parse.c index 3e02057bf7b..08de53ae0b6 100644 --- a/gdb/parse.c +++ b/gdb/parse.c @@ -939,24 +939,20 @@ operator_length_standard (const struct expression *expr, int endpos, case OP_RANGE: oplen = 3; + args = 0; range_type = (enum range_type) longest_to_int (expr->elts[endpos - 2].longconst); - switch (range_type) - { - case LOW_BOUND_DEFAULT: - case LOW_BOUND_DEFAULT_EXCLUSIVE: - case HIGH_BOUND_DEFAULT: - args = 1; - break; - case BOTH_BOUND_DEFAULT: - args = 0; - break; - case NONE_BOUND_DEFAULT: - case NONE_BOUND_DEFAULT_EXCLUSIVE: - args = 2; - break; - } + /* Increment the argument counter for each argument + provided by the user. */ + if ((range_type & SUBARRAY_LOW_BOUND) == SUBARRAY_LOW_BOUND) + args++; + + if ((range_type & SUBARRAY_HIGH_BOUND) == SUBARRAY_HIGH_BOUND) + args++; + + if ((range_type & SUBARRAY_STRIDE) == SUBARRAY_STRIDE) + args++; break; diff --git a/gdb/ppc-linux-nat.c b/gdb/ppc-linux-nat.c index 628e3d5e8f6..c7421366f83 100644 --- a/gdb/ppc-linux-nat.c +++ b/gdb/ppc-linux-nat.c @@ -285,7 +285,7 @@ struct ppc_linux_nat_target final : public linux_nat_target int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override; - int region_ok_for_hw_watchpoint (CORE_ADDR, int) override; + int region_ok_for_hw_watchpoint (CORE_ADDR, LONGEST) override; int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, struct expression *) override; @@ -303,9 +303,9 @@ struct ppc_linux_nat_target final : public linux_nat_target bool stopped_data_address (CORE_ADDR *) override; - bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override; + bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, LONGEST) override; - bool can_accel_watchpoint_condition (CORE_ADDR, int, int, struct expression *) + bool can_accel_watchpoint_condition (CORE_ADDR, LONGEST, int, struct expression *) override; int masked_watch_num_registers (CORE_ADDR, CORE_ADDR) override; @@ -1692,7 +1692,7 @@ ppc_linux_nat_target::can_use_hw_breakpoint (enum bptype type, int cnt, int ot) } int -ppc_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) +ppc_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, LONGEST len) { /* Handle sub-8-byte quantities. */ if (len <= 0) @@ -2041,11 +2041,11 @@ can_use_watchpoint_cond_accel (void) CONDITION_VALUE will hold the value which should be put in the DVC register. */ static void -calculate_dvc (CORE_ADDR addr, int len, CORE_ADDR data_value, +calculate_dvc (CORE_ADDR addr, LONGEST len, CORE_ADDR data_value, uint32_t *condition_mode, uint64_t *condition_value) { - int i, num_byte_enable, align_offset, num_bytes_off_dvc, - rightmost_enabled_byte; + LONGEST i, num_byte_enable; + int align_offset, num_bytes_off_dvc, rightmost_enabled_byte; CORE_ADDR addr_end_data, addr_end_dvc; /* The DVC register compares bytes within fixed-length windows which @@ -2133,7 +2133,7 @@ num_memory_accesses (const std::vector &chain) of the constant. */ static int check_condition (CORE_ADDR watch_addr, struct expression *cond, - CORE_ADDR *data_value, int *len) + CORE_ADDR *data_value, LONGEST *len) { int pc = 1, num_accesses_left, num_accesses_right; struct value *left_val, *right_val; @@ -2184,7 +2184,8 @@ check_condition (CORE_ADDR watch_addr, struct expression *cond, the condition expression, thus only triggering the watchpoint when it is true. */ bool -ppc_linux_nat_target::can_accel_watchpoint_condition (CORE_ADDR addr, int len, +ppc_linux_nat_target::can_accel_watchpoint_condition (CORE_ADDR addr, + LONGEST len, int rw, struct expression *cond) { @@ -2202,7 +2203,7 @@ ppc_linux_nat_target::can_accel_watchpoint_condition (CORE_ADDR addr, int len, static void create_watchpoint_request (struct ppc_hw_breakpoint *p, CORE_ADDR addr, - int len, enum target_hw_bp_type type, + LONGEST len, enum target_hw_bp_type type, struct expression *cond, int insert) { if (len == 1 @@ -2468,7 +2469,7 @@ ppc_linux_nat_target::stopped_by_watchpoint () bool ppc_linux_nat_target::watchpoint_addr_within_range (CORE_ADDR addr, CORE_ADDR start, - int length) + LONGEST length) { int mask; diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c index 82277a03f89..1e95959d062 100644 --- a/gdb/ppc-linux-tdep.c +++ b/gdb/ppc-linux-tdep.c @@ -2259,7 +2259,7 @@ ppc_init_linux_record_tdep (struct linux_record_tdep *record_tdep, const struct floatformat ** ppc_floatformat_for_type (struct gdbarch *gdbarch, - const char *name, int len) + const char *name, LONGEST len) { if (len == 128 && name) { diff --git a/gdb/ppc-sysv-tdep.c b/gdb/ppc-sysv-tdep.c index 22757c2472a..493f1f8f0fe 100644 --- a/gdb/ppc-sysv-tdep.c +++ b/gdb/ppc-sysv-tdep.c @@ -69,7 +69,7 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int opencl_abi = ppc_sysv_use_opencl_abi (value_type (function)); ULONGEST saved_sp; - int argspace = 0; /* 0 is an initial wrong guess. */ + LONGEST argspace = 0; /* 0 is an initial wrong guess. */ int write_pass; gdb_assert (tdep->wordsize == 4); @@ -100,9 +100,9 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Next available vector register for vector arguments. */ int vreg = 2; /* Arguments start above the "LR save word" and "Back chain". */ - int argoffset = 2 * tdep->wordsize; + LONGEST argoffset = 2 * tdep->wordsize; /* Structures start after the arguments. */ - int structoffset = argoffset + argspace; + LONGEST structoffset = argoffset + argspace; /* If the function is returning a `struct', then the first word (which will be passed in r3) is used for struct return @@ -121,7 +121,7 @@ ppc_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, { struct value *arg = args[argno]; struct type *type = check_typedef (value_type (arg)); - int len = TYPE_LENGTH (type); + ssize_t len = TYPE_LENGTH (type); const bfd_byte *val = value_contents (arg); if (TYPE_CODE (type) == TYPE_CODE_FLT && len <= 8 @@ -1247,11 +1247,11 @@ struct ppc64_sysv_argpos static void ppc64_sysv_abi_push_val (struct gdbarch *gdbarch, - const bfd_byte *val, int len, int align, + const bfd_byte *val, ssize_t len, int align, struct ppc64_sysv_argpos *argpos) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - int offset = 0; + LONGEST offset = 0; /* Enforce alignment of stack location, if requested. */ if (align > tdep->wordsize) @@ -1288,7 +1288,7 @@ ppc64_sysv_abi_push_val (struct gdbarch *gdbarch, { if (argpos->regcache && argpos->greg <= 10) argpos->regcache->cooked_write_part - (tdep->ppc_gp0_regnum + argpos->greg, offset, len, val); + (tdep->ppc_gp0_regnum + argpos->greg, offset, (LONGEST) len, val); argpos->greg++; } } @@ -1347,7 +1347,7 @@ ppc64_sysv_abi_push_freg (struct gdbarch *gdbarch, if (argpos->regcache && argpos->freg <= 13) { int regnum = tdep->ppc_fp0_regnum + argpos->freg; - int offset = 0; + LONGEST offset = 0; if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) offset = 8 - TYPE_LENGTH (type); @@ -1797,7 +1797,7 @@ ppc64_sysv_abi_return_value_base (struct gdbarch *gdbarch, struct type *valtype, && TYPE_CODE (valtype) == TYPE_CODE_DECFLOAT) { int regnum = tdep->ppc_fp0_regnum + 1 + index; - int offset = 0; + LONGEST offset = 0; if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) offset = 8 - TYPE_LENGTH (valtype); @@ -1873,7 +1873,7 @@ ppc64_sysv_abi_return_value_base (struct gdbarch *gdbarch, struct type *valtype, && TYPE_CODE (valtype) == TYPE_CODE_ARRAY && TYPE_VECTOR (valtype)) { int regnum = tdep->ppc_gp0_regnum + 3 + index; - int offset = 0; + LONGEST offset = 0; if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) offset = 8 - TYPE_LENGTH (valtype); @@ -1981,7 +1981,8 @@ ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct value *function, && TYPE_LENGTH (TYPE_TARGET_TYPE (valtype)) == 1) { int regnum = tdep->ppc_gp0_regnum + 3; - int offset = (register_size (gdbarch, regnum) - TYPE_LENGTH (valtype)); + LONGEST offset + = (register_size (gdbarch, regnum) - TYPE_LENGTH (valtype)); if (writebuf != NULL) regcache->cooked_write_part (regnum, offset, TYPE_LENGTH (valtype), diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 9e84594fe68..a8ae7f5b9a7 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -276,7 +276,7 @@ print_formatted (struct value *val, int size, struct ui_file *stream) { struct type *type = check_typedef (value_type (val)); - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); if (VALUE_LVAL (val) == lval_memory) next_address = value_address (val) + len; @@ -352,7 +352,7 @@ print_scalar_formatted (const gdb_byte *valaddr, struct type *type, int size, struct ui_file *stream) { struct gdbarch *gdbarch = get_type_arch (type); - unsigned int len = TYPE_LENGTH (type); + ULONGEST len = TYPE_LENGTH (type); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* String printing should go through val_print_scalar_formatted. */ @@ -588,6 +588,14 @@ build_address_symbolic (struct gdbarch *gdbarch, addr = overlay_mapped_address (addr, section); } } + /* To ensure that the symbol returned belongs to the correct setion + (and that the last [random] symbol from the previous section + isn't returned) try to find the section containing PC. First try + the overlay code (which by default returns NULL); and second try + the normal section code (which almost always succeeds). */ + section = find_pc_overlay (addr); + if (section == NULL) + section = find_pc_section (addr); /* First try to find the address in the symbol table, then in the minsyms. Take the closest one. */ @@ -1182,6 +1190,10 @@ print_command_1 (const char *exp, int voidprint) if (exp && *exp) { + /* '*((int *(*) (void)) __errno_location) ()' is incompatible with + function descriptors. */ + if (target_has_execution && strcmp (exp, "errno") == 0) + exp = "*(*(int *(*)(void)) __errno_location) ()"; expression_up expr = parse_expression (exp); val = evaluate_expression (expr.get ()); } diff --git a/gdb/proc-service.list b/gdb/proc-service.list index 60b8cc8232d..2113fa299f4 100644 --- a/gdb/proc-service.list +++ b/gdb/proc-service.list @@ -37,4 +37,7 @@ ps_pstop; ps_ptread; ps_ptwrite; + + /* gdb-6.6-buildid-locate-rpm.patch */ + rpmsqEnable; }; diff --git a/gdb/procfs.c b/gdb/procfs.c index 020336e5ba4..c77094852de 100644 --- a/gdb/procfs.c +++ b/gdb/procfs.c @@ -1546,7 +1546,7 @@ procfs_address_to_host_pointer (CORE_ADDR addr) } static int -proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, int len, int wflags) +proc_set_watchpoint (procinfo *pi, CORE_ADDR addr, LONGEST len, int wflags) { struct { procfs_ctl_t cmd; @@ -3232,7 +3232,7 @@ procfs_target::pid_to_exec_file (int pid) /* Insert a watchpoint. */ static int -procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, int len, int rwflag, +procfs_set_watchpoint (ptid_t ptid, CORE_ADDR addr, LONGEST len, int rwflag, int after) { int pflags = 0; @@ -3368,7 +3368,7 @@ procfs_target::remove_watchpoint (CORE_ADDR addr, int len, } int -procfs_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) +procfs_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, LONGEST len) { /* The man page for proc(4) on Solaris 2.6 and up says that the system can support "thousands" of hardware watchpoints, but gives diff --git a/gdb/python/lib/gdb/FrameWrapper.py b/gdb/python/lib/gdb/FrameWrapper.py new file mode 100644 index 00000000000..34ba4a2a12e --- /dev/null +++ b/gdb/python/lib/gdb/FrameWrapper.py @@ -0,0 +1,122 @@ +# Wrapper API for frames. + +# Copyright (C) 2008, 2009 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 . + +import gdb + +# FIXME: arguably all this should be on Frame somehow. +class FrameWrapper: + def __init__ (self, frame): + self.frame = frame; + + def write_symbol (self, stream, sym, block): + if len (sym.linkage_name): + nsym, is_field_of_this = gdb.lookup_symbol (sym.linkage_name, block) + if nsym.addr_class != gdb.SYMBOL_LOC_REGISTER: + sym = nsym + + stream.write (sym.print_name + "=") + try: + val = self.read_var (sym) + if val != None: + val = str (val) + # FIXME: would be nice to have a more precise exception here. + except RuntimeError as text: + val = text + if val == None: + stream.write ("???") + else: + stream.write (str (val)) + + def print_frame_locals (self, stream, func): + + try: + block = self.frame.block() + except RuntimeError: + block = None + + while block != None: + if block.is_global or block.is_static: + break + + for sym in block: + if sym.is_argument: + continue; + + self.write_symbol (stream, sym, block) + stream.write ('\n') + + def print_frame_args (self, stream, func): + + try: + block = self.frame.block() + except RuntimeError: + block = None + + while block != None: + if block.function != None: + break + block = block.superblock + + first = True + for sym in block: + if not sym.is_argument: + continue; + + if not first: + stream.write (", ") + + self.write_symbol (stream, sym, block) + first = False + + # FIXME: this should probably just be a method on gdb.Frame. + # But then we need stream wrappers. + def describe (self, stream, full): + if self.type () == gdb.DUMMY_FRAME: + stream.write (" \n") + elif self.type () == gdb.SIGTRAMP_FRAME: + stream.write (" \n") + else: + sal = self.find_sal () + pc = self.pc () + name = self.name () + if not name: + name = "??" + if pc != sal.pc or not sal.symtab: + stream.write (" 0x%08x in" % pc) + stream.write (" " + name + " (") + + func = self.function () + self.print_frame_args (stream, func) + + stream.write (")") + + if sal.symtab and sal.symtab.filename: + stream.write (" at " + sal.symtab.filename) + stream.write (":" + str (sal.line)) + + if not self.name () or (not sal.symtab or not sal.symtab.filename): + lib = gdb.solib_name (pc) + if lib: + stream.write (" from " + lib) + + stream.write ("\n") + + if full: + self.print_frame_locals (stream, func) + + def __getattr__ (self, name): + return getattr (self.frame, name) diff --git a/gdb/python/lib/gdb/backtrace.py b/gdb/python/lib/gdb/backtrace.py new file mode 100644 index 00000000000..06c893f2395 --- /dev/null +++ b/gdb/python/lib/gdb/backtrace.py @@ -0,0 +1,42 @@ +# Filtering backtrace. + +# Copyright (C) 2008, 2011 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 . + +import gdb +import itertools + +# Our only exports. +__all__ = ['push_frame_filter', 'create_frame_filter'] + +old_frame_filter = None + +def push_frame_filter (constructor): + """Register a new backtrace filter class with the 'backtrace' command. +The filter will be passed an iterator as an argument. The iterator +will return gdb.Frame-like objects. The filter should in turn act as +an iterator returning such objects.""" + global old_frame_filter + if old_frame_filter == None: + old_frame_filter = constructor + else: + old_frame_filter = lambda iterator, filter = frame_filter: constructor (filter(iterator)) + +def create_frame_filter (iter): + global old_frame_filter + if old_frame_filter is None: + return iter + return old_frame_filter (iter) + diff --git a/gdb/python/lib/gdb/command/backtrace.py b/gdb/python/lib/gdb/command/backtrace.py new file mode 100644 index 00000000000..eeea9093e83 --- /dev/null +++ b/gdb/python/lib/gdb/command/backtrace.py @@ -0,0 +1,106 @@ +# New backtrace command. + +# Copyright (C) 2008, 2009, 2011 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 . + +import gdb +import gdb.backtrace +import itertools +from gdb.FrameIterator import FrameIterator +from gdb.FrameWrapper import FrameWrapper +import sys + +class ReverseBacktraceParameter (gdb.Parameter): + """The new-backtrace command can show backtraces in 'reverse' order. +This means that the innermost frame will be printed last. +Note that reverse backtraces are more expensive to compute.""" + + set_doc = "Enable or disable reverse backtraces." + show_doc = "Show whether backtraces will be printed in reverse order." + + def __init__(self): + gdb.Parameter.__init__ (self, "reverse-backtrace", + gdb.COMMAND_STACK, gdb.PARAM_BOOLEAN) + # Default to compatibility with gdb. + self.value = False + +class FilteringBacktrace (gdb.Command): + """Print backtrace of all stack frames, or innermost COUNT frames. +With a negative argument, print outermost -COUNT frames. +Use of the 'full' qualifier also prints the values of the local variables. +Use of the 'raw' qualifier avoids any filtering by loadable modules. +""" + + def __init__ (self): + # FIXME: this is not working quite well enough to replace + # "backtrace" yet. + gdb.Command.__init__ (self, "new-backtrace", gdb.COMMAND_STACK) + self.reverse = ReverseBacktraceParameter() + + def reverse_iter (self, iter): + result = [] + for item in iter: + result.append (item) + result.reverse() + return result + + def final_n (self, iter, x): + result = [] + for item in iter: + result.append (item) + return result[x:] + + def invoke (self, arg, from_tty): + i = 0 + count = 0 + filter = True + full = False + + for word in arg.split (" "): + if word == '': + continue + elif word == 'raw': + filter = False + elif word == 'full': + full = True + else: + count = int (word) + + # FIXME: provide option to start at selected frame + # However, should still number as if starting from newest + newest_frame = gdb.newest_frame() + iter = itertools.imap (FrameWrapper, + FrameIterator (newest_frame)) + if filter: + iter = gdb.backtrace.create_frame_filter (iter) + + # Now wrap in an iterator that numbers the frames. + iter = itertools.izip (itertools.count (0), iter) + + # Reverse if the user wanted that. + if self.reverse.value: + iter = self.reverse_iter (iter) + + # Extract sub-range user wants. + if count < 0: + iter = self.final_n (iter, count) + elif count > 0: + iter = itertools.islice (iter, 0, count) + + for pair in iter: + sys.stdout.write ("#%-2d" % pair[0]) + pair[1].describe (sys.stdout, full) + +FilteringBacktrace() diff --git a/gdb/python/lib/gdb/command/ignore_errors.py b/gdb/python/lib/gdb/command/ignore_errors.py new file mode 100644 index 00000000000..6fa48ff0816 --- /dev/null +++ b/gdb/python/lib/gdb/command/ignore_errors.py @@ -0,0 +1,37 @@ +# Ignore errors in user commands. + +# Copyright (C) 2008 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 . + +import gdb + +class IgnoreErrorsCommand (gdb.Command): + """Execute a single command, ignoring all errors. +Only one-line commands are supported. +This is primarily useful in scripts.""" + + def __init__ (self): + super (IgnoreErrorsCommand, self).__init__ ("ignore-errors", + gdb.COMMAND_OBSCURE, + # FIXME... + gdb.COMPLETE_COMMAND) + + def invoke (self, arg, from_tty): + try: + gdb.execute (arg, from_tty) + except: + pass + +IgnoreErrorsCommand () diff --git a/gdb/python/lib/gdb/function/in_scope.py b/gdb/python/lib/gdb/function/in_scope.py new file mode 100644 index 00000000000..87426806149 --- /dev/null +++ b/gdb/python/lib/gdb/function/in_scope.py @@ -0,0 +1,47 @@ +# In-scope function. + +# Copyright (C) 2008 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 . + +import gdb + +class InScope (gdb.Function): + """Return True if all the given variables or macros are in scope. +Takes one argument for each variable name to be checked.""" + + def __init__ (self): + super (InScope, self).__init__ ("in_scope") + + def invoke (self, *vars): + if len (vars) == 0: + raise (TypeError, "in_scope takes at least one argument") + + # gdb.Value isn't hashable so it can't be put in a map. + # Convert to string first. + wanted = set (map (lambda x: x.string (), vars)) + found = set () + block = gdb.selected_frame ().block () + while block: + for sym in block: + if (sym.is_argument or sym.is_constant + or sym.is_function or sym.is_variable): + if sym.name in wanted: + found.add (sym.name) + + block = block.superblock + + return wanted == found + +InScope () diff --git a/gdb/python/py-block.c b/gdb/python/py-block.c index 90140ebc34a..9269c2c72f9 100644 --- a/gdb/python/py-block.c +++ b/gdb/python/py-block.c @@ -102,6 +102,115 @@ blpy_iter (PyObject *self) return (PyObject *) block_iter_obj; } + +typedef struct { + PyObject_HEAD + struct mdict_iterator iter; + int finished; + void *value; + PyObject *(*func)(void *); +} DictIter; + +PyObject* DictIter_iter(PyObject *self); +PyObject* DictIter_iter(PyObject *self) +{ + Py_INCREF(self); + return self; +} + +static PyObject *obj_to_sym(void *val) +{ + PyObject *v = symbol_to_symbol_object ((struct symbol*)val); + return v; +} + +PyObject* DictIter_iternext(PyObject *self); +PyObject* DictIter_iternext(PyObject *self) +{ + DictIter *p = (DictIter *)self; + PyObject *v; + void *n; + + if (p->finished == 1) + return NULL; + + v = p->func((struct symbol*)p->value); + + n = mdict_iterator_next(&p->iter); + + if (!n) + p->finished = 1; + else p->value = n; + + return v; +} + +static PyTypeObject DictIterType = { + PyVarObject_HEAD_INIT(NULL, 0) + "gdb._DictIter", /* tp_name */ + sizeof(DictIter), /* tp_basicsize */ + 0, /* tp_itemsize */ + 0, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /* tp_flags */ + "gdb dictionary iterator object.", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + DictIter_iter, /* tp_iter */ + DictIter_iternext, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +static PyObject * +blpy_get_symbols(PyObject *self, void *closure) +{ + PyObject *tmp; + const struct block *block = NULL; + struct symbol *s; + + BLPY_REQUIRE_VALID (self, block); + + tmp = (PyObject*)PyObject_New(DictIter, &DictIterType); + if (!tmp) return NULL; + + if (!PyObject_Init((PyObject *)tmp, &DictIterType)) { + Py_DECREF(tmp); + return NULL; + } + + s = mdict_iterator_first(block->multidict, &((DictIter*)tmp)->iter); + + ((DictIter*)tmp)->value = s; + ((DictIter*)tmp)->func = obj_to_sym; + + return tmp; +} + static PyObject * blpy_get_start (PyObject *self, void *closure) { @@ -399,6 +508,7 @@ gdbpy_initialize_blocks (void) if (PyType_Ready (&block_syms_iterator_object_type) < 0) return -1; + if (PyType_Ready(&DictIterType) < 0) return -1; /* Register an objfile "free" callback so we can properly invalidate blocks when an object file is about to be deleted. */ @@ -423,6 +533,7 @@ Return true if this block is valid, false if not." }, }; static gdb_PyGetSetDef block_object_getset[] = { + { "symbols", blpy_get_symbols, NULL, "Get symbols", NULL }, { "start", blpy_get_start, NULL, "Start address of the block.", NULL }, { "end", blpy_get_end, NULL, "End address of the block.", NULL }, { "function", blpy_get_function, NULL, diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c index 017ea90f619..c7e3d8143dc 100644 --- a/gdb/python/py-framefilter.c +++ b/gdb/python/py-framefilter.c @@ -1138,6 +1138,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang, htab_eq_pointer, NULL)); + int count_printed = 0; while (true) { gdbpy_ref<> item (PyIter_Next (iterable.get ())); @@ -1147,7 +1148,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang, if (PyErr_Occurred ()) { gdbpy_print_stack_or_quit (); - return EXT_LANG_BT_ERROR; + return count_printed > 0 ? EXT_LANG_BT_ERROR : EXT_LANG_BT_NO_FILTERS; } break; } @@ -1180,6 +1181,7 @@ gdbpy_apply_frame_filter (const struct extension_language_defn *extlang, error and continue with other frames. */ if (success == EXT_LANG_BT_ERROR) gdbpy_print_stack_or_quit (); + count_printed++; } return success; diff --git a/gdb/python/py-inferior.c b/gdb/python/py-inferior.c index 984cebb101d..7e323c270e6 100644 --- a/gdb/python/py-inferior.c +++ b/gdb/python/py-inferior.c @@ -29,6 +29,7 @@ #include "common/gdb_signals.h" #include "py-event.h" #include "py-stopevent.h" +#include "py-inferior.h" struct threadlist_entry { thread_object *thread_obj; @@ -375,6 +376,8 @@ delete_thread_object (struct thread_info *tp, int ignore) *entry = (*entry)->next; inf_obj->nthreads--; + del_thread_registers (tmp->thread_obj); + Py_DECREF (tmp->thread_obj); xfree (tmp); } @@ -412,6 +415,109 @@ infpy_threads (PyObject *self, PyObject *args) return tuple; } +static PyObject * +infpy_new_thread (PyObject *self, PyObject *args) +{ + struct inferior *inf; + struct thread_info *info = NULL; + int pid; + long lwp; + long tid; + PyObject *pypriv = Py_None; + + if (!PyArg_ParseTuple(args, "(ill)|O:ptid", + &pid, &lwp, &tid, &pypriv)) + return NULL; + + inf = current_inferior(); + if (inf->pid != 0 && inf->pid != pid) + { + inf = find_inferior_pid (pid); + if (!inf) + inf = current_inferior(); + } + inferior_appeared(inf, pid); + + try + { + ptid_t ptid(pid, lwp, tid); + infpy_thread_info *priv = new infpy_thread_info; + Py_INCREF(pypriv); + priv->object = pypriv; + + info = add_thread_silent(ptid); + info->priv.reset(priv); + + if (inferior_ptid == null_ptid) + inferior_ptid = info->ptid; + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION(except); + } + + return (PyObject *)create_thread_object(info); +} + +static PyObject * +infpy_appeared (PyObject *self, PyObject *args) +{ + inferior_object *inf_obj = (inferior_object *) self; + int pid; + + if (!PyArg_ParseTuple(args, "i:pid", &pid)) + return NULL; + + try + { + inferior_appeared (inf_obj->inferior, pid); + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION(except); + } + + Py_RETURN_NONE; +} + +static PyObject * +infpy_delete_thread (PyObject *self, PyObject *args) +{ + struct thread_info *info = NULL; + int pid; + long lwp; + long tid; + + if (!PyArg_ParseTuple(args, "(ill)|O:ptid", &pid, &lwp, &tid)) + return NULL; + + try + { + ptid_t ptid(pid, lwp, tid); + + info = find_thread_ptid(ptid); + if (!info) + { + PyErr_SetString (PyExc_RuntimeError, _("Thread does not exist.")); + return NULL; + } + + + delete_thread_silent(info); + if (ptid == inferior_ptid) + { + inferior_ptid = null_ptid; + } + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION(except); + } + + Py_RETURN_NONE; +} + + static PyObject * infpy_get_num (PyObject *self, void *closure) { @@ -458,6 +564,54 @@ infpy_get_progspace (PyObject *self, void *closure) return pspace_to_pspace_object (pspace).release (); } +static PyObject * +infpy_get_executing (PyObject *self, void *closure) +{ + inferior_object *inf = (inferior_object *) self; + + INFPY_REQUIRE_VALID (inf); + + try + { + target_update_thread_list (); + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + return PyBool_FromLong(threads_are_executing()); +} + +static int +infpy_set_executing (PyObject *self, PyObject *newvalue, void *ignore) +{ + inferior_object *inf = (inferior_object *) self; + + if (!inf->inferior) + { + PyErr_SetString (PyExc_RuntimeError, _("Inferior no longer exists.")); + return -1; + } + + if (!PyBool_Check (newvalue)) + { + PyErr_SetString (PyExc_TypeError, "requires Bool"); + return -1; + } + + try + { + ptid_t ptid(inf->inferior->pid, 0, 0); + set_executing (ptid, newvalue == Py_True); + } + catch (const gdb_exception &except) + { + GDB_PY_SET_HANDLE_EXCEPTION (except); + } + + return 0; +} + static int build_inferior_list (struct inferior *inf, void *arg) { @@ -934,6 +1088,8 @@ static gdb_PyGetSetDef inferior_object_getset[] = { "was_attached", infpy_get_was_attached, NULL, "True if the inferior was created using 'attach'.", NULL }, { "progspace", infpy_get_progspace, NULL, "Program space of this inferior" }, + { "executing", infpy_get_executing, infpy_set_executing, + "True if there are threads executing." }, { NULL } }; @@ -944,6 +1100,12 @@ static PyMethodDef inferior_object_methods[] = Return true if this inferior is valid, false if not." }, { "threads", infpy_threads, METH_NOARGS, "Return all the threads of this inferior." }, + { "new_thread", infpy_new_thread, METH_VARARGS, + "Adds a new thread to this inferior with optional object(s)" }, + { "delete_thread", infpy_delete_thread, METH_VARARGS, + "Deletes a thread from this inferior" }, + { "appeared", infpy_appeared, METH_VARARGS, + "Informs gdb that a PID has appeared for this inferior." }, { "read_memory", (PyCFunction) infpy_read_memory, METH_VARARGS | METH_KEYWORDS, "read_memory (address, length) -> buffer\n\ diff --git a/gdb/python/py-inferior.h b/gdb/python/py-inferior.h new file mode 100644 index 00000000000..32975d1e84b --- /dev/null +++ b/gdb/python/py-inferior.h @@ -0,0 +1,33 @@ +/* Gdb/Python header for private use by Python module. + + Copyright (C) 2008-2019 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 . */ + +#ifndef PYTHON_PYTHON_INFERIOR_H +#define PYTHON_PYTHON_INFERIOR_H + +#include "python-internal.h" +#include "gdbthread.h" +struct infpy_thread_info : public private_thread_info +{ + PyObject *object; + ~infpy_thread_info() { + Py_DECREF (object); + }; +}; + +#endif /* PYTHON_PYTHON_INFERIOR_H */ diff --git a/gdb/python/py-infthread.c b/gdb/python/py-infthread.c index 8c556f92ea8..f52aa9b5b2e 100644 --- a/gdb/python/py-infthread.c +++ b/gdb/python/py-infthread.c @@ -20,6 +20,7 @@ #include "defs.h" #include "gdbthread.h" #include "inferior.h" +#include "py-inferior.h" #include "python-internal.h" extern PyTypeObject thread_object_type @@ -51,6 +52,7 @@ create_thread_object (struct thread_info *tp) thread_obj->thread = tp; thread_obj->inf_obj = (PyObject *) inf_obj.release (); + thread_obj->register_objs = NULL; return thread_obj; } @@ -286,6 +288,126 @@ thpy_thread_handle (PyObject *self, PyObject *args) return object; } +static PyObject * +thpy_get_registers (PyObject *self, void *closure) +{ + thread_object *thread_obj = (thread_object *) self; + PyObject *d = NULL; + + THPY_REQUIRE_VALID (thread_obj); + + try + { + struct gdbarch *gdbarch; + int i, numregs; + gdbarch = target_gdbarch (); + numregs = gdbarch_num_regs (gdbarch); + + d = PyDict_New(); + for (i = 0; i < numregs; i++) + { + PyObject *reg; + const char *name = gdbarch_register_name (gdbarch, i); + + if (!name || !*name) + continue; + + reg = register_to_register_object (thread_obj, i); + if (!reg) { + Py_DECREF (d); + return NULL; + } + + if (PyDict_SetItemString (d, name, reg)) { + Py_DECREF (reg); + Py_DECREF (d); + return NULL; + } + } + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + + /* Does this leak d? */ + return PyDictProxy_New(d); +} + +static PyObject * +thpy_get_info (PyObject *self, void *closure) +{ + thread_object *obj = (thread_object *) self; + private_thread_info *priv_info; + infpy_thread_info *info; + THPY_REQUIRE_VALID(obj); + + priv_info = obj->thread->priv.get (); + if (!priv_info) + { + Py_INCREF (Py_None); + return Py_None; + } + + info = dynamic_cast(priv_info); + if (!info) + { + PyErr_SetString(PyExc_TypeError, + "thread private data is not available for native targets"); + return NULL; + } + + Py_INCREF(info->object); + return info->object; +} + +static PyObject * +thpy_get_executing (PyObject *self, void *closure) +{ + thread_object *obj = (thread_object *) self; + PyObject *ret = Py_False; + + THPY_REQUIRE_VALID(obj); + + if (obj->thread->executing) + ret = Py_True; + + Py_INCREF(ret); + return ret; +} + +static int +thpy_set_executing (PyObject *self, PyObject *newvalue, void *ignore) +{ + thread_object *thread_obj = (thread_object *) self; + + if (!thread_obj->thread) + { + PyErr_SetString (PyExc_RuntimeError, _("Thread no longer exists.")); + return -1; + } + + if (!PyBool_Check (newvalue)) + { + PyErr_SetString (PyExc_TypeError, "requires Bool"); + return -1; + } + + try + { + /* + * We do a needless search here, but we can't set + * threads_executing directly. + */ + set_executing (thread_obj->thread->ptid, newvalue == Py_True); + } + catch (const gdb_exception &except) + { + GDB_PY_SET_HANDLE_EXCEPTION (except); + } + return 0; +} + /* Return a reference to a new Python object representing a ptid_t. The object is a tuple containing (pid, lwp, tid). */ PyObject * @@ -344,6 +466,9 @@ static gdb_PyGetSetDef thread_object_getset[] = NULL }, { "inferior", thpy_get_inferior, NULL, "The Inferior object this thread belongs to.", NULL }, + { "registers", thpy_get_registers, NULL, "Registers for this thread.", NULL }, + { "info", thpy_get_info, NULL, "Info associated with thread", NULL }, + { "executing", thpy_get_executing, thpy_set_executing, "Execution state of this thread.", NULL }, { NULL } }; diff --git a/gdb/python/py-minsymbol.c b/gdb/python/py-minsymbol.c new file mode 100644 index 00000000000..62966d0c009 --- /dev/null +++ b/gdb/python/py-minsymbol.c @@ -0,0 +1,475 @@ +/* Python interface to minsymbols. + + Copyright (C) 2008-2013 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 . */ + +#include "defs.h" +#include "block.h" +#include "exceptions.h" +#include "frame.h" +#include "symtab.h" +#include "python-internal.h" +#include "objfiles.h" +#include "value.h" + +typedef struct msympy_symbol_object { + PyObject_HEAD + + /* The GDB bound_minimal_symbol structure this object is wrapping. */ + struct bound_minimal_symbol bound; + + /* A minsym object is associated with an objfile, so keep track with + doubly-linked list, rooted in the objfile. This lets us + invalidate the underlying struct minimal_symbol when the objfile is + deleted. */ + struct msympy_symbol_object *prev; + struct msympy_symbol_object *next; +} minsym_object; + +/* Return the symbol that is wrapped by this symbol object. */ +static struct minimal_symbol * +minsym_object_to_minsym (PyObject *obj) +{ + if (! PyObject_TypeCheck (obj, &minsym_object_type)) + return NULL; + return ((minsym_object *) obj)->bound.minsym; +} + +static struct objfile * +minsym_object_to_objfile (PyObject *obj) +{ + if (! PyObject_TypeCheck (obj, &minsym_object_type)) + return NULL; + return ((minsym_object *) obj)->bound.objfile; +} + +/* Require a valid symbol. All access to minsym_object->symbol should be + gated by this call. */ +#define MSYMPY_REQUIRE_VALID(minsym_obj, minsym) \ + do { \ + minsym = minsym_object_to_minsym (minsym_obj); \ + if (minsym == NULL) \ + { \ + PyErr_SetString (PyExc_RuntimeError, \ + _("MinSymbol is invalid.")); \ + return NULL; \ + } \ + } while (0) + +#define MSYMPY_REQUIRE_VALID_BOUND(minsym_obj, minsym, objfile) \ + do { \ + minsym = minsym_object_to_minsym (minsym_obj); \ + objfile = minsym_object_to_objfile (minsym_obj); \ + if (minsym == NULL || objfile == NULL) \ + { \ + PyErr_SetString (PyExc_RuntimeError, \ + _("MinSymbol is invalid.")); \ + return NULL; \ + } \ + } while (0) + +static const struct objfile_data *msympy_objfile_data_key; + +static PyObject * +msympy_str (PyObject *self) +{ + struct minimal_symbol *minsym = NULL; + + MSYMPY_REQUIRE_VALID (self, minsym); + + return PyString_FromString (MSYMBOL_PRINT_NAME (minsym)); +} + +static PyObject * +msympy_get_name (PyObject *self, void *closure) +{ + struct minimal_symbol *minsym = NULL; + + MSYMPY_REQUIRE_VALID (self, minsym); + + return PyString_FromString (MSYMBOL_NATURAL_NAME (minsym)); +} + +static PyObject * +msympy_get_file_name (PyObject *self, void *closure) +{ + struct minimal_symbol *minsym = NULL; + + MSYMPY_REQUIRE_VALID (self, minsym); + + return PyString_FromString (minsym->filename); +} + +static PyObject * +msympy_get_linkage_name (PyObject *self, void *closure) +{ + struct minimal_symbol *minsym = NULL; + + MSYMPY_REQUIRE_VALID (self, minsym); + + return PyString_FromString (MSYMBOL_LINKAGE_NAME (minsym)); +} + +static PyObject * +msympy_get_print_name (PyObject *self, void *closure) +{ + struct minimal_symbol *minsym = NULL; + + MSYMPY_REQUIRE_VALID (self, minsym); + + return msympy_str (self); +} + +static PyObject * +msympy_get_section (PyObject *self, void *closure) +{ + struct minimal_symbol *minsym = NULL; + struct objfile *objfile = NULL; + struct obj_section *section; + const char *name; + + MSYMPY_REQUIRE_VALID_BOUND (self, minsym, objfile); + + section = MSYMBOL_OBJ_SECTION (objfile, minsym); + if (section) { + name = bfd_section_name (objfile->obfd, section->the_bfd_section); + if (name) + return PyString_FromString (name); + } + + Py_RETURN_NONE; +} + +static PyObject * +msympy_get_type (PyObject *self, void *closure) +{ + struct minimal_symbol *minsym = NULL; + + MSYMPY_REQUIRE_VALID (self, minsym); + return PyInt_FromLong(MSYMBOL_TYPE(minsym)); +} + +static PyObject * +msympy_is_valid (PyObject *self, PyObject *args) +{ + struct minimal_symbol *minsym = NULL; + + minsym = minsym_object_to_minsym (self); + if (minsym == NULL) + Py_RETURN_FALSE; + + Py_RETURN_TRUE; +} + +static struct type * +minsym_type(struct minimal_symbol *minsym) +{ + struct type *type; + switch (minsym->type) { + case mst_text: + case mst_solib_trampoline: + case mst_file_text: + case mst_text_gnu_ifunc: + case mst_slot_got_plt: + type = builtin_type (python_gdbarch)->builtin_func_ptr; + break; + + case mst_data: + case mst_abs: + case mst_bss: + case mst_file_data: + case mst_file_bss: + type = builtin_type (python_gdbarch)->builtin_data_ptr; + break; + + case mst_unknown: + default: + type = builtin_type (python_gdbarch)->builtin_void; + break; + } + + return type; +} + +static PyObject * +msympy_is_code (PyObject *self, PyObject *args) +{ + struct minimal_symbol *minsym = NULL; + struct type *type = builtin_type (python_gdbarch)->builtin_func_ptr; + MSYMPY_REQUIRE_VALID (self, minsym); + + if (minsym_type(minsym) == type) + Py_RETURN_TRUE; + + Py_RETURN_FALSE; +} + +static PyObject * +msympy_is_data (PyObject *self, PyObject *args) +{ + struct minimal_symbol *minsym = NULL; + struct type *type = builtin_type (python_gdbarch)->builtin_data_ptr; + MSYMPY_REQUIRE_VALID (self, minsym); + + if (minsym_type(minsym) == type) + Py_RETURN_TRUE; + + Py_RETURN_FALSE; +} + +/* Implementation of gdb.MinSymbol.value (self) -> gdb.Value. Returns + the value of the symbol, or an error in various circumstances. */ + +static PyObject * +msympy_value (PyObject *self, PyObject *args) +{ + struct minimal_symbol *minsym = NULL; + struct objfile *objfile = NULL; + struct value *value = NULL; + + if (!PyArg_ParseTuple (args, "")) + return NULL; + + MSYMPY_REQUIRE_VALID (self, minsym); + try + { + objfile = minsym_object_to_objfile (self); + if (!objfile) + error(_("gdb.MinSymbol has no objfile")); + value = evaluate_var_msym_value (EVAL_NORMAL, objfile, minsym); + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + + return value_to_value_object (value); +} + +static void +set_symbol (minsym_object *obj, struct bound_minimal_symbol *bound) +{ + obj->bound = *bound; + obj->prev = NULL; + if (bound->objfile) + { + obj->next = (minsym_object *) objfile_data (bound->objfile, + msympy_objfile_data_key); + if (obj->next) + obj->next->prev = obj; + set_objfile_data (bound->objfile, msympy_objfile_data_key, obj); + } + else + obj->next = NULL; +} + +static PyObject * +bound_minsym_to_minsym_object (struct bound_minimal_symbol *bound) +{ + minsym_object *msym_obj; + + msym_obj = PyObject_New (minsym_object, &minsym_object_type); + if (msym_obj) + set_symbol (msym_obj, bound); + + return (PyObject *) msym_obj; +} + +static void +msympy_dealloc (PyObject *obj) +{ + minsym_object *msym_obj = (minsym_object *) obj; + + if (msym_obj->prev) + msym_obj->prev->next = msym_obj->next; + else if (msym_obj->bound.objfile != NULL) + set_objfile_data (msym_obj->bound.objfile, + msympy_objfile_data_key, msym_obj->next); + if (msym_obj->next) + msym_obj->next->prev = msym_obj->prev; + msym_obj->bound.minsym = NULL; + msym_obj->bound.objfile = NULL; +} + +/* Implementation of + gdb.lookup_minimal_symbol (name, [sfile, [objfile]]) -> symbol or None. */ + +PyObject * +gdbpy_lookup_minimal_symbol (PyObject *self, PyObject *args, PyObject *kw) +{ + const char *name, *sfile = NULL; + struct objfile *objfile = NULL; + static const char *keywords[] = { "name", "sfile", "objfile", NULL }; + struct bound_minimal_symbol bound_minsym = {}; + PyObject *msym_obj = NULL, *sfile_obj = NULL, *objfile_obj = NULL; + + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|OO", keywords, &name, + &sfile_obj, &objfile_obj)) + return NULL; + + if (sfile_obj && sfile_obj != Py_None) + { + gdb::unique_xmalloc_ptr + str(python_string_to_host_string(sfile_obj)); + if (!str) + return NULL; + sfile = str.get(); + } + + if (objfile_obj && objfile_obj != Py_None) + { + objfile = objfpy_object_to_objfile (objfile_obj); + if (!objfile) + return NULL; + } + + try + { + bound_minsym = lookup_minimal_symbol (name, sfile, objfile); + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + + if (bound_minsym.minsym) + msym_obj = bound_minsym_to_minsym_object (&bound_minsym); + + if (msym_obj) + return msym_obj; + + Py_RETURN_NONE; +} + +static void +del_objfile_msymbols (struct objfile *objfile, void *datum) +{ + minsym_object *obj = (minsym_object *) datum; + while (obj) + { + obj->bound.minsym = NULL; + obj->bound.objfile = NULL; + obj->next = NULL; + obj->prev = NULL; + + obj = obj->next; + } +} + +int +gdbpy_initialize_minsymbols (void) +{ + if (PyType_Ready (&minsym_object_type) < 0) + return -1; + + msympy_objfile_data_key + = register_objfile_data_with_cleanup (NULL, del_objfile_msymbols); + + if (PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_UNKNOWN", + mst_unknown) < 0 + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_TEXT", mst_text) < 0 + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_TEXT_GNU_IFUNC", + mst_text_gnu_ifunc) < 0 + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_SLOT_GOT_PLT", + mst_slot_got_plt) < 0 + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_DATA", mst_data) < 0 + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_BSS", mst_bss) < 0 + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_ABS", mst_abs) < 0 + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_SOLIB_TRAMPOLINE", + mst_solib_trampoline) < 0 + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_FILE_TEXT", + mst_file_text) < 0 + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_FILE_DATA", + mst_file_data) < 0 + || PyModule_AddIntConstant (gdb_module, "MINSYMBOL_TYPE_FILE_BSS", + mst_file_bss) < 0) + return -1; + + return gdb_pymodule_addobject (gdb_module, "MinSymbol", + (PyObject *) &minsym_object_type); +} + + + +static gdb_PyGetSetDef minsym_object_getset[] = { + { "name", msympy_get_name, NULL, + "Name of the minimal symbol, as it appears in the source code.", NULL }, + { "linkage_name", msympy_get_linkage_name, NULL, + "Name of the minimal symbol, as used by the linker (i.e., may be mangled).", + NULL }, + { "filename", msympy_get_file_name, NULL, + "Name of source file that contains this minimal symbol. Only applies for mst_file_*.", + NULL }, + { "print_name", msympy_get_print_name, NULL, + "Name of the minimal symbol in a form suitable for output.\n\ +This is either name or linkage_name, depending on whether the user asked GDB\n\ +to display demangled or mangled names.", NULL }, + { "section", msympy_get_section, NULL, + "Section that contains this minimal symbol, if any", NULL, }, + { "type", msympy_get_type, NULL, + "Type that this minimal symbol represents." }, + { NULL } /* Sentinel */ +}; + +static PyMethodDef minsym_object_methods[] = { + { "is_valid", msympy_is_valid, METH_NOARGS, + "is_valid () -> Boolean.\n\ +Return true if this minimal symbol is valid, false if not." }, + { "is_code", msympy_is_code, METH_NOARGS, + "is_code () -> Boolean.\n\ +Return true if this minimal symbol represents code." }, + { "is_data", msympy_is_data, METH_NOARGS, + "is_data () -> Boolean.\n\ +Return true if this minimal symbol represents data." }, + { "value", msympy_value, METH_VARARGS, + "value ([frame]) -> gdb.Value\n\ +Return the value of the minimal symbol." }, + {NULL} /* Sentinel */ +}; + +PyTypeObject minsym_object_type = { + PyVarObject_HEAD_INIT (NULL, 0) + "gdb.MinSymbol", /*tp_name*/ + sizeof (minsym_object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + msympy_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + msympy_str, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "GDB minimal symbol object", /*tp_doc */ + 0, /*tp_traverse */ + 0, /*tp_clear */ + 0, /*tp_richcompare */ + 0, /*tp_weaklistoffset */ + 0, /*tp_iter */ + 0, /*tp_iternext */ + minsym_object_methods, /*tp_methods */ + 0, /*tp_members */ + minsym_object_getset /*tp_getset */ +}; diff --git a/gdb/python/py-objfile.c b/gdb/python/py-objfile.c index 199c567a044..3dcf4acc3a3 100644 --- a/gdb/python/py-objfile.c +++ b/gdb/python/py-objfile.c @@ -132,7 +132,7 @@ objfpy_get_build_id (PyObject *self, void *closure) try { - build_id = build_id_bfd_get (objfile->obfd); + build_id = build_id_bfd_shdr_get (objfile->obfd); } catch (const gdb_exception &except) { @@ -363,6 +363,24 @@ objfpy_get_xmethods (PyObject *o, void *ignore) return self->xmethods; } +static PyObject * +objfpy_get_architecture (PyObject *o, void *ignore) +{ + objfile_object *self = (objfile_object *) o; + struct gdbarch *gdbarch = NULL; + + try + { + gdbarch = get_objfile_arch(self->objfile); + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + + return gdbarch_to_arch_object (gdbarch); +} + /* Set the 'type_printers' attribute. */ static int @@ -406,6 +424,35 @@ objfpy_is_valid (PyObject *self, PyObject *args) Py_RETURN_TRUE; } +/* Implementation of gdb.Objfile.is_has_symbols (self) -> Boolean. + Returns True if this object file has even partial symbols available. */ + +static PyObject * +objfpy_has_symbols (PyObject *self, PyObject *args) +{ + objfile_object *obj = (objfile_object *) self; + + if (! obj->objfile) + Py_RETURN_FALSE; + + if (objfile_has_symbols (obj->objfile)) + { + Py_RETURN_TRUE; + } + + Py_RETURN_FALSE; +} + + +struct objfile * +objfpy_object_to_objfile(PyObject *self) +{ + objfile_object *obj = (objfile_object *) self; + OBJFPY_REQUIRE_VALID(obj); + + return obj->objfile; +} + /* Implementation of gdb.Objfile.add_separate_debug_file (self) -> Boolean. */ static PyObject * @@ -533,7 +580,7 @@ objfpy_lookup_objfile_by_build_id (const char *build_id) /* Don't return separate debug files. */ if (objfile->separate_debug_objfile_backlink != NULL) continue; - obfd_build_id = build_id_bfd_get (objfile->obfd); + obfd_build_id = build_id_bfd_shdr_get (objfile->obfd); if (obfd_build_id == NULL) continue; if (objfpy_build_id_matches (obfd_build_id, build_id)) @@ -646,6 +693,9 @@ static PyMethodDef objfile_object_methods[] = { "is_valid", objfpy_is_valid, METH_NOARGS, "is_valid () -> Boolean.\n\ Return true if this object file is valid, false if not." }, + { "has_symbols", objfpy_has_symbols, METH_NOARGS, + "has_symbols () -> Boolean.\n\ +Return true if this object file has symbols associated with it." }, { "add_separate_debug_file", (PyCFunction) objfpy_add_separate_debug_file, METH_VARARGS | METH_KEYWORDS, @@ -680,6 +730,8 @@ static gdb_PyGetSetDef objfile_getset[] = "Type printers.", NULL }, { "xmethods", objfpy_get_xmethods, NULL, "Debug methods.", NULL }, + { "architecture", objfpy_get_architecture, NULL, "Objfile Architecture", + NULL }, { NULL } }; diff --git a/gdb/python/py-register.c b/gdb/python/py-register.c new file mode 100644 index 00000000000..7746d14ddd0 --- /dev/null +++ b/gdb/python/py-register.c @@ -0,0 +1,373 @@ +#include "defs.h" +#include "python-internal.h" +#include "gdbthread.h" +#include "regcache.h" +#include "target.h" + +extern PyTypeObject register_object_type; + +typedef struct register_object { + PyObject_HEAD + thread_object *thread; + int regnum; + struct register_object *next; + struct register_object *prev; +} register_object; + +#define REGPY_REQUIRE_VALID(register_obj, reg, ret) \ + do { \ + reg = register_object_to_register(register_obj); \ + if (reg == NULL) \ + { \ + PyErr_SetString (PyExc_RuntimeError, \ + _("Register is invalid.")); \ + return ret; \ + } \ + } while(0) + +static void +set_register(register_object *obj, thread_object *thread_obj, int regnum) +{ + obj->thread = thread_obj; + obj->regnum = regnum; + obj->prev = NULL; + obj->next = (register_object *)thread_obj->register_objs; + if (obj->next) + obj->next->prev = obj; + thread_obj->register_objs = (PyObject *)obj; +} + +PyObject * +register_to_register_object (thread_object *thread_obj, int reg) +{ + register_object *register_obj; + + register_obj = PyObject_New (register_object, ®ister_object_type); + if (register_obj) + set_register (register_obj, thread_obj, reg); + return (PyObject *) register_obj; + +} + +static register_object * +register_object_to_register (PyObject *obj) +{ + register_object *reg; + if (! PyObject_TypeCheck (obj, ®ister_object_type)) + return NULL; + reg = (register_object *) obj; + if (!reg->thread) + return NULL; + return reg; +} + +static PyObject * +register_get_name(PyObject *self, void *closure) +{ + register_object *obj; + const char *name = NULL; + + REGPY_REQUIRE_VALID(self, obj, NULL); + try + { + struct gdbarch *gdbarch = target_gdbarch(); + name = gdbarch_register_name (gdbarch, obj->regnum); + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + + return PyString_FromString(name); +} + +static PyObject * +register_get_value(PyObject *self, void *closure) +{ + register_object *obj; + struct value *value = NULL; + + REGPY_REQUIRE_VALID(self, obj, NULL); + + try + { + struct gdbarch *gdbarch = target_gdbarch (); + struct thread_info *ti = obj->thread->thread; + struct regcache *regcache = get_thread_regcache (ti->ptid); + if (obj->regnum == gdbarch_pc_regnum (gdbarch)) + { + CORE_ADDR pc = regcache_read_pc (regcache); + value = allocate_value (register_type (gdbarch, obj->regnum)); + + VALUE_LVAL (value) = lval_register; + VALUE_REGNUM (value) = obj->regnum; + memcpy (value_contents_raw (value), &pc, sizeof (pc)); + } + else + { + /* + * We don't want raw read since that expects to + * read it from the core file + */ + value = regcache->cooked_read_value (obj->regnum); + } + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + + return value_to_value_object(value); +} + +static const char * +type_prefix (struct type *type) +{ + switch (TYPE_CODE(type)) + { + case TYPE_CODE_UNION: + return "union "; + case TYPE_CODE_STRUCT: + return "struct "; + case TYPE_CODE_ENUM: + return "enum "; + } + + return ""; +} + +static int +check_size (size_t len, size_t size) +{ + if (len < size) + { + PyErr_Format (PyExc_TypeError, + "Value must be at least %zd bytes in size.", size); + return -1; + } + return 0; +} + +static int +write_register (struct regcache *regcache, int reg, const void *data) +{ + struct gdbarch *gdbarch = target_gdbarch (); + if (target_has_execution && reg == gdbarch_pc_regnum (gdbarch) && data) + { + CORE_ADDR pc = *(CORE_ADDR *)data; + regcache_write_pc (regcache, pc); + } + else + regcache->raw_supply (reg, data); + + return 0; +} + +static int +register_set_value(PyObject *self, PyObject *value_obj, void *closure) +{ + struct type *type = NULL; + register_object *obj; + int ret = -1; + + REGPY_REQUIRE_VALID(self, obj, -1); + + try + { + struct gdbarch *gdbarch = target_gdbarch (); + size_t size = register_size (gdbarch, obj->regnum); + struct thread_info *ti = obj->thread->thread; + struct regcache *regcache = get_thread_regcache_for_ptid(ti->ptid); + struct value *value; + unsigned long ul_value; + + type = register_type (gdbarch, obj->regnum); + + if (value_obj == Py_None) + ret = write_register (regcache, obj->regnum, NULL); + else if (PyByteArray_Check (value_obj)) + { + Py_ssize_t len = PyByteArray_Size (value_obj); + char *buf = PyByteArray_AsString (value_obj); + if (!check_size (len, size)) + ret = write_register (regcache, obj->regnum, buf); + } + else if (PyLong_Check (value_obj)) + { + ul_value = PyLong_AsUnsignedLong (value_obj); + + if (!check_size (sizeof (ul_value), size)) + { + /* Let the value code do the type checking */ + value = value_from_ulongest (type, ul_value); + ret = write_register (regcache, obj->regnum, &ul_value); + } + } +#ifndef IS_PY3K + else if (PyInt_Check (value_obj)) + { + ul_value = PyInt_AsUnsignedLongMask (value_obj); + + if (!check_size (sizeof (ul_value), size)) + { + /* Let the value code do the type checking */ + value = value_from_ulongest (type, ul_value); + ret = write_register (regcache, obj->regnum, &ul_value); + } + } +#endif + else + { + value = value_object_to_value(value_obj); + if (value) + { + value = value_cast (type, value); + ret = write_register (regcache, obj->regnum, + value_contents (value)); + } + else + PyErr_Format (PyExc_TypeError, + "Value must be int, long, bytearray, or gdb.Value and convertible to `%s%s'", + type_prefix (type), TYPE_NAME (type)); + } + } + catch (const gdb_exception &except) + { + GDB_PY_SET_HANDLE_EXCEPTION (except); + } + + return ret; +} + +static PyObject * +register_get_size(PyObject *self, void *closure) +{ + register_object *obj; + int size = 0; + + REGPY_REQUIRE_VALID(self, obj, NULL); + + try + { + struct gdbarch *gdbarch = target_gdbarch(); + size = register_size (gdbarch, obj->regnum); + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + + return PyInt_FromLong(size); +} + +static PyObject * +register_get_regnum(PyObject *self, void *closure) +{ + register_object *obj; + REGPY_REQUIRE_VALID(self, obj, NULL); + + return PyInt_FromLong(obj->regnum); +} + +static PyObject * +register_get_regtype(PyObject *self, void *closure) +{ + register_object *obj; + struct type *type = NULL; + + REGPY_REQUIRE_VALID(self, obj, NULL); + + try + { + struct gdbarch *gdbarch = target_gdbarch (); + type = register_type (gdbarch, obj->regnum); + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + + return type_to_type_object(type); +} + +static void +register_object_dealloc (PyObject *self) +{ + register_object *reg = (register_object *) self; + + if (reg->prev) + reg->prev->next = reg->next; + else if (reg->thread) + reg->thread->register_objs = (PyObject *)reg->next; + + if (reg->next) + reg->next->prev = reg->prev; +} + +void +del_thread_registers (thread_object *thread) +{ + register_object *obj = (register_object *) thread->register_objs; + + while (obj) + { + register_object *next = obj->next; + + obj->thread = NULL; + obj->prev = NULL; + obj->next = NULL; + + obj = next; + } +} + +static gdb_PyGetSetDef register_object_getset[] = { + { "name", register_get_name, NULL, "Register name.", NULL }, + { "value", register_get_value, register_set_value, "Register value.", NULL }, + { "size", register_get_size, NULL, "Register size.", NULL }, + { "regnum", register_get_regnum, NULL, "Register number.", NULL }, + { "type", register_get_regtype, NULL, "Register type.", NULL }, + { NULL } /* Sentinal */ +}; + +PyTypeObject register_object_type = { + PyVarObject_HEAD_INIT (NULL, 0) + "gdb.Register", /*tp_name*/ + sizeof(register_object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + register_object_dealloc, /*tp_delalloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "GDB Register object", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + register_object_getset, /* tp_getset */ +}; + +int gdbpy_initialize_register (void) +{ + if (PyType_Ready (®ister_object_type) < 0) + return -1; + + return (gdb_pymodule_addobject(gdb_module, "Register", + (PyObject *)®ister_object_type)); +} diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c index 8605ae71a24..52a7fa5f6d2 100644 --- a/gdb/python/py-symbol.c +++ b/gdb/python/py-symbol.c @@ -73,8 +73,7 @@ sympy_get_type (PyObject *self, void *closure) if (SYMBOL_TYPE (symbol) == NULL) { - Py_INCREF (Py_None); - return Py_None; + Py_RETURN_NONE; } return type_to_type_object (SYMBOL_TYPE (symbol)); @@ -238,6 +237,26 @@ sympy_is_valid (PyObject *self, PyObject *args) Py_RETURN_TRUE; } +static PyObject * +sympy_section (PyObject *self, void *closure) +{ + struct symbol *symbol = NULL; + struct obj_section *section; + const char *name; + + SYMPY_REQUIRE_VALID (self, symbol); + + section = SYMBOL_OBJ_SECTION (symbol_objfile(symbol), symbol); + if (section) { + name = bfd_section_name (symbol_objfile(objfile)->obfd, + section->the_bfd_section); + if (name) + return PyString_FromString (name); + } + + Py_RETURN_NONE; +} + /* Implementation of gdb.Symbol.value (self[, frame]) -> gdb.Value. Returns the value of the symbol, or an error in various circumstances. */ @@ -375,25 +394,36 @@ gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw) PyObject *block_obj = NULL, *sym_obj, *bool_obj; const struct block *block = NULL; - if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!i", keywords, &name, - &block_object_type, &block_obj, - &domain)) + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|Oi", keywords, &name, + &block_obj, &domain)) return NULL; - if (block_obj) - block = block_object_to_block (block_obj); - else + if (block_obj && block_obj != Py_None && + !PyObject_TypeCheck (block_obj, &block_object_type)) { - struct frame_info *selected_frame; + PyErr_Format (PyExc_TypeError, + "argument 2 must be gdb.Block or None, not %s", + block_obj->ob_type->tp_name); + return NULL; + } - try - { - selected_frame = get_selected_frame (_("No frame selected.")); - block = get_frame_block (selected_frame, NULL); - } - catch (const gdb_exception &except) + if (block_obj != Py_None) + { + if (block_obj) + block = block_object_to_block (block_obj); + else { - GDB_PY_HANDLE_EXCEPTION (except); + struct frame_info *selected_frame; + + try + { + selected_frame = get_selected_frame (_("No frame selected.")); + block = get_frame_block (selected_frame, NULL); + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } } } @@ -464,8 +494,7 @@ gdbpy_lookup_global_symbol (PyObject *self, PyObject *args, PyObject *kw) } else { - sym_obj = Py_None; - Py_INCREF (Py_None); + Py_RETURN_NONE; } return sym_obj; @@ -594,6 +623,8 @@ to display demangled or mangled names.", NULL }, "True if the symbol requires a frame for evaluation." }, { "line", sympy_line, NULL, "The source line number at which the symbol was defined." }, + { "section", sympy_section, NULL, + "Section of executable where symbol resides." }, { NULL } /* Sentinel */ }; diff --git a/gdb/python/py-target.c b/gdb/python/py-target.c new file mode 100644 index 00000000000..a75638c63dd --- /dev/null +++ b/gdb/python/py-target.c @@ -0,0 +1,1335 @@ +/* Python interface to target operations. + + Copyright (C) 2016 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 . */ + +#include "defs.h" +#include "gdbthread.h" +#include "inferior.h" +#include "python-internal.h" +#include "language.h" +#include "arch-utils.h" +#include "process-stratum-target.h" + +static PyObject *py_target_xfer_eof_error; +static PyObject *py_target_xfer_unavailable_error; + +extern PyTypeObject target_object_type + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("target_object"); + +class python_target final : public process_stratum_target +{ +public: + python_target (PyObject *owner) : owner(owner), registered(false) { + _info.shortname = NULL; + _info.longname = NULL; + _info.doc = NULL; + } + virtual ~python_target () override { + if (registered) + unregister_target (); + xfree (const_cast(_info.shortname)); + xfree (const_cast(_info.longname)); + xfree (const_cast(_info.doc)); + } + const target_info &info () const override { + return _info; + } + strata stratum () const override { return thread_stratum; } + + void open (const char *name, int from_tty); + + void close () override; + + enum target_xfer_status xfer_partial (enum target_object object, + const char *annex, + gdb_byte *gdb_readbuf, + const gdb_byte *gdb_writebuf, + ULONGEST offset, ULONGEST len, + ULONGEST *xfered_len) override; + const char *thread_name (struct thread_info *info) override; + const char *extra_thread_info (struct thread_info *info) override; + void update_thread_list (void) override; + std::string pid_to_str (ptid_t ptid) override; + bool thread_alive (ptid_t ptid) override; + void fetch_registers (struct regcache *regcache, int reg) override; + bool has_execution (ptid_t ptid) override; + void store_registers (struct regcache *regcache, int reg) override; + void prepare_to_store (struct regcache *regcache) override; + + int set_shortname (PyObject *name); + int set_longname (PyObject *name); + int set_docstring (PyObject *name); + + PyObject *get_owner(void); + + void register_target (void); + void unregister_target (void); +private: + target_info _info; + PyObject *owner; + bool registered; +}; + +typedef struct +{ + PyObject_HEAD + + target_ops *ops; + bool native_target; + bool registered; +} pytarget_object; + +/* Container of, courtesy of Linux Kernel for now */ +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER)) +#endif +#ifndef container_of +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) +#endif + +#define ENTRY() {} while(0) +#define EXIT() {} while(0) + +/* Large spacing between sections during development for clear divisions */ + +/***************************************************************************** + * + * Target Operation Python Bindings + * + * These bindings map from the target_ops structure to the python object, + * and call into any functions provided - or fall back to delegating to the + * operations from beneath + * + *****************************************************************************/ + +static char scratch_buf[4096]; + +#define pytarget_has_op(op) \ + PyObject_HasAttrString (owner, #op) + + +static python_target * +get_writable_python_target (pytarget_object *target_obj) +{ + if (target_obj->native_target) + { + PyErr_SetString (PyExc_AttributeError, + _("Property is read-only on native targets.")); + return NULL; + } + + if (target_obj->registered) + { + PyErr_SetString (PyExc_AttributeError, + _("Property is read-only on registered targets.")); + return NULL; + } + + return dynamic_cast(target_obj->ops); +} + +void +python_target::open (const char *argstring, int from_tty) +{ + target_ops *ops; + PyObject *callback = NULL; + PyObject *arglist = NULL; + PyObject *ret = NULL; + bool stacked = false; + + gdbpy_enter enter_py (target_gdbarch (), current_language); + + if (!pytarget_has_op (open)) + error (_("Python target has no open callback")); + + ops = find_target_at (thread_stratum); + if (ops && !have_inferiors ()) + { + if (from_tty && !query (_("Another target is open. Close it?"))) + error (_("Refusing to replace other target.")); + } + + if (pytarget_has_op(stacked_target)) + { + callback = PyObject_GetAttrString (owner, "stacked_target"); + if (!callback) + goto error; + + ret = gdb_PyObject_CallFunction (callback, "()", NULL); + if (!ret) + goto error; + + if (!PyBool_Check (ret)) + { + PyErr_SetString (PyExc_RuntimeError, + "stacked_target callback must return True or False"); + goto error; + } + stacked = ret == Py_True; + Py_XDECREF (ret); + ret = NULL; + } + + if (!stacked) + { + target_preopen (from_tty); + reopen_exec_file (); + } + registers_changed (); + + callback = PyObject_GetAttrString (owner, "open"); + if (!callback) + goto error; + + if (!argstring) + argstring = ""; + + arglist = Py_BuildValue ("(si)", argstring, from_tty); + if (!arglist) + goto error; + + ret = PyObject_Call(callback, arglist, NULL); + if (!ret) + { + gdbpy_handle_exception(); + PyErr_Clear(); + } + else + { + Py_INCREF (owner); + target_ops_up target_holder (this); + push_target (std::move (target_holder)); + reread_symbols (); + init_thread_list (); + } + +error: + Py_XDECREF (callback); + Py_XDECREF (arglist); + Py_XDECREF (ret); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + error (_("Error in Python while executing open callback.")); + } +} + +void +python_target::close (void) +{ + PyObject *callback = NULL; + PyObject *ret = NULL; + + gdbpy_enter enter_py (target_gdbarch (), current_language); + + pop_all_targets_at_and_above (thread_stratum); + + if (!pytarget_has_op (close)) + error (_("Python target has no close callback")); + + inferior_ptid = null_ptid; + discard_all_inferiors (); + + trace_reset_local_state (); + + callback = PyObject_GetAttrString (owner, "close"); + if (!callback) + goto error; + + ret = gdb_PyObject_CallFunction (callback, "()", NULL); + if (!ret) + goto error; + +error: + Py_XDECREF (callback); + Py_XDECREF (ret); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + error (_("Error in Python while executing close callback.")); + } +} + +const char * +python_target::thread_name (struct thread_info *info) +{ + PyObject *arglist = NULL; + PyObject *result = NULL; + PyObject *callback = NULL; + PyObject *thread = NULL; + + gdb::unique_xmalloc_ptr host_string_holder; + char *host_string = NULL; + + gdbpy_enter enter_py (target_gdbarch (), current_language); + if (!pytarget_has_op (info)) + return process_stratum_target::thread_name (info); + + callback = PyObject_GetAttrString (owner, "thread_name"); + if (!callback) + goto error; + + /* (re-)initialise the static string before use in case of error */ + scratch_buf[0] = '\0'; + + thread = gdbpy_selected_thread (NULL, NULL); + if (!thread) + goto error; + + /* Time to call the callback */ + arglist = Py_BuildValue ("(O)", thread); + if (!arglist) + goto error; + + result = PyObject_Call (callback, arglist, NULL); + if (!result) + goto error; + + /* + * GDB will raise an exception that the caller will catch. + * Python will raise an exception and return NULL. + */ + host_string_holder = python_string_to_host_string (result); + if (!host_string_holder) + goto error; + + host_string = host_string_holder.get (); + + strncpy (scratch_buf, host_string, sizeof (scratch_buf) - 1); + scratch_buf[sizeof (scratch_buf) - 1] = '\0'; + +error: + Py_XDECREF (result); + Py_XDECREF (arglist); + Py_XDECREF (thread); + Py_XDECREF (callback); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + error (_("Error in Python while executing thread_name callback.")); + } + + return scratch_buf; +} + +enum target_xfer_status +python_target::xfer_partial (enum target_object object, const char *annex, + gdb_byte *gdb_readbuf, const gdb_byte *gdb_writebuf, + ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) +{ + PyObject *callback = NULL; + PyObject *readbuf = NULL; + PyObject *writebuf = NULL; + PyObject *arglist = NULL; + PyObject *ret = NULL; + + enum target_xfer_status rt = TARGET_XFER_E_IO; + unsigned long lret; + + gdbpy_enter enter_py (target_gdbarch (), current_language); + + if (!pytarget_has_op (xfer_partial)) + return process_stratum_target::xfer_partial (object, annex, gdb_readbuf, + gdb_writebuf, offset, + len, xfered_len); + + callback = PyObject_GetAttrString (owner, "xfer_partial"); + if (!callback) + goto error; + + if (gdb_readbuf) + { + readbuf = PyByteArray_FromStringAndSize ((char *) gdb_readbuf, len); + if (!readbuf) + goto error; + } + else + { + readbuf = Py_None; + Py_INCREF (Py_None); + } + + if (gdb_writebuf) + { + writebuf = PyByteArray_FromStringAndSize ((char *) gdb_writebuf, len); + if (!writebuf) + goto error; + } + else + { + writebuf = Py_None; + Py_INCREF (Py_None); + } + + arglist = Py_BuildValue ("(isOOKK)", (int)object, annex, readbuf, + writebuf, offset, len); + if (!arglist) + goto error; + + ret = PyObject_Call(callback, arglist, NULL); + if (PyErr_Occurred ()) + { + if (PyErr_ExceptionMatches (py_target_xfer_eof_error)) + { + PyErr_Clear (); + rt = TARGET_XFER_EOF; + goto error; + } + else if (PyErr_ExceptionMatches (PyExc_IOError)) + { + PyErr_Clear (); + rt = TARGET_XFER_E_IO; + goto error; + } + else if (PyErr_ExceptionMatches (py_target_xfer_unavailable_error)) + { + PyErr_Clear (); + rt = TARGET_XFER_UNAVAILABLE; + *xfered_len = len; + goto error; + } + else + goto error; + } + + lret = PyLong_AsUnsignedLongLong (ret); + if (gdb_readbuf) + { + const char *str = PyByteArray_AsString (readbuf); + int l = PyByteArray_Size (readbuf); + memcpy (gdb_readbuf, str, l); + } + + rt = TARGET_XFER_OK; + *xfered_len = lret; + +error: + Py_XDECREF (ret); + Py_XDECREF (writebuf); + Py_XDECREF (readbuf); + Py_XDECREF (callback); + Py_XDECREF (arglist); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + error (_("Error in Python while executing xfer_partial callback.")); + } + + return rt; +} + +const char * +python_target::extra_thread_info (struct thread_info *info) +{ + PyObject *callback = NULL; + PyObject *arglist = NULL; + PyObject *result = NULL; + + gdb::unique_xmalloc_ptr host_string_holder; + char *host_string = NULL; + + scratch_buf[0] = '\0'; + + gdbpy_enter enter_py (target_gdbarch (), current_language); + + if (!pytarget_has_op (extra_thread_info)) + return NULL; + + callback = PyObject_GetAttrString (owner, "extra_thread_info"); + if (!callback) + goto error; + + arglist = Py_BuildValue ("()"); + if (!arglist) + goto error; + + result = PyObject_Call (callback, arglist, NULL); + if (!result) + goto error; + + host_string_holder = python_string_to_host_string (result); + if (!host_string_holder) + goto error; + + host_string = host_string_holder.get (); + strncpy (scratch_buf, host_string, sizeof (scratch_buf) - 1); + scratch_buf[sizeof (scratch_buf) - 1] = '\0'; + +error: + Py_XDECREF (result); + Py_XDECREF (arglist); + Py_XDECREF (callback); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + error (_("Error in Python while executing update_thread_list callback.")); + } + + return scratch_buf; +} + +void +python_target::update_thread_list (void) +{ + PyObject *callback = NULL; + PyObject *arglist = NULL; + PyObject *result = NULL; + + gdbpy_enter enter_py (target_gdbarch (), current_language); + + if (!pytarget_has_op (update_thread_list)) + return; + + callback = PyObject_GetAttrString (owner, "update_thread_list"); + if (!callback) + goto error; + + arglist = Py_BuildValue ("()"); + if (!arglist) + goto error; + + result = PyObject_Call (callback, arglist, NULL); + if (!result) + goto error; + +error: + Py_XDECREF (result); + Py_XDECREF (arglist); + Py_XDECREF (callback); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + error (_("Error in Python while executing update_thread_list callback.")); + } + +} + +bool +python_target::thread_alive (ptid_t ptid) +{ + PyObject *ptid_obj = NULL; + PyObject *arglist = NULL; + PyObject *result = NULL; + PyObject *callback = NULL; + + long ret = 0; + + gdbpy_enter enter_py (target_gdbarch (), current_language); + + if (!pytarget_has_op (thread_alive)) { + printf("target doesn't have thread_alive\n"); + return false; + } + + callback = PyObject_GetAttrString (owner, "thread_alive"); + if (!callback) + goto error; + + ptid_obj = gdbpy_create_ptid_object (ptid); + if (!ptid_obj) + goto error; + + arglist = Py_BuildValue ("(O)", ptid_obj); + if (!arglist) + goto error; + + result = PyObject_Call (callback, arglist, NULL); + if (!result) + goto error; + + ret = PyInt_AsLong (result); + +error: + Py_XDECREF (result); + Py_XDECREF (arglist); + Py_XDECREF (ptid_obj); + Py_XDECREF (callback); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + error (_("Error in Python while executing thread_alive callback.")); + } + + return ret; +} + +std::string +python_target::pid_to_str (ptid_t ptid) +{ + PyObject *ptid_obj = NULL; + PyObject *arglist = NULL; + PyObject *result = NULL; + PyObject *callback = NULL; + + gdb::unique_xmalloc_ptr host_string_holder; + char *host_string = NULL; + + scratch_buf[0] = '\0'; + + gdbpy_enter enter_py (target_gdbarch (), current_language); + + if (!pytarget_has_op (pid_to_str)) + return process_stratum_target::pid_to_str (ptid); + + callback = PyObject_GetAttrString (owner, "pid_to_str"); + if (!callback) + goto error; + + ptid_obj = gdbpy_create_ptid_object (ptid); + if (!ptid_obj) + goto error; + + arglist = Py_BuildValue ("(O)", ptid_obj); + if (!arglist) + goto error; + + result = PyObject_Call (callback, arglist, NULL); + + if (!result) + goto error; + + host_string_holder = python_string_to_host_string (result); + if (!host_string_holder) + goto error; + + host_string = host_string_holder.get (); + + strncpy (scratch_buf, host_string, sizeof (scratch_buf) - 1); + scratch_buf[sizeof (scratch_buf) - 1] = '\0'; + +error: + Py_XDECREF (arglist); + Py_XDECREF (ptid_obj); + Py_XDECREF (callback); + Py_XDECREF (result); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + error (_("Error in Python while executing pid_to_str callback.")); + } + + return scratch_buf; +} + +void +python_target::fetch_registers (struct regcache *regcache, int reg) +{ + thread_info *info; + PyObject *arglist = NULL; + PyObject *result = NULL; + PyObject *callback = NULL; + PyObject *reg_obj = NULL; + PyObject *thread = NULL; + gdbpy_ref<> thread_ref; + + gdbpy_enter enter_py (target_gdbarch (), current_language); + + if (!pytarget_has_op (fetch_registers)) { + printf("target has no fetch_registers\n"); + return; + } + + callback = PyObject_GetAttrString (owner, "fetch_registers"); + if (!callback) + goto error; + + info = find_thread_ptid (regcache->ptid ()); + if (!info) + { + PyErr_SetString(PyExc_RuntimeError, "No such ptid for registers."); + goto error; + } + + thread_ref = thread_to_thread_object (info); + if (thread_ref == NULL) + goto error; + + thread = thread_ref.release(); + + if (reg != -1) + { + reg_obj = register_to_register_object ((thread_object *) thread, reg); + if (!reg_obj) + goto error; + } + else + { + reg_obj = Py_None; + Py_INCREF(reg_obj); + } + + arglist = Py_BuildValue ("(OO)", thread, reg_obj); + if (!arglist) + goto error; + + result = PyObject_Call (callback, arglist, NULL); + if (!result) + goto error; + +error: + Py_XDECREF (reg_obj); + Py_XDECREF (result); + Py_XDECREF (arglist); + Py_XDECREF (reg_obj); + Py_XDECREF (thread); + Py_XDECREF (callback); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + error (_("Error in Python while executing fetch_registers callback.")); + } + +} + +void +python_target::prepare_to_store (struct regcache *regcache) +{ + PyObject *arglist = NULL; + PyObject *result = NULL; + PyObject *callback = NULL; + PyObject *thread = NULL; + + gdbpy_enter enter_py (target_gdbarch (), current_language); + if (!pytarget_has_op (prepare_to_store)) + return; + + callback = PyObject_GetAttrString (owner, "prepare_to_store"); + if (!callback) + goto error; + + thread = gdbpy_selected_thread (NULL, NULL); + if (!thread) + goto error; + + arglist = Py_BuildValue ("(O)", thread); + if (!arglist) + goto error; + + result = PyObject_Call (callback, arglist, NULL); + if (!result) + goto error; + +error: + Py_XDECREF (result); + Py_XDECREF (arglist); + Py_XDECREF (thread); + Py_XDECREF (callback); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + error (_("Error in Python while executing prepare_to_store callback.")); + } +} + +void +python_target::store_registers (struct regcache *regcache, int reg) +{ + PyObject *arglist = NULL; + PyObject *result = NULL; + PyObject *callback = NULL; + PyObject *reg_obj = NULL; + PyObject *thread = NULL; + + gdbpy_enter enter_py (target_gdbarch (), current_language); + + if (!pytarget_has_op (store_registers)) + return; + + callback = PyObject_GetAttrString (owner, "store_registers"); + if (!callback) + goto error; + + thread = gdbpy_selected_thread (NULL, NULL); + if (!thread) + goto error; + + reg_obj = register_to_register_object ((thread_object *) thread, reg); + if (!reg_obj) + goto error; + + arglist = Py_BuildValue ("(OO)", thread, reg_obj); + if (!arglist) + goto error; + + result = PyObject_Call (callback, arglist, NULL); + if (!result) + goto error; + +error: + Py_XDECREF (result); + Py_XDECREF (arglist); + Py_XDECREF (reg_obj); + Py_XDECREF (thread); + Py_XDECREF (callback); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + error (_("Error in Python while executing store_registers callback.")); + } +} + +bool +python_target::has_execution (ptid_t ptid) +{ + PyObject *arglist = NULL; + PyObject *result = NULL; + PyObject *callback = NULL; + + int ret = 0; + + gdbpy_enter enter_py (target_gdbarch (), current_language); + if (!pytarget_has_op (has_execution)) + return process_stratum_target::has_execution (ptid); + + callback = PyObject_GetAttrString (owner, "has_execution"); + if (!callback) + goto error; + + arglist = Py_BuildValue ("((iii))", ptid.pid (), ptid.lwp (), ptid.tid ()); + if (!arglist) + goto error; + + result = PyObject_Call (callback, arglist, NULL); + if (!result) + goto error; + + if (!PyBool_Check (result)) + { + PyErr_SetString (PyExc_RuntimeError, + "has_exception callback must return True or False"); + goto error; + } + + ret = (result == Py_True); + +error: + Py_XDECREF (result); + Py_XDECREF (arglist); + Py_XDECREF (callback); + + if (PyErr_Occurred ()) + { + gdbpy_print_stack (); + error (_("Error in Python while executing has_execution callback.")); + } + + return ret; +} + +int +python_target::set_shortname (PyObject *name) +{ + gdb::unique_xmalloc_ptr name_holder; + + if (registered) { + PyErr_SetString (PyExc_RuntimeError, + _("Cannot set name on registered Target.")); + return -1; + } + + name_holder = python_string_to_host_string (name); + if (!name_holder) + return -1; + + _info.shortname = xstrdup (name_holder.get ()); + + return 0; +} + +int +python_target::set_longname (PyObject *name) +{ + gdb::unique_xmalloc_ptr name_holder; + + if (registered) { + PyErr_SetString (PyExc_RuntimeError, + _("Cannot set name on registered Target.")); + return -1; + } + + name_holder = python_string_to_host_string (name); + if (!name_holder) + return -1; + + _info.longname = xstrdup (name_holder.get ()); + + return 0; +} + +int +python_target::set_docstring (PyObject *name) +{ + gdb::unique_xmalloc_ptr name_holder; + + if (registered) { + PyErr_SetString (PyExc_RuntimeError, + _("Cannot set docstring on registered Target.")); + return -1; + } + + name_holder = python_string_to_host_string (name); + if (!name_holder) + return -1; + + _info.doc = xstrdup (name_holder.get ()); + + return 0; +} + +python_target *hacky_target; + +void +pytarget_open (const char *args, int from_tty) +{ + hacky_target->open (args, from_tty); +} + +void +python_target::register_target (void) +{ + if (!_info.shortname) + { + PyErr_SetString (PyExc_RuntimeError, + "Cannot register nameless target."); + return; + } + + if (hacky_target) { + PyErr_SetString (PyExc_RuntimeError, + "This implementation only supports one python target at a time"); + return; + } + + if (!_info.longname) + { + _info.longname = xstrdup (_info.shortname); + } + + if (!_info.doc) + { + _info.doc = xstrdup (_info.longname); + } + + hacky_target = this; + registered = true; + + add_target (info (), pytarget_open, NULL); +} + +void +python_target::unregister_target (void) +{ + if (!registered) + error (_("Target is not registered.")); + delete_target (info (), pytarget_open); + hacky_target = NULL; + + registered = false; +} + +PyObject * +python_target::get_owner (void) +{ + Py_INCREF(owner); + return owner; +} + +/*****************************************************************************/ +/* Python Object Methods and Functionality */ +/*****************************************************************************/ + +static void +target_dealloc (PyObject *owner) +{ + pytarget_object *obj = (pytarget_object *)owner; + ENTRY (); + + if (!obj->native_target) + delete obj->ops; + obj->ops = NULL; + + // Py_DECREF (((pytarget_object *) owner)->inf_obj); + // Decremement any references taken.... + Py_TYPE (owner)->tp_free (owner); + + EXIT (); +} + +static int +tgt_py_set_shortname (PyObject *owner, PyObject *name, void * arg) +{ + pytarget_object *target_obj = (pytarget_object *) owner; + python_target *target = get_writable_python_target (target_obj); + + if (!target) + return -1; + + return target->set_shortname (name); +} + +static int +tgt_py_set_longname (PyObject *owner, PyObject *name, void * arg) +{ + pytarget_object *target_obj = (pytarget_object *) owner; + python_target *target = get_writable_python_target (target_obj); + + if (!target) + return -1; + + return target->set_longname (name); +} + +static int +tgt_py_set_docstring (PyObject *owner, PyObject *name, void * arg) +{ + pytarget_object *target_obj = (pytarget_object *) owner; + python_target *target = get_writable_python_target (target_obj); + + if (!target) + return -1; + + return target->set_docstring (name); +} + +static PyObject * +tgt_py_get_name (PyObject *owner, void * arg) +{ + pytarget_object *target_obj = (pytarget_object *) owner; + return PyString_FromFormat ("%s (%s)", + target_obj->ops->shortname (), + target_obj->ops->longname ()); +} + +static PyObject * +tgt_py_get_shortname (PyObject *owner, void * arg) +{ + pytarget_object *target_obj = (pytarget_object *) owner; + return PyString_FromString (target_obj->ops->shortname ()); +} + +static PyObject * +tgt_py_get_longname (PyObject *owner, void * arg) +{ + pytarget_object *target_obj = (pytarget_object *) owner; + return PyString_FromString (target_obj->ops->longname ()); +} + +static PyObject * +tgt_py_get_docstring (PyObject *owner, void * arg) +{ + pytarget_object *target_obj = (pytarget_object *) owner; + return PyString_FromString (target_obj->ops->info ().doc); +} + +static PyObject * +tgt_py_get_stratum (PyObject *owner, void * arg) +{ + pytarget_object *target_obj = (pytarget_object *) owner; + return PyInt_FromLong (target_obj->ops->stratum()); +} + +static PyObject * +tgt_py_get_arch (PyObject *owner, void *arg) +{ + return gdbarch_to_arch_object (target_gdbarch ()); +} + +static PyObject *target_getconst (PyObject *_owner, void *_value) +{ + return PyInt_FromLong ((long)_value); +} + +#define CONST_GET(x) {#x, target_getconst, NULL, #x, (void*)x} + +static gdb_PyGetSetDef pytarget_object_getset[] = +{ + { "name", tgt_py_get_name, NULL, "The name of the target", NULL }, + { "shortname", tgt_py_get_shortname, tgt_py_set_shortname, + "The shortname of the target", NULL }, + { "longname", tgt_py_get_longname, tgt_py_set_longname, + "The longname of the target", NULL }, + { "docstring", tgt_py_get_docstring, tgt_py_set_docstring, + "The docstring of the target", NULL }, + { "stratum", tgt_py_get_stratum, NULL, "The stratum of the target.", NULL }, + { "arch", tgt_py_get_arch, NULL, "The architecture of the target.", NULL }, + CONST_GET(TARGET_OBJECT_AVR), + CONST_GET(TARGET_OBJECT_SPU), + CONST_GET(TARGET_OBJECT_MEMORY), + CONST_GET(TARGET_OBJECT_RAW_MEMORY), + CONST_GET(TARGET_OBJECT_STACK_MEMORY), + CONST_GET(TARGET_OBJECT_CODE_MEMORY), + CONST_GET(TARGET_OBJECT_UNWIND_TABLE), + CONST_GET(TARGET_OBJECT_AUXV), + CONST_GET(TARGET_OBJECT_WCOOKIE), + CONST_GET(TARGET_OBJECT_MEMORY_MAP), + CONST_GET(TARGET_OBJECT_FLASH), + CONST_GET(TARGET_OBJECT_AVAILABLE_FEATURES), + CONST_GET(TARGET_OBJECT_LIBRARIES), + CONST_GET(TARGET_OBJECT_LIBRARIES_SVR4), + CONST_GET(TARGET_OBJECT_LIBRARIES_AIX), + CONST_GET(TARGET_OBJECT_OSDATA), + CONST_GET(TARGET_OBJECT_SIGNAL_INFO), + CONST_GET(TARGET_OBJECT_THREADS), + CONST_GET(TARGET_OBJECT_STATIC_TRACE_DATA), + CONST_GET(TARGET_OBJECT_TRACEFRAME_INFO), + CONST_GET(TARGET_OBJECT_FDPIC), + CONST_GET(TARGET_OBJECT_DARWIN_DYLD_INFO), + CONST_GET(TARGET_OBJECT_OPENVMS_UIB), + CONST_GET(TARGET_OBJECT_BTRACE), + CONST_GET(TARGET_OBJECT_BTRACE_CONF), + CONST_GET(TARGET_OBJECT_EXEC_FILE), + CONST_GET(TARGET_OBJECT_FREEBSD_VMMAP), + CONST_GET(TARGET_OBJECT_FREEBSD_PS_STRINGS), + + { NULL } +}; + +static PyObject * +pytarget_register_target(PyObject *object, PyObject *unused) +{ + pytarget_object *owner = (pytarget_object *) object; + + if (owner->native_target) + { + PyErr_SetString (PyExc_AttributeError, + _("Native targets cannot be registered.")); + return NULL; + } + + python_target *target = dynamic_cast(owner->ops); + + PyErr_Clear(); + target->register_target(); + + if (PyErr_Occurred ()) + return NULL; + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +pytarget_unregister_target (PyObject *object, PyObject *unused) +{ + pytarget_object *owner = (pytarget_object *) object; + + if (owner->native_target) + { + PyErr_SetString (PyExc_AttributeError, + _("Native targets cannot be unregistered.")); + return NULL; + } + + python_target *target = dynamic_cast(owner->ops); + try + { + target->unregister_target (); + } + catch (const gdb_exception &except) + { + GDB_PY_HANDLE_EXCEPTION (except); + } + + Py_INCREF (Py_None); + return Py_None; +} + + +static PyMethodDef pytarget_object_methods[] = +{ + { "register", pytarget_register_target, METH_NOARGS, + "register ()\nRegister this target for use with GDB." }, + { "unregister", pytarget_unregister_target, METH_NOARGS, + "unregister ()\nUnregister this target for use with GDB." }, + { NULL } +}; + + +static PyObject * +pytarget_new (PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + ENTRY (); + + PyObject *self = type->tp_alloc (type, 0); + + if (self) + { + try + { + pytarget_object *target_obj = (pytarget_object *)self; + target_obj->ops = new python_target (self); + target_obj->native_target = false; + target_obj->registered = false; + } + catch (const gdb_exception &except) + { + Py_DECREF (self); + GDB_PY_HANDLE_EXCEPTION (except); + } + } + + EXIT (); + + return self; +} + +static PyObject * +pytarget_from_native (struct target_ops *target) +{ + PyObject *self = target_object_type.tp_alloc (&target_object_type, 0); + + if (self) + { + try + { + pytarget_object *target_obj = (pytarget_object *)self; + target_obj->ops = target; + target_obj->native_target = true; + target_obj->registered = true; + } + catch (const gdb_exception &except) + { + Py_DECREF (self); + GDB_PY_HANDLE_EXCEPTION (except); + } + } + + return self; +} + +int +gdbpy_initialize_target (void) +{ + + ENTRY (); + + /* Allow us to create instantiations of this class ... */ + target_object_type.tp_new = pytarget_new; + + if (PyType_Ready (&target_object_type) < 0) + return -1; + + py_target_xfer_eof_error = PyErr_NewException ("gdb.TargetXferEOF", + PyExc_EOFError, NULL); + if (!py_target_xfer_eof_error) + goto fail; + + if (gdb_pymodule_addobject (gdb_module, "TargetXferEOF", + py_target_xfer_eof_error) < 0) + goto fail; + + py_target_xfer_unavailable_error = PyErr_NewException ( + "gdb.TargetXferUnavailable", + PyExc_LookupError, NULL); + if (!py_target_xfer_unavailable_error) + goto fail; + + if (gdb_pymodule_addobject (gdb_module, "TargetXferUnavailable", + py_target_xfer_unavailable_error) < 0) + goto fail; + + EXIT (); + + return gdb_pymodule_addobject (gdb_module, "Target", + (PyObject *) &target_object_type); +fail: + gdbpy_print_stack (); + EXIT (); + return -1; +} + +PyTypeObject target_object_type = +{ + PyVarObject_HEAD_INIT (NULL, 0) + "gdb.Target", /*tp_name*/ + sizeof (pytarget_object), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + target_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + "GDB target object", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + pytarget_object_methods, /* tp_methods */ + 0, /* tp_members */ + pytarget_object_getset, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + pytarget_new, /* tp_new */ +}; + +PyObject * +gdbpy_current_target (PyObject *self, PyObject *args) +{ + PyObject *target_obj = NULL; + target_ops *target = current_top_target (); + + python_target *pytarget = dynamic_cast(target); + if (pytarget) + { + target_obj = pytarget->get_owner(); + } + else + { + target_obj = pytarget_from_native (target); + } + + return target_obj; +} diff --git a/gdb/python/py-target.h b/gdb/python/py-target.h new file mode 100644 index 00000000000..846fde3d46e --- /dev/null +++ b/gdb/python/py-target.h @@ -0,0 +1,34 @@ +/* Python interface to target operations. + + Copyright (C) 2016 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 . */ + +#ifndef GDB_PY_TARGET_H +#define GDB_PY_TARGET_H + +#include "target.h" + +typedef struct +{ + PyObject_HEAD + + /* The target operations we represent. */ + struct target_ops ops; + +} target_object; + +#endif /* GDB_PY_TARGET_H */ diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index 22cc658a8b4..0495c6a6c85 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -1008,7 +1008,10 @@ typy_richcompare (PyObject *self, PyObject *other, int op) { try { + result = types_equal (type1, type2); +#if 0 result = types_deeply_equal (type1, type2); +#endif } catch (const gdb_exception &except) { @@ -1353,7 +1356,7 @@ gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw) &type_name, &block_obj)) return NULL; - if (block_obj) + if (block_obj && block_obj != Py_None) { block = block_object_to_block (block_obj); if (! block) diff --git a/gdb/python/py-utils.c b/gdb/python/py-utils.c index 9fee8817781..e601f1387eb 100644 --- a/gdb/python/py-utils.c +++ b/gdb/python/py-utils.c @@ -237,6 +237,8 @@ gdbpy_convert_exception (struct gdb_exception exception) exc_class = PyExc_KeyboardInterrupt; else if (exception.error == MEMORY_ERROR) exc_class = gdbpy_gdb_memory_error; + else if (exception.error == NOT_AVAILABLE_ERROR) + exc_class = gdbpy_gdb_not_available_error; else exc_class = gdbpy_gdb_error; diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index d3f4de40540..47afd67a6f7 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -1670,6 +1670,7 @@ valpy_int (PyObject *self) { struct value *value = ((value_object *) self)->value; struct type *type = value_type (value); + int is_unsigned = 0; LONGEST l = 0; try @@ -1684,6 +1685,9 @@ valpy_int (PyObject *self) && TYPE_CODE (type) != TYPE_CODE_PTR) error (_("Cannot convert value to int.")); + if (TYPE_CODE (type) == TYPE_CODE_PTR || + TYPE_UNSIGNED (type)) + is_unsigned = 1; l = value_as_long (value); } catch (const gdb_exception &except) @@ -1691,7 +1695,7 @@ valpy_int (PyObject *self) GDB_PY_HANDLE_EXCEPTION (except); } - if (TYPE_UNSIGNED (type)) + if (is_unsigned) return gdb_py_object_from_ulongest (l).release (); else return gdb_py_object_from_longest (l).release (); @@ -1704,6 +1708,7 @@ valpy_long (PyObject *self) { struct value *value = ((value_object *) self)->value; struct type *type = value_type (value); + int is_unsigned = 0; LONGEST l = 0; try @@ -1720,6 +1725,9 @@ valpy_long (PyObject *self) && TYPE_CODE (type) != TYPE_CODE_PTR) error (_("Cannot convert value to long.")); + if (TYPE_CODE (type) == TYPE_CODE_PTR || + TYPE_UNSIGNED (type)) + is_unsigned = 1; l = value_as_long (value); } catch (const gdb_exception &except) @@ -1727,7 +1735,7 @@ valpy_long (PyObject *self) GDB_PY_HANDLE_EXCEPTION (except); } - if (TYPE_UNSIGNED (type)) + if (is_unsigned) return gdb_py_long_from_ulongest (l); else return gdb_py_long_from_longest (l); diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h index 449926ca874..eda3847c95e 100644 --- a/gdb/python/python-internal.h +++ b/gdb/python/python-internal.h @@ -115,6 +115,8 @@ #define PyGILState_Release(ARG) ((void)(ARG)) #define PyEval_InitThreads() #define PyThreadState_Swap(ARG) ((void)(ARG)) +#define PyEval_SaveThread() ((void)(ARG)) +#define PyEval_RestoreThread(ARG) ((void)(ARG)) #define PyEval_ReleaseLock() #endif @@ -288,6 +290,20 @@ gdb_PyArg_ParseTupleAndKeywords (PyObject *args, PyObject *kw, return res; } +static inline PyObject * +gdb_PyObject_CallFunction (PyObject *callable, const char *format, ...) +{ + va_list ap; + PyObject *res; + + va_start (ap, format); + res = PyObject_CallFunction (callable, const_cast(format), ap); + va_end (ap); + + return res; +} + + /* In order to be able to parse symtab_and_line_to_sal_object function a real symtab_and_line structure is needed. */ #include "symtab.h" @@ -315,6 +331,8 @@ extern PyTypeObject block_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF("block_object"); extern PyTypeObject symbol_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("symbol_object"); +extern PyTypeObject minsym_object_type; + CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("minsym_object"); extern PyTypeObject event_object_type CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("event_object"); extern PyTypeObject breakpoint_object_type @@ -374,12 +392,22 @@ typedef struct /* The thread we represent. */ struct thread_info *thread; + /* Regcache */ + PyObject *regcache; + /* The Inferior object to which this thread belongs. */ PyObject *inf_obj; + + /* + * Registers associated with this thread. Python code may hold outstanding + * references and we need to be able to mark them invalid. + */ + PyObject *register_objs; } thread_object; struct inferior_object; + extern struct cmd_list_element *set_python_list; extern struct cmd_list_element *show_python_list; @@ -427,6 +455,8 @@ PyObject *gdbpy_lookup_global_symbol (PyObject *self, PyObject *args, PyObject *gdbpy_start_recording (PyObject *self, PyObject *args); PyObject *gdbpy_current_recording (PyObject *self, PyObject *args); PyObject *gdbpy_stop_recording (PyObject *self, PyObject *args); +PyObject *gdbpy_lookup_minimal_symbol (PyObject *self, PyObject *args, + PyObject *kw); PyObject *gdbpy_newest_frame (PyObject *self, PyObject *args); PyObject *gdbpy_selected_frame (PyObject *self, PyObject *args); PyObject *gdbpy_lookup_type (PyObject *self, PyObject *args, PyObject *kw); @@ -438,6 +468,7 @@ PyObject *gdbpy_inferiors (PyObject *unused, PyObject *unused2); PyObject *gdbpy_create_ptid_object (ptid_t ptid); PyObject *gdbpy_selected_thread (PyObject *self, PyObject *args); PyObject *gdbpy_selected_inferior (PyObject *self, PyObject *args); +PyObject *gdbpy_current_target (PyObject *self, PyObject *args); PyObject *gdbpy_string_to_argv (PyObject *self, PyObject *args); PyObject *gdbpy_parameter_value (enum var_types type, void *var); char *gdbpy_parse_command_name (const char *name, @@ -465,6 +496,7 @@ PyObject *objfpy_get_frame_filters (PyObject *, void *); PyObject *objfpy_get_frame_unwinders (PyObject *, void *); PyObject *objfpy_get_xmethods (PyObject *, void *); PyObject *gdbpy_lookup_objfile (PyObject *self, PyObject *args, PyObject *kw); +struct objfile *objfpy_object_to_objfile(PyObject *self); PyObject *gdbarch_to_arch_object (struct gdbarch *gdbarch); @@ -501,6 +533,8 @@ int gdbpy_initialize_commands (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_symbols (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; +int gdbpy_initialize_minsymbols (void) + CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_symtabs (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_blocks (void) @@ -523,8 +557,10 @@ int gdbpy_initialize_linetable (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_parameters (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; -int gdbpy_initialize_thread (void) +int gdbpy_initialize_target (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; +int gdbpy_initialize_thread (void) +CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_inferior (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_eventregistry (void) @@ -539,6 +575,8 @@ int gdbpy_initialize_xmethods (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; int gdbpy_initialize_unwind (void) CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; +int gdbpy_initialize_register (void) + CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION; /* A wrapper for PyErr_Fetch that handles reference counting for the caller. */ @@ -728,6 +766,7 @@ extern PyObject *gdbpy_value_cst; extern PyObject *gdbpy_gdb_error; extern PyObject *gdbpy_gdb_memory_error; extern PyObject *gdbpy_gdberror_exc; +extern PyObject *gdbpy_gdb_not_available_error; extern void gdbpy_convert_exception (struct gdb_exception) CPYCHECKER_SETS_EXCEPTION; @@ -763,4 +802,6 @@ struct Py_buffer_deleter /* A unique_ptr specialization for Py_buffer. */ typedef std::unique_ptr Py_buffer_up; +PyObject *register_to_register_object (thread_object *thread_obj, int reg); +void del_thread_registers (thread_object *thread); #endif /* PYTHON_PYTHON_INTERNAL_H */ diff --git a/gdb/python/python.c b/gdb/python/python.c index 4dad8ec10d1..46d681afbb8 100644 --- a/gdb/python/python.c +++ b/gdb/python/python.c @@ -94,6 +94,8 @@ const struct extension_language_defn extension_language_python = #include "linespec.h" #include "source.h" #include "common/version.h" +#include "inferior.h" +#include "gdbthread.h" #include "target.h" #include "gdbthread.h" #include "interps.h" @@ -131,6 +133,9 @@ PyObject *gdbpy_gdb_error; /* The `gdb.MemoryError' exception. */ PyObject *gdbpy_gdb_memory_error; +/* The `gdb.NotAvailableError' exception. */ +PyObject *gdbpy_gdb_not_available_error; + static script_sourcer_func gdbpy_source_script; static objfile_script_sourcer_func gdbpy_source_objfile_script; static objfile_script_executor_func gdbpy_execute_objfile_script; @@ -543,12 +548,16 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) { const char *arg; PyObject *from_tty_obj = NULL, *to_string_obj = NULL; - int from_tty, to_string; - static const char *keywords[] = { "command", "from_tty", "to_string", NULL }; + int from_tty, to_string, release_gil; + static const char *keywords[] = {"command", "from_tty", "to_string", "release_gil", NULL }; + PyObject *release_gil_obj = NULL; + /* Initialize it just to avoid a GCC false warning. */ + PyThreadState *state = NULL; - if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!O!", keywords, &arg, + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!O!O!", keywords, &arg, &PyBool_Type, &from_tty_obj, - &PyBool_Type, &to_string_obj)) + &PyBool_Type, &to_string_obj, + &PyBool_Type, &release_gil_obj)) return NULL; from_tty = 0; @@ -569,6 +578,15 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) to_string = cmp; } + release_gil = 0; + if (release_gil_obj) + { + int cmp = PyObject_IsTrue (release_gil_obj); + if (cmp < 0) + return NULL; + release_gil = cmp; + } + std::string to_string_res; scoped_restore preventer = prevent_dont_repeat (); @@ -593,10 +611,16 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) counted_command_line lines = read_command_lines_1 (reader, 1, nullptr); + /* In the case of long running GDB commands, allow the user to + release the Python GIL acquired by Python. Restore the GIL + after the command has completed before handing back to + Python. */ + if (release_gil) + state = PyEval_SaveThread(); + { scoped_restore save_async = make_scoped_restore (¤t_ui->async, 0); - scoped_restore save_uiout = make_scoped_restore (¤t_uiout); /* Use the console interpreter uiout to have the same print format @@ -611,12 +635,24 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw) execute_control_commands (lines.get (), from_tty); } + /* Reacquire the GIL if it was released earlier. */ + if (release_gil) + PyEval_RestoreThread (state); + /* Do any commands attached to breakpoint we stopped at. */ bpstat_do_actions (); } catch (const gdb_exception &except) { - GDB_PY_HANDLE_EXCEPTION (except); + if (except.reason < 0) + { + /* Reacquire the GIL if it was released earlier. */ + if (release_gil) + PyEval_RestoreThread (state); + + gdbpy_convert_exception (except); + return NULL; + } } if (to_string) @@ -1128,8 +1164,8 @@ gdbpy_write (PyObject *self, PyObject *args, PyObject *kw) static const char *keywords[] = { "text", "stream", NULL }; int stream_type = 0; - if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &arg, - &stream_type)) + if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "es|i", keywords, "utf-8", + &arg, &stream_type)) return NULL; try @@ -1276,6 +1312,93 @@ gdbpy_print_stack_or_quit () +/* Return the current Progspace. + There always is one. */ +/* True if 'gdb -P' was used, false otherwise. */ +static int running_python_script; + +/* True if we are currently in a call to 'gdb.cli', false otherwise. */ +static int in_cli; + +/* Enter the command loop. */ + +static PyObject * +gdbpy_cli (PyObject *unused1, PyObject *unused2) +{ + if (! running_python_script || in_cli) + return PyErr_Format (PyExc_RuntimeError, "cannot invoke CLI recursively"); + + if (current_uiout->is_mi_like_p ()) + return PyErr_Format (PyExc_RuntimeError, _("Cannot invoke CLI from MI.")); + + in_cli = 1; + /* See captured_command_loop. */ + + /* Give the interpreter a chance to print a prompt. */ + interp_pre_command_loop (top_level_interpreter ()); + + /* Now it's time to start the event loop. */ + start_event_loop (); + + in_cli = 0; + + Py_RETURN_NONE; +} + +/* Set up the Python argument vector and evaluate a script. This is + used to implement 'gdb -P'. */ + +void +run_python_script (int argc, char **argv) +{ + FILE *input; + + gdbpy_enter enter_py (get_current_arch (), current_language); + + running_python_script = 1; + +#if PYTHON_ABI_VERSION < 3 + PySys_SetArgv (argc - 1, argv + 1); +#else + { + wchar_t **wargv = (wchar_t **) alloca (sizeof (*wargv) * (argc + 1)); + int i; + + for (i = 1; i < argc; i++) + { + size_t len = mbstowcs (NULL, argv[i], 0); + /* Python-related GDB sources are built with -DNDEBUG + https://sourceware.org/bugzilla/show_bug.cgi?id=20445 */ + size_t len2 ATTRIBUTE_UNUSED; + + if (len == (size_t) -1) + { + fprintf (stderr, "Invalid multibyte argument #%d \"%s\"\n", + i, argv[i]); + exit (1); + } + wargv[i] = (wchar_t *) alloca (sizeof (**wargv) * (len + 1)); + len2 = mbstowcs (wargv[i], argv[i], len + 1); + assert (len2 == len); + } + wargv[argc] = NULL; + PySys_SetArgv (argc - 1, wargv + 1); + } +#endif + + input = fopen (argv[0], "r"); + if (! input) + { + fprintf (stderr, "could not open %s: %s\n", argv[0], strerror (errno)); + exit (1); + } + PyRun_SimpleFile (input, argv[0]); + fclose (input); + exit (0); +} + + + /* Return a sequence holding all the Progspaces. */ static PyObject * @@ -1550,7 +1673,7 @@ finalize_python (void *ignore) { struct active_ext_lang_state *previous_active; - /* We don't use ensure_python_env here because if we ever ran the + /* We don't use gdbpy_enter here because if we ever ran the cleanup, gdb would crash -- because the cleanup calls into the Python interpreter, which we are about to destroy. It seems clearer to make the needed calls explicitly here than to create a @@ -1663,6 +1786,13 @@ do_start_initialization () gdbpy_gdb_memory_error) < 0) return false; + gdbpy_gdb_not_available_error = PyErr_NewException ("gdb.NotAvailableError", + gdbpy_gdb_error, NULL); + if (gdbpy_gdb_not_available_error == NULL + || gdb_pymodule_addobject (gdb_module, "NotAvailableError", + gdbpy_gdb_not_available_error) < 0) + return false; + gdbpy_gdberror_exc = PyErr_NewException ("gdb.GdbError", NULL, NULL); if (gdbpy_gdberror_exc == NULL || gdb_pymodule_addobject (gdb_module, "GdbError", @@ -1679,6 +1809,7 @@ do_start_initialization () || gdbpy_initialize_record () < 0 || gdbpy_initialize_btrace () < 0 || gdbpy_initialize_symbols () < 0 + || gdbpy_initialize_minsymbols () < 0 || gdbpy_initialize_symtabs () < 0 || gdbpy_initialize_blocks () < 0 || gdbpy_initialize_functions () < 0 @@ -1691,6 +1822,7 @@ do_start_initialization () || gdbpy_initialize_lazy_string () < 0 || gdbpy_initialize_linetable () < 0 || gdbpy_initialize_thread () < 0 + || gdbpy_initialize_target() < 0 || gdbpy_initialize_inferior () < 0 || gdbpy_initialize_events () < 0 || gdbpy_initialize_eventregistry () < 0 @@ -1698,7 +1830,8 @@ do_start_initialization () || gdbpy_initialize_event () < 0 || gdbpy_initialize_arch () < 0 || gdbpy_initialize_xmethods () < 0 - || gdbpy_initialize_unwind () < 0) + || gdbpy_initialize_unwind () < 0 + || gdbpy_initialize_register () < 0) return false; #define GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base) \ @@ -1928,6 +2061,8 @@ PyMethodDef python_GdbMethods[] = Evaluate command, a string, as a gdb CLI command. Optionally returns\n\ a Python String containing the output of the command if to_string is\n\ set to True." }, + { "cli", gdbpy_cli, METH_NOARGS, + "Enter the gdb CLI" }, { "parameter", gdbpy_parameter, METH_VARARGS, "Return a gdb parameter's value" }, @@ -1979,6 +2114,10 @@ a boolean indicating if name is a field of the current implied argument\n\ METH_VARARGS | METH_KEYWORDS, "lookup_global_symbol (name [, domain]) -> symbol\n\ Return the symbol corresponding to the given name (or None)." }, +{ "lookup_minimal_symbol", (PyCFunction) gdbpy_lookup_minimal_symbol, + METH_VARARGS | METH_KEYWORDS, + "lookup_minimal_symbol (name, [sfile, [objfile]]) -> minsym\n\ +Return the symbol corresponding to the given name (or None)." }, { "lookup_objfile", (PyCFunction) gdbpy_lookup_objfile, METH_VARARGS | METH_KEYWORDS, @@ -2043,6 +2182,10 @@ or None if not set." }, "convenience_variable (NAME, VALUE) -> None.\n\ Set the value of the convenience variable $NAME." }, + { "current_target", gdbpy_current_target, METH_NOARGS, + "current_target () -> gdb.Target.\n\ +Return the current target object." }, + {NULL, NULL, 0, NULL} }; diff --git a/gdb/python/python.h b/gdb/python/python.h index 10cd90d00e1..2af0b2934d5 100644 --- a/gdb/python/python.h +++ b/gdb/python/python.h @@ -28,4 +28,6 @@ extern const struct extension_language_defn extension_language_python; /* Command element for the 'python' command. */ extern cmd_list_element *python_cmd_element; +extern void run_python_script (int argc, char **argv); + #endif /* PYTHON_PYTHON_H */ diff --git a/gdb/regcache.c b/gdb/regcache.c index 6e3eee96631..4ecd6ae109e 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -763,7 +763,7 @@ regcache::cooked_write (int regnum, const gdb_byte *buf) /* See regcache.h. */ enum register_status -readable_regcache::read_part (int regnum, int offset, int len, +readable_regcache::read_part (int regnum, LONGEST offset, LONGEST len, gdb_byte *out, bool is_raw) { int reg_size = register_size (arch (), regnum); @@ -830,7 +830,7 @@ reg_buffer::raw_collect_part (int regnum, int offset, int len, /* See regcache.h. */ enum register_status -regcache::write_part (int regnum, int offset, int len, +regcache::write_part (int regnum, LONGEST offset, LONGEST len, const gdb_byte *in, bool is_raw) { int reg_size = register_size (arch (), regnum); @@ -901,7 +901,7 @@ reg_buffer::raw_supply_part (int regnum, int offset, int len, } enum register_status -readable_regcache::raw_read_part (int regnum, int offset, int len, +readable_regcache::raw_read_part (int regnum, int offset, LONGEST len, gdb_byte *buf) { assert_regnum (regnum); @@ -911,7 +911,7 @@ readable_regcache::raw_read_part (int regnum, int offset, int len, /* See regcache.h. */ void -regcache::raw_write_part (int regnum, int offset, int len, +regcache::raw_write_part (int regnum, int offset, LONGEST len, const gdb_byte *buf) { assert_regnum (regnum); @@ -921,7 +921,7 @@ regcache::raw_write_part (int regnum, int offset, int len, /* See regcache.h. */ enum register_status -readable_regcache::cooked_read_part (int regnum, int offset, int len, +readable_regcache::cooked_read_part (int regnum, LONGEST offset, LONGEST len, gdb_byte *buf) { gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers); @@ -931,7 +931,7 @@ readable_regcache::cooked_read_part (int regnum, int offset, int len, /* See regcache.h. */ void -regcache::cooked_write_part (int regnum, int offset, int len, +regcache::cooked_write_part (int regnum, LONGEST offset, LONGEST len, const gdb_byte *buf) { gdb_assert (regnum >= 0 && regnum < m_descr->nr_cooked_registers); diff --git a/gdb/regcache.h b/gdb/regcache.h index 2b703ea4a4b..bfa616e76d2 100644 --- a/gdb/regcache.h +++ b/gdb/regcache.h @@ -273,8 +273,8 @@ class readable_regcache : public reg_buffer enum register_status raw_read (int regnum, T *val); /* Partial transfer of raw registers. Return the status of the register. */ - enum register_status raw_read_part (int regnum, int offset, int len, - gdb_byte *buf); + enum register_status raw_read_part (int regnum, int offset, + LONGEST len, gdb_byte *buf); /* Make certain that the register REGNUM is up-to-date. */ virtual void raw_update (int regnum) = 0; @@ -286,8 +286,8 @@ class readable_regcache : public reg_buffer enum register_status cooked_read (int regnum, T *val); /* Partial transfer of a cooked register. */ - enum register_status cooked_read_part (int regnum, int offset, int len, - gdb_byte *buf); + enum register_status cooked_read_part (int regnum, LONGEST offset, + LONGEST len, gdb_byte *buf); /* Read register REGNUM from the regcache and return a new value. This will call mark_value_bytes_unavailable as appropriate. */ @@ -297,7 +297,7 @@ class readable_regcache : public reg_buffer /* Perform a partial register transfer using a read, modify, write operation. Will fail if register is currently invalid. */ - enum register_status read_part (int regnum, int offset, int len, + enum register_status read_part (int regnum, LONGEST offset, LONGEST len, gdb_byte *out, bool is_raw); }; @@ -355,11 +355,12 @@ class regcache : public detached_regcache /* Partial transfer of raw registers. Perform read, modify, write style operations. */ - void raw_write_part (int regnum, int offset, int len, const gdb_byte *buf); + void raw_write_part (int regnum, int offset, LONGEST len, + const gdb_byte *buf); /* Partial transfer of a cooked register. Perform read, modify, write style operations. */ - void cooked_write_part (int regnum, int offset, int len, + void cooked_write_part (int regnum, LONGEST offset, LONGEST len, const gdb_byte *buf); void supply_regset (const struct regset *regset, @@ -410,7 +411,7 @@ class regcache : public detached_regcache /* Perform a partial register transfer using a read, modify, write operation. */ - enum register_status write_part (int regnum, int offset, int len, + enum register_status write_part (int regnum, LONGEST offset, LONGEST len, const gdb_byte *in, bool is_raw); /* The address space of this register cache (for registers where it diff --git a/gdb/remote.c b/gdb/remote.c index 69b479b40c1..721a22e9d8d 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -440,7 +440,7 @@ class remote_target : public process_stratum_target bool stopped_data_address (CORE_ADDR *) override; - bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) override; + bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, LONGEST) override; int can_use_hw_breakpoint (enum bptype, int, int) override; @@ -448,7 +448,7 @@ class remote_target : public process_stratum_target int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override; - int region_ok_for_hw_watchpoint (CORE_ADDR, int) override; + int region_ok_for_hw_watchpoint (CORE_ADDR, LONGEST) override; int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, struct expression *) override; @@ -10298,7 +10298,7 @@ remote_target::insert_watchpoint (CORE_ADDR addr, int len, p = strchr (rs->buf.data (), '\0'); addr = remote_address_masked (addr); p += hexnumstr (p, (ULONGEST) addr); - xsnprintf (p, endbuf - p, ",%x", len); + xsnprintf (p, endbuf - p, ",%s", phex_nz (len, sizeof (len))); putpkt (rs->buf); getpkt (&rs->buf, 0); @@ -10318,7 +10318,7 @@ remote_target::insert_watchpoint (CORE_ADDR addr, int len, bool remote_target::watchpoint_addr_within_range (CORE_ADDR addr, - CORE_ADDR start, int length) + CORE_ADDR start, LONGEST length) { CORE_ADDR diff = remote_address_masked (addr - start); @@ -10347,7 +10347,7 @@ remote_target::remove_watchpoint (CORE_ADDR addr, int len, p = strchr (rs->buf.data (), '\0'); addr = remote_address_masked (addr); p += hexnumstr (p, (ULONGEST) addr); - xsnprintf (p, endbuf - p, ",%x", len); + xsnprintf (p, endbuf - p, ",%s", phex_nz (len, sizeof (len))); putpkt (rs->buf); getpkt (&rs->buf, 0); @@ -10369,7 +10369,7 @@ int remote_hw_watchpoint_length_limit = -1; int remote_hw_breakpoint_limit = -1; int -remote_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) +remote_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, LONGEST len) { if (remote_hw_watchpoint_length_limit == 0) return 0; @@ -13920,7 +13920,17 @@ remote_target::pid_to_exec_file (int pid) char *annex = NULL; if (packet_support (PACKET_qXfer_exec_file) != PACKET_ENABLE) - return NULL; + { + warning (_("Remote gdbserver does not support determining executable " + "automatically.\n" +"RHEL <=6.8 and <=7.2 versions of gdbserver do not support such automatic executable detection.\n" +"The following versions of gdbserver support it:\n" +"- Upstream version of gdbserver (unsupported) 7.10 or later\n" +"- Red Hat Developer Toolset (DTS) version of gdbserver from DTS 4.0 or later (only on x86_64)\n" +"- RHEL-7.3 versions of gdbserver (on any architecture)" +)); + return NULL; + } inf = find_inferior_pid (pid); if (inf == NULL) diff --git a/gdb/rl78-tdep.c b/gdb/rl78-tdep.c index 52e52a40b9f..e5ecd05da70 100644 --- a/gdb/rl78-tdep.c +++ b/gdb/rl78-tdep.c @@ -1347,8 +1347,8 @@ rl78_push_dummy_call (struct gdbarch *gdbarch, struct value *function, for (i = nargs - 1; i >= 0; i--) { struct type *value_type = value_enclosing_type (args[i]); - int len = TYPE_LENGTH (value_type); - int container_len = (len + 1) & ~1; + LONGEST len = TYPE_LENGTH (value_type); + LONGEST container_len = (len + 1) & ~1; sp -= container_len; write_memory (rl78_make_data_address (sp), diff --git a/gdb/rs6000-aix-tdep.c b/gdb/rs6000-aix-tdep.c index e99865682fd..a1b0388cefd 100644 --- a/gdb/rs6000-aix-tdep.c +++ b/gdb/rs6000-aix-tdep.c @@ -291,9 +291,9 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int ii; - int len = 0; + LONGEST len = 0; int argno; /* current argument number */ - int argbytes; /* current argument byte */ + LONGEST argbytes; /* current argument byte */ gdb_byte tmp_buffer[50]; int f_argno = 0; /* current floating point argno */ int wordsize = gdbarch_tdep (gdbarch)->wordsize; @@ -421,7 +421,7 @@ rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function, if ((argno < nargs) || argbytes) { - int space = 0, jj; + LONGEST space = 0, jj; if (argbytes) { diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 375b960f0ba..505c2f79211 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -157,6 +157,7 @@ static const char *powerpc_vector_abi_string = "auto"; struct rs6000_framedata { + CORE_ADDR func_start; /* True function start. */ int offset; /* total size of frame --- the distance by which we decrement sp to allocate the frame */ @@ -1447,7 +1448,6 @@ static CORE_ADDR skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) { - CORE_ADDR orig_pc = pc; CORE_ADDR last_prologue_pc = pc; CORE_ADDR li_found_pc = 0; gdb_byte buf[4]; @@ -1466,12 +1466,14 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, int minimal_toc_loaded = 0; int prev_insn_was_prologue_insn = 1; int num_skip_non_prologue_insns = 0; + int num_skip_ppc64_gnu_linux_syscall_insn = 0; int r0_contains_arg = 0; const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); memset (fdata, 0, sizeof (struct rs6000_framedata)); + fdata->func_start = pc; fdata->saved_gpr = -1; fdata->saved_fpr = -1; fdata->saved_vr = -1; @@ -1505,6 +1507,55 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, break; op = extract_unsigned_integer (buf, 4, byte_order); + /* A PPC64 GNU/Linux system call function is split into two + sub-functions: a non-threaded fast-path (__NAME_nocancel) + which does not use a frame; and a threaded slow-path + (Lpseudo_cancel) that does create a frame. Ref: + nptl/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h + + *INDENT-OFF* + NAME: + SINGLE_THREAD_P + bne- .Lpseudo_cancel + __NAME_nocancel: + li r0,162 + sc + bnslr+ + b 0x7fe014ef64 <.__syscall_error> + Lpseudo_cancel: + stdu r1,-128(r1) + ... + *INDENT-ON* + + Unfortunatly, because the latter case uses a local label (not + in the symbol table) a PC in "Lpseudo_cancel" appears to be + in "__NAME_nocancel". The following code recognizes this, + adjusting FUNC_START to point to where "Lpseudo_cancel" + should be, and parsing the prologue sequence as if + "Lpseudo_cancel" was the entry point. */ + + if (((op & 0xffff0000) == 0x38000000 /* li r0,N */ + && pc == fdata->func_start + 0 + && num_skip_ppc64_gnu_linux_syscall_insn == 0) + || (op == 0x44000002 /* sc */ + && pc == fdata->func_start + 4 + && num_skip_ppc64_gnu_linux_syscall_insn == 1) + || (op == 0x4ca30020 /* bnslr+ */ + && pc == fdata->func_start + 8 + && num_skip_ppc64_gnu_linux_syscall_insn == 2)) + { + num_skip_ppc64_gnu_linux_syscall_insn++; + continue; + } + else if ((op & 0xfc000003) == 0x48000000 /* b __syscall_error */ + && pc == fdata->func_start + 12 + && num_skip_ppc64_gnu_linux_syscall_insn == 3) + { + num_skip_ppc64_gnu_linux_syscall_insn = -1; + fdata->func_start = pc; + continue; + } + if ((op & 0xfc1fffff) == 0x7c0802a6) { /* mflr Rx */ /* Since shared library / PIC code, which needs to get its @@ -1694,9 +1745,9 @@ skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, CORE_ADDR lim_pc, we have no line table information or the line info tells us that the subroutine call is not part of the line associated with the prologue. */ - if ((pc - orig_pc) > 8) + if ((pc - fdata->func_start) > 8) { - struct symtab_and_line prologue_sal = find_pc_line (orig_pc, 0); + struct symtab_and_line prologue_sal = find_pc_line (fdata->func_start, 0); struct symtab_and_line this_sal = find_pc_line (pc, 0); if ((prologue_sal.line == 0) diff --git a/gdb/rust-exp.y b/gdb/rust-exp.y index 15932638397..8c9dbfd6b16 100644 --- a/gdb/rust-exp.y +++ b/gdb/rust-exp.y @@ -2492,24 +2492,28 @@ rust_parser::convert_ast_to_expression (const struct rust_op *operation, case OP_RANGE: { - enum range_type kind = BOTH_BOUND_DEFAULT; + enum range_type kind = SUBARRAY_NONE_BOUND; if (operation->left.op != NULL) { convert_ast_to_expression (operation->left.op, top); - kind = HIGH_BOUND_DEFAULT; + kind = SUBARRAY_LOW_BOUND; } if (operation->right.op != NULL) { convert_ast_to_expression (operation->right.op, top); - if (kind == BOTH_BOUND_DEFAULT) - kind = (operation->inclusive - ? LOW_BOUND_DEFAULT : LOW_BOUND_DEFAULT_EXCLUSIVE); + if (kind == SUBARRAY_NONE_BOUND) + { + kind = (range_type) SUBARRAY_HIGH_BOUND; + if (!operation->inclusive) + kind = (range_type) (kind | SUBARRAY_HIGH_BOUND_EXCLUSIVE); + } else { - gdb_assert (kind == HIGH_BOUND_DEFAULT); - kind = (operation->inclusive - ? NONE_BOUND_DEFAULT : NONE_BOUND_DEFAULT_EXCLUSIVE); + gdb_assert (kind == SUBARRAY_LOW_BOUND); + kind = (range_type) (kind | SUBARRAY_HIGH_BOUND); + if (!operation->inclusive) + kind = (range_type) (kind | SUBARRAY_HIGH_BOUND_EXCLUSIVE); } } else diff --git a/gdb/rust-lang.c b/gdb/rust-lang.c index 9a123c338ef..5291fd398d9 100644 --- a/gdb/rust-lang.c +++ b/gdb/rust-lang.c @@ -301,7 +301,7 @@ rust_printchar (int c, struct type *type, struct ui_file *stream) static void rust_printstr (struct ui_file *stream, struct type *type, - const gdb_byte *string, unsigned int length, + const gdb_byte *string, ULONGEST length, const char *user_encoding, int force_ellipses, const struct value_print_options *options) { @@ -517,7 +517,7 @@ static const struct generic_val_print_decorations rust_decorations = /* la_val_print implementation for Rust. */ static void -rust_val_print (struct type *type, int embedded_offset, +rust_val_print (struct type *type, LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options) @@ -1193,13 +1193,11 @@ rust_range (struct expression *exp, int *pos, enum noside noside) kind = (enum range_type) longest_to_int (exp->elts[*pos + 1].longconst); *pos += 3; - if (kind == HIGH_BOUND_DEFAULT || kind == NONE_BOUND_DEFAULT - || kind == NONE_BOUND_DEFAULT_EXCLUSIVE) + if ((kind & SUBARRAY_LOW_BOUND) == SUBARRAY_LOW_BOUND) low = evaluate_subexp (NULL_TYPE, exp, pos, noside); - if (kind == LOW_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT_EXCLUSIVE - || kind == NONE_BOUND_DEFAULT || kind == NONE_BOUND_DEFAULT_EXCLUSIVE) + if ((kind & SUBARRAY_HIGH_BOUND) == SUBARRAY_HIGH_BOUND) high = evaluate_subexp (NULL_TYPE, exp, pos, noside); - bool inclusive = (kind == NONE_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT); + bool inclusive = (!((kind & SUBARRAY_HIGH_BOUND_EXCLUSIVE) == SUBARRAY_HIGH_BOUND_EXCLUSIVE)); if (noside == EVAL_SKIP) return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1); @@ -1288,7 +1286,7 @@ rust_compute_range (struct type *type, struct value *range, *low = 0; *high = 0; - *kind = BOTH_BOUND_DEFAULT; + *kind = SUBARRAY_NONE_BOUND; if (TYPE_NFIELDS (type) == 0) return; @@ -1296,15 +1294,14 @@ rust_compute_range (struct type *type, struct value *range, i = 0; if (strcmp (TYPE_FIELD_NAME (type, 0), "start") == 0) { - *kind = HIGH_BOUND_DEFAULT; + *kind = SUBARRAY_LOW_BOUND; *low = value_as_long (value_field (range, 0)); ++i; } if (TYPE_NFIELDS (type) > i && strcmp (TYPE_FIELD_NAME (type, i), "end") == 0) { - *kind = (*kind == BOTH_BOUND_DEFAULT - ? LOW_BOUND_DEFAULT : NONE_BOUND_DEFAULT); + *kind = (range_type) (*kind | SUBARRAY_HIGH_BOUND); *high = value_as_long (value_field (range, i)); if (rust_inclusive_range_type_p (type)) @@ -1322,7 +1319,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside, struct type *rhstype; LONGEST low, high_bound; /* Initialized to appease the compiler. */ - enum range_type kind = BOTH_BOUND_DEFAULT; + enum range_type kind = SUBARRAY_NONE_BOUND; LONGEST high = 0; int want_slice = 0; @@ -1420,7 +1417,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside, error (_("Cannot subscript non-array type")); if (want_slice - && (kind == BOTH_BOUND_DEFAULT || kind == LOW_BOUND_DEFAULT)) + && ((kind & SUBARRAY_LOW_BOUND) != SUBARRAY_LOW_BOUND)) low = low_bound; if (low < 0) error (_("Index less than zero")); @@ -1438,7 +1435,7 @@ rust_subscript (struct expression *exp, int *pos, enum noside noside, CORE_ADDR addr; struct value *addrval, *tem; - if (kind == BOTH_BOUND_DEFAULT || kind == HIGH_BOUND_DEFAULT) + if ((kind & SUBARRAY_HIGH_BOUND) != SUBARRAY_HIGH_BOUND) high = high_bound; if (high < 0) error (_("High index less than zero")); diff --git a/gdb/s390-linux-nat.c b/gdb/s390-linux-nat.c index e2f13def9de..be985d96e21 100644 --- a/gdb/s390-linux-nat.c +++ b/gdb/s390-linux-nat.c @@ -122,7 +122,7 @@ class s390_linux_nat_target final : public linux_nat_target override; int remove_hw_breakpoint (struct gdbarch *, struct bp_target_info *) override; - int region_ok_for_hw_watchpoint (CORE_ADDR, int) override; + int region_ok_for_hw_watchpoint (CORE_ADDR, LONGEST) override; bool stopped_by_watchpoint () override; int insert_watchpoint (CORE_ADDR, int, enum target_hw_bp_type, struct expression *) override; @@ -952,7 +952,8 @@ s390_linux_nat_target::remove_hw_breakpoint (struct gdbarch *gdbarch, } int -s390_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int cnt) +s390_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, + LONGEST cnt) { return 1; } diff --git a/gdb/score-tdep.c b/gdb/score-tdep.c index 02f4ed4a12b..4628f944fe0 100644 --- a/gdb/score-tdep.c +++ b/gdb/score-tdep.c @@ -517,7 +517,7 @@ score_push_dummy_call (struct gdbarch *gdbarch, struct value *function, enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int argnum; int argreg; - int arglen = 0; + LONGEST arglen = 0; CORE_ADDR stack_offset = 0; CORE_ADDR addr = 0; diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index de53dcd8285..602f713af3d 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -812,7 +812,7 @@ sh_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) static int sh_use_struct_convention (int renesas_abi, struct type *type) { - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); int nelem = TYPE_NFIELDS (type); /* The Renesas ABI returns aggregate types always on stack. */ @@ -914,7 +914,7 @@ sh_frame_align (struct gdbarch *ignore, CORE_ADDR sp) /* Helper function to justify value in register according to endianess. */ static const gdb_byte * -sh_justify_value_in_reg (struct gdbarch *gdbarch, struct value *val, int len) +sh_justify_value_in_reg (struct gdbarch *gdbarch, struct value *val, LONGEST len) { static gdb_byte valbuf[4]; @@ -1074,7 +1074,8 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, struct type *type; CORE_ADDR regval; const gdb_byte *val; - int len, reg_size = 0; + LONGEST len; + int reg_size = 0; int pass_on_stack = 0; int treat_as_flt; int last_reg_arg = INT_MAX; @@ -1216,7 +1217,8 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch, struct type *type; CORE_ADDR regval; const gdb_byte *val; - int len, reg_size = 0; + LONGEST len; + int reg_size = 0; int pass_on_stack = 0; int last_reg_arg = INT_MAX; diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index cf83196721f..c1553937fe3 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -45,6 +45,7 @@ #include "auxv.h" #include "gdb_bfd.h" #include "probe.h" +#include "build-id.h" static struct link_map_offsets *svr4_fetch_link_map_offsets (void); static int svr4_have_link_map_offsets (void); @@ -1344,9 +1345,48 @@ svr4_read_so_list (CORE_ADDR lm, CORE_ADDR prev_lm, continue; } - strncpy (newobj->so_name, buffer.get (), SO_NAME_MAX_PATH_SIZE - 1); - newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; - strcpy (newobj->so_original_name, newobj->so_name); + { + struct bfd_build_id *build_id = NULL; + + strncpy (newobj->so_original_name, buffer.get (), SO_NAME_MAX_PATH_SIZE - 1); + newobj->so_original_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; + /* May get overwritten below. */ + strcpy (newobj->so_name, newobj->so_original_name); + + /* In the case the main executable was found according to its build-id + (from a core file) prevent loading a different build of a library + with accidentally the same SO_NAME. + + It suppresses bogus backtraces (and prints "??" there instead) if + the on-disk files no longer match the running program version. + + If the main executable was not loaded according to its build-id do + not do any build-id checking of the libraries. There may be missing + build-ids dumped in the core file and we would map all the libraries + to the only existing file loaded that time - the executable. */ + if (symfile_objfile != NULL + && (symfile_objfile->flags & OBJF_BUILD_ID_CORE_LOADED) != 0) + build_id = build_id_addr_get (li->l_ld); + if (build_id != NULL) + { + char *name, *build_id_filename; + + /* Missing the build-id matching separate debug info file + would be handled while SO_NAME gets loaded. */ + name = build_id_to_filename (build_id, &build_id_filename); + if (name != NULL) + { + strncpy (newobj->so_name, name, SO_NAME_MAX_PATH_SIZE - 1); + newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; + xfree (name); + } + else + debug_print_missing (newobj->so_name, build_id_filename); + + xfree (build_id_filename); + xfree (build_id); + } + } /* If this entry has no name, or its name matches the name for the main executable, don't include it in the list. */ diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index a155cfa7384..841d5759c4a 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -1465,6 +1465,7 @@ sparc32_store_return_value (struct type *type, struct regcache *regcache, if (sparc_floating_p (type) || sparc_complex_floating_p (type)) { /* Floating return values. */ + len = (len <= 8) ? len : 8; memcpy (buf, valbuf, len); regcache->cooked_write (SPARC_F0_REGNUM, buf); if (len > 4) diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c index 5b7d57a2163..026e83230f0 100644 --- a/gdb/sparc64-tdep.c +++ b/gdb/sparc64-tdep.c @@ -1205,7 +1205,7 @@ sparc64_16_byte_align_p (struct type *type) static void sparc64_store_floating_fields (struct regcache *regcache, struct type *type, - const gdb_byte *valbuf, int element, int bitpos) + const gdb_byte *valbuf, int element, LONGEST bitpos) { struct gdbarch *gdbarch = regcache->arch (); int len = TYPE_LENGTH (type); @@ -1265,7 +1265,7 @@ sparc64_store_floating_fields (struct regcache *regcache, struct type *type, for (i = 0; i < TYPE_NFIELDS (type); i++) { struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i)); - int subpos = bitpos + TYPE_FIELD_BITPOS (type, i); + LONGEST subpos = bitpos + TYPE_FIELD_BITPOS (type, i); sparc64_store_floating_fields (regcache, subtype, valbuf, element, subpos); @@ -1297,7 +1297,7 @@ sparc64_store_floating_fields (struct regcache *regcache, struct type *type, static void sparc64_extract_floating_fields (struct regcache *regcache, struct type *type, - gdb_byte *valbuf, int bitpos) + gdb_byte *valbuf, LONGEST bitpos) { struct gdbarch *gdbarch = regcache->arch (); @@ -1353,7 +1353,7 @@ sparc64_extract_floating_fields (struct regcache *regcache, struct type *type, for (i = 0; i < TYPE_NFIELDS (type); i++) { struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i)); - int subpos = bitpos + TYPE_FIELD_BITPOS (type, i); + LONGEST subpos = bitpos + TYPE_FIELD_BITPOS (type, i); sparc64_extract_floating_fields (regcache, subtype, valbuf, subpos); } @@ -1387,7 +1387,7 @@ sparc64_store_arguments (struct regcache *regcache, int nargs, for (i = 0; i < nargs; i++) { struct type *type = value_type (args[i]); - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); if (sparc64_structure_or_union_p (type) || (sparc64_complex_floating_p (type) && len == 32)) @@ -1487,7 +1487,7 @@ sparc64_store_arguments (struct regcache *regcache, int nargs, { const gdb_byte *valbuf = value_contents (args[i]); struct type *type = value_type (args[i]); - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); int regnum = -1; gdb_byte buf[16]; diff --git a/gdb/spu-multiarch.c b/gdb/spu-multiarch.c index 88ad291dbd6..a017eece305 100644 --- a/gdb/spu-multiarch.c +++ b/gdb/spu-multiarch.c @@ -65,7 +65,7 @@ struct spu_multiarch_target final : public target_ops const gdb_byte *pattern, ULONGEST pattern_len, CORE_ADDR *found_addrp) override; - int region_ok_for_hw_watchpoint (CORE_ADDR, int) override; + int region_ok_for_hw_watchpoint (CORE_ADDR, LONGEST) override; struct gdbarch *thread_architecture (ptid_t) override; }; @@ -162,7 +162,7 @@ spu_multiarch_target::thread_architecture (ptid_t ptid) /* Override the to_region_ok_for_hw_watchpoint routine. */ int -spu_multiarch_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) +spu_multiarch_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, LONGEST len) { /* We cannot watch SPU local store. */ if (SPUADDR_SPU (addr) != -1) diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c index c3f5d4e6a78..fb7509ddc15 100644 --- a/gdb/spu-tdep.c +++ b/gdb/spu-tdep.c @@ -1432,7 +1432,7 @@ spu_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct value *arg = args[i]; struct type *type = check_typedef (value_type (arg)); const gdb_byte *contents = value_contents (arg); - int n_regs = align_up (TYPE_LENGTH (type), 16) / 16; + LONGEST n_regs = align_up (TYPE_LENGTH (type), 16) / 16; /* If the argument doesn't wholly fit into registers, it and all subsequent arguments go to the stack. */ @@ -1464,7 +1464,7 @@ spu_push_dummy_call (struct gdbarch *gdbarch, struct value *function, { struct value *arg = args[i]; struct type *type = check_typedef (value_type (arg)); - int len = TYPE_LENGTH (type); + LONGEST len = TYPE_LENGTH (type); int preferred_slot; if (spu_scalar_value_p (type)) diff --git a/gdb/stack.c b/gdb/stack.c index f7fd9433b56..c81844c05d5 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -193,7 +193,7 @@ print_stack_frame (struct frame_info *frame, int print_level, argument (not just the first nameless argument). */ static void -print_frame_nameless_args (struct frame_info *frame, long start, int num, +print_frame_nameless_args (struct frame_info *frame, LONGEST start, int num, int first, struct ui_file *stream) { struct gdbarch *gdbarch = get_frame_arch (frame); @@ -536,7 +536,7 @@ print_frame_args (struct symbol *func, struct frame_info *frame, /* Offset of next stack argument beyond the one we have seen that is at the highest offset, or -1 if we haven't come to a stack argument yet. */ - long highest_offset = -1; + LONGEST highest_offset = -1; /* Number of ints of arguments that we have printed so far. */ int args_printed = 0; /* True if we should print arguments, false otherwise. */ @@ -565,8 +565,8 @@ print_frame_args (struct symbol *func, struct frame_info *frame, case LOC_ARG: case LOC_REF_ARG: { - long current_offset = SYMBOL_VALUE (sym); - int arg_size = TYPE_LENGTH (SYMBOL_TYPE (sym)); + LONGEST current_offset = SYMBOL_VALUE (sym); + LONGEST arg_size = TYPE_LENGTH (SYMBOL_TYPE (sym)); /* Compute address of next argument by adding the size of this argument and rounding to an int boundary. */ @@ -701,7 +701,7 @@ print_frame_args (struct symbol *func, struct frame_info *frame, enough about the stack to find them. */ if (num != -1) { - long start; + LONGEST start; if (highest_offset == -1) start = gdbarch_frame_args_skip (get_frame_arch (frame)); diff --git a/gdb/symfile-add-flags.h b/gdb/symfile-add-flags.h index b29baa15e39..0450ce6470c 100644 --- a/gdb/symfile-add-flags.h +++ b/gdb/symfile-add-flags.h @@ -44,6 +44,10 @@ enum symfile_add_flag : unsigned /* The new objfile should be marked OBJF_NOT_FILENAME. */ SYMFILE_NOT_FILENAME = 1 << 5, + + /* Do not execute the new objfile callback event in + symbol_file_add_with_addrs. */ + SYMFILE_NO_EVENT = 1 << 6, }; DEF_ENUM_FLAGS_TYPE (enum symfile_add_flag, symfile_add_flags); diff --git a/gdb/symfile.c b/gdb/symfile.c index dd9c4ae9856..721b0ac2224 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -669,7 +669,7 @@ default_symfile_offsets (struct objfile *objfile, if (bfd_section_vma (abfd, cur_sec) != 0) break; - if (cur_sec == NULL) + if (1 || cur_sec == NULL) { CORE_ADDR *offsets = objfile->section_offsets->offsets; @@ -1164,7 +1164,8 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name, finish_new_objfile (objfile, add_flags); - gdb::observers::new_objfile.notify (objfile); + if (!(add_flags & SYMFILE_NO_EVENT)) + gdb::observers::new_objfile.notify (objfile); bfd_cache_close_all (); return (objfile); @@ -2272,6 +2273,7 @@ add_symbol_file_command (const char *args, int from_tty) offset = parse_and_eval_address (arg); seen_offset = true; + add_flags |= SYMFILE_NO_EVENT; } else if (strcmp (arg, "--") == 0) stop_processing_options = true; @@ -2341,6 +2343,8 @@ add_symbol_file_command (const char *args, int from_tty) set_objfile_default_section_offset (objf, section_addrs, offset); add_target_sections_of_objfile (objf); + if (seen_offset) + gdb::observers::new_objfile.notify (objf); /* Getting new symbols may change our opinion about what is frameless. */ @@ -3617,6 +3621,12 @@ default_symfile_relocate (struct objfile *objfile, asection *sectp, DWO file. */ bfd *abfd = sectp->owner; + /* Executable files have all the relocations already resolved. + Handle files linked with --emit-relocs. + http://sources.redhat.com/ml/gdb/2006-08/msg00137.html */ + if ((abfd->flags & EXEC_P) != 0) + return NULL; + /* We're only interested in sections with relocation information. */ if ((sectp->flags & SEC_RELOC) == 0) diff --git a/gdb/symfile.h b/gdb/symfile.h index a873dfe9451..e7a778f1d8b 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -531,6 +531,12 @@ void expand_symtabs_matching void map_symbol_filenames (symbol_filename_ftype *fun, void *data, int need_fullname); +/* build-id support. */ +extern struct bfd_build_id *build_id_addr_get (CORE_ADDR addr); +extern void debug_print_missing (const char *binary, const char *debug); +extern void debug_flush_missing (void); +#define BUILD_ID_MAIN_EXECUTABLE_FILENAME _("the main executable file") + /* From dwarf2read.c */ /* Names for a dwarf2 debugging section. The field NORMAL is the normal diff --git a/gdb/symmisc.c b/gdb/symmisc.c index 7666de390cd..ae926796db2 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -579,7 +579,7 @@ print_symbol (struct gdbarch *gdbarch, struct symbol *symbol, case LOC_CONST_BYTES: { - unsigned i; + ULONGEST i; struct type *type = check_typedef (SYMBOL_TYPE (symbol)); fprintf_filtered (outfile, "const %s hex bytes:", diff --git a/gdb/symtab.c b/gdb/symtab.c index 16e641a830b..0954ba70bb8 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -3168,6 +3168,13 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) SYMBOL_LINKAGE_NAME (msymbol)); */ ; /* fall through */ + /* `msymbol' trampoline may be located before its .text symbol + but this text symbol may be the address we were looking for. + Avoid `find_pc_sect_line'<->`find_pc_line' infinite loop. + Red Hat Bug 218379. */ + else if (BMSYMBOL_VALUE_ADDRESS (mfunsym) == pc) + warning ("In stub for %s (0x%s); interlocked, please submit the binary to http://bugzilla.redhat.com", MSYMBOL_LINKAGE_NAME (msymbol.minsym), paddress (target_gdbarch (), pc)); + /* fall through */ else return find_pc_line (BMSYMBOL_VALUE_ADDRESS (mfunsym), 0); } diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c index cfc0ce06e99..b78060a58a3 100644 --- a/gdb/target-delegates.c +++ b/gdb/target-delegates.c @@ -37,9 +37,9 @@ struct dummy_target : public target_ops bool stopped_by_watchpoint () override; bool have_steppable_watchpoint () override; bool stopped_data_address (CORE_ADDR *arg0) override; - bool watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int arg2) override; - int region_ok_for_hw_watchpoint (CORE_ADDR arg0, int arg1) override; - bool can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2, struct expression *arg3) override; + bool watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, LONGEST arg2) override; + int region_ok_for_hw_watchpoint (CORE_ADDR arg0, LONGEST arg1) override; + bool can_accel_watchpoint_condition (CORE_ADDR arg0, LONGEST arg1, int arg2, struct expression *arg3) override; int masked_watch_num_registers (CORE_ADDR arg0, CORE_ADDR arg1) override; int can_do_single_step () override; bool supports_terminal_ours () override; @@ -205,9 +205,9 @@ struct debug_target : public target_ops bool stopped_by_watchpoint () override; bool have_steppable_watchpoint () override; bool stopped_data_address (CORE_ADDR *arg0) override; - bool watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int arg2) override; - int region_ok_for_hw_watchpoint (CORE_ADDR arg0, int arg1) override; - bool can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2, struct expression *arg3) override; + bool watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, LONGEST arg2) override; + int region_ok_for_hw_watchpoint (CORE_ADDR arg0, LONGEST arg1) override; + bool can_accel_watchpoint_condition (CORE_ADDR arg0, LONGEST arg1, int arg2, struct expression *arg3) override; int masked_watch_num_registers (CORE_ADDR arg0, CORE_ADDR arg1) override; int can_do_single_step () override; bool supports_terminal_ours () override; @@ -1043,19 +1043,19 @@ debug_target::stopped_data_address (CORE_ADDR *arg0) } bool -target_ops::watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int arg2) +target_ops::watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, LONGEST arg2) { return this->beneath ()->watchpoint_addr_within_range (arg0, arg1, arg2); } bool -dummy_target::watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int arg2) +dummy_target::watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, LONGEST arg2) { return default_watchpoint_addr_within_range (this, arg0, arg1, arg2); } bool -debug_target::watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int arg2) +debug_target::watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, LONGEST arg2) { bool result; fprintf_unfiltered (gdb_stdlog, "-> %s->watchpoint_addr_within_range (...)\n", this->beneath ()->shortname ()); @@ -1065,7 +1065,7 @@ debug_target::watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int fputs_unfiltered (", ", gdb_stdlog); target_debug_print_CORE_ADDR (arg1); fputs_unfiltered (", ", gdb_stdlog); - target_debug_print_int (arg2); + target_debug_print_LONGEST (arg2); fputs_unfiltered (") = ", gdb_stdlog); target_debug_print_bool (result); fputs_unfiltered ("\n", gdb_stdlog); @@ -1073,19 +1073,19 @@ debug_target::watchpoint_addr_within_range (CORE_ADDR arg0, CORE_ADDR arg1, int } int -target_ops::region_ok_for_hw_watchpoint (CORE_ADDR arg0, int arg1) +target_ops::region_ok_for_hw_watchpoint (CORE_ADDR arg0, LONGEST arg1) { return this->beneath ()->region_ok_for_hw_watchpoint (arg0, arg1); } int -dummy_target::region_ok_for_hw_watchpoint (CORE_ADDR arg0, int arg1) +dummy_target::region_ok_for_hw_watchpoint (CORE_ADDR arg0, LONGEST arg1) { return default_region_ok_for_hw_watchpoint (this, arg0, arg1); } int -debug_target::region_ok_for_hw_watchpoint (CORE_ADDR arg0, int arg1) +debug_target::region_ok_for_hw_watchpoint (CORE_ADDR arg0, LONGEST arg1) { int result; fprintf_unfiltered (gdb_stdlog, "-> %s->region_ok_for_hw_watchpoint (...)\n", this->beneath ()->shortname ()); @@ -1093,7 +1093,7 @@ debug_target::region_ok_for_hw_watchpoint (CORE_ADDR arg0, int arg1) fprintf_unfiltered (gdb_stdlog, "<- %s->region_ok_for_hw_watchpoint (", this->beneath ()->shortname ()); target_debug_print_CORE_ADDR (arg0); fputs_unfiltered (", ", gdb_stdlog); - target_debug_print_int (arg1); + target_debug_print_LONGEST (arg1); fputs_unfiltered (") = ", gdb_stdlog); target_debug_print_int (result); fputs_unfiltered ("\n", gdb_stdlog); @@ -1101,19 +1101,19 @@ debug_target::region_ok_for_hw_watchpoint (CORE_ADDR arg0, int arg1) } bool -target_ops::can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2, struct expression *arg3) +target_ops::can_accel_watchpoint_condition (CORE_ADDR arg0, LONGEST arg1, int arg2, struct expression *arg3) { return this->beneath ()->can_accel_watchpoint_condition (arg0, arg1, arg2, arg3); } bool -dummy_target::can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2, struct expression *arg3) +dummy_target::can_accel_watchpoint_condition (CORE_ADDR arg0, LONGEST arg1, int arg2, struct expression *arg3) { return false; } bool -debug_target::can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2, struct expression *arg3) +debug_target::can_accel_watchpoint_condition (CORE_ADDR arg0, LONGEST arg1, int arg2, struct expression *arg3) { bool result; fprintf_unfiltered (gdb_stdlog, "-> %s->can_accel_watchpoint_condition (...)\n", this->beneath ()->shortname ()); @@ -1121,7 +1121,7 @@ debug_target::can_accel_watchpoint_condition (CORE_ADDR arg0, int arg1, int arg2 fprintf_unfiltered (gdb_stdlog, "<- %s->can_accel_watchpoint_condition (", this->beneath ()->shortname ()); target_debug_print_CORE_ADDR (arg0); fputs_unfiltered (", ", gdb_stdlog); - target_debug_print_int (arg1); + target_debug_print_LONGEST (arg1); fputs_unfiltered (", ", gdb_stdlog); target_debug_print_int (arg2); fputs_unfiltered (", ", gdb_stdlog); diff --git a/gdb/target.c b/gdb/target.c index f492102b6d4..de193ff87ac 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -55,10 +55,10 @@ static void generic_tls_error (void) ATTRIBUTE_NORETURN; static void default_terminal_info (struct target_ops *, const char *, int); static int default_watchpoint_addr_within_range (struct target_ops *, - CORE_ADDR, CORE_ADDR, int); + CORE_ADDR, CORE_ADDR, LONGEST); static int default_region_ok_for_hw_watchpoint (struct target_ops *, - CORE_ADDR, int); + CORE_ADDR, LONGEST); static void default_rcmd (struct target_ops *, const char *, struct ui_file *); @@ -287,6 +287,23 @@ information on the arguments for a particular protocol, type\n\ set_cmd_completer (c, completer); } +void +delete_target (const target_info &t, target_open_ftype *func) +{ + struct cmd_list_element *c = NULL; + auto &func_slot = target_factories[&t]; + if (target_factories[&t] != func) + { + internal_error (__FILE__, __LINE__, + _("target to be deleted was not added (\"%s\")."), + t.shortname); + } + func_slot = nullptr; + + c = add_alias_cmd (t.shortname, c, no_class, 0, &targetlist); + gdb_assert (c == NULL); +} + /* See target.h. */ void @@ -3126,7 +3143,7 @@ target_fileio_read_stralloc (struct inferior *inf, const char *filename) static int default_region_ok_for_hw_watchpoint (struct target_ops *self, - CORE_ADDR addr, int len) + CORE_ADDR addr, LONGEST len) { return (len <= gdbarch_ptr_bit (target_gdbarch ()) / TARGET_CHAR_BIT); } @@ -3134,7 +3151,7 @@ default_region_ok_for_hw_watchpoint (struct target_ops *self, static int default_watchpoint_addr_within_range (struct target_ops *target, CORE_ADDR addr, - CORE_ADDR start, int length) + CORE_ADDR start, LONGEST length) { return addr >= start && addr < start + length; } diff --git a/gdb/target.h b/gdb/target.h index 9078a420018..71c74d38f5d 100644 --- a/gdb/target.h +++ b/gdb/target.h @@ -561,15 +561,15 @@ struct target_ops TARGET_DEFAULT_RETURN (false); virtual bool stopped_data_address (CORE_ADDR *) TARGET_DEFAULT_RETURN (false); - virtual bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, int) + virtual bool watchpoint_addr_within_range (CORE_ADDR, CORE_ADDR, LONGEST) TARGET_DEFAULT_FUNC (default_watchpoint_addr_within_range); /* Documentation of this routine is provided with the corresponding target_* macro. */ - virtual int region_ok_for_hw_watchpoint (CORE_ADDR, int) + virtual int region_ok_for_hw_watchpoint (CORE_ADDR, LONGEST) TARGET_DEFAULT_FUNC (default_region_ok_for_hw_watchpoint); - virtual bool can_accel_watchpoint_condition (CORE_ADDR, int, int, + virtual bool can_accel_watchpoint_condition (CORE_ADDR, LONGEST, int, struct expression *) TARGET_DEFAULT_RETURN (false); virtual int masked_watch_num_registers (CORE_ADDR, CORE_ADDR) @@ -1980,9 +1980,11 @@ extern gdb::byte_vector target_thread_info_to_thread_handle one. OTHERTYPE is the number of watchpoints of other types than this one used so far. */ +#ifndef target_can_use_hardware_watchpoint #define target_can_use_hardware_watchpoint(TYPE,CNT,OTHERTYPE) \ (current_top_target ()->can_use_hw_breakpoint) ( \ TYPE, CNT, OTHERTYPE) +#endif /* Returns the number of debug registers needed to watch the given memory region, or zero if not supported. */ @@ -2333,6 +2335,9 @@ extern void add_target (const target_info &info, target_open_ftype *func, completer_ftype *completer = NULL); + +extern void delete_target (const target_info &t, target_open_ftype *func); + /* Adds a command ALIAS for the target described by INFO and marks it deprecated. This is useful for maintaining backwards compatibility when renaming targets. */ diff --git a/gdb/target.py b/gdb/target.py new file mode 100644 index 00000000000..9df497676d3 --- /dev/null +++ b/gdb/target.py @@ -0,0 +1,137 @@ +# -*- coding: utf-8 -*- +# vim:set shiftwidth=4 softtabstop=4 expandtab textwidth=79: + +from __future__ import absolute_import +from __future__ import print_function +from __future__ import division + +import gdb +import sys +from kdumpfile import kdumpfile, KDUMP_KVADDR +from kdumpfile.exceptions import * +import addrxlat + +if sys.version_info.major >= 3: + long = int + +class SymbolCallback(object): + "addrxlat symbolic callback" + + def __init__(self, ctx=None, *args, **kwargs): + super(SymbolCallback, self).__init__(*args, **kwargs) + self.ctx = ctx + + def __call__(self, symtype, *args): + if self.ctx is not None: + try: + return self.ctx.next_cb_sym(symtype, *args) + except addrxlat.BaseException: + self.ctx.clear_err() + + if symtype == addrxlat.SYM_VALUE: + ms = gdb.lookup_minimal_symbol(args[0]) + if ms is not None: + return long(ms.value().address) + raise addrxlat.NoDataError() + +class Target(gdb.Target): + def __init__(self, debug=False): + super(Target, self).__init__() + self.arch = None + self.debug = debug + self.shortname = "kdumpfile" + self.longname = "Use a Linux kernel kdump file as a target" + + self.register() + + def open(self, filename, from_tty): + try: + self.kdump = kdumpfile(file=filename) + except Exception as e: + raise gdb.GdbError("Failed to open `{}': {}" + .format(filename, str(e))) + + self.kdump.attr['addrxlat.ostype'] = 'linux' + ctx = self.kdump.get_addrxlat_ctx() + ctx.cb_sym = SymbolCallback(ctx) + + KERNELOFFSET = "linux.vmcoreinfo.lines.KERNELOFFSET" + try: + attr = self.kdump.attr.get(KERNELOFFSET, "0") + self.base_offset = long(attr, base=16) + except Exception as e: + self.base_offset = 0 + + vmlinux = gdb.objfiles()[0].filename + + # Load the kernel at the relocated address + gdb.execute(f"add-symbol-file {vmlinux} -o {self.base_offset:#x} -s .data..percpu 0") + + # Clear out the old symbol cache + gdb.execute(f"file {vmlinux}") + + def close(self): + self.unregister() + del self.kdump + + @classmethod + def report_error(cls, addr, length, error): + print("Error while reading {:d} bytes from {:#x}: {}" + .format(length, addr, str(error)), + file=sys.stderr) + + def xfer_partial(self, obj, annex, readbuf, writebuf, offset, ln): + ret = -1 + if obj == self.TARGET_OBJECT_MEMORY: + try: + r = self.kdump.read(KDUMP_KVADDR, offset, ln) + readbuf[:] = r + ret = ln + except EOFException as e: + if self.debug: + self.report_error(offset, ln, e) + raise gdb.TargetXferEof(str(e)) + except NoDataException as e: + if self.debug: + self.report_error(offset, ln, e) + raise gdb.TargetXferUnavailable(str(e)) + except AddressTranslationException as e: + if self.debug: + self.report_error(offset, ln, e) + raise gdb.TargetXferUnavailable(str(e)) + else: + raise IOError("Unknown obj type") + return ret + + @staticmethod + def _thread_alive(ptid): + return True + + @staticmethod + def pid_to_str(ptid): + return "pid {:d}".format(ptid[1]) + + def fetch_registers(self, register): + return False + + @staticmethod + def prepare_to_store(thread): + pass + + # We don't need to store anything; The regcache is already written. + @staticmethod + def store_registers(thread): + pass + + @staticmethod + def has_execution(ptid): + return False + +x = Target(True) +#print("Created / Unregistering") +#x.unregister() +#print("Unregstered / Destroying") +#print("Destroying") + +#del x +#print("Destroyed") diff --git a/gdb/test.sh b/gdb/test.sh new file mode 100644 index 00000000000..99d54aad7ba --- /dev/null +++ b/gdb/test.sh @@ -0,0 +1 @@ +./gdb --data-directory ./data-directory -nh -x gdbinit diff --git a/gdb/testsuite/gdb.ada/packed_array.exp b/gdb/testsuite/gdb.ada/packed_array.exp index 7ad9d770c83..0e13c09d5ee 100644 --- a/gdb/testsuite/gdb.ada/packed_array.exp +++ b/gdb/testsuite/gdb.ada/packed_array.exp @@ -56,5 +56,11 @@ gdb_test_multiple "$test" "$test" { # are. Observed with (FSF GNU Ada 4.5.3 20110124). xfail $test } + -re "= \\(\\)\[\r\n\]+$gdb_prompt $" { + # archer-jankratochvil-vla resolves it as a dynamic type resolved as an + # empty array [0..-1]. + # DW_AT_upper_bound : (DW_OP_fbreg: -48; DW_OP_deref) + xfail $test + } } diff --git a/gdb/testsuite/gdb.arch/amd64-clflushopt.S b/gdb/testsuite/gdb.arch/amd64-clflushopt.S new file mode 100644 index 00000000000..dee4f006dc4 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-clflushopt.S @@ -0,0 +1,19 @@ +/* Copyright 2016 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 . + + This file is part of the gdb testsuite. */ + +_start: .globl _start + clflushopt (%edi) diff --git a/gdb/testsuite/gdb.arch/amd64-clflushopt.exp b/gdb/testsuite/gdb.arch/amd64-clflushopt.exp new file mode 100644 index 00000000000..22a9decee28 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-clflushopt.exp @@ -0,0 +1,25 @@ +# Copyright 2016 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 . + +if { ![istarget "x86_64-*-*"] && ![istarget "i?86-*-*"] } then { + verbose "Skipping amd64 clflushopt test." + return +} + +if [prepare_for_testing amd64-clflushopt.exp amd64-clflushopt amd64-clflushopt.S [list debug "additional_flags=-nostdlib"]] { + return -1 +} + +gdb_test "disas _start" "Dump of assembler code for function _start:\r\n *0x\[0-9a-f\]+ <\[+\]0>:\tclflushopt \\(%edi\\)\r\nEnd of assembler dump\\." "clflushopt" diff --git a/gdb/testsuite/gdb.arch/amd64-ivy-bridge.S b/gdb/testsuite/gdb.arch/amd64-ivy-bridge.S new file mode 100644 index 00000000000..24e41c0e024 --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-ivy-bridge.S @@ -0,0 +1,98 @@ +/* Copyright 2011 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 . + + This file is part of the gdb testsuite. */ + + .globl _start +_start: .text + +/* gas/i386/x86-64-rdrnd.s */ + .att_syntax prefix + rdrand %bx + rdrand %ebx + rdrand %rbx + rdrand %r8w + rdrand %r8d + rdrand %r8 + + .intel_syntax noprefix + rdrand bx + rdrand ebx + rdrand rbx + rdrand r8w + rdrand r8d + rdrand r8 + +/* gas/i386/x86-64-f16c.s */ + .att_syntax prefix + vcvtph2ps %xmm4,%ymm4 + vcvtph2ps (%r8),%ymm8 + vcvtph2ps %xmm4,%xmm6 + vcvtph2ps (%rcx),%xmm4 + vcvtps2ph $0x2,%ymm4,%xmm4 + vcvtps2ph $0x2,%ymm8,(%r8) + vcvtps2ph $0x2,%xmm4,%xmm4 + vcvtps2ph $0x2,%xmm4,(%rcx) + + .intel_syntax noprefix + vcvtph2ps ymm4,xmm4 + vcvtph2ps ymm8,XMMWORD PTR [r8] + vcvtph2ps ymm4,[rcx] + vcvtph2ps xmm6,xmm4 + vcvtph2ps xmm4,QWORD PTR [rcx] + vcvtph2ps xmm4,[rcx] + vcvtps2ph xmm4,ymm4,0x2 + vcvtps2ph XMMWORD PTR [rcx],ymm4,0x2 + vcvtps2ph [rcx],ymm4,0x2 + vcvtps2ph xmm4,xmm4,0x2 + vcvtps2ph QWORD PTR [r8],xmm8,0x2 + vcvtps2ph [rcx],xmm4,0x2 + +/* gas/i386/x86-64-fsgs.s */ + .att_syntax prefix + rdfsbase %ebx + rdfsbase %rbx + rdfsbase %r8d + rdfsbase %r8 + rdgsbase %ebx + rdgsbase %rbx + rdgsbase %r8d + rdgsbase %r8 + wrfsbase %ebx + wrfsbase %rbx + wrfsbase %r8d + wrfsbase %r8 + wrgsbase %ebx + wrgsbase %rbx + wrgsbase %r8d + wrgsbase %r8 + + .intel_syntax noprefix + rdfsbase ebx + rdfsbase rbx + rdfsbase r8d + rdfsbase r8 + rdgsbase ebx + rdgsbase rbx + rdgsbase r8d + rdgsbase r8 + wrfsbase ebx + wrfsbase rbx + wrfsbase r8d + wrfsbase r8 + wrgsbase ebx + wrgsbase rbx + wrgsbase r8d + wrgsbase r8 diff --git a/gdb/testsuite/gdb.arch/amd64-ivy-bridge.exp b/gdb/testsuite/gdb.arch/amd64-ivy-bridge.exp new file mode 100644 index 00000000000..d1b1f27db4b --- /dev/null +++ b/gdb/testsuite/gdb.arch/amd64-ivy-bridge.exp @@ -0,0 +1,170 @@ +# Copyright 2011 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 . + +if {![istarget "x86_64-*-*"]} then { + return +} + +set testfile amd64-ivy-bridge +set test compilation +if [prepare_for_testing ${testfile}.exp ${testfile}.x ${testfile}.S [list debug "additional_flags=-m64 -nostdlib"]] { + fail $test + return -1 +} +pass $test + +gdb_test_no_output "set disassembly-flavor att" +# gas/i386/x86-64-rdrnd.d +# gas/i386/x86-64-f16c.d +# gas/i386/x86-64-fsgs.d +gdb_test "disassemble/r _start" "\r +Dump of assembler code for function _start:\r +\[^\r\n\]+:\t66 0f c7 f3\t\( \)?rdrand %bx\r +\[^\r\n\]+:\t0f c7 f3\t\( \)?rdrand %ebx\r +\[^\r\n\]+:\t48 0f c7 f3\t\( \)?rdrand %rbx\r +\[^\r\n\]+:\t66 41 0f c7 f0\t\( \)?rdrand %r8w\r +\[^\r\n\]+:\t41 0f c7 f0\t\( \)?rdrand %r8d\r +\[^\r\n\]+:\t49 0f c7 f0\t\( \)?rdrand %r8\r +\[^\r\n\]+:\t66 0f c7 f3\t\( \)?rdrand %bx\r +\[^\r\n\]+:\t0f c7 f3\t\( \)?rdrand %ebx\r +\[^\r\n\]+:\t48 0f c7 f3\t\( \)?rdrand %rbx\r +\[^\r\n\]+:\t66 41 0f c7 f0\t\( \)?rdrand %r8w\r +\[^\r\n\]+:\t41 0f c7 f0\t\( \)?rdrand %r8d\r +\[^\r\n\]+:\t49 0f c7 f0\t\( \)?rdrand %r8\r +\[^\r\n\]+:\tc4 e2 7d 13 e4\t\( \)?vcvtph2ps %xmm4,%ymm4\r +\[^\r\n\]+:\tc4 42 7d 13 00\t\( \)?vcvtph2ps \\(%r8\\),%ymm8\r +\[^\r\n\]+:\tc4 e2 79 13 f4\t\( \)?vcvtph2ps %xmm4,%xmm6\r +\[^\r\n\]+:\tc4 e2 79 13 21\t\( \)?vcvtph2ps \\(%rcx\\),%xmm4\r +\[^\r\n\]+:\tc4 e3 7d 1d e4 02\t\( \)?vcvtps2ph \\\$0x2,%ymm4,%xmm4\r +\[^\r\n\]+:\tc4 43 7d 1d 00 02\t\( \)?vcvtps2ph \\\$0x2,%ymm8,\\(%r8\\)\r +\[^\r\n\]+:\tc4 e3 79 1d e4 02\t\( \)?vcvtps2ph \\\$0x2,%xmm4,%xmm4\r +\[^\r\n\]+:\tc4 e3 79 1d 21 02\t\( \)?vcvtps2ph \\\$0x2,%xmm4,\\(%rcx\\)\r +\[^\r\n\]+:\tc4 e2 7d 13 e4\t\( \)?vcvtph2ps %xmm4,%ymm4\r +\[^\r\n\]+:\tc4 42 7d 13 00\t\( \)?vcvtph2ps \\(%r8\\),%ymm8\r +\[^\r\n\]+:\tc4 e2 7d 13 21\t\( \)?vcvtph2ps \\(%rcx\\),%ymm4\r +\[^\r\n\]+:\tc4 e2 79 13 f4\t\( \)?vcvtph2ps %xmm4,%xmm6\r +\[^\r\n\]+:\tc4 e2 79 13 21\t\( \)?vcvtph2ps \\(%rcx\\),%xmm4\r +\[^\r\n\]+:\tc4 e2 79 13 21\t\( \)?vcvtph2ps \\(%rcx\\),%xmm4\r +\[^\r\n\]+:\tc4 e3 7d 1d e4 02\t\( \)?vcvtps2ph \\\$0x2,%ymm4,%xmm4\r +\[^\r\n\]+:\tc4 e3 7d 1d 21 02\t\( \)?vcvtps2ph \\\$0x2,%ymm4,\\(%rcx\\)\r +\[^\r\n\]+:\tc4 e3 7d 1d 21 02\t\( \)?vcvtps2ph \\\$0x2,%ymm4,\\(%rcx\\)\r +\[^\r\n\]+:\tc4 e3 79 1d e4 02\t\( \)?vcvtps2ph \\\$0x2,%xmm4,%xmm4\r +\[^\r\n\]+:\tc4 43 79 1d 00 02\t\( \)?vcvtps2ph \\\$0x2,%xmm8,\\(%r8\\)\r +\[^\r\n\]+:\tc4 e3 79 1d 21 02\t\( \)?vcvtps2ph \\\$0x2,%xmm4,\\(%rcx\\)\r +\[^\r\n\]+:\tf3 0f ae c3\t\( \)?rdfsbase %ebx\r +\[^\r\n\]+:\tf3 48 0f ae c3\t\( \)?rdfsbase %rbx\r +\[^\r\n\]+:\tf3 41 0f ae c0\t\( \)?rdfsbase %r8d\r +\[^\r\n\]+:\tf3 49 0f ae c0\t\( \)?rdfsbase %r8\r +\[^\r\n\]+:\tf3 0f ae cb\t\( \)?rdgsbase %ebx\r +\[^\r\n\]+:\tf3 48 0f ae cb\t\( \)?rdgsbase %rbx\r +\[^\r\n\]+:\tf3 41 0f ae c8\t\( \)?rdgsbase %r8d\r +\[^\r\n\]+:\tf3 49 0f ae c8\t\( \)?rdgsbase %r8\r +\[^\r\n\]+:\tf3 0f ae d3\t\( \)?wrfsbase %ebx\r +\[^\r\n\]+:\tf3 48 0f ae d3\t\( \)?wrfsbase %rbx\r +\[^\r\n\]+:\tf3 41 0f ae d0\t\( \)?wrfsbase %r8d\r +\[^\r\n\]+:\tf3 49 0f ae d0\t\( \)?wrfsbase %r8\r +\[^\r\n\]+:\tf3 0f ae db\t\( \)?wrgsbase %ebx\r +\[^\r\n\]+:\tf3 48 0f ae db\t\( \)?wrgsbase %rbx\r +\[^\r\n\]+:\tf3 41 0f ae d8\t\( \)?wrgsbase %r8d\r +\[^\r\n\]+:\tf3 49 0f ae d8\t\( \)?wrgsbase %r8\r +\[^\r\n\]+:\tf3 0f ae c3\t\( \)?rdfsbase %ebx\r +\[^\r\n\]+:\tf3 48 0f ae c3\t\( \)?rdfsbase %rbx\r +\[^\r\n\]+:\tf3 41 0f ae c0\t\( \)?rdfsbase %r8d\r +\[^\r\n\]+:\tf3 49 0f ae c0\t\( \)?rdfsbase %r8\r +\[^\r\n\]+:\tf3 0f ae cb\t\( \)?rdgsbase %ebx\r +\[^\r\n\]+:\tf3 48 0f ae cb\t\( \)?rdgsbase %rbx\r +\[^\r\n\]+:\tf3 41 0f ae c8\t\( \)?rdgsbase %r8d\r +\[^\r\n\]+:\tf3 49 0f ae c8\t\( \)?rdgsbase %r8\r +\[^\r\n\]+:\tf3 0f ae d3\t\( \)?wrfsbase %ebx\r +\[^\r\n\]+:\tf3 48 0f ae d3\t\( \)?wrfsbase %rbx\r +\[^\r\n\]+:\tf3 41 0f ae d0\t\( \)?wrfsbase %r8d\r +\[^\r\n\]+:\tf3 49 0f ae d0\t\( \)?wrfsbase %r8\r +\[^\r\n\]+:\tf3 0f ae db\t\( \)?wrgsbase %ebx\r +\[^\r\n\]+:\tf3 48 0f ae db\t\( \)?wrgsbase %rbx\r +\[^\r\n\]+:\tf3 41 0f ae d8\t\( \)?wrgsbase %r8d\r +\[^\r\n\]+:\tf3 49 0f ae d8\t\( \)?wrgsbase %r8\r +End of assembler dump\\." "att" + +gdb_test_no_output "set disassembly-flavor intel" +# gas/i386/x86-64-rdrnd-intel.d +# gas/i386/x86-64-f16c-intel.d +# gas/i386/x86-64-fsgs-intel.d +gdb_test "disassemble/r _start" "\r +Dump of assembler code for function _start:\r +\[^\r\n\]+:\t66 0f c7 f3\t\( \)?rdrand bx\r +\[^\r\n\]+:\t0f c7 f3\t\( \)?rdrand ebx\r +\[^\r\n\]+:\t48 0f c7 f3\t\( \)?rdrand rbx\r +\[^\r\n\]+:\t66 41 0f c7 f0\t\( \)?rdrand r8w\r +\[^\r\n\]+:\t41 0f c7 f0\t\( \)?rdrand r8d\r +\[^\r\n\]+:\t49 0f c7 f0\t\( \)?rdrand r8\r +\[^\r\n\]+:\t66 0f c7 f3\t\( \)?rdrand bx\r +\[^\r\n\]+:\t0f c7 f3\t\( \)?rdrand ebx\r +\[^\r\n\]+:\t48 0f c7 f3\t\( \)?rdrand rbx\r +\[^\r\n\]+:\t66 41 0f c7 f0\t\( \)?rdrand r8w\r +\[^\r\n\]+:\t41 0f c7 f0\t\( \)?rdrand r8d\r +\[^\r\n\]+:\t49 0f c7 f0\t\( \)?rdrand r8\r +\[^\r\n\]+:\tc4 e2 7d 13 e4\t\( \)?vcvtph2ps ymm4,xmm4\r +\[^\r\n\]+:\tc4 42 7d 13 00\t\( \)?vcvtph2ps ymm8,XMMWORD PTR \\\[r8\\\]\r +\[^\r\n\]+:\tc4 e2 79 13 f4\t\( \)?vcvtph2ps xmm6,xmm4\r +\[^\r\n\]+:\tc4 e2 79 13 21\t\( \)?vcvtph2ps xmm4,QWORD PTR \\\[rcx\\\]\r +\[^\r\n\]+:\tc4 e3 7d 1d e4 02\t\( \)?vcvtps2ph xmm4,ymm4,0x2\r +\[^\r\n\]+:\tc4 43 7d 1d 00 02\t\( \)?vcvtps2ph XMMWORD PTR \\\[r8\\\],ymm8,0x2\r +\[^\r\n\]+:\tc4 e3 79 1d e4 02\t\( \)?vcvtps2ph xmm4,xmm4,0x2\r +\[^\r\n\]+:\tc4 e3 79 1d 21 02\t\( \)?vcvtps2ph QWORD PTR \\\[rcx\\\],xmm4,0x2\r +\[^\r\n\]+:\tc4 e2 7d 13 e4\t\( \)?vcvtph2ps ymm4,xmm4\r +\[^\r\n\]+:\tc4 42 7d 13 00\t\( \)?vcvtph2ps ymm8,XMMWORD PTR \\\[r8\\\]\r +\[^\r\n\]+:\tc4 e2 7d 13 21\t\( \)?vcvtph2ps ymm4,XMMWORD PTR \\\[rcx\\\]\r +\[^\r\n\]+:\tc4 e2 79 13 f4\t\( \)?vcvtph2ps xmm6,xmm4\r +\[^\r\n\]+:\tc4 e2 79 13 21\t\( \)?vcvtph2ps xmm4,QWORD PTR \\\[rcx\\\]\r +\[^\r\n\]+:\tc4 e2 79 13 21\t\( \)?vcvtph2ps xmm4,QWORD PTR \\\[rcx\\\]\r +\[^\r\n\]+:\tc4 e3 7d 1d e4 02\t\( \)?vcvtps2ph xmm4,ymm4,0x2\r +\[^\r\n\]+:\tc4 e3 7d 1d 21 02\t\( \)?vcvtps2ph XMMWORD PTR \\\[rcx\\\],ymm4,0x2\r +\[^\r\n\]+:\tc4 e3 7d 1d 21 02\t\( \)?vcvtps2ph XMMWORD PTR \\\[rcx\\\],ymm4,0x2\r +\[^\r\n\]+:\tc4 e3 79 1d e4 02\t\( \)?vcvtps2ph xmm4,xmm4,0x2\r +\[^\r\n\]+:\tc4 43 79 1d 00 02\t\( \)?vcvtps2ph QWORD PTR \\\[r8\\\],xmm8,0x2\r +\[^\r\n\]+:\tc4 e3 79 1d 21 02\t\( \)?vcvtps2ph QWORD PTR \\\[rcx\\\],xmm4,0x2\r +\[^\r\n\]+:\tf3 0f ae c3\t\( \)?rdfsbase ebx\r +\[^\r\n\]+:\tf3 48 0f ae c3\t\( \)?rdfsbase rbx\r +\[^\r\n\]+:\tf3 41 0f ae c0\t\( \)?rdfsbase r8d\r +\[^\r\n\]+:\tf3 49 0f ae c0\t\( \)?rdfsbase r8\r +\[^\r\n\]+:\tf3 0f ae cb\t\( \)?rdgsbase ebx\r +\[^\r\n\]+:\tf3 48 0f ae cb\t\( \)?rdgsbase rbx\r +\[^\r\n\]+:\tf3 41 0f ae c8\t\( \)?rdgsbase r8d\r +\[^\r\n\]+:\tf3 49 0f ae c8\t\( \)?rdgsbase r8\r +\[^\r\n\]+:\tf3 0f ae d3\t\( \)?wrfsbase ebx\r +\[^\r\n\]+:\tf3 48 0f ae d3\t\( \)?wrfsbase rbx\r +\[^\r\n\]+:\tf3 41 0f ae d0\t\( \)?wrfsbase r8d\r +\[^\r\n\]+:\tf3 49 0f ae d0\t\( \)?wrfsbase r8\r +\[^\r\n\]+:\tf3 0f ae db\t\( \)?wrgsbase ebx\r +\[^\r\n\]+:\tf3 48 0f ae db\t\( \)?wrgsbase rbx\r +\[^\r\n\]+:\tf3 41 0f ae d8\t\( \)?wrgsbase r8d\r +\[^\r\n\]+:\tf3 49 0f ae d8\t\( \)?wrgsbase r8\r +\[^\r\n\]+:\tf3 0f ae c3\t\( \)?rdfsbase ebx\r +\[^\r\n\]+:\tf3 48 0f ae c3\t\( \)?rdfsbase rbx\r +\[^\r\n\]+:\tf3 41 0f ae c0\t\( \)?rdfsbase r8d\r +\[^\r\n\]+:\tf3 49 0f ae c0\t\( \)?rdfsbase r8\r +\[^\r\n\]+:\tf3 0f ae cb\t\( \)?rdgsbase ebx\r +\[^\r\n\]+:\tf3 48 0f ae cb\t\( \)?rdgsbase rbx\r +\[^\r\n\]+:\tf3 41 0f ae c8\t\( \)?rdgsbase r8d\r +\[^\r\n\]+:\tf3 49 0f ae c8\t\( \)?rdgsbase r8\r +\[^\r\n\]+:\tf3 0f ae d3\t\( \)?wrfsbase ebx\r +\[^\r\n\]+:\tf3 48 0f ae d3\t\( \)?wrfsbase rbx\r +\[^\r\n\]+:\tf3 41 0f ae d0\t\( \)?wrfsbase r8d\r +\[^\r\n\]+:\tf3 49 0f ae d0\t\( \)?wrfsbase r8\r +\[^\r\n\]+:\tf3 0f ae db\t\( \)?wrgsbase ebx\r +\[^\r\n\]+:\tf3 48 0f ae db\t\( \)?wrgsbase rbx\r +\[^\r\n\]+:\tf3 41 0f ae d8\t\( \)?wrgsbase r8d\r +\[^\r\n\]+:\tf3 49 0f ae d8\t\( \)?wrgsbase r8\r +End of assembler dump\\." "intel" diff --git a/gdb/testsuite/gdb.arch/i386-ivy-bridge.S b/gdb/testsuite/gdb.arch/i386-ivy-bridge.S new file mode 100644 index 00000000000..ff9608d3894 --- /dev/null +++ b/gdb/testsuite/gdb.arch/i386-ivy-bridge.S @@ -0,0 +1,67 @@ +/* Copyright 2011 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 . + + This file is part of the gdb testsuite. */ + + .globl _start +_start: .text + +/* gas/i386/rdrnd.s */ + .att_syntax prefix + rdrand %bx + rdrand %ebx + + .intel_syntax noprefix + rdrand bx + rdrand ebx + +/* gas/i386/f16c.s */ + .att_syntax prefix + vcvtph2ps %xmm4,%ymm4 + vcvtph2ps (%ecx),%ymm4 + vcvtph2ps %xmm4,%xmm6 + vcvtph2ps (%ecx),%xmm4 + vcvtps2ph $0x2,%ymm4,%xmm4 + vcvtps2ph $0x2,%ymm4,(%ecx) + vcvtps2ph $0x2,%xmm4,%xmm4 + vcvtps2ph $0x2,%xmm4,(%ecx) + + .intel_syntax noprefix + vcvtph2ps ymm4,xmm4 + vcvtph2ps ymm4,XMMWORD PTR [ecx] + vcvtph2ps ymm4,[ecx] + vcvtph2ps xmm6,xmm4 + vcvtph2ps xmm4,QWORD PTR [ecx] + vcvtph2ps xmm4,[ecx] + vcvtps2ph xmm4,ymm4,0x2 + vcvtps2ph XMMWORD PTR [ecx],ymm4,0x2 + vcvtps2ph [ecx],ymm4,0x2 + vcvtps2ph xmm4,xmm4,0x2 + vcvtps2ph QWORD PTR [ecx],xmm4,0x2 + vcvtps2ph [ecx],xmm4,0x2 + +/* gas/i386/fsgs.s */ + .att_syntax prefix + rdfsbase %ebx + rdgsbase %ebx + wrfsbase %ebx + wrgsbase %ebx + + .intel_syntax noprefix + rdfsbase ebx + rdgsbase ebx + wrfsbase ebx + wrgsbase ebx + diff --git a/gdb/testsuite/gdb.arch/i386-ivy-bridge.exp b/gdb/testsuite/gdb.arch/i386-ivy-bridge.exp new file mode 100644 index 00000000000..4ea93edb062 --- /dev/null +++ b/gdb/testsuite/gdb.arch/i386-ivy-bridge.exp @@ -0,0 +1,106 @@ +# Copyright 2011 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 . + +if {![istarget "x86_64-*-*"] && ![istarget "i?86-*-*"]} then { + return +} + +set testfile i386-ivy-bridge +set test compilation +if [prepare_for_testing ${testfile}.exp ${testfile}.x ${testfile}.S [list debug "additional_flags=-m32 -nostdlib"]] { + fail $test + return -1 +} +pass $test + +gdb_test_no_output "set disassembly-flavor att" +# gas/i386/rdrnd.d +# gas/i386/f16c.d +# gas/i386/fsgs.d +gdb_test "disassemble/r _start" "\r +Dump of assembler code for function _start:\r +\[^\r\n\]+:\t66 0f c7 f3\t\( \)?rdrand %bx\r +\[^\r\n\]+:\t0f c7 f3\t\( \)?rdrand %ebx\r +\[^\r\n\]+:\t66 0f c7 f3\t\( \)?rdrand %bx\r +\[^\r\n\]+:\t0f c7 f3\t\( \)?rdrand %ebx\r +\[^\r\n\]+:\tc4 e2 7d 13 e4\t\( \)?vcvtph2ps %xmm4,%ymm4\r +\[^\r\n\]+:\tc4 e2 7d 13 21\t\( \)?vcvtph2ps \\(%ecx\\),%ymm4\r +\[^\r\n\]+:\tc4 e2 79 13 f4\t\( \)?vcvtph2ps %xmm4,%xmm6\r +\[^\r\n\]+:\tc4 e2 79 13 21\t\( \)?vcvtph2ps \\(%ecx\\),%xmm4\r +\[^\r\n\]+:\tc4 e3 7d 1d e4 02\t\( \)?vcvtps2ph \\\$0x2,%ymm4,%xmm4\r +\[^\r\n\]+:\tc4 e3 7d 1d 21 02\t\( \)?vcvtps2ph \\\$0x2,%ymm4,\\(%ecx\\)\r +\[^\r\n\]+:\tc4 e3 79 1d e4 02\t\( \)?vcvtps2ph \\\$0x2,%xmm4,%xmm4\r +\[^\r\n\]+:\tc4 e3 79 1d 21 02\t\( \)?vcvtps2ph \\\$0x2,%xmm4,\\(%ecx\\)\r +\[^\r\n\]+:\tc4 e2 7d 13 e4\t\( \)?vcvtph2ps %xmm4,%ymm4\r +\[^\r\n\]+:\tc4 e2 7d 13 21\t\( \)?vcvtph2ps \\(%ecx\\),%ymm4\r +\[^\r\n\]+:\tc4 e2 7d 13 21\t\( \)?vcvtph2ps \\(%ecx\\),%ymm4\r +\[^\r\n\]+:\tc4 e2 79 13 f4\t\( \)?vcvtph2ps %xmm4,%xmm6\r +\[^\r\n\]+:\tc4 e2 79 13 21\t\( \)?vcvtph2ps \\(%ecx\\),%xmm4\r +\[^\r\n\]+:\tc4 e2 79 13 21\t\( \)?vcvtph2ps \\(%ecx\\),%xmm4\r +\[^\r\n\]+:\tc4 e3 7d 1d e4 02\t\( \)?vcvtps2ph \\\$0x2,%ymm4,%xmm4\r +\[^\r\n\]+:\tc4 e3 7d 1d 21 02\t\( \)?vcvtps2ph \\\$0x2,%ymm4,\\(%ecx\\)\r +\[^\r\n\]+:\tc4 e3 7d 1d 21 02\t\( \)?vcvtps2ph \\\$0x2,%ymm4,\\(%ecx\\)\r +\[^\r\n\]+:\tc4 e3 79 1d e4 02\t\( \)?vcvtps2ph \\\$0x2,%xmm4,%xmm4\r +\[^\r\n\]+:\tc4 e3 79 1d 21 02\t\( \)?vcvtps2ph \\\$0x2,%xmm4,\\(%ecx\\)\r +\[^\r\n\]+:\tc4 e3 79 1d 21 02\t\( \)?vcvtps2ph \\\$0x2,%xmm4,\\(%ecx\\)\r +\[^\r\n\]+:\tf3 0f ae c3\t\( \)?rdfsbase %ebx\r +\[^\r\n\]+:\tf3 0f ae cb\t\( \)?rdgsbase %ebx\r +\[^\r\n\]+:\tf3 0f ae d3\t\( \)?wrfsbase %ebx\r +\[^\r\n\]+:\tf3 0f ae db\t\( \)?wrgsbase %ebx\r +\[^\r\n\]+:\tf3 0f ae c3\t\( \)?rdfsbase %ebx\r +\[^\r\n\]+:\tf3 0f ae cb\t\( \)?rdgsbase %ebx\r +\[^\r\n\]+:\tf3 0f ae d3\t\( \)?wrfsbase %ebx\r +\[^\r\n\]+:\tf3 0f ae db\t\( \)?wrgsbase %ebx\r +End of assembler dump\\." "att" + +gdb_test_no_output "set disassembly-flavor intel" +# gas/i386/rdrnd-intel.d +# gas/i386/f16c-intel.d +# gas/i386/fsgs-intel.d +gdb_test "disassemble/r _start" "\r +Dump of assembler code for function _start:\r +\[^\r\n\]+:\t66 0f c7 f3\t\( \)?rdrand bx\r +\[^\r\n\]+:\t0f c7 f3\t\( \)?rdrand ebx\r +\[^\r\n\]+:\t66 0f c7 f3\t\( \)?rdrand bx\r +\[^\r\n\]+:\t0f c7 f3\t\( \)?rdrand ebx\r +\[^\r\n\]+:\tc4 e2 7d 13 e4\t\( \)?vcvtph2ps ymm4,xmm4\r +\[^\r\n\]+:\tc4 e2 7d 13 21\t\( \)?vcvtph2ps ymm4,XMMWORD PTR \\\[ecx\\\]\r +\[^\r\n\]+:\tc4 e2 79 13 f4\t\( \)?vcvtph2ps xmm6,xmm4\r +\[^\r\n\]+:\tc4 e2 79 13 21\t\( \)?vcvtph2ps xmm4,QWORD PTR \\\[ecx\\\]\r +\[^\r\n\]+:\tc4 e3 7d 1d e4 02\t\( \)?vcvtps2ph xmm4,ymm4,0x2\r +\[^\r\n\]+:\tc4 e3 7d 1d 21 02\t\( \)?vcvtps2ph XMMWORD PTR \\\[ecx\\\],ymm4,0x2\r +\[^\r\n\]+:\tc4 e3 79 1d e4 02\t\( \)?vcvtps2ph xmm4,xmm4,0x2\r +\[^\r\n\]+:\tc4 e3 79 1d 21 02\t\( \)?vcvtps2ph QWORD PTR \\\[ecx\\\],xmm4,0x2\r +\[^\r\n\]+:\tc4 e2 7d 13 e4\t\( \)?vcvtph2ps ymm4,xmm4\r +\[^\r\n\]+:\tc4 e2 7d 13 21\t\( \)?vcvtph2ps ymm4,XMMWORD PTR \\\[ecx\\\]\r +\[^\r\n\]+:\tc4 e2 7d 13 21\t\( \)?vcvtph2ps ymm4,XMMWORD PTR \\\[ecx\\\]\r +\[^\r\n\]+:\tc4 e2 79 13 f4\t\( \)?vcvtph2ps xmm6,xmm4\r +\[^\r\n\]+:\tc4 e2 79 13 21\t\( \)?vcvtph2ps xmm4,QWORD PTR \\\[ecx\\\]\r +\[^\r\n\]+:\tc4 e2 79 13 21\t\( \)?vcvtph2ps xmm4,QWORD PTR \\\[ecx\\\]\r +\[^\r\n\]+:\tc4 e3 7d 1d e4 02\t\( \)?vcvtps2ph xmm4,ymm4,0x2\r +\[^\r\n\]+:\tc4 e3 7d 1d 21 02\t\( \)?vcvtps2ph XMMWORD PTR \\\[ecx\\\],ymm4,0x2\r +\[^\r\n\]+:\tc4 e3 7d 1d 21 02\t\( \)?vcvtps2ph XMMWORD PTR \\\[ecx\\\],ymm4,0x2\r +\[^\r\n\]+:\tc4 e3 79 1d e4 02\t\( \)?vcvtps2ph xmm4,xmm4,0x2\r +\[^\r\n\]+:\tc4 e3 79 1d 21 02\t\( \)?vcvtps2ph QWORD PTR \\\[ecx\\\],xmm4,0x2\r +\[^\r\n\]+:\tc4 e3 79 1d 21 02\t\( \)?vcvtps2ph QWORD PTR \\\[ecx\\\],xmm4,0x2\r +\[^\r\n\]+:\tf3 0f ae c3\t\( \)?rdfsbase ebx\r +\[^\r\n\]+:\tf3 0f ae cb\t\( \)?rdgsbase ebx\r +\[^\r\n\]+:\tf3 0f ae d3\t\( \)?wrfsbase ebx\r +\[^\r\n\]+:\tf3 0f ae db\t\( \)?wrgsbase ebx\r +\[^\r\n\]+:\tf3 0f ae c3\t\( \)?rdfsbase ebx\r +\[^\r\n\]+:\tf3 0f ae cb\t\( \)?rdgsbase ebx\r +\[^\r\n\]+:\tf3 0f ae d3\t\( \)?wrfsbase ebx\r +\[^\r\n\]+:\tf3 0f ae db\t\( \)?wrgsbase ebx\r +End of assembler dump\\." "intel" diff --git a/gdb/testsuite/gdb.arch/powerpc-bcl-prologue-asm32.S b/gdb/testsuite/gdb.arch/powerpc-bcl-prologue-asm32.S new file mode 100644 index 00000000000..1e4301af894 --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-bcl-prologue-asm32.S @@ -0,0 +1,78 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + .section ".text" + .align 2 + .globl func0 + .type func0, @function +func0: + stwu 1,-16(1) + mflr 0 + stw 31,12(1) + stw 0,20(1) + mr 31,1 + bl abort + .size func0, .-func0 + .align 2 + .globl func1 + .type func1, @function +func1: + stwu 1,-16(1) + mflr 0 +/* 20 = BO = branch always + 31 = BI = CR bit (ignored) */ + bcl 20,31,.Lpie +.Lpie: stw 31,12(1) + stw 0,20(1) + mr 31,1 + bl func0 + mr 0,3 + lis 9,var@ha + lwz 9,var@l(9) + add 0,0,9 + mr 3,0 + lwz 11,0(1) + lwz 0,4(11) + mtlr 0 + lwz 31,-4(11) + mr 1,11 + blr + .size func1, .-func1 + .section .note.GNU-stack,"",@progbits + .ident "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-8)" + +/* Original source file: + +#include + +extern volatile int var; + +int func0 (void) __attribute__((__noinline__)); +int func0 (void) +{ + abort (); + return var; +} + +int func1 (void) __attribute__((__noinline__)); +int func1 (void) +{ + return func0 () + var; +} + +*/ diff --git a/gdb/testsuite/gdb.arch/powerpc-bcl-prologue-asm64.S b/gdb/testsuite/gdb.arch/powerpc-bcl-prologue-asm64.S new file mode 100644 index 00000000000..1af5c19a16a --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-bcl-prologue-asm64.S @@ -0,0 +1,98 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + + .section ".toc","aw" + .section ".text" + .align 2 + .globl func0 + .section ".opd","aw" + .align 3 +func0: + .quad .L.func0,.TOC.@tocbase + .previous + .type func0, @function +.L.func0: + mflr 0 + std 31,-8(1) + std 0,16(1) + stdu 1,-128(1) + mr 31,1 + bl abort + nop + .long 0 + .byte 0,0,0,1,128,1,0,1 + .size func0,.-.L.func0 + .section ".toc","aw" +.LC1: + .tc var[TC],var + .section ".text" + .align 2 + .globl func1 + .section ".opd","aw" + .align 3 +func1: + .quad .L.func1,.TOC.@tocbase + .previous + .type func1, @function +.L.func1: + mflr 0 +/* 20 = BO = branch always + 31 = BI = CR bit (ignored) */ + bcl 20,31,.Lpie +.Lpie: std 31,-8(1) + std 0,16(1) + stdu 1,-128(1) + mr 31,1 + bl func0 + mr 11,3 + ld 9,.LC1@toc(2) + lwz 0,0(9) + add 0,11,0 + extsw 0,0 + mr 3,0 + ld 1,0(1) + ld 0,16(1) + mtlr 0 + ld 31,-8(1) + blr + .long 0 + .byte 0,0,0,1,128,1,0,1 + .size func1,.-.L.func1 + .section .note.GNU-stack,"",@progbits + .ident "GCC: (GNU) 3.4.6 20060404 (Red Hat 3.4.6-8)" + +/* Original source file: + +#include + +extern volatile int var; + +int func0 (void) __attribute__((__noinline__)); +int func0 (void) +{ + abort (); + return var; +} + +int func1 (void) __attribute__((__noinline__)); +int func1 (void) +{ + return func0 () + var; +} + +*/ diff --git a/gdb/testsuite/gdb.arch/powerpc-bcl-prologue.c b/gdb/testsuite/gdb.arch/powerpc-bcl-prologue.c new file mode 100644 index 00000000000..6b5bb08d0f5 --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-bcl-prologue.c @@ -0,0 +1,29 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* Force `-fpie' double jump bl->blrl. */ +/* No longer used. */ +volatile int var; + +extern int func1 (void); + +int main (void) +{ + func1 (); + return 0; +} diff --git a/gdb/testsuite/gdb.arch/powerpc-bcl-prologue.exp b/gdb/testsuite/gdb.arch/powerpc-bcl-prologue.exp new file mode 100644 index 00000000000..5f50c4ef432 --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-bcl-prologue.exp @@ -0,0 +1,72 @@ +# Copyright 2006, 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Test unwinding fixes of the PPC platform, specifically on the coping with BCL +# jump of the PIE code. + +if ![istarget "powerpc*-*-linux*"] then { + verbose "Skipping powerpc-linux prologue tests." + return +} + +set testfile "powerpc-bcl-prologue" +set srcfile1 ${testfile}.c +set flags "debug" +if [istarget "powerpc-*"] then { + set srcfile2 ${testfile}-asm32.S + set flags "$flags additional_flags=-m32" +} elseif [istarget "powerpc64-*"] then { + set srcfile2 ${testfile}-asm64.S + set flags "$flags additional_flags=-m64" +} else { + fail "powerpc arch test" + return +} +set objfile2 [standard_output_file ${testfile}-asm.o] +set binfile [standard_output_file ${testfile}] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile1} ${srcdir}/${subdir}/${srcfile2}" ${binfile} executable $flags] != ""} { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# We should stop in abort(3). + +gdb_run_cmd + +gdb_test_multiple {} "continue to abort()" { + -re ".*Program received signal SIGABRT,.*$gdb_prompt $" { + pass "continue to abort()" + } +} + +# Check backtrace: +# #3 0x0804835f in func0 () +# #4 0x0804836a in func1 () +# #5 0x0804838c in main () +# (gdb) +# `\\.?' prefixes are needed for ppc64 without `debug' (another bug). + +set test "matching unwind" +gdb_test_multiple "backtrace" $test { + -re "\r\n#\[0-9\]\[^\r\n\]* in \\.?func0 \\(\[^\r\n\]*\r\n#\[0-9\]\[^\r\n\]* in \\.?func1 \\(\[^\r\n\]*\r\n#\[0-9\]\[^\r\n\]* in \\.?main \\(\[^\r\n\]*\r\n$gdb_prompt $" { + pass $test + } +} diff --git a/gdb/testsuite/gdb.arch/powerpc-power6.exp b/gdb/testsuite/gdb.arch/powerpc-power6.exp new file mode 100644 index 00000000000..082a4b7802a --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-power6.exp @@ -0,0 +1,54 @@ +# Copyright 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Test PowerPC Power6 instructions disassembly. + +if {![istarget "powerpc*-*-*"]} then { + verbose "Skipping PowerPC Power6 instructions disassembly." + return +} + +set testfile "powerpc-power6" +set srcfile ${testfile}.s +set objfile [standard_output_file ${testfile}.o] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] != "" } { + untested "PowerPC prologue tests" + return -1 +} + + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${objfile} + +# Disassemble the function. + +gdb_test "disass func" ":\tblr\r\n.*" "Basic disassembly" + +gdb_test "disass func" ":\tdcbzl *r8,r9\r\n.*" "Power5 disassembly dcbzl" +gdb_test "disass func" ":\tfrsqrtes *f10,f11\r\n.*" "Power5 disassembly frsqrtes" +gdb_test "disass func" ":\tdadd *f1,f2,f1\r\n.*" "Power6 disassembly dadd" +gdb_test "disass func" ":\tdaddq *f0,f2,f0\r\n.*" "Power6 disassembly daddq" +gdb_test "disass func" ":\tdsub *f1,f2,f1\r\n.*" "Power6 disassembly dsub" +gdb_test "disass func" ":\tdsubq *f0,f2,f0\r\n.*" "Power6 disassembly dsubq" +gdb_test "disass func" ":\tdmul *f1,f2,f1\r\n.*" "Power6 disassembly dmul" +gdb_test "disass func" ":\tdmulq *f0,f2,f0\r\n.*" "Power6 disassembly dmulq" +gdb_test "disass func" ":\tddiv *f1,f2,f1\r\n.*" "Power6 disassembly ddiv" +gdb_test "disass func" ":\tddivq *f0,f2,f0\r\n.*" "Power6 disassembly ddivq" +gdb_test "disass func" ":\tdcmpu *cr1,f2,f1\r\n.*" "Power6 disassembly dcmpu" +gdb_test "disass func" ":\tdcmpuq *cr1,f2,f0\r\n.*" "Power6 disassembly dcmpuq" diff --git a/gdb/testsuite/gdb.arch/powerpc-power6.s b/gdb/testsuite/gdb.arch/powerpc-power6.s new file mode 100644 index 00000000000..6694b237abf --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-power6.s @@ -0,0 +1,16 @@ + .text + .globl func +func: + blr + .long 0x7c284fec /* dcbzl r8,r9 */ + .long 0xed405834 /* frsqrtes f10,f11 */ + .long 0xec220804 /* dadd f1,f2,f1 */ + .long 0xfc020004 /* daddq f0,f2,f0 */ + .long 0xec220c04 /* dsub f1,f2,f1 */ + .long 0xfc020404 /* dsubq f0,f2,f0 */ + .long 0xec220844 /* dmul f1,f2,f1 */ + .long 0xfc020044 /* dmulq f0,f2,f0 */ + .long 0xec220c44 /* ddiv f1,f2,f1 */ + .long 0xfc020444 /* ddivq f0,f2,f0 */ + .long 0xec820d04 /* dcmpu cr1,f2,f1 */ + .long 0xfc820504 /* dcmpuq cr1,f2,f0 */ diff --git a/gdb/testsuite/gdb.arch/powerpc-power7rh.exp b/gdb/testsuite/gdb.arch/powerpc-power7rh.exp new file mode 100644 index 00000000000..0c2bbdaedef --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-power7rh.exp @@ -0,0 +1,178 @@ +# Copyright 2009 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Test PowerPC Power7 instructions disassembly. + +if {![istarget "powerpc*-*-*"]} then { + verbose "Skipping PowerPC Power7 instructions disassembly." + return +} + +set testfile "powerpc-power7rh" +set srcfile ${testfile}.s +set objfile [standard_output_file ${testfile}.o] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objfile}" object {debug}] != "" } { + untested "PowerPC Power7 instructions disassembly" + return -1 +} + + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${objfile} + + +# Disassemble the function. + +set test "disass func" +gdb_test_multiple $test $test { + -re "\r\nDump of assembler code for function func:(\r\n.*\r\n)End of assembler dump.\r\n$gdb_prompt $" { + set func $expect_out(1,string) + pass $test + } +} + +proc instr_to_patt {offset instr} { + # 0x0000000000000018 : stxvd2x vs43,r4,r5 + return ".*\r\n\[ \t\]*[string map {0x 0x0*} $offset] <(func)?\\+?\[0-9\]*>:\[ \t\]*[string map [list { } "\[ \t\]+" . {\.}] $instr]\[ \t\]*\r\n.*" +} + +# KFAIL strings would not exist if -Many would print the same as -Mpower7. +# That means the power7 form should be the preferred one. +# http://sourceware.org/ml/gdb-patches/2009-03/threads.html#00020 + +proc func_check {offset instr {kfail ""}} { + global func + + set test "Found $offset: $instr" + if [regexp -nocase -line [instr_to_patt $offset $instr] $func] { + pass $test + } elseif {$kfail != "" && [regexp -nocase -line [instr_to_patt $offset $kfail] $func]} { + kfail gdb/NNNN $test + } else { + fail $test + } +} + +func_check 0x0 "lxvd2x vs3,r4,r5" +# [PATCH] Remove support for POWER7 VSX load/store with update instructions +# http://sourceware.org/ml/binutils/2009-09/msg00680.html +# http://sourceware.org/ml/binutils-cvs/2009-09/msg00331.html +func_check 0x4 "lxvb16x vs3,r4,r5" +func_check 0x8 "lxvd2x vs43,r4,r5" +func_check 0xc "lxvb16x vs43,r4,r5" +func_check 0x10 "stxvd2x vs3,r4,r5" +func_check 0x14 "stxvb16x vs3,r4,r5" +func_check 0x18 "stxvd2x vs43,r4,r5" +func_check 0x1c "stxvb16x vs43,r4,r5" +func_check 0x20 "xxmrghd vs3,vs4,vs5" +func_check 0x24 "xxmrghd vs43,vs44,vs45" +func_check 0x28 "xxmrgld vs3,vs4,vs5" +func_check 0x2c "xxmrgld vs43,vs44,vs45" +func_check 0x30 "xxmrghd vs3,vs4,vs5" +func_check 0x34 "xxmrghd vs43,vs44,vs45" +func_check 0x38 "xxmrgld vs3,vs4,vs5" +func_check 0x3c "xxmrgld vs43,vs44,vs45" +func_check 0x40 "xxpermdi vs3,vs4,vs5,1" +func_check 0x44 "xxpermdi vs43,vs44,vs45,1" +func_check 0x48 "xxpermdi vs3,vs4,vs5,2" +func_check 0x4c "xxpermdi vs43,vs44,vs45,2" +func_check 0x50 "xvmovdp vs3,vs4" +func_check 0x54 "xvmovdp vs43,vs44" +func_check 0x58 "xvmovdp vs3,vs4" +func_check 0x5c "xvmovdp vs43,vs44" +func_check 0x60 "xvcpsgndp vs3,vs4,vs5" +func_check 0x64 "xvcpsgndp vs43,vs44,vs45" +func_check 0x68 "wait" +func_check 0x6c "wait" +func_check 0x70 "waitrsv" +func_check 0x74 "waitrsv" +func_check 0x78 "waitimpl" +func_check 0x7c "waitimpl" +func_check 0x80 "doze" +func_check 0x84 "nap" +func_check 0x88 "sleep" +func_check 0x8c "rvwinkle" +func_check 0x90 "prtyw r3,r4" +func_check 0x94 "prtyd r13,r14" +func_check 0x98 "mfcfar r10" "mfspr r10,28" +func_check 0x9c "mtcfar r11" "mtspr 28,r11" +func_check 0xa0 "cmpb r3,r4,r5" +func_check 0xa4 "lwzcix r10,r11,r12" +func_check 0xa8 "dadd f16,f17,f18" +func_check 0xac "daddq f20,f22,f24" +func_check 0xb0 "dss 3" +func_check 0xb4 "dssall" +func_check 0xb8 "dst r5,r4,1" +func_check 0xbc "dstt r8,r7,0" +func_check 0xc0 "dstst r5,r6,3" +func_check 0xc4 "dststt r4,r5,2" +func_check 0xc8 "divwe r10,r11,r12" +func_check 0xcc "divwe. r11,r12,r13" +func_check 0xd0 "divweo r12,r13,r14" +func_check 0xd4 "divweo. r13,r14,r15" +func_check 0xd8 "divweu r10,r11,r12" +func_check 0xdc "divweu. r11,r12,r13" +func_check 0xe0 "divweuo r12,r13,r14" +func_check 0xe4 "divweuo. r13,r14,r15" +func_check 0xe8 "bpermd r7,r17,r27" +func_check 0xec "popcntw r10,r20" +func_check 0xf0 "popcntd r10,r20" +func_check 0xf4 "ldbrx r20,r21,r22" +func_check 0xf8 "stdbrx r20,r21,r22" +func_check 0xfc "lfiwzx f10,0,r10" +func_check 0x100 "lfiwzx f10,r9,r10" +func_check 0x104 "fcfids f4,f5" +func_check 0x108 "fcfids. f4,f5" +func_check 0x10c "fcfidus f4,f5" +func_check 0x110 "fcfidus. f4,f5" +func_check 0x114 "fctiwu f4,f5" +func_check 0x118 "fctiwu. f4,f5" +func_check 0x11c "fctiwuz f4,f5" +func_check 0x120 "fctiwuz. f4,f5" +func_check 0x124 "fctidu f4,f5" +func_check 0x128 "fctidu. f4,f5" +func_check 0x12c "fctiduz f4,f5" +func_check 0x130 "fctiduz. f4,f5" +func_check 0x134 "fcfidu f4,f5" +func_check 0x138 "fcfidu. f4,f5" +func_check 0x13c "ftdiv cr0,f10,f11" +func_check 0x140 "ftdiv cr7,f10,f11" +func_check 0x144 "ftsqrt cr0,f10" +func_check 0x148 "ftsqrt cr7,f10" +func_check 0x14c "dcbtt r8,r9" "dcbt 16,r8,r9" +func_check 0x150 "dcbtstt r8,r9" "dcbtst 16,r8,r9" +func_check 0x154 "dcffix f10,f12" +func_check 0x158 "dcffix. f20,f22" +func_check 0x15c "lbarx r10,r11,r12" +func_check 0x160 "lbarx r10,r11,r12" +func_check 0x164 "lbarx r10,r11,r12,1" +func_check 0x168 "lharx r20,r21,r22" +func_check 0x16c "lharx r20,r21,r22" +func_check 0x170 "lharx r20,r21,r22,1" +func_check 0x174 "stbcx. r10,r11,r12" +func_check 0x178 "sthcx. r10,r11,r12" +func_check 0x17c "fre f14,f15" +func_check 0x180 "fre. f14,f15" +func_check 0x184 "fres f14,f15" +func_check 0x188 "fres. f14,f15" +func_check 0x18c "frsqrte f14,f15" +func_check 0x190 "frsqrte. f14,f15" +func_check 0x194 "frsqrtes f14,f15" +func_check 0x198 "frsqrtes. f14,f15" +func_check 0x19c "isel r2,r3,r4,28" diff --git a/gdb/testsuite/gdb.arch/powerpc-power7rh.s b/gdb/testsuite/gdb.arch/powerpc-power7rh.s new file mode 100644 index 00000000000..98b2e797e7b --- /dev/null +++ b/gdb/testsuite/gdb.arch/powerpc-power7rh.s @@ -0,0 +1,107 @@ + .text + .globl func +func: + .long 0x7c642e98 /* 0: lxvd2x vs3,r4,r5 */ + .long 0x7c642ed8 /* 4: lxvd2ux vs3,r4,r5 */ + .long 0x7d642e99 /* 8: lxvd2x vs43,r4,r5 */ + .long 0x7d642ed9 /* c: lxvd2ux vs43,r4,r5 */ + .long 0x7c642f98 /* 10: stxvd2x vs3,r4,r5 */ + .long 0x7c642fd8 /* 14: stxvd2ux vs3,r4,r5 */ + .long 0x7d642f99 /* 18: stxvd2x vs43,r4,r5 */ + .long 0x7d642fd9 /* 1c: stxvd2ux vs43,r4,r5 */ + .long 0xf0642850 /* 20: xxmrghd vs3,vs4,vs5 */ + .long 0xf16c6857 /* 24: xxmrghd vs43,vs44,vs45 */ + .long 0xf0642b50 /* 28: xxmrgld vs3,vs4,vs5 */ + .long 0xf16c6b57 /* 2c: xxmrgld vs43,vs44,vs45 */ + .long 0xf0642850 /* 30: xxmrghd vs3,vs4,vs5 */ + .long 0xf16c6857 /* 34: xxmrghd vs43,vs44,vs45 */ + .long 0xf0642b50 /* 38: xxmrgld vs3,vs4,vs5 */ + .long 0xf16c6b57 /* 3c: xxmrgld vs43,vs44,vs45 */ + .long 0xf0642950 /* 40: xxpermdi vs3,vs4,vs5,1 */ + .long 0xf16c6957 /* 44: xxpermdi vs43,vs44,vs45,1 */ + .long 0xf0642a50 /* 48: xxpermdi vs3,vs4,vs5,2 */ + .long 0xf16c6a57 /* 4c: xxpermdi vs43,vs44,vs45,2 */ + .long 0xf0642780 /* 50: xvmovdp vs3,vs4 */ + .long 0xf16c6787 /* 54: xvmovdp vs43,vs44 */ + .long 0xf0642780 /* 58: xvmovdp vs3,vs4 */ + .long 0xf16c6787 /* 5c: xvmovdp vs43,vs44 */ + .long 0xf0642f80 /* 60: xvcpsgndp vs3,vs4,vs5 */ + .long 0xf16c6f87 /* 64: xvcpsgndp vs43,vs44,vs45 */ + .long 0x7c00007c /* 68: wait */ + .long 0x7c00007c /* 6c: wait */ + .long 0x7c20007c /* 70: waitrsv */ + .long 0x7c20007c /* 74: waitrsv */ + .long 0x7c40007c /* 78: waitimpl */ + .long 0x7c40007c /* 7c: waitimpl */ + .long 0x4c000324 /* 80: doze */ + .long 0x4c000364 /* 84: nap */ + .long 0x4c0003a4 /* 88: sleep */ + .long 0x4c0003e4 /* 8c: rvwinkle */ + .long 0x7c830134 /* 90: prtyw r3,r4 */ + .long 0x7dcd0174 /* 94: prtyd r13,r14 */ + .long 0x7d5c02a6 /* 98: mfcfar r10 */ + .long 0x7d7c03a6 /* 9c: mtcfar r11 */ + .long 0x7c832bf8 /* a0: cmpb r3,r4,r5 */ + .long 0x7d4b662a /* a4: lwzcix r10,r11,r12 */ + .long 0xee119004 /* a8: dadd f16,f17,f18 */ + .long 0xfe96c004 /* ac: daddq f20,f22,f24 */ + .long 0x7c60066c /* b0: dss 3 */ + .long 0x7e00066c /* b4: dssall */ + .long 0x7c2522ac /* b8: dst r5,r4,1 */ + .long 0x7e083aac /* bc: dstt r8,r7,0 */ + .long 0x7c6532ec /* c0: dstst r5,r6,3 */ + .long 0x7e442aec /* c4: dststt r4,r5,2 */ + .long 0x7d4b6356 /* c8: divwe r10,r11,r12 */ + .long 0x7d6c6b57 /* cc: divwe. r11,r12,r13 */ + .long 0x7d8d7756 /* d0: divweo r12,r13,r14 */ + .long 0x7dae7f57 /* d4: divweo. r13,r14,r15 */ + .long 0x7d4b6316 /* d8: divweu r10,r11,r12 */ + .long 0x7d6c6b17 /* dc: divweu. r11,r12,r13 */ + .long 0x7d8d7716 /* e0: divweuo r12,r13,r14 */ + .long 0x7dae7f17 /* e4: divweuo. r13,r14,r15 */ + .long 0x7e27d9f8 /* e8: bpermd r7,r17,r27 */ + .long 0x7e8a02f4 /* ec: popcntw r10,r20 */ + .long 0x7e8a03f4 /* f0: popcntd r10,r20 */ + .long 0x7e95b428 /* f4: ldbrx r20,r21,r22 */ + .long 0x7e95b528 /* f8: stdbrx r20,r21,r22 */ + .long 0x7d4056ee /* fc: lfiwzx f10,0,r10 */ + .long 0x7d4956ee /* 100: lfiwzx f10,r9,r10 */ + .long 0xec802e9c /* 104: fcfids f4,f5 */ + .long 0xec802e9d /* 108: fcfids. f4,f5 */ + .long 0xec802f9c /* 10c: fcfidus f4,f5 */ + .long 0xec802f9d /* 110: fcfidus. f4,f5 */ + .long 0xfc80291c /* 114: fctiwu f4,f5 */ + .long 0xfc80291d /* 118: fctiwu. f4,f5 */ + .long 0xfc80291e /* 11c: fctiwuz f4,f5 */ + .long 0xfc80291f /* 120: fctiwuz. f4,f5 */ + .long 0xfc802f5c /* 124: fctidu f4,f5 */ + .long 0xfc802f5d /* 128: fctidu. f4,f5 */ + .long 0xfc802f5e /* 12c: fctiduz f4,f5 */ + .long 0xfc802f5f /* 130: fctiduz. f4,f5 */ + .long 0xfc802f9c /* 134: fcfidu f4,f5 */ + .long 0xfc802f9d /* 138: fcfidu. f4,f5 */ + .long 0xfc0a5900 /* 13c: ftdiv cr0,f10,f11 */ + .long 0xff8a5900 /* 140: ftdiv cr7,f10,f11 */ + .long 0xfc005140 /* 144: ftsqrt cr0,f10 */ + .long 0xff805140 /* 148: ftsqrt cr7,f10 */ + .long 0x7e084a2c /* 14c: dcbtt r8,r9 */ + .long 0x7e0849ec /* 150: dcbtstt r8,r9 */ + .long 0xed406644 /* 154: dcffix f10,f12 */ + .long 0xee80b645 /* 158: dcffix. f20,f22 */ + .long 0x7d4b6068 /* 15c: lbarx r10,r11,r12 */ + .long 0x7d4b6068 /* 160: lbarx r10,r11,r12 */ + .long 0x7d4b6069 /* 164: lbarx r10,r11,r12,1 */ + .long 0x7e95b0e8 /* 168: lharx r20,r21,r22 */ + .long 0x7e95b0e8 /* 16c: lharx r20,r21,r22 */ + .long 0x7e95b0e9 /* 170: lharx r20,r21,r22,1 */ + .long 0x7d4b656d /* 174: stbcx. r10,r11,r12 */ + .long 0x7d4b65ad /* 178: sthcx. r10,r11,r12 */ + .long 0xfdc07830 /* 17c: fre f14,f15 */ + .long 0xfdc07831 /* 180: fre. f14,f15 */ + .long 0xedc07830 /* 184: fres f14,f15 */ + .long 0xedc07831 /* 188: fres. f14,f15 */ + .long 0xfdc07834 /* 18c: frsqrte f14,f15 */ + .long 0xfdc07835 /* 190: frsqrte. f14,f15 */ + .long 0xedc07834 /* 194: frsqrtes f14,f15 */ + .long 0xedc07835 /* 198: frsqrtes. f14,f15 */ + .long 0x7c43271e /* 19c: isel r2,r3,r4,28 */ diff --git a/gdb/testsuite/gdb.arch/powerpc-prologue.exp b/gdb/testsuite/gdb.arch/powerpc-prologue.exp index 819890f9d5a..999ec4195be 100644 --- a/gdb/testsuite/gdb.arch/powerpc-prologue.exp +++ b/gdb/testsuite/gdb.arch/powerpc-prologue.exp @@ -16,8 +16,9 @@ # Test PowerPC prologue analyzer. # Do not run on AIX (where we won't be able to build the tests without -# some surgery) or on PowerPC64 (ditto, dot symbols). -if {[istarget *-*-aix*] || ![istarget "powerpc-*-*"]} then { +# some surgery). PowerPC64 target would break due to dot symbols but we build +# there PowerPC32 inferior. +if {[istarget *-*-aix*] || ![istarget "powerpc*-*-*"]} then { verbose "Skipping PowerPC prologue tests." return } diff --git a/gdb/testsuite/gdb.arch/ppc-clobbered-registers-O2.c b/gdb/testsuite/gdb.arch/ppc-clobbered-registers-O2.c new file mode 100644 index 00000000000..698ff8a0b5c --- /dev/null +++ b/gdb/testsuite/gdb.arch/ppc-clobbered-registers-O2.c @@ -0,0 +1,21 @@ + +unsigned * __attribute__((noinline)) +start_sequence (unsigned * x, unsigned * y) +{ + return (unsigned *)0xdeadbeef; +}; + +unsigned __attribute__((noinline)) +gen_movsd (unsigned * operand0, unsigned * operand1) +{ + return *start_sequence(operand0, operand1); +} + +int main(void) +{ + unsigned x, y; + + x = 13; + y = 14; + return (int)gen_movsd (&x, &y); +} diff --git a/gdb/testsuite/gdb.arch/ppc-clobbered-registers-O2.exp b/gdb/testsuite/gdb.arch/ppc-clobbered-registers-O2.exp new file mode 100644 index 00000000000..c9ebd0e5229 --- /dev/null +++ b/gdb/testsuite/gdb.arch/ppc-clobbered-registers-O2.exp @@ -0,0 +1,54 @@ +# Copyright 2006 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# This file is part of the gdb testsuite. + +# Test displaying call clobbered registers in optimized binaries for ppc. +# GDB should not show incorrect values. + +if ![istarget "powerpc*-*"] then { + verbose "Skipping powerpc* call clobbered registers testing." + return +} + +set testfile "ppc-clobbered-registers-O2" +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +set compile_flags "debug additional_flags=-O2" + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable ${compile_flags}] != "" } { + unsupported "Testcase compile failed." + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] then { + perror "Couldn't run to breakpoint" + continue +} + +gdb_test "b start_sequence" ".*Breakpoint 2 at.*line 6.*" \ + "Insert breakpoint at problematic function" + +gdb_test continue ".*Breakpoint 2.*in start_sequence.*" \ + "Run until problematic function" + +gdb_test backtrace ".*operand0=.*operand1=.*" \ + "Check value of call clobbered registers" diff --git a/gdb/testsuite/gdb.arch/ppc64-prologue-skip.exp b/gdb/testsuite/gdb.arch/ppc64-prologue-skip.exp new file mode 100644 index 00000000000..2f54c1f9811 --- /dev/null +++ b/gdb/testsuite/gdb.arch/ppc64-prologue-skip.exp @@ -0,0 +1,34 @@ +# Copyright 2015 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if { ![istarget powerpc64-*linux-*] || ![is_lp64_target] } { + verbose "Skipping ppc64-prologue-skip.exp" + return +} + +set testfile "ppc64-prologue-skip" +set uufile "${srcdir}/${subdir}/${testfile}.o.uu" +set ofile "${srcdir}/${subdir}/${testfile}.o" + +if { [catch "system \"uudecode -o ${ofile} ${uufile}\"" ] != 0 } { + untested "failed uudecode" + return -1 +} + +gdb_exit +gdb_start +gdb_load $ofile + +gdb_test "break ___newselect_nocancel" "Breakpoint $decimal at 0xc: file ../sysdeps/unix/syscall-template.S, line 81." "breakpoint on ___newselect_nocancel" diff --git a/gdb/testsuite/gdb.arch/ppc64-prologue-skip.o.uu b/gdb/testsuite/gdb.arch/ppc64-prologue-skip.o.uu new file mode 100644 index 00000000000..9196bbac477 --- /dev/null +++ b/gdb/testsuite/gdb.arch/ppc64-prologue-skip.o.uu @@ -0,0 +1,70 @@ +begin 644 ppc64-skip-prologue.o.uu +M?T5,1@("`0`````````````!`!4````!```````````````````````````` +M``-(``````!```````!``!0`$8%-B-`L"@``0,(`-#@``(Y$```"3.,`('P( +M`J;X`0`0^"'_D4@```%@````Z`$`@#@A`'!\"`.F3H``(/@A_X%]*`*F^2$` +MD/CA`-#XP0#(^*$`P/B!`+CX80"P2````6````#X80!PZ.$`T.C!`,CHH0#` +MZ($`N.AA`+`X``".1````GP``";X80!X^`$`B.AA`'!(```!8````.DA`)#H +M`0"(Z&$`>'TH`Z9\#_$@."$`@$SC`"!+__]@```````,($``````````O``( +M7U]S96QE8W0```````````````````````````!6``(````Y!`'[#@T``0$! +M`0````$```$N+B]S>7-D97!S+W5N:7@``'-Y"]S>7-C86QL+71E;7!L871E +M+E,`+W)O;W0O9VQI8F,O9VQI8F,M,BXQ-RTW."YE;#$$!&PP!```` +M`#`````8`````````+P`20YP$4%^1`X`009!0@Z``4(107Y2$49_20X`!D$& +M1@``````+G-Y;71A8@`N`````````!(````$@````$`````````"``````````8```` +M)@````$``````````P```````````````````1@````````````````````` +M``````````$``````````````"P````(``````````,````````````````` +M``$8```````````````````````````````!```````````````V`````0`` +M```````#```````````````````!&``````````0```````````````````` +M"```````````````,0````0`````````````````````````````"L`````` +M````,````!(````%``````````@`````````&````#L````!```````````` +M``````````````````$H```````````````````````````````!```````` +M``````!0`````0`````````````````````````````!*`````````!:```` +M`````````````````0``````````````2P````0````````````````````` +M````````"O``````````&````!(````(``````````@`````````&````&$` +M```!``````````````````````````````&"`````````),````````````` +M```````!``````````````!<````!``````````````````````````````+ +M"`````````!@````$@````H`````````"``````````8````;0````$````` +M`````````````````````````A4`````````%`````````````````````$` +M`````````````(`````!``````````````````````````````(P```````` +M`#`````````````````````0``````````````![````!``````````````` +M```````````````+:``````````P````$@````T`````````"``````````8 +M````E`````$``````````@```````````````````F``````````2``````` +M``````````````@``````````````(\````$```````````````````````` +M``````N8`````````!@````2````#P`````````(`````````!@````1```` +M`P`````````````````````````````"J`````````">```````````````` +M`````0```````````````0````(`````````````````````````````"$@` +M```````!L````!,````+``````````@`````````&`````D````#```````` +M``````````````````````GX`````````'H````````````````````!```` +M`````````````````````````````````````````````P```0`````````` +M`````````````````P```P```````````````````````````P``!``````` +M`````````````````````P``!0```````````````````````````P``"@`` +M`````````````````````````P``#````````````````````````````P`` +M"````````````````````````````P``#0`````````````````````````` +M`P``#P```````````````````````````P``!P`````````````````````` +M```!$@``!0```````````````````-@````*$@```0`````````,```````` +M`#`````@$``````````````````````````````P$``````````````````` +M``````````!*$`````````````````````````````!E(@``!0`````````` +M`````````-@```!S(@``!0```````````````````-@`7U]S96QE8W0`7U]? +M;F5W6YC8V%N8V5L`%]?;&EB8U]D:7-A8FQE7V%S>6YC8V%N8V5L`%]? +M;&EB8U]S96QE8W0`. + +#if { ![istarget s390x-*linux-*] || ![is_lp64_target] } { +# verbose "Skipping s390x-prologue-skip.exp" +# return +#} + +set testfile "s390x-arch12" +set uufile "${srcdir}/${subdir}/${testfile}.o.uu" +set ofile "${srcdir}/${subdir}/${testfile}.o" + +if { [catch "system \"uudecode -o ${ofile} ${uufile}\"" ] != 0 } { + untested "failed uudecode" + return -1 +} + +gdb_exit +gdb_start +gdb_load $ofile + +gdb_test "disas load_guarded" " <\\+28>:\tlgg\t%r1,0\\(%r1\\)\r\n\[^\r\n\]* <\\+34>:\tstg\t%r1,168\\(%r11\\)\r\n.*" diff --git a/gdb/testsuite/gdb.arch/s390x-arch12.o.uu b/gdb/testsuite/gdb.arch/s390x-arch12.o.uu new file mode 100644 index 00000000000..2cee883b0fb --- /dev/null +++ b/gdb/testsuite/gdb.arch/s390x-arch12.o.uu @@ -0,0 +1,20 @@ +begin 644 s390x-arch12.o +M?T5,1@("`0`````````````!`!8````!```````````````````````````` +M``$X``````!```````!```<`!.N_\%@`)./P_U#_<;D$`+_C(+"@`"3C$+"@ +M``3C$!```$SC$+"H`"3C$+"H``2Y!``AXT"Q(``$Z[^Q"``$!_0`+G-Y;71A +M8@`N. + +if { ![istarget s390x-*linux-*] || ![is_lp64_target] } { + verbose "Skipping s390x-prologue-skip.exp" + return +} + +set testfile "s390x-prologue-skip" +set uufile "${srcdir}/${subdir}/${testfile}.o.uu" +set ofile "${srcdir}/${subdir}/${testfile}.o" + +if { [catch "system \"uudecode -o ${ofile} ${uufile}\"" ] != 0 } { + untested "failed uudecode" + return -1 +} + +gdb_exit +gdb_start +gdb_load $ofile + +gdb_test "break select" "Breakpoint $decimal at 0x48: file ../sysdeps/unix/syscall-template.S, line 81." "breakpoint on select" diff --git a/gdb/testsuite/gdb.arch/s390x-prologue-skip.o.uu b/gdb/testsuite/gdb.arch/s390x-prologue-skip.o.uu new file mode 100644 index 00000000000..6442e6048d2 --- /dev/null +++ b/gdb/testsuite/gdb.arch/s390x-prologue-skip.o.uu @@ -0,0 +1,64 @@ +begin 644 s390x-prologue-skip.o.uu +M?T5,1@("`0`````````````!`!8````!```````````````````````````` +M``+```````!```````!``!(`#^LE\!``).O?\&@`)+D$`.^G^_]@X^#P```D +MP.4`````N00``NLE\+``!`J.N00`TKD$`"#`Y0````"Y!``MZ]_Q"``$I_0` +M"L`0`````+\/$`"G=/_7"HZG2?`!N2$`),"T``````?^````5@`"````.0$! +M^PX-``$!`0$````!```!+BXO7-C86QL+71E;7!L +M871E+E,``0`````)`@```````````]```0)F$P("``$!````CP`"``````@! +M```````````````````````````N+B]S>7-D97!S+W5N:7@OE(``7@. +M`1L,#Z`!````````&````!P`````````1`!,CP6.!HT'2`[``@```!`````X +M`````````"```````"YS>6UT86(`+G-T``````````&````!`````&``````````@````````` +M&````%<````!``````````````````````````````$"`````````),````` +M```````````````!``````````````!2````!``````````````````````` +M```````)^`````````!@````$`````@`````````"``````````8````8P`` +M``$``````````````````````````````94`````````%``````````````` +M``````$``````````````'8````!``````````````````````````````&P +M`````````#`````````````````````0``````````````!Q````!``````` +M```````````````````````*6``````````P````$`````L`````````"``` +M```````8````B@````$``````````@```````````````````>`````````` +M2`````````````````````@``````````````(4````$```````````````` +M``````````````J(`````````#`````0````#0`````````(`````````!@` +M```1`````P`````````````````````````````"*`````````"4```````` +M`````````````0```````````````0````(````````````````````````` +M````!T`````````!L````!$````*``````````@`````````&`````D````# +M``````````````````````````````CP`````````(X````````````````` +M```!`````````````````````````````````````````````````P```0`` +M`````````````````````````P```P```````````````````````````P`` +M!````````````````````````````P``"``````````````````````````` +M`P``"@```````````````````````````P``!@`````````````````````` +M`````P``"P```````````````````````````P``#0`````````````````` +M`````````P``!0`````````````````````````!$``````````````````` +M```````````;$``````````````````````````````V$@```0````````!( +M`````````"`````_$`````````````````````````````!7$@```0`````` +M``!6`````````!````!I$`````````````````````````````!Y(@```0`` +M``````!(`````````"````"'(@```0````````!(`````````"``7U]L:6)C +M7V5N86)L95]AP!$/'_____^*#EZ-A!SP36P&_:G0#=14``04A&8,'U +M2*9`>$$)P`*RN"#*;#4R()IJ8C$TT&FC3$&@`T`#:C1H8C0T,@,FC,D"4T2! +M"/2CU'B90]31ZAD#U`&AZF@/4:``!HT&F@!H<`#0-`-#0``#3$-&F@```#0R +M``#")2FD]2>4]0TTT-!HTT--,0,"#$`R!I@AD`#1H,3&GZT.4TO$#H40/`0C +M2$IRXS,<55!8T,&&,R.Z441"?J9I%G6GUA2!.[]Z"C5S[&19,%VS7E6[3"60 +M@`-*2G)QEQ(;?0Y<=MK]/U?Q)LB%+F37TJ9BI*46)H'*Z@V"`"$"P7]&XZ:JE0E<*:#1M$P3G]>VCI)(A!O$64`5$4`E$$-.``7&(09`8HO`B6K!Q^& +M562%N)2+0@*HB@%D@5$%!*0!L1&0D4D6\:-$A`)`+<6D82PP*H(J(H!?F;0$ +M%PXB7N!2D4!44`W7"ADEQM6O9TBO5,_]1) +M($Q2))#),UE,QQK)E$,3D\W.>!4)QO8A_@^Z_SXS4;Q8=HV6[:&$@2$@$R29IBW)K%3"O` +M9^Y0YJ&BXY1U2HTZ5)2H-V\_(.DZHWE+C#WS($(!I"3CUH2#(+(OWUV"*<<9 +MJ%A!J[%O.P&V%GI.`L7<1@0>,^1F\MY=V5UT,&NOG%7TTZ[03!@BHB@&)P` +` +end diff --git a/gdb/testsuite/gdb.arch/x86_64-pid0-core.exp b/gdb/testsuite/gdb.arch/x86_64-pid0-core.exp new file mode 100644 index 00000000000..7a5a1cac198 --- /dev/null +++ b/gdb/testsuite/gdb.arch/x86_64-pid0-core.exp @@ -0,0 +1,46 @@ +# This testcase is part of GDB, the GNU debugger. +# +# Copyright 2010 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Some kernel core files have PID 0 - for the idle task. + +if ![istarget "x86_64-*-*"] { + verbose "Skipping x86_64-pid0-core test." + return +} + +set testfile "x86_64-pid0-core" +set corebz2uufile ${srcdir}/${subdir}/${testfile}.core.bz2.uu +set corefile [standard_output_file ${testfile}.core] + +if {[catch "system \"uudecode -o - ${corebz2uufile} | bzip2 -dc >${corefile}\""] != 0} { + untested "failed uudecode or bzip2" + return -1 +} +file stat ${corefile} corestat +if {$corestat(size) != 8798208} { + untested "uudecode or bzip2 produce invalid result" + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir + +# Former crash was: +# thread.c:884: internal-error: switch_to_thread: Assertion `inf != NULL' failed. +gdb_test "core-file ${corefile}" "Program terminated with signal (11|SIGSEGV), Segmentation fault\\.\r\n.*" diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-pointer-foo.S b/gdb/testsuite/gdb.arch/x86_64-vla-pointer-foo.S new file mode 100644 index 00000000000..3a983e6b22e --- /dev/null +++ b/gdb/testsuite/gdb.arch/x86_64-vla-pointer-foo.S @@ -0,0 +1,358 @@ + .file "x86_64-vla-pointer.c" + .text +.Ltext0: + .globl foo + .type foo, @function +foo: +.LFB0: + .file 1 "gdb.arch/x86_64-vla-pointer.c" + # gdb.arch/x86_64-vla-pointer.c:22 + .loc 1 22 0 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset 6, -16 + movq %rsp, %rbp + .cfi_def_cfa_register 6 + pushq %rbx + subq $56, %rsp + .cfi_offset 3, -24 + movl %edi, -52(%rbp) + # gdb.arch/x86_64-vla-pointer.c:22 + .loc 1 22 0 + movq %rsp, %rax + movq %rax, %rsi + # gdb.arch/x86_64-vla-pointer.c:23 + .loc 1 23 0 + movl -52(%rbp), %eax + movslq %eax, %rdx + subq $1, %rdx + movq %rdx, -32(%rbp) + movslq %eax, %rdx + movq %rdx, %r8 + movl $0, %r9d + # gdb.arch/x86_64-vla-pointer.c:24 + .loc 1 24 0 + movslq %eax, %rdx + movq %rdx, %rcx + movl $0, %ebx + cltq + movl $16, %edx + subq $1, %rdx + addq %rdx, %rax + movl $16, %ebx + movl $0, %edx + divq %rbx + imulq $16, %rax, %rax + subq %rax, %rsp + movq %rsp, %rax + addq $0, %rax + movq %rax, -40(%rbp) + # gdb.arch/x86_64-vla-pointer.c:27 + .loc 1 27 0 + movl $0, -20(%rbp) +# SUCC: 4 [100.0%] + jmp .L2 +# BLOCK 3 seq:1 +# PRED: 4 +.L3: + # gdb.arch/x86_64-vla-pointer.c:28 + .loc 1 28 0 discriminator 3 + movl -20(%rbp), %eax + movl %eax, %ecx + movq -40(%rbp), %rdx + movl -20(%rbp), %eax + cltq + movb %cl, (%rdx,%rax) +# SUCC: 4 (FALLTHRU,DFS_BACK) + # gdb.arch/x86_64-vla-pointer.c:27 + .loc 1 27 0 discriminator 3 + addl $1, -20(%rbp) +# BLOCK 4 seq:2 +# PRED: 3 (FALLTHRU,DFS_BACK) 2 [100.0%] +.L2: + # gdb.arch/x86_64-vla-pointer.c:27 + .loc 1 27 0 is_stmt 0 discriminator 1 + movl -20(%rbp), %eax + cmpl -52(%rbp), %eax +# SUCC: 3 5 (FALLTHRU) + jl .L3 +# BLOCK 5 seq:3 +# PRED: 4 (FALLTHRU) + # gdb.arch/x86_64-vla-pointer.c:30 + .loc 1 30 0 is_stmt 1 + movq -40(%rbp), %rax + movb $0, (%rax) + movq %rsi, %rsp + # gdb.arch/x86_64-vla-pointer.c:31 + .loc 1 31 0 + nop + movq -8(%rbp), %rbx + leave + .cfi_def_cfa 7, 8 +# SUCC: EXIT [100.0%] + ret + .cfi_endproc +.LFE0: + .size foo, .-foo +.Letext0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .long 0xa5 # Length of Compilation Unit Info + .value 0x4 # DWARF version number + .long .Ldebug_abbrev0 # Offset Into Abbrev. Section + .byte 0x8 # Pointer Size (in bytes) + .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit) + .long .LASF3 # DW_AT_producer: "GNU C11 6.2.1 20160916 (Red Hat 6.2.1-2) -mtune=generic -march=x86-64 -g" + .byte 0xc # DW_AT_language + .long .LASF4 # DW_AT_name: "gdb.arch/x86_64-vla-pointer.c" + .long .LASF5 # DW_AT_comp_dir: "/home/jkratoch/redhat/fedora/gdb/master/gdb-7.12/gdb/testsuite" + .quad .Ltext0 # DW_AT_low_pc + .quad .Letext0-.Ltext0 # DW_AT_high_pc + .long .Ldebug_line0 # DW_AT_stmt_list + .uleb128 0x2 # (DIE (0x2d) DW_TAG_subprogram) + # DW_AT_external + .ascii "foo\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (gdb.arch/x86_64-vla-pointer.c) + .byte 0x15 # DW_AT_decl_line + # DW_AT_prototyped + .quad .LFB0 # DW_AT_low_pc + .quad .LFE0-.LFB0 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + # DW_AT_GNU_all_call_sites + .long 0x80 # DW_AT_sibling + .uleb128 0x3 # (DIE (0x4a) DW_TAG_formal_parameter) + .long .LASF6 # DW_AT_name: "size" + .byte 0x1 # DW_AT_decl_file (gdb.arch/x86_64-vla-pointer.c) + .byte 0x15 # DW_AT_decl_line + .long 0x80 # DW_AT_type + .uleb128 0x3 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -68 + .uleb128 0x4 # (DIE (0x59) DW_TAG_typedef) + .long .LASF7 # DW_AT_name: "array_t" + .byte 0x1 # DW_AT_decl_file (gdb.arch/x86_64-vla-pointer.c) + .byte 0x17 # DW_AT_decl_line + .long 0x87 # DW_AT_type + .uleb128 0x5 # (DIE (0x64) DW_TAG_variable) + .long .LASF0 # DW_AT_name: "array" + .byte 0x1 # DW_AT_decl_file (gdb.arch/x86_64-vla-pointer.c) + .byte 0x18 # DW_AT_decl_line + .long 0x59 # DW_AT_type + .uleb128 0x3 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -56 + .byte 0x6 # DW_OP_deref + .uleb128 0x6 # (DIE (0x73) DW_TAG_variable) + .ascii "i\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (gdb.arch/x86_64-vla-pointer.c) + .byte 0x19 # DW_AT_decl_line + .long 0x80 # DW_AT_type + .uleb128 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -36 + .byte 0 # end of children of DIE 0x2d + .uleb128 0x7 # (DIE (0x80) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .uleb128 0x8 # (DIE (0x87) DW_TAG_array_type) + .long 0xa1 # DW_AT_type + .long 0x9a # DW_AT_sibling + .uleb128 0x9 # (DIE (0x90) DW_TAG_subrange_type) + .long 0x9a # DW_AT_type + .uleb128 0x3 # DW_AT_upper_bound + .byte 0x91 # DW_OP_fbreg + .sleb128 -48 + .byte 0x6 # DW_OP_deref + .byte 0 # end of children of DIE 0x87 + .uleb128 0xa # (DIE (0x9a) DW_TAG_base_type) + .byte 0x8 # DW_AT_byte_size + .byte 0x7 # DW_AT_encoding + .long .LASF1 # DW_AT_name: "sizetype" + .uleb128 0xa # (DIE (0xa1) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x6 # DW_AT_encoding + .long .LASF2 # DW_AT_name: "char" + .byte 0 # end of children of DIE 0xb + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x10 # (DW_AT_stmt_list) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0 + .byte 0 + .uleb128 0x2 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .uleb128 0x2117 # (DW_AT_GNU_all_call_sites) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x3 # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x4 # (abbrev code) + .uleb128 0x16 # (TAG: DW_TAG_typedef) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x5 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x6 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0x7 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0 + .byte 0 + .uleb128 0x8 # (abbrev code) + .uleb128 0x1 # (TAG: DW_TAG_array_type) + .byte 0x1 # DW_children_yes + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x9 # (abbrev code) + .uleb128 0x21 # (TAG: DW_TAG_subrange_type) + .byte 0 # DW_children_no + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2f # (DW_AT_upper_bound) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0 + .byte 0 + .uleb128 0xa # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .byte 0 + .byte 0 + .byte 0 + .section .debug_aranges,"",@progbits + .long 0x2c # Length of Address Ranges Info + .value 0x2 # DWARF Version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .byte 0x8 # Size of Address + .byte 0 # Size of Segment Descriptor + .value 0 # Pad to 16 byte boundary + .value 0 + .quad .Ltext0 # Address + .quad .Letext0-.Ltext0 # Length + .quad 0 + .quad 0 + .section .debug_line,"",@progbits +.Ldebug_line0: + .section .debug_str,"MS",@progbits,1 +.LASF4: + .string "gdb.arch/x86_64-vla-pointer.c" +.LASF7: + .string "array_t" +.LASF3: + .string "GNU C11 6.2.1 20160916 (Red Hat 6.2.1-2) -mtune=generic -march=x86-64 -g" +.LASF2: + .string "char" +.LASF1: + .string "sizetype" +.LASF5: + .string "/home/jkratoch/redhat/fedora/gdb/master/gdb-7.12/gdb/testsuite" +.LASF6: + .string "size" +.LASF0: + .string "array" + .ident "GCC: (GNU) 6.2.1 20160916 (Red Hat 6.2.1-2)" + .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-pointer.c b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.c new file mode 100644 index 00000000000..98ee43bbf24 --- /dev/null +++ b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.c @@ -0,0 +1,45 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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 . */ + +#if 0 + +void +foo (int size) +{ + typedef char array_t[size]; + array_t array; + int i; + + for (i = 0; i < size; i++) + array[i] = i; + + array[0] = 0; /* break-here */ +} + +#else + +void foo (int size); + +int +main (void) +{ + foo (26); + foo (78); + return 0; +} + +#endif diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-pointer.exp b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.exp new file mode 100644 index 00000000000..3e2e64a6ab6 --- /dev/null +++ b/gdb/testsuite/gdb.arch/x86_64-vla-pointer.exp @@ -0,0 +1,65 @@ +# Copyright 2009 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 . + +if ![istarget "x86_64-*-*"] then { + verbose "Skipping over gdb.arch/x86_64-vla-pointer.exp test made only for x86_64." + return +} + +set testfile x86_64-vla-pointer +set srcasmfile ${testfile}-foo.S +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +set binobjfile [standard_output_file ${testfile}-foo.o] +if { [gdb_compile "${srcdir}/${subdir}/${srcasmfile}" "${binobjfile}" object {}] != "" } { + untested "Couldn't compile test program" + return -1 +} +if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${binobjfile}" "${binfile}" executable {}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] { + untested x86_64-vla-pointer + return -1 +} + +gdb_breakpoint $srcfile:[gdb_get_line_number "break-here"] + +gdb_continue_to_breakpoint "break-here" + +gdb_test "whatis array" "type = array_t" "first: whatis array" +gdb_test "whatis array_t" "type = char \\\[variable length\\\]" "first: whatis array_t" +gdb_test "ptype array" "type = char \\\[26\\\]" "first: ptype array" + +gdb_test "whatis *array" "type = char" "first: whatis *array" +gdb_test "ptype *array" "type = char" "first: ptype *array" + +gdb_test "p array\[1\]" "\\$\[0-9\] = 1 '\\\\001'" +gdb_test "p array\[2\]" "\\$\[0-9\] = 2 '\\\\002'" +gdb_test "p array\[3\]" "\\$\[0-9\] = 3 '\\\\003'" +gdb_test "p array\[4\]" "\\$\[0-9\] = 4 '\\\\004'" + +gdb_continue_to_breakpoint "break_here" + +gdb_test "whatis array" "type = array_t" "second: whatis array" +gdb_test "whatis array_t" "type = char \\\[variable length\\\]" "second: whatis array_t" +gdb_test "ptype array" "type = char \\\[78\\\]" "second: ptype array" diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S new file mode 100644 index 00000000000..66f7a399bf7 --- /dev/null +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef-foo.S @@ -0,0 +1,455 @@ + .file "x86_64-vla-typedef.c" + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .section .debug_line,"",@progbits +.Ldebug_line0: + .text +.Ltext0: +.globl foo + .type foo, @function +foo: +.LFB2: + .file 1 "x86_64-vla-typedef.c" + .loc 1 22 0 + pushq %rbp +.LCFI0: + movq %rsp, %rbp +.LCFI1: + subq $64, %rsp +.LCFI2: + movl %edi, -36(%rbp) + .loc 1 22 0 + movq %rsp, %rax + movq %rax, -48(%rbp) + .loc 1 23 0 + movl -36(%rbp), %edx + movslq %edx,%rax + subq $1, %rax + movq %rax, -24(%rbp) + .loc 1 24 0 + movslq %edx,%rax + addq $15, %rax + addq $15, %rax + shrq $4, %rax + salq $4, %rax + subq %rax, %rsp + movq %rsp, -56(%rbp) + movq -56(%rbp), %rax + addq $15, %rax + shrq $4, %rax + salq $4, %rax + movq %rax, -56(%rbp) + movq -56(%rbp), %rax + movq %rax, -16(%rbp) + .loc 1 27 0 + movl $0, -4(%rbp) + jmp .L2 +.L3: + .loc 1 28 0 + movl -4(%rbp), %esi + movl -4(%rbp), %eax + movl %eax, %ecx + movq -16(%rbp), %rdx + movslq %esi,%rax + movb %cl, (%rdx,%rax) + .loc 1 27 0 + addl $1, -4(%rbp) +.L2: + movl -4(%rbp), %eax + cmpl -36(%rbp), %eax + jl .L3 + .loc 1 30 0 + .globl break_here +break_here: + movq -16(%rbp), %rax + movb $0, (%rax) + movq -48(%rbp), %rsp + .loc 1 31 0 + leave + ret +.LFE2: + .size foo, .-foo + .section .debug_frame,"",@progbits +.Lframe0: + .long .LECIE0-.LSCIE0 +.LSCIE0: + .long 0xffffffff + .byte 0x1 + .string "" + .uleb128 0x1 + .sleb128 -8 + .byte 0x10 + .byte 0xc + .uleb128 0x7 + .uleb128 0x8 + .byte 0x90 + .uleb128 0x1 + .align 8 +.LECIE0: +.LSFDE0: + .long .LEFDE0-.LASFDE0 +.LASFDE0: + .long .Lframe0 + .quad .LFB2 + .quad .LFE2-.LFB2 + .byte 0x4 + .long .LCFI0-.LFB2 + .byte 0xe + .uleb128 0x10 + .byte 0x86 + .uleb128 0x2 + .byte 0x4 + .long .LCFI1-.LCFI0 + .byte 0xd + .uleb128 0x6 + .align 8 +.LEFDE0: + .section .eh_frame,"a",@progbits +.Lframe1: + .long .LECIE1-.LSCIE1 +.LSCIE1: + .long 0x0 + .byte 0x1 + .string "zR" + .uleb128 0x1 + .sleb128 -8 + .byte 0x10 + .uleb128 0x1 + .byte 0x3 + .byte 0xc + .uleb128 0x7 + .uleb128 0x8 + .byte 0x90 + .uleb128 0x1 + .align 8 +.LECIE1: +.LSFDE1: + .long .LEFDE1-.LASFDE1 +.LASFDE1: + .long .LASFDE1-.Lframe1 + .long .LFB2 + .long .LFE2-.LFB2 + .uleb128 0x0 + .byte 0x4 + .long .LCFI0-.LFB2 + .byte 0xe + .uleb128 0x10 + .byte 0x86 + .uleb128 0x2 + .byte 0x4 + .long .LCFI1-.LCFI0 + .byte 0xd + .uleb128 0x6 + .align 8 +.LEFDE1: + .text +.Letext0: + .section .debug_loc,"",@progbits +.Ldebug_loc0: +.LLST0: + .quad .LFB2-.Ltext0 + .quad .LCFI0-.Ltext0 + .value 0x2 + .byte 0x77 + .sleb128 8 + .quad .LCFI0-.Ltext0 + .quad .LCFI1-.Ltext0 + .value 0x2 + .byte 0x77 + .sleb128 16 + .quad .LCFI1-.Ltext0 + .quad .LFE2-.Ltext0 + .value 0x2 + .byte 0x76 + .sleb128 16 + .quad 0x0 + .quad 0x0 + .section .debug_info + .long .Ldebug_end - .Ldebug_start +.Ldebug_start: + .value 0x2 + .long .Ldebug_abbrev0 + .byte 0x8 + .uleb128 0x1 + .long .LASF2 + .byte 0x1 + .long .LASF3 + .long .LASF4 + .quad .Ltext0 + .quad .Letext0 + .long .Ldebug_line0 + .uleb128 0x2 + .byte 0x1 + .string "foo" + .byte 0x1 + .byte 0x16 + .byte 0x1 + .quad .LFB2 + .quad .LFE2 + .long .LLST0 + .long 0x83 + .uleb128 0x3 + .long .LASF5 + .byte 0x1 + .byte 0x15 + .long 0x83 + .byte 0x2 + .byte 0x91 + .sleb128 -52 +.Ltag_typedef: + .uleb128 0x4 + .long .LASF6 + .byte 0x1 + .byte 0x17 + .long .Ltag_array_type - .debug_info + .uleb128 0x5 /* Abbrev Number: 5 (DW_TAG_variable) */ + .long .LASF0 + .byte 0x1 + .byte 0x18 +#if 1 + .long .Ltag_typedef - .debug_info +#else + /* Debugging only: Skip the typedef indirection. */ + .long .Ltag_array_type - .debug_info +#endif + /* DW_AT_location: DW_FORM_block1: start */ + .byte 0x3 + .byte 0x91 + .sleb128 -32 +#if 0 + .byte 0x6 /* DW_OP_deref */ +#else + .byte 0x96 /* DW_OP_nop */ +#endif + /* DW_AT_location: DW_FORM_block1: end */ + .uleb128 0x6 + .string "i" + .byte 0x1 + .byte 0x19 + .long 0x83 + .byte 0x2 + .byte 0x91 + .sleb128 -20 + .byte 0x0 + .uleb128 0x7 + .byte 0x4 + .byte 0x5 + .string "int" +.Ltag_array_type: + .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */ + .long 0xa0 + (2f - 1f) /* DW_AT_type: DW_FORM_ref4 */ + .long 0x9d + (2f - 1f) /* DW_AT_sibling: DW_FORM_ref4 */ +1: /* DW_AT_data_location: DW_FORM_block1: start */ + .byte 2f - 3f /* length */ +3: + .byte 0x97 /* DW_OP_push_object_address */ + .byte 0x6 /* DW_OP_deref */ +2: /* DW_AT_data_location: DW_FORM_block1: end */ + .uleb128 0x9 + .long 0x9d + (2b - 1b) /* DW_AT_type: DW_FORM_ref4 */ + .byte 0x3 + .byte 0x91 + .sleb128 -40 + .byte 0x6 + .byte 0x0 + .uleb128 0xa + .byte 0x8 + .byte 0x7 + .uleb128 0xb + .byte 0x1 + .byte 0x6 + .long .LASF1 + .byte 0x0 +.Ldebug_end: + .section .debug_abbrev + .uleb128 0x1 + .uleb128 0x11 + .byte 0x1 + .uleb128 0x25 + .uleb128 0xe + .uleb128 0x13 + .uleb128 0xb + .uleb128 0x3 + .uleb128 0xe + .uleb128 0x1b + .uleb128 0xe + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x1 + .uleb128 0x10 + .uleb128 0x6 + .byte 0x0 + .byte 0x0 + .uleb128 0x2 + .uleb128 0x2e + .byte 0x1 + .uleb128 0x3f + .uleb128 0xc + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x27 + .uleb128 0xc + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x1 + .uleb128 0x40 + .uleb128 0x6 + .uleb128 0x1 + .uleb128 0x13 + .byte 0x0 + .byte 0x0 + .uleb128 0x3 + .uleb128 0x5 + .byte 0x0 + .uleb128 0x3 + .uleb128 0xe + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x2 + .uleb128 0xa + .byte 0x0 + .byte 0x0 + .uleb128 0x4 + .uleb128 0x16 + .byte 0x0 + .uleb128 0x3 + .uleb128 0xe + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .byte 0x0 + .byte 0x0 + .uleb128 0x5 + .uleb128 0x34 + .byte 0x0 + .uleb128 0x3 + .uleb128 0xe + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x2 + .uleb128 0xa + .byte 0x0 + .byte 0x0 + .uleb128 0x6 + .uleb128 0x34 + .byte 0x0 + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x2 + .uleb128 0xa + .byte 0x0 + .byte 0x0 + .uleb128 0x7 + .uleb128 0x24 + .byte 0x0 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x3e + .uleb128 0xb + .uleb128 0x3 + .uleb128 0x8 + .byte 0x0 + .byte 0x0 + .uleb128 0x8 /* Abbrev Number: 8 (DW_TAG_array_type) */ + .uleb128 0x1 + .byte 0x1 + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x1 /* DW_AT_sibling */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x50 /* DW_AT_data_location */ + .uleb128 0xa /* DW_FORM_block1 */ + .byte 0x0 + .byte 0x0 + .uleb128 0x9 + .uleb128 0x21 + .byte 0x0 + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x2f + .uleb128 0xa + .byte 0x0 + .byte 0x0 + .uleb128 0xa + .uleb128 0x24 + .byte 0x0 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x3e + .uleb128 0xb + .byte 0x0 + .byte 0x0 + .uleb128 0xb + .uleb128 0x24 + .byte 0x0 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x3e + .uleb128 0xb + .uleb128 0x3 + .uleb128 0xe + .byte 0x0 + .byte 0x0 + .byte 0x0 + .section .debug_pubnames,"",@progbits + .long 0x16 + .value 0x2 + .long .Ldebug_info0 + .long 0xa8 + .long 0x2d + .string "foo" + .long 0x0 + .section .debug_aranges,"",@progbits + .long 0x2c + .value 0x2 + .long .Ldebug_info0 + .byte 0x8 + .byte 0x0 + .value 0x0 + .value 0x0 + .quad .Ltext0 + .quad .Letext0-.Ltext0 + .quad 0x0 + .quad 0x0 + .section .debug_str,"MS",@progbits,1 +.LASF0: + .string "array" +.LASF5: + .string "size" +.LASF3: + .string "x86_64-vla-typedef.c" +.LASF6: + .string "array_t" +.LASF1: + .string "char" +.LASF4: + .string "gdb.arch" +.LASF2: + .string "GNU C 4.3.2 20081105 (Red Hat 4.3.2-7)" + .ident "GCC: (GNU) 4.3.2 20081105 (Red Hat 4.3.2-7)" + .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c new file mode 100644 index 00000000000..40099e9d393 --- /dev/null +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.c @@ -0,0 +1,45 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008 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 . */ + +#if 0 + +void +foo (int size) +{ + typedef char array_t[size]; + array_t array; + int i; + + for (i = 0; i < size; i++) + array[i] = i; + + array[0] = 0; /* break-here */ +} + +#else + +void foo (int size); + +int +main (void) +{ + foo (26); + foo (78); + return 0; +} + +#endif diff --git a/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp new file mode 100644 index 00000000000..4ef6214629a --- /dev/null +++ b/gdb/testsuite/gdb.arch/x86_64-vla-typedef.exp @@ -0,0 +1,64 @@ +# Copyright 2009 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 . + +# Test DW_AT_data_location accessed through DW_TAG_typedef intermediate. + +if ![istarget "x86_64-*-*"] then { + verbose "Skipping over gdb.arch/x86_64-vla-typedef.exp test made only for x86_64." + return +} + +set testfile x86_64-vla-typedef +set srcasmfile ${testfile}-foo.S +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +set binobjfile [standard_output_file ${testfile}-foo.o] +if { [gdb_compile "${srcdir}/${subdir}/${srcasmfile}" "${binobjfile}" object {}] != "" } { + untested "Couldn't compile test program" + return -1 +} +if { [gdb_compile "${srcdir}/${subdir}/${srcfile} ${binobjfile}" "${binfile}" executable {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] { + untested x86_64-vla-typedef + return -1 +} + +gdb_breakpoint "break_here" + +gdb_continue_to_breakpoint "break_here" + +gdb_test "whatis array" "type = array_t" "first: whatis array" + +gdb_test "ptype array" "type = char \\\[26\\\]" "first: ptype array" + +gdb_test "p array\[1\]" "\\$\[0-9\] = 1 '\\\\001'" +gdb_test "p array\[2\]" "\\$\[0-9\] = 2 '\\\\002'" +gdb_test "p array\[3\]" "\\$\[0-9\] = 3 '\\\\003'" +gdb_test "p array\[4\]" "\\$\[0-9\] = 4 '\\\\004'" + +gdb_continue_to_breakpoint "break_here" + +gdb_test "whatis array" "type = array_t" "second: whatis array" + +gdb_test "ptype array" "type = char \\\[78\\\]" "second: ptype array" diff --git a/gdb/testsuite/gdb.base/annota1.exp b/gdb/testsuite/gdb.base/annota1.exp index 5237bc9715b..8299b25acc2 100644 --- a/gdb/testsuite/gdb.base/annota1.exp +++ b/gdb/testsuite/gdb.base/annota1.exp @@ -39,6 +39,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb clean_restart ${binfile} +gdb_test "set breakpoint pending off" "" "Avoid lockup on nonexisting functions" + # The commands we test here produce many lines of output; disable "press # to continue" prompts. gdb_test_no_output "set height 0" diff --git a/gdb/testsuite/gdb.base/annota3.exp b/gdb/testsuite/gdb.base/annota3.exp index e4f7d38eb91..404dbfbd892 100644 --- a/gdb/testsuite/gdb.base/annota3.exp +++ b/gdb/testsuite/gdb.base/annota3.exp @@ -38,6 +38,8 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb clean_restart ${binfile} +gdb_test "set breakpoint pending off" "" "Avoid lockup on nonexisting functions" + # The commands we test here produce many lines of output; disable "press # to continue" prompts. gdb_test_no_output "set height 0" diff --git a/gdb/testsuite/gdb.base/arrayidx.c b/gdb/testsuite/gdb.base/arrayidx.c index 3a4631c9372..d7f750f6a82 100644 --- a/gdb/testsuite/gdb.base/arrayidx.c +++ b/gdb/testsuite/gdb.base/arrayidx.c @@ -17,6 +17,13 @@ int array[] = {1, 2, 3, 4}; +#ifdef __GNUC__ +struct + { + int a[0]; + } unbound; +#endif + int main (void) { diff --git a/gdb/testsuite/gdb.base/arrayidx.exp b/gdb/testsuite/gdb.base/arrayidx.exp index 256a47e5084..8e75072697c 100644 --- a/gdb/testsuite/gdb.base/arrayidx.exp +++ b/gdb/testsuite/gdb.base/arrayidx.exp @@ -49,4 +49,12 @@ gdb_test "print array" \ "\\{\\\[0\\\] = 1, \\\[1\\\] = 2, \\\[2\\\] = 3, \\\[3\\\] = 4\\}" \ "print array with array-indexes on" - +set test "p unbound.a == &unbound.a\[0\]" +gdb_test_multiple $test $test { + -re " = 1\r\n$gdb_prompt $" { + pass $test + } + -re "No symbol \"unbound\" in current context.\r\n$gdb_prompt $" { + unsupported "$test (no GCC)" + } +} diff --git a/gdb/testsuite/gdb.base/attach-32.c b/gdb/testsuite/gdb.base/attach-32.c new file mode 100644 index 00000000000..0041b4732d2 --- /dev/null +++ b/gdb/testsuite/gdb.base/attach-32.c @@ -0,0 +1,20 @@ +/* This program is intended to be started outside of gdb, and then + attached to by gdb. Thus, it simply spins in a loop. The loop + is exited when & if the variable 'should_exit' is non-zero. (It + is initialized to zero in this program, so the loop will never + exit unless/until gdb sets the variable to non-zero.) + */ +#include + +int should_exit = 0; + +int main () +{ + int local_i = 0; + + while (! should_exit) + { + local_i++; + } + return 0; +} diff --git a/gdb/testsuite/gdb.base/attach-32.exp b/gdb/testsuite/gdb.base/attach-32.exp new file mode 100644 index 00000000000..67ded02ccfb --- /dev/null +++ b/gdb/testsuite/gdb.base/attach-32.exp @@ -0,0 +1,245 @@ +# Copyright 2005 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# This test was based on attach.exp and modified for 32/64 bit Linux systems. */ + +# On HP-UX 11.0, this test is causing a process running the program +# "attach" to be left around spinning. Until we figure out why, I am +# commenting out the test to avoid polluting tiamat (our 11.0 nightly +# test machine) with these processes. RT +# +# Setting the magic bit in the target app should work. I added a +# "kill", and also a test for the R3 register warning. JB +if { ![istarget "x86_64*-*linux*"] + && ![istarget "powerpc64*-*linux*"]} { + return 0 +} + +# are we on a target board +if [is_remote target] then { + return 0 +} + +set testfile "attach-32" +set srcfile ${testfile}.c +set srcfile2 ${testfile}b.c +set binfile [standard_output_file ${testfile}] +set binfile2 [standard_output_file ${testfile}b] +set escapedbinfile [string_to_regexp [standard_output_file ${testfile}]] + +#execute_anywhere "rm -f ${binfile} ${binfile2}" +remote_exec build "rm -f ${binfile} ${binfile2}" +# For debugging this test +# +#log_user 1 + +# build the first test case +# +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "additional_flags=-m32"]] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +# Build the in-system-call test + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable [list debug "additional_flags=-m32"]] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +if [get_compiler_info ${binfile}] { + return -1 +} + +proc do_attach_tests {} { + global gdb_prompt + global binfile + global escapedbinfile + global srcfile + global testfile + global objdir + global subdir + global timeout + global testpid + + # Verify that we can "see" the variable "should_exit" in the + # program, and that it is zero. + + gdb_test "print should_exit" " = 0" "after attach-32, print should_exit" + + # Verify that we can modify the variable "should_exit" in the + # program. + + gdb_test "set should_exit=1" "" "after attach-32, set should_exit" + + # Verify that the modification really happened. + + send_gdb "tbreak 19\n" + gdb_expect { + -re "reakpoint .*at.*$srcfile, line 19.*$gdb_prompt $" { + pass "after attach-32, set tbreak postloop" + } + -re "$gdb_prompt $" { + fail "after attach-32, set tbreak postloop" + } + timeout { + fail "(timeout) after attach-32, set tbreak postloop" + } + } + send_gdb "continue\n" + gdb_expect { + -re "main.*at.*$srcfile:19.*$gdb_prompt $" { + pass "after attach-32, reach tbreak postloop" + } + -re "$gdb_prompt $" { + fail "after attach-32, reach tbreak postloop" + } + timeout { + fail "(timeout) after attach-32, reach tbreak postloop" + } + } + + # Allow the test process to exit, to cleanup after ourselves. + + gdb_test "continue" {\[Inferior .* exited normally\]} "after attach-32, exit" + + # Make sure we don't leave a process around to confuse + # the next test run (and prevent the compile by keeping + # the text file busy), in case the "set should_exit" didn't + # work. + + remote_exec build "kill -9 ${testpid}" + + # Start the program running and then wait for a bit, to be sure + # that it can be attached to. + + set testpid [eval exec $binfile &] + exec sleep 2 + if { [istarget "*-*-cygwin*"] } { + # testpid is the Cygwin PID, GDB uses the Windows PID, which might be + # different due to the way fork/exec works. + set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ] + } + + # Verify that we can attach to the process, and find its a.out + # when we're cd'd to some directory that doesn't contain the + # a.out. (We use the source path set by the "dir" command.) + + gdb_test "dir ${objdir}/${subdir}" "Source directories searched: .*" \ + "set source path" + + gdb_test "cd /tmp" "Working directory /tmp." \ + "cd away from process working directory" + + # Explicitly flush out any knowledge of the previous attachment. + + set test "before attach-32-3, flush symbols" + gdb_test_multiple "symbol" "$test" { + -re "Discard symbol table from.*y or n. $" { + gdb_test "y" "No symbol file now." \ + "$test" + } + -re "No symbol file now.*$gdb_prompt $" { + pass "$test" + } + } + + gdb_test "exec" "No executable file now." \ + "before attach-32-3, flush exec" + + gdb_test "attach $testpid" \ + "Attaching to process $testpid.*Reading symbols from $escapedbinfile.*main.*at .*" \ + "attach-32 when process' a.out not in cwd" + + set test "after attach-32-3, exit" + gdb_test_multiple "kill" "$test" { + -re "Kill the program being debugged.*y or n. $" { + gdb_test "y" "" "$test" + } + } + + # Another "don't leave a process around" + remote_exec build "kill -9 ${testpid}" +} + +proc do_call_attach_tests {} { + global gdb_prompt + global binfile2 + global testpid + + # See if other registers are problems + + set test "info other register" + gdb_test_multiple "i r r3" "$test" { + -re "warning: reading register.*$gdb_prompt $" { + fail "$test" + } + -re "r3.*$gdb_prompt $" { + pass "$test" + } + } + + # Get rid of the process + + gdb_test "p should_exit = 1" + gdb_test "c" {\[Inferior .* exited normally\]} + + # Be paranoid + + remote_exec build "kill -9 ${testpid}" +} + + +# Start with a fresh gdb + +gdb_exit +set testpid [eval exec $binfile &] +exec sleep 3 +if { [istarget "*-*-cygwin*"] } { + # testpid is the Cygwin PID, GDB uses the Windows PID, which might be + # different due to the way fork/exec works. + set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ] +} + +set GDBFLAGS_orig $GDBFLAGS +set GDBFLAGS "--pid=$testpid" +gdb_start +set GDBFLAGS $GDBFLAGS_orig + +gdb_reinitialize_dir $srcdir/$subdir + +# This is a test of gdb's ability to attach to a running process. + +do_attach_tests + +# Test attaching when the target is inside a system call + +gdb_exit +set testpid [eval exec $binfile2 &] +exec sleep 3 +if { [istarget "*-*-cygwin*"] } { + # testpid is the Cygwin PID, GDB uses the Windows PID, which might be + # different due to the way fork/exec works. + set testpid [ exec ps -e | gawk "{ if (\$1 == $testpid) print \$4; }" ] +} + +set GDBFLAGS_orig $GDBFLAGS +set GDBFLAGS "--pid=$testpid" +gdb_start +set GDBFLAGS $GDBFLAGS_orig + +gdb_reinitialize_dir $srcdir/$subdir +do_call_attach_tests + +return 0 diff --git a/gdb/testsuite/gdb.base/attach-32b.c b/gdb/testsuite/gdb.base/attach-32b.c new file mode 100644 index 00000000000..a78037ed387 --- /dev/null +++ b/gdb/testsuite/gdb.base/attach-32b.c @@ -0,0 +1,24 @@ +/* This program is intended to be started outside of gdb, and then + attached to by gdb. Thus, it simply spins in a loop. The loop + is exited when & if the variable 'should_exit' is non-zero. (It + is initialized to zero in this program, so the loop will never + exit unless/until gdb sets the variable to non-zero.) + */ +#include +#include +#include + +int should_exit = 0; + +int main () +{ + int local_i = 0; + + sleep( 10 ); /* System call causes register fetch to fail */ + /* This is a known HPUX "feature" */ + while (! should_exit) + { + local_i++; + } + return (0); +} diff --git a/gdb/testsuite/gdb.base/attach-kills.c b/gdb/testsuite/gdb.base/attach-kills.c new file mode 100644 index 00000000000..2398f004425 --- /dev/null +++ b/gdb/testsuite/gdb.base/attach-kills.c @@ -0,0 +1,25 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2015 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +int +main (void) +{ + sleep (600); + return 0; +} diff --git a/gdb/testsuite/gdb.base/attach-kills.exp b/gdb/testsuite/gdb.base/attach-kills.exp new file mode 100644 index 00000000000..9a93cb75845 --- /dev/null +++ b/gdb/testsuite/gdb.base/attach-kills.exp @@ -0,0 +1,49 @@ +# Copyright (C) 2015 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if { ![can_spawn_for_attach] } { + return 0 +} + +standard_testfile + +if { [build_executable ${testfile}.exp $testfile] == -1 } { + return -1 +} + +# Start the program running and then wait for a bit, to be sure +# that it can be attached to. + +set test_spawn_id [spawn_wait_for_attach $binfile] +set testpid [spawn_id_get_pid $test_spawn_id] + +remote_exec target "cp -pf -- $binfile $binfile-copy" +remote_exec target "rm -f -- $binfile" + +set test "start gdb" +set res [gdb_spawn_with_cmdline_opts \ + "-iex \"set height 0\" -iex \"set width 0\" /DoEsNoTeXySt $testpid"] +if { $res != 0} { + fail "$test (spawn)" + kill_wait_spawned_process $test_spawn_id + return -1 +} +gdb_test_multiple "" $test { + -re "\r\nAttaching to .*\r\n$gdb_prompt $" { + pass $test + } +} + +kill_wait_spawned_process $test_spawn_id diff --git a/gdb/testsuite/gdb.base/attach-see-vdso.c b/gdb/testsuite/gdb.base/attach-see-vdso.c new file mode 100644 index 00000000000..cf3c7207a50 --- /dev/null +++ b/gdb/testsuite/gdb.base/attach-see-vdso.c @@ -0,0 +1,25 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#include + +int main () +{ + pause (); + return 1; +} diff --git a/gdb/testsuite/gdb.base/attach-see-vdso.exp b/gdb/testsuite/gdb.base/attach-see-vdso.exp new file mode 100644 index 00000000000..e8a538097e0 --- /dev/null +++ b/gdb/testsuite/gdb.base/attach-see-vdso.exp @@ -0,0 +1,72 @@ +# Copyright 2007 + +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# This file was created by Jan Kratochvil . + +# This test only works on Linux +if { ![istarget "*-*-linux-gnu*"] } { + return 0 +} + +set testfile "attach-see-vdso" +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +set escapedbinfile [string_to_regexp [standard_output_file ${testfile}]] + +# The kernel VDSO is used for the syscalls returns only on i386 (not x86_64). +# +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-m32}] != "" } { + gdb_suppress_entire_file "Testcase nonthraded compile failed, so all tests in this file will automatically fail." +} + +if [get_compiler_info ${binfile}] { + return -1 +} + +# Start the program running and then wait for a bit, to be sure +# that it can be attached to. + +set testpid [eval exec $binfile &] + +# Avoid some race: +sleep 2 + +# Start with clean gdb +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +# Never call: gdb_load ${binfile} +# as the former problem would not reproduce otherwise. + +set test "attach" +gdb_test_multiple "attach $testpid" "$test" { + -re "Attaching to process $testpid\r?\n.*$gdb_prompt $" { + pass "$test" + } +} + +gdb_test "bt" "#0 *0x\[0-9a-f\]* in \[^?\].*" "backtrace decodes VDSO" + +# Exit and detach the process. + +gdb_exit + +# Make sure we don't leave a process around to confuse +# the next test run (and prevent the compile by keeping +# the text file busy), in case the "set should_exit" didn't +# work. + +remote_exec build "kill -9 ${testpid}" diff --git a/gdb/testsuite/gdb.base/cfi-without-die-caller.c b/gdb/testsuite/gdb.base/cfi-without-die-caller.c new file mode 100644 index 00000000000..afdfd5331ae --- /dev/null +++ b/gdb/testsuite/gdb.base/cfi-without-die-caller.c @@ -0,0 +1,28 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2005, 2007, 2008, 2009, 2010 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 . */ + +typedef int (*callback_t) (void); + +int +caller (callback_t callback) +{ + /* Ensure some frame content to push away the return address. */ + volatile const long one = 1; + + /* Modify the return value to prevent any tail-call optimization. */ + return (*callback) () - one; +} diff --git a/gdb/testsuite/gdb.base/cfi-without-die-main.c b/gdb/testsuite/gdb.base/cfi-without-die-main.c new file mode 100644 index 00000000000..8451c4be706 --- /dev/null +++ b/gdb/testsuite/gdb.base/cfi-without-die-main.c @@ -0,0 +1,32 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2005, 2007, 2008, 2009, 2010 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 . */ + +typedef int (*callback_t) (void); + +extern int caller (callback_t callback); + +int +callback (void) +{ + return 1; +} + +int +main (void) +{ + return caller (callback); +} diff --git a/gdb/testsuite/gdb.base/cfi-without-die.exp b/gdb/testsuite/gdb.base/cfi-without-die.exp new file mode 100644 index 00000000000..5880d46f6d2 --- /dev/null +++ b/gdb/testsuite/gdb.base/cfi-without-die.exp @@ -0,0 +1,71 @@ +# Copyright 2010 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 . + +# Test CFI is parsed even for range (function) not described by any DIE. + +set testfile cfi-without-die +set srcmainfile ${testfile}-main.c +set srccallerfile ${testfile}-caller.c +set executable ${testfile} +set objmainfile [standard_output_file ${testfile}-main.o] +set objcallerfile [standard_output_file ${testfile}-caller.o] +set binfile [standard_output_file ${executable}] + +if { [gdb_compile "${srcdir}/${subdir}/${srccallerfile}" ${objcallerfile} \ + object [list {additional_flags=-fomit-frame-pointer -fno-unwind-tables -fno-asynchronous-unwind-tables}]] != "" + || [gdb_compile "${srcdir}/${subdir}/${srcmainfile}" ${objmainfile} object {debug}] != "" + || [gdb_compile "${objmainfile} ${objcallerfile}" ${binfile} executable {}] != "" } { + untested ${testfile}.exp + return -1 +} + +clean_restart $executable + +if ![runto callback] then { + fail "verify unwinding: Can't run to callback" + return 0 +} +set test "verify unwinding breaks without CFI" +gdb_test_multiple "bt" $test { + -re " in \[?\]\[?\] .*\r\n$gdb_prompt $" { + # It may backtrace through some random frames even to main(). + pass $test + } + -re " in main .*\r\n$gdb_prompt $" { + fail $test + } + -re "\r\n$gdb_prompt $" { + pass $test + } +} + +if { [gdb_compile "${srcdir}/${subdir}/${srccallerfile}" ${objcallerfile} \ + object [list {additional_flags=-fomit-frame-pointer -funwind-tables -fasynchronous-unwind-tables}]] != "" + || [gdb_compile "${srcdir}/${subdir}/${srcmainfile}" ${objmainfile} object {debug}] != "" + || [gdb_compile "${objmainfile} ${objcallerfile}" ${binfile} executable {}] != "" } { + untested ${testfile}.exp + return -1 +} + +clean_restart $executable + +if ![runto callback] then { + fail "test CFI without DIEs: Can't run to callback" + return 0 +} +# #0 callback () at ... +# #1 0x00000000004004e9 in caller () +# #2 0x00000000004004cd in main () at ... +gdb_test "bt" "#0 +callback \[^\r\n\]+\r\n#1 \[^\r\n\]+ in caller \[^\r\n\]+\r\n#2 \[^\r\n\]+ in main \[^\r\n\]+" "verify unwindin works for CFI without DIEs" diff --git a/gdb/testsuite/gdb.base/charsign.c b/gdb/testsuite/gdb.base/charsign.c new file mode 100644 index 00000000000..41d175ff9d4 --- /dev/null +++ b/gdb/testsuite/gdb.base/charsign.c @@ -0,0 +1,37 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +int main() +{ + return 0; +} + +char n[]="A"; +signed char s[]="A"; +unsigned char u[]="A"; + +typedef char char_n; +typedef signed char char_s; +typedef unsigned char char_u; + +char_n n_typed[]="A"; +char_s s_typed[]="A"; +char_u u_typed[]="A"; diff --git a/gdb/testsuite/gdb.base/charsign.exp b/gdb/testsuite/gdb.base/charsign.exp new file mode 100644 index 00000000000..b5fa5804900 --- /dev/null +++ b/gdb/testsuite/gdb.base/charsign.exp @@ -0,0 +1,63 @@ +# Copyright 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +set testfile charsign +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] + +proc do_test { cflags } { + global srcdir + global binfile + global subdir + global srcfile + global gdb_prompt + + if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug additional_flags=$cflags]] != "" } { + untested "Couldn't compile test program" + return -1 + } + + # Get things started. + + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + # For C programs, "start" should stop in main(). + + gdb_test "p n" \ + "= \"A\"" + gdb_test "p s" \ + "= \\{65 'A', 0 '\\\\0'\\}" + gdb_test "p u" \ + "= \\{65 'A', 0 '\\\\0'\\}" + gdb_test "p n_typed" \ + "= \"A\"" + gdb_test "p s_typed" \ + "= \\{65 'A', 0 '\\\\0'\\}" + gdb_test "p u_typed" \ + "= \\{65 'A', 0 '\\\\0'\\}" +} + +# The string identification works despite the compiler flags below due to +# gdbtypes.c: +# if (name && strcmp (name, "char") == 0) +# TYPE_FLAGS (type) |= TYPE_FLAG_NOSIGN; + +do_test {} +do_test {-fsigned-char} +do_test {-funsigned-char} diff --git a/gdb/testsuite/gdb.base/corefile.exp b/gdb/testsuite/gdb.base/corefile.exp index 0053f059458..32e359fce46 100644 --- a/gdb/testsuite/gdb.base/corefile.exp +++ b/gdb/testsuite/gdb.base/corefile.exp @@ -311,3 +311,33 @@ gdb_test_multiple "core-file $corefile" $test { pass $test } } + + +# Test auto-loading of binary files through build-id from the core file. +set buildid [build_id_debug_filename_get $binfile] +set wholetest "binfile found by build-id" +if {$buildid == ""} { + untested "$wholetest (binary has no build-id)" +} else { + gdb_exit + gdb_start + + regsub {\.debug$} $buildid {} buildid + set debugdir [standard_output_file ${testfile}-debugdir] + file delete -force -- $debugdir + file mkdir $debugdir/[file dirname $buildid] + file copy $binfile $debugdir/$buildid + + set test "show debug-file-directory" + gdb_test_multiple $test $test { + -re "The directory where separate debug symbols are searched for is \"(.*)\"\\.\r\n$gdb_prompt $" { + set debugdir_orig $expect_out(1,string) + pass $test + } + } + gdb_test_no_output "set debug-file-directory $debugdir:$debugdir_orig" "set debug-file-directory" + gdb_test "show build-id-core-loads" {Whether CORE-FILE loads the build-id associated files automatically is on\.} + gdb_test "core-file $corefile" "\r\nProgram terminated with .*" "core-file without executable" + gdb_test "info files" "Local exec file:\r\n\[ \t\]*`[string_to_regexp $debugdir/$buildid]', file type .*" + pass $wholetest +} diff --git a/gdb/testsuite/gdb.base/datalib-lib.c b/gdb/testsuite/gdb.base/datalib-lib.c new file mode 100644 index 00000000000..dd39e23746d --- /dev/null +++ b/gdb/testsuite/gdb.base/datalib-lib.c @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +int var; diff --git a/gdb/testsuite/gdb.base/datalib-main.c b/gdb/testsuite/gdb.base/datalib-main.c new file mode 100644 index 00000000000..4e0b80d2d61 --- /dev/null +++ b/gdb/testsuite/gdb.base/datalib-main.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/datalib.exp b/gdb/testsuite/gdb.base/datalib.exp new file mode 100644 index 00000000000..385716d901e --- /dev/null +++ b/gdb/testsuite/gdb.base/datalib.exp @@ -0,0 +1,51 @@ +# Copyright 2008 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +set testfile datalib +set srcfilemain ${testfile}-main.c +set srcfilelib ${testfile}-lib.c +set libfile [standard_output_file ${testfile}-lib.so] +set binfile [standard_output_file ${testfile}-main] +if { [gdb_compile "${srcdir}/${subdir}/${srcfilelib}" "${libfile}" executable [list debug {additional_flags=-shared -nostdlib}]] != "" } { + untested "Couldn't compile test program" + return -1 +} +if { [gdb_compile "${srcdir}/${subdir}/${srcfilemain}" "${binfile} ${libfile}" executable {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +# Get things started. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# We must use a separate library as the main executable is compiled to the +# address 0 by default and it would get fixed up already at the end of +# INIT_OBJFILE_SECT_INDICES. We also cannot PRELINK it as PRELINK is missing +# on ia64. The library must be NOSTDLIB as otherwise some stub code would +# create the `.text' section there. Also DEBUG option is useful as some of +# the crashes occur in dwarf2read.c. + +# FAIL case: +# ../../gdb/ia64-tdep.c:2838: internal-error: sect_index_text not initialized +# A problem internal to GDB has been detected, + +gdb_test "start" \ + "main \\(\\) at .*${srcfilemain}.*" \ + "start" diff --git a/gdb/testsuite/gdb.base/fileio.c b/gdb/testsuite/gdb.base/fileio.c index 7f482a34d39..1caadbae84f 100644 --- a/gdb/testsuite/gdb.base/fileio.c +++ b/gdb/testsuite/gdb.base/fileio.c @@ -560,6 +560,28 @@ strerrno (int err) int main () { + /* These tests + Open for write but no write permission returns EACCES + Unlinking a file in a directory w/o write access returns EACCES + fail if we are being run as root - drop the privileges here. */ + + if (geteuid () == 0) + { + uid_t uid = 99; + + if (chown (OUTDIR, uid, uid) != 0) + { + printf ("chown %d.%d %s: %s\n", (int) uid, (int) uid, + OUTDIR, strerror (errno)); + exit (1); + } + if (setuid (uid) || geteuid () == 0) + { + printf ("setuid %d: %s\n", (int) uid, strerror (errno)); + exit (1); + } + } + /* Don't change the order of the calls. They partly depend on each other */ test_open (); test_write (); diff --git a/gdb/testsuite/gdb.base/fileio.exp b/gdb/testsuite/gdb.base/fileio.exp index 56a7f42fa8d..22679a49f0f 100644 --- a/gdb/testsuite/gdb.base/fileio.exp +++ b/gdb/testsuite/gdb.base/fileio.exp @@ -24,9 +24,9 @@ if [target_info exists gdb,nofileio] { standard_testfile if {[is_remote host]} { - set outdir . + set outdir "fileio.dir" } else { - set outdir [standard_output_file {}] + set outdir [standard_output_file "fileio.dir"] } if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" \ @@ -47,7 +47,8 @@ set dir2 [standard_output_file dir2.fileio.test] if {[file exists $dir2] && ![file writable $dir2]} { system "chmod +w $dir2" } -system "rm -rf [standard_output_file *.fileio.test]" +system "rm -rf [standard_output_file fileio.dir]" +system "mkdir -m777 [standard_output_file fileio.dir]" set oldtimeout $timeout set timeout [expr "$timeout + 60"] @@ -89,7 +90,7 @@ gdb_test continue \ gdb_test "continue" ".*" "" -catch "system \"chmod -f -w [standard_output_file nowrt.fileio.test]\"" +catch "system \"chmod -f -w [standard_output_file fileio.dir/nowrt.fileio.test]\"" gdb_test continue \ "Continuing\\..*open 5:.*EACCES$stop_msg" \ @@ -276,9 +277,7 @@ gdb_test continue \ gdb_exit # Make dir2 writable again so rm -rf of a build tree Just Works. -if {[file exists $dir2] && ![file writable $dir2]} { - system "chmod +w $dir2" -} +system "chmod -R +w $outdir" set timeout $oldtimeout return 0 diff --git a/gdb/testsuite/gdb.base/focus-cmd-prev.exp b/gdb/testsuite/gdb.base/focus-cmd-prev.exp new file mode 100644 index 00000000000..d5a653f6846 --- /dev/null +++ b/gdb/testsuite/gdb.base/focus-cmd-prev.exp @@ -0,0 +1,40 @@ +# Copyright 2008 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +if $tracelevel then { + strace $tracelevel +} + +gdb_exit +gdb_start + +# Do not use gdb_test or \r\n there since: +# commit d7e747318f4d04af033f16325f9b6d74f67079ec +# Eliminate make_cleanup_ui_file_delete / make ui_file a class hierarchy + +set test "focus cmd" +gdb_test_multiple $test $test { + -re "$gdb_prompt $" { + pass $test + } +} + +set test "focus prev" +gdb_test_multiple $test $test { + -re "$gdb_prompt $" { + pass $test + } +} diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c new file mode 100644 index 00000000000..d74b690c73e --- /dev/null +++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-lib.c @@ -0,0 +1,21 @@ +/* Copyright 2010 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 . */ + +void +lib (void) +{ +} diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-main.c b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-main.c new file mode 100644 index 00000000000..46b9dfe1610 --- /dev/null +++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib-main.c @@ -0,0 +1,25 @@ +/* Copyright 2010 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 . */ + +extern void lib (void); + +int +main (void) +{ + lib (); + return 0; +} diff --git a/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp new file mode 100644 index 00000000000..0c46489f315 --- /dev/null +++ b/gdb/testsuite/gdb.base/gcore-buildid-exec-but-not-solib.exp @@ -0,0 +1,105 @@ +# Copyright 2016 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 . + +if {[skip_shlib_tests]} { + return 0 +} + +set testfile "gcore-buildid-exec-but-not-solib" +set srcmainfile ${testfile}-main.c +set srclibfile ${testfile}-lib.c +set libfile [standard_output_file ${testfile}-lib.so] +set objfile [standard_output_file ${testfile}-main.o] +set executable ${testfile}-main +set binfile [standard_output_file ${executable}] +set gcorefile [standard_output_file ${executable}.gcore] +set outdir [file dirname $binfile] + +if { [gdb_compile_shlib ${srcdir}/${subdir}/${srclibfile} ${libfile} "debug additional_flags=-Wl,--build-id"] != "" + || [gdb_compile ${srcdir}/${subdir}/${srcmainfile} ${objfile} object {debug}] != "" } { + unsupported "-Wl,--build-id compilation failed" + return -1 +} +set opts [list debug shlib=${libfile} "additional_flags=-Wl,--build-id"] +if { [gdb_compile ${objfile} ${binfile} executable $opts] != "" } { + unsupported "-Wl,--build-id compilation failed" + return -1 +} + +clean_restart $executable +gdb_load_shlib $libfile + +# Does this gdb support gcore? +set test "help gcore" +gdb_test_multiple $test $test { + -re "Undefined command: .gcore.*\r\n$gdb_prompt $" { + # gcore command not supported -- nothing to test here. + unsupported "gdb does not support gcore on this target" + return -1; + } + -re "Save a core file .*\r\n$gdb_prompt $" { + pass $test + } +} + +if { ![runto lib] } then { + return -1 +} + +set escapedfilename [string_to_regexp ${gcorefile}] + +set test "save a corefile" +gdb_test_multiple "gcore ${gcorefile}" $test { + -re "Saved corefile ${escapedfilename}\r\n$gdb_prompt $" { + pass $test + } + -re "Can't create a corefile\r\n$gdb_prompt $" { + unsupported $test + return -1 + } +} + +# Now restart gdb and load the corefile. + +clean_restart $executable +gdb_load_shlib $libfile + +set buildid [build_id_debug_filename_get $libfile] + +regsub {\.debug$} $buildid {} buildid + +set debugdir [standard_output_file ${testfile}-debugdir] +file delete -force -- $debugdir + +file mkdir $debugdir/[file dirname $libfile] +file copy $libfile $debugdir/${libfile} + +file mkdir $debugdir/[file dirname $buildid] +file copy $libfile $debugdir/${buildid} + +remote_exec build "ln -s /lib ${debugdir}/" +remote_exec build "ln -s /lib64 ${debugdir}/" +# /usr is not needed, all the libs are in /lib64: libm.so.6 libc.so.6 ld-linux-x86-64.so.2 + +gdb_test "set solib-absolute-prefix $debugdir" + +gdb_test_no_output "set debug-file-directory $debugdir" "set debug-file-directory" + +gdb_test "core ${gcorefile}" "Core was generated by .*" "re-load generated corefile" + +gdb_test "frame" "#0 \[^\r\n\]* lib .*" "library got loaded" + +gdb_test "bt" +gdb_test "info shared" diff --git a/gdb/testsuite/gdb.base/gcore-excessive-memory.c b/gdb/testsuite/gdb.base/gcore-excessive-memory.c new file mode 100644 index 00000000000..56b4d3a63a5 --- /dev/null +++ b/gdb/testsuite/gdb.base/gcore-excessive-memory.c @@ -0,0 +1,37 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +#include +#include + +#define MEGS 64 + +int main() +{ + void *mem; + + mem = malloc (MEGS * 1024ULL * 1024ULL); + + for (;;) + sleep (1); + + return 0; +} diff --git a/gdb/testsuite/gdb.base/gcore-excessive-memory.exp b/gdb/testsuite/gdb.base/gcore-excessive-memory.exp new file mode 100644 index 00000000000..4e71b5534e0 --- /dev/null +++ b/gdb/testsuite/gdb.base/gcore-excessive-memory.exp @@ -0,0 +1,94 @@ +# Copyright 2008 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +set testfile gcore-excessive-memory +set srcfile ${testfile}.c +set shfile [standard_output_file ${testfile}-gdb.sh] +set corefile [standard_output_file ${testfile}.core] +set binfile [standard_output_file ${testfile}] +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +set f [open "|getconf PAGESIZE" "r"] +gets $f pagesize +close $f + +set pid_of_bin [eval exec $binfile &] +sleep 2 + +# Get things started. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +set pid_of_gdb [exp_pid -i [board_info host fileid]] + +gdb_test "attach $pid_of_bin" "Attaching to .*" "attach" +gdb_test "up 99" "in main .*" "verify we can get to main" + +proc memory_v_pages_get {} { + global pid_of_gdb pagesize + set fd [open "/proc/$pid_of_gdb/statm"] + gets $fd line + close $fd + # number of pages of virtual memory + scan $line "%d" drs + return $drs +} + +set pages_found [memory_v_pages_get] + +# It must be definitely less than `MEGS' of `gcore-excessive-memory.c'. +set mb_gcore_reserve 4 +verbose -log "pages_found = $pages_found, mb_gcore_reserve = $mb_gcore_reserve" +set kb_found [expr $pages_found * $pagesize / 1024] +set kb_permit [expr $kb_found + 1 * 1024 + $mb_gcore_reserve * 1024] +verbose -log "kb_found = $kb_found, kb_permit = $kb_permit" + +# Create the ulimit wrapper. +set f [open $shfile "w"] +puts $f "#! /bin/sh" +puts $f "ulimit -v $kb_permit" +puts $f "exec $GDB \"\$@\"" +close $f +remote_exec host "chmod +x $shfile" + +gdb_exit +set GDBold $GDB +set GDB "$shfile" +gdb_start +set GDB $GDBold + +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +set pid_of_gdb [exp_pid -i [board_info host fileid]] + +gdb_test "attach $pid_of_bin" "Attaching to .*" "attach" +gdb_test "up 99" "in main .*" "verify we can get to main" + +verbose -log "kb_found before gcore = [expr [memory_v_pages_get] * $pagesize / 1024]" + +gdb_test "gcore $corefile" "Saved corefile \[^\n\r\]*" "Save the core file" + +verbose -log "kb_found after gcore = [expr [memory_v_pages_get] * $pagesize / 1024]" + +# Cleanup. +exec kill -9 $pid_of_bin diff --git a/gdb/testsuite/gdb.base/gcore-shmid0.c b/gdb/testsuite/gdb.base/gcore-shmid0.c new file mode 100644 index 00000000000..bb9709a75ce --- /dev/null +++ b/gdb/testsuite/gdb.base/gcore-shmid0.c @@ -0,0 +1,128 @@ +/* Copyright 2007, 2009 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* + * Test GDB's handling of gcore for mapping with a name but zero inode. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* The same test running in a parallel testsuite may steal us the zero SID, + even if we never get any EEXIST. Just try a while. */ + +#define TIMEOUT_SEC 10 + +static volatile int v; + +static void +initialized (void) +{ + v++; +} + +static void +unresolved (void) +{ + v++; +} + +int +main (void) +{ + int sid; + unsigned int *addr = (void *) -1L; + int attempt, round = 0; + time_t ts_start, ts; + + if (time (&ts_start) == (time_t) -1) + { + printf ("time (): %m\n"); + exit (1); + } + + /* The generated SID will cycle with an increment of 32768, attempt until it + * wraps to 0. */ + + for (attempt = 0; addr == (void *) -1L; attempt++) + { + /* kernel-2.6.25-8.fc9.x86_64 just never returns the value 0 by + shmget(2). shmget returns SID range 0..1<<31 in steps of 32768, + 0x1000 should be enough but wrap the range it to be sure. */ + + if (attempt > 0x21000) + { + if (time (&ts) == (time_t) -1) + { + printf ("time (): %m\n"); + exit (1); + } + + if (ts >= ts_start && ts < ts_start + TIMEOUT_SEC) + { + attempt = 0; + round++; + continue; + } + + printf ("Problem is not reproducible on this kernel (attempt %d, " + "round %d)\n", attempt, round); + unresolved (); + exit (1); + } + + sid = shmget ((key_t) rand (), 0x1000, IPC_CREAT | IPC_EXCL | 0777); + if (sid == -1) + { + if (errno == EEXIST) + continue; + + printf ("shmget (%d, 0x1000, IPC_CREAT): errno %d\n", 0, errno); + exit (1); + } + + /* Use SID only if it is 0, retry it otherwise. */ + + if (sid == 0) + { + addr = shmat (sid, NULL, SHM_RND); + if (addr == (void *) -1L) + { + printf ("shmat (%d, NULL, SHM_RND): errno %d\n", sid, + errno); + exit (1); + } + } + if (shmctl (sid, IPC_RMID, NULL) != 0) + { + printf ("shmctl (%d, IPC_RMID, NULL): errno %d\n", sid, errno); + exit (1); + } + } + + initialized (); + + return 0; +} diff --git a/gdb/testsuite/gdb.base/gcore-shmid0.exp b/gdb/testsuite/gdb.base/gcore-shmid0.exp new file mode 100644 index 00000000000..b1fec682aa4 --- /dev/null +++ b/gdb/testsuite/gdb.base/gcore-shmid0.exp @@ -0,0 +1,101 @@ +# Copyright 2007, 2009 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Test GDB's handling of gcore for mapping with a name but zero inode. + +if { [prepare_for_testing gcore-shmid0.exp gcore-shmid0] } { + return -1 +} + +# Does this gdb support gcore? +set test "help gcore" +gdb_test_multiple $test $test { + -re "Undefined command: .gcore.*$gdb_prompt $" { + # gcore command not supported -- nothing to test here. + unsupported "gdb does not support gcore on this target" + return -1; + } + -re "Save a core file .*$gdb_prompt $" { + pass $test + } +} + +if { ! [ runto_main ] } then { + untested gcore-shmid0.exp + return -1 +} + +gdb_breakpoint "initialized" +gdb_breakpoint "unresolved" + +set oldtimeout $timeout +set timeout [expr $oldtimeout + 120] + +set test "Continue to initialized." +gdb_test_multiple "continue" $test { + -re "Breakpoint .*, initialized .* at .*\r\n$gdb_prompt $" { + pass $test + } + -re "Breakpoint .*, unresolved .* at .*\r\n$gdb_prompt $" { + set timeout $oldtimeout + unsupported $test + return -1 + } +} +set timeout $oldtimeout + +set escapedfilename [string_to_regexp [standard_output_file gcore-shmid0.test]] + +set test "save a corefile" +gdb_test_multiple "gcore [standard_output_file gcore-shmid0.test]" $test { + -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" { + pass $test + } + -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" { + unsupported $test + } +} + +# Be sure to remove the handle first. +# But it would get removed even on a kill by GDB as the handle is already +# deleted, just it is still attached. +gdb_continue_to_end "finish" + +set test "core-file command" +gdb_test_multiple "core-file [standard_output_file gcore-shmid0.test]" $test { + -re ".* program is being debugged already.*y or n. $" { + # gdb_load may connect us to a gdbserver. + send_gdb "y\n" + exp_continue; + } + -re "Core was generated by .*\r\n\#0 .*\\\(\\\).*\r\n$gdb_prompt $" { + # The filename does not fit there anyway so do not check it. + pass $test + } + -re ".*registers from core file: File in wrong format.* $" { + fail "core-file command (could not read registers from core file)" + } +} + +set test "backtrace" +gdb_test_multiple "bt" $test { + -re "#0 *initialized \\\(\\\) at .*#1 .* main \\\(.*$gdb_prompt $" { + pass $test + } + -re "#0 *initialized \\\(\\\) at .*Cannot access memory at address .*$gdb_prompt $" { + fail $test + } +} diff --git a/gdb/testsuite/gdb.base/gcorebg.c b/gdb/testsuite/gdb.base/gcorebg.c new file mode 100644 index 00000000000..427ebe9b4fe --- /dev/null +++ b/gdb/testsuite/gdb.base/gcorebg.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include + +int main (int argc, char **argv) +{ + pid_t pid = 0; + pid_t ppid; + char buf[1024*2 + 500]; + int gotint; + + if (argc != 4) + { + fprintf (stderr, "Syntax: %s {standard|detached} \n", + argv[0]); + exit (1); + } + + pid = fork (); + + switch (pid) + { + case 0: + if (strcmp (argv[1], "detached") == 0) + setpgrp (); + ppid = getppid (); + gotint = snprintf (buf, sizeof (buf), "sh %s -o %s %d", argv[2], argv[3], (int) ppid); + assert (gotint < sizeof (buf)); + system (buf); + fprintf (stderr, "Killing parent PID %d\n", ppid); + kill (ppid, SIGTERM); + break; + + case -1: + perror ("fork err\n"); + exit (1); + break; + + default: + fprintf (stderr,"Sleeping as PID %d\n", getpid ()); + sleep (60); + } + + return 0; +} diff --git a/gdb/testsuite/gdb.base/gcorebg.exp b/gdb/testsuite/gdb.base/gcorebg.exp new file mode 100644 index 00000000000..a5471ba5df5 --- /dev/null +++ b/gdb/testsuite/gdb.base/gcorebg.exp @@ -0,0 +1,113 @@ +# Copyright 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Jan Kratochvil . +# This is a test for `gdb_gcore.sh' functionality. +# It also tests a regression with `gdb_gcore.sh' being run without its +# accessible terminal. + +if ![info exists GCORE] { + set GCORE "[standard_output_file ../../../../gcore]" +} +verbose "using GCORE = $GCORE" 2 + +set testfile "gcorebg" +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +set corefile [standard_output_file ${testfile}.test] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested gcorebg.exp + return -1 +} + +# Cleanup. + +proc core_clean {} { + global corefile + + foreach file [glob -nocomplain [join [list $corefile *] ""]] { + verbose "Delete file $file" 1 + remote_file target delete $file + } +} +core_clean +remote_file target delete "./gdb" + +# Generate the core file. + +# Provide `./gdb' for `gdb_gcore.sh' running it as a bare `gdb' command. +# Setup also `$PATH' appropriately. +# If GDB was not found let `gdb_gcore.sh' to find the system GDB by `$PATH'. +if {$GDB != "gdb"} { + file link ./gdb $GDB +} +global env +set oldpath $env(PATH) +set env(PATH) [join [list . $env(PATH)] ":"] +verbose "PATH = $env(PATH)" 2 + +# Test file body. +# $detached == "standard" || $detached == "detached" + +proc test_body { detached } { + global binfile + global GCORE + global corefile + + set res [remote_spawn target "$binfile $detached $GCORE $corefile"] + if { $res < 0 || $res == "" } { + fail "Spawning $detached gcore" + return 1 + } + pass "Spawning $detached gcore" + remote_expect target 20 { + timeout { + fail "Spawned $detached gcore finished (timeout)" + remote_exec target "kill -9 -[exp_pid -i $res]" + return 1 + } + "Saved corefile .*\r\nKilling parent PID " { + pass "Spawned $detached gcore finished" + remote_wait target 20 + } + } + + if {1 == [llength [glob -nocomplain [join [list $corefile *] ""]]]} { + pass "Core file generated by $detached gcore" + } else { + fail "Core file generated by $detached gcore" + } + core_clean +} + +# First a general `gdb_gcore.sh' spawn with its controlling terminal available. + +test_body standard + +# And now `gdb_gcore.sh' spawn without its controlling terminal available. +# It is spawned through `gcorebg.c' using setpgrp (). + +test_body detached + + +# Cleanup. + +set env(PATH) $oldpath +remote_file target delete "./gdb" diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.c b/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.c new file mode 100644 index 00000000000..947258e22ff --- /dev/null +++ b/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.c @@ -0,0 +1,11 @@ +#include +#include + +int +main (int argc, char **argv) +{ + if (fork () == 0) + sleep (1); + chdir ("."); + return 0; +} diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.exp b/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.exp new file mode 100644 index 00000000000..96d31d70189 --- /dev/null +++ b/gdb/testsuite/gdb.base/gdb-rhbz1149205-catch-syscall-fork.exp @@ -0,0 +1,58 @@ +# Copyright 2015 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if { [is_remote target] || ![isnative] } then { + continue +} + +set testfile "gdb-rhbz1149205-catch-syscall-fork" +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] + +# Until "catch syscall" is implemented on other targets... +if {![istarget "hppa*-hp-hpux*"] && ![istarget "*-linux*"]} then { + continue +} + +# This shall be updated whenever 'catch syscall' is implemented +# on some architecture. +#if { ![istarget "i\[34567\]86-*-linux*"] +if { ![istarget "x86_64-*-linux*"] && ![istarget "i\[34567\]86-*-linux*"] + && ![istarget "powerpc-*-linux*"] && ![istarget "powerpc64-*-linux*"] + && ![istarget "sparc-*-linux*"] && ![istarget "sparc64-*-linux*"] } { + continue +} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested ${testfile}.exp + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load $binfile + +if { ![runto_main] } { + return -1 +} + +gdb_test "catch syscall chdir" \ + "Catchpoint $decimal \\\(syscall (.)?chdir(.)? \\\[$decimal\\\]\\\)" \ + "catch syscall chdir" + +gdb_test "continue" \ + "Continuing\.\r\n.*\r\nCatchpoint $decimal \\\(call to syscall .?chdir.?.*" \ + "continue from catch syscall after fork" diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen-libbar.c b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen-libbar.c new file mode 100644 index 00000000000..6ecf50d2ad0 --- /dev/null +++ b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen-libbar.c @@ -0,0 +1,30 @@ +/* Testcase for recursive dlopen calls. + + Copyright (C) 2014 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 . */ + +/* This test was copied from glibc's testcase called + and related files. */ + +#include +#include + +void +bar (void) +{ + printf ("Called bar.\n"); +} diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen-libfoo.c b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen-libfoo.c new file mode 100644 index 00000000000..e4523933db2 --- /dev/null +++ b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen-libfoo.c @@ -0,0 +1,30 @@ +/* Testcase for recursive dlopen calls. + + Copyright (C) 2014 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 . */ + +/* This test was copied from glibc's testcase called + and related files. */ + +#include +#include + +void +foo (void) +{ + printf ("Called foo.\n"); +} diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen.c b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen.c new file mode 100644 index 00000000000..17b29904efb --- /dev/null +++ b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen.c @@ -0,0 +1,124 @@ +/* Testcase for recursive dlopen calls. + + Copyright (C) 2014 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 . */ + +/* This test was copied from glibc's testcase called + and related files. */ + +#include +#include +#include +#include + +#define DSO "gdb-rhbz1156192-recursive-dlopen-libfoo.so" +#define FUNC "foo" + +#define DSO1 "gdb-rhbz1156192-recursive-dlopen-libbar.so" +#define FUNC1 "bar" + +/* Prototype for my hook. */ +void *custom_malloc_hook (size_t, const void *); + +/* Pointer to old malloc hooks. */ +void *(*old_malloc_hook) (size_t, const void *); + +/* Call function func_name in DSO dso_name via dlopen. */ +void +call_func (const char *dso_name, const char *func_name) +{ + int ret; + void *dso; + void (*func) (void); + char *err; + + /* Open the DSO. */ + dso = dlopen (dso_name, RTLD_NOW|RTLD_GLOBAL); + if (dso == NULL) + { + err = dlerror (); + fprintf (stderr, "%s\n", err); + exit (1); + } + /* Clear any errors. */ + dlerror (); + + /* Lookup func. */ + *(void **) (&func) = dlsym (dso, func_name); + if (func == NULL) + { + err = dlerror (); + if (err != NULL) + { + fprintf (stderr, "%s\n", err); + exit (1); + } + } + /* Call func twice. */ + (*func) (); + + /* Close the library and look for errors too. */ + ret = dlclose (dso); + if (ret != 0) + { + err = dlerror (); + fprintf (stderr, "%s\n", err); + exit (1); + } + +} + +/* Empty hook that does nothing. */ +void * +custom_malloc_hook (size_t size, const void *caller) +{ + void *result; + /* Restore old hooks. */ + __malloc_hook = old_malloc_hook; + /* First call a function in another library via dlopen. */ + call_func (DSO1, FUNC1); + /* Called recursively. */ + result = malloc (size); + /* Restore new hooks. */ + __malloc_hook = custom_malloc_hook; + return result; +} + +int +main (void) +{ + + /* Save old hook. */ + old_malloc_hook = __malloc_hook; + /* Install new hook. */ + __malloc_hook = custom_malloc_hook; + + /* Attempt to dlopen a shared library. This dlopen will + trigger an access to the ld.so.cache, and that in turn + will require a malloc to duplicate data in the cache. + The malloc will call our malloc hook which calls dlopen + recursively, and upon return of this dlopen the non-ref + counted ld.so.cache mapping will be unmapped. We will + return to the original dlopen and crash trying to access + dlopened data. */ + call_func (DSO, FUNC); + + /* Restore old hook. */ + __malloc_hook = old_malloc_hook; + + return 0; +} diff --git a/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen.exp b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen.exp new file mode 100644 index 00000000000..2c32676e504 --- /dev/null +++ b/gdb/testsuite/gdb.base/gdb-rhbz1156192-recursive-dlopen.exp @@ -0,0 +1,137 @@ +# Copyright 2014 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 . + +if { [skip_shlib_tests] } { + return 0 +} + +# Library foo +set libname1 "gdb-rhbz1156192-recursive-dlopen-libfoo" +set srcfile_lib1 ${srcdir}/${subdir}/${libname1}.c +set binfile_lib1 [standard_output_file ${libname1}.so] +# Library bar +set libname2 "gdb-rhbz1156192-recursive-dlopen-libbar" +set srcfile_lib2 ${srcdir}/${subdir}/${libname2}.c +set binfile_lib2 [standard_output_file ${libname2}.so] + +set testfile "gdb-rhbz1156192-recursive-dlopen" +set srcfile ${testfile}.c +set executable ${testfile} +set binfile [standard_output_file ${executable}] + +if { [gdb_compile_shlib ${srcfile_lib1} ${binfile_lib1} \ + { debug "additional_flags=-fPIC" }] != "" } { + untested "Could not compile ${binfile_lib1}" + return -1 +} + +if { [gdb_compile_shlib ${srcfile_lib2} ${binfile_lib2} \ + { debug "additional_flags=-fPIC" }] != "" } { + untested "Could not compile ${binfile_lib2}" + return -1 +} + +if { [prepare_for_testing ${testfile}.exp ${executable} ${srcfile} \ + [ list debug shlib_load "additional_flags=-Wno-deprecated-declarations" ]] } { + untested "Could not compile ${executable}" + return -1 +} + +proc do_test { has_libfoo has_libbar } { + global hex binfile_lib2 binfile_lib1 gdb_prompt + set libbar_match "[string_to_regexp $binfile_lib2]" + set libfoo_match "[string_to_regexp $binfile_lib1]" + + gdb_test_multiple "info shared" "info shared" { + -re ".*$libfoo_match\r\n.*$libbar_match\(\r\n.*Shared library is missing\)?.*\r\n${gdb_prompt} $" { + if { $has_libfoo && $has_libbar } { + pass "matched libfoo and libbar" + } else { + fail "matched libfoo and libbar (has_libfoo = $has_libfoo, has_libbar = $has_libbar)" + } + } + -re ".*$libfoo_match\(\r\n.*Shared library is missing\)?.*\r\n${gdb_prompt} $" { + if { $has_libfoo && !$has_libbar } { + pass "matched libfoo" + } else { + fail "matched libfoo (has_libfoo = $has_libfoo, has_libbar = $has_libbar)" + } + } + -re ".*$libbar_match\(\r\n.*Shared library is missing\)?.*\r\n${gdb_prompt} $" { + if { $has_libbar && !$has_libfoo } { + pass "matched libbar" + } else { + fail "matched libbar (has_libfoo = $has_libfoo, has_libbar = $has_libbar)" + } + } + "\r\n${gdb_prompt} $" { + if { !$has_libfoo && !$has_libbar } { + pass "did not match libfoo nor libbar" + } else { + fail "did not match libfoo nor libbar (has_libfoo = $has_libfoo, has_libbar = $has_libbar)" + } + } + } +} + +proc test_stop_on_solib_events { } { + set pass 0 + # This variable holds the information about whether libfoo and + # libbar (respectively) are expected in the "info shared" output. + set solib_event_order { { 0 0 } { 0 0 } { 0 0 } { 0 1 } \ + { 0 1 } { 0 0 } { 0 0 } { 0 1 } \ + { 0 1 } { 0 0 } { 0 0 } { 0 1 } \ + { 0 1 } { 0 0 } { 0 0 1 } { 1 1 } \ + { 1 1 } { 1 0 } { 1 0 } { 1 1 } \ + { 1 1 } { 1 0 1 } { 1 0 } { 1 0 } } + + with_test_prefix "stop-on-solib-events" { + gdb_test_no_output "set stop-on-solib-events 1" "setting stop-on-solib-events" + + gdb_run_cmd + foreach l $solib_event_order { + incr pass + with_test_prefix "pass #$pass" { + set should_be_corrupted [expr 0+0[lindex $l 2]] + do_test [lindex $l 0] [lindex $l 1] + set test "continue" + global gdb_prompt + gdb_test_multiple $test $test { + -re "\r\nwarning: Corrupted shared library list:.*\r\nStopped due to shared library event.*\r\n$gdb_prompt $" { + set corrupted 1 + pass $test + } + -re "\r\nStopped due to shared library event.*\r\n$gdb_prompt $" { + set corrupted 0 + pass $test + } + } + set test "corrupted=$corrupted but should_be_corrupted=$should_be_corrupted" + if {$corrupted == $should_be_corrupted} { + pass $test + } else { + fail $test + } + } + } + # In the last pass we do not expect to see libfoo or libbar. + incr pass + with_test_prefix "pass #$pass" { + do_test 0 0 + } + } +} + +test_stop_on_solib_events diff --git a/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp b/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp new file mode 100644 index 00000000000..5469cd73543 --- /dev/null +++ b/gdb/testsuite/gdb.base/gnu-ifunc-strstr-workaround.exp @@ -0,0 +1,108 @@ +# Copyright (C) 2012 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 . + +# Workaround for: +# invalid IFUNC DW_AT_linkage_name: memmove strstr time +# http://sourceware.org/bugzilla/show_bug.cgi?id=14166 + +if {[skip_shlib_tests]} { + return 0 +} + +set testfile "gnu-ifunc-strstr-workaround" +set executable ${testfile} +set srcfile start.c +set binfile [standard_output_file ${executable}] + +if [prepare_for_testing ${testfile}.exp $executable $srcfile] { + return -1 +} + +if ![runto_main] { + return 0 +} + +set test "ptype atoi" +gdb_test_multiple $test $test { + -re "type = int \\(const char \\*\\)\r\n$gdb_prompt $" { + pass $test + } + -re "type = int \\(\\)\r\n$gdb_prompt $" { + untested "$test (no DWARF)" + return 0 + } +} + +set addr "" +set test "print strstr" +gdb_test_multiple $test $test { + -re " = {} (0x\[0-9a-f\]+) \r\n$gdb_prompt $" { + set addr $expect_out(1,string) + pass $test + } + -re " = {} (0x\[0-9a-f\]+) <__strstr>\r\n$gdb_prompt $" { + set addr $expect_out(1,string) + pass "$test (GDB workaround)" + } + -re " = {} (0x\[0-9a-f\]+) <__libc_strstr>\r\n$gdb_prompt $" { + set addr $expect_out(1,string) + pass "$test (fixed glibc)" + } + -re " = {char \\*\\(const char \\*, const char \\*\\)} 0x\[0-9a-f\]+ \r\n$gdb_prompt $" { + untested "$test (gnu-ifunc not in use by glibc)" + return 0 + } +} + +set test "info sym" +gdb_test_multiple "info sym $addr" $test { + -re "strstr in section \\.text of /lib\[^/\]*/libc.so.6\r\n$gdb_prompt $" { + pass $test + } + -re " = {char \\*\\(const char \\*, const char \\*\\)} 0x\[0-9a-f\]+ \r\n$gdb_prompt $" { + # unexpected + xfail "$test (not in libc.so.6)" + return 0 + } +} + +set test "info addr strstr" +gdb_test_multiple $test $test { + -re "Symbol \"strstr\" is a function at address $addr\\.\r\n$gdb_prompt $" { + fail "$test (DWARF for strstr)" + } + -re "Symbol \"strstr\" is at $addr in a file compiled without debugging\\.\r\n$gdb_prompt $" { + pass "$test" + } +} + +set test "print strstr second time" +gdb_test_multiple "print strstr" $test { + -re " = {} $addr \r\n$gdb_prompt $" { + pass $test + } + -re " = {} $addr <__strstr>\r\n$gdb_prompt $" { + pass "$test (GDB workaround)" + } + -re " = {} $addr <__libc_strstr>\r\n$gdb_prompt $" { + pass "$test (fixed glibc)" + } + -re " = {void \\*\\(void\\)} 0x\[0-9a-f\]+ \r\n$gdb_prompt $" { + fail $test + } +} + +gdb_test {print strstr("abc","b")} { = 0x[0-9a-f]+ "bc"} +gdb_test {print strstr("def","e")} { = 0x[0-9a-f]+ "ef"} diff --git a/gdb/testsuite/gdb.base/gstack.c b/gdb/testsuite/gdb.base/gstack.c new file mode 100644 index 00000000000..dc10813f04c --- /dev/null +++ b/gdb/testsuite/gdb.base/gstack.c @@ -0,0 +1,43 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2005, 2007, 2008, 2009 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 . */ + +#include +#include +#include + +void +func (void) +{ + const char msg[] = "looping\n"; + + /* Use the most simple notification not to get caught by attach on exiting + the function. */ + write (1, msg, strlen (msg)); + + for (;;); +} + +int +main (void) +{ + alarm (60); + nice (100); + + func (); + + return 0; +} diff --git a/gdb/testsuite/gdb.base/gstack.exp b/gdb/testsuite/gdb.base/gstack.exp new file mode 100644 index 00000000000..1186ec57bce --- /dev/null +++ b/gdb/testsuite/gdb.base/gstack.exp @@ -0,0 +1,66 @@ +# Copyright (C) 2012 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 . + +set testfile gstack +set executable ${testfile} +set binfile [standard_output_file $executable] +if {[build_executable ${testfile} ${executable} "" {debug}] == -1} { + return -1 +} + +set test "spawn inferior" +set command "${binfile}" +set res [remote_spawn host $command]; +if { $res < 0 || $res == "" } { + perror "Spawning $command failed." + fail $test + return +} +set use_gdb_stub 1 +set pid [exp_pid -i $res] +gdb_expect { + -re "looping\r\n" { + pass $test + } + eof { + fail "$test (eof)" + return + } + timeout { + fail "$test (timeout)" + return + } +} +gdb_exit + +# Testcase uses the most simple notification not to get caught by attach on +# exiting the function. Still we could retry the gstack command if we fail. + +set test "spawn gstack" +set command "sh -c GDB=$GDB\\ GDBARGS=-data-directory\\\\\\ $BUILD_DATA_DIRECTORY\\ sh\\ ${srcdir}/../gstack.sh\\ $pid\\;echo\\ GSTACK-END" +set res [remote_spawn host $command]; +if { $res < 0 || $res == "" } { + perror "Spawning $command failed." + fail $test +} +set pid [exp_pid -i $res] +gdb_test_multiple "" $test { + -re "^#0 +(0x\[0-9a-f\]+ in )?\\.?func \\(\\) at \[^\r\n\]*\r\n#1 +0x\[0-9a-f\]+ in \\.?main \\(\\) at \[^\r\n\]*\r\nGSTACK-END\r\n\$" { + pass $test + } +} +gdb_exit + +remote_exec host "kill -9 $pid" diff --git a/gdb/testsuite/gdb.base/internal-var-field-address.c b/gdb/testsuite/gdb.base/internal-var-field-address.c new file mode 100644 index 00000000000..eeb7b8501c4 --- /dev/null +++ b/gdb/testsuite/gdb.base/internal-var-field-address.c @@ -0,0 +1,20 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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 . */ + +struct { + int field; +} staticstruct = { 1 }; diff --git a/gdb/testsuite/gdb.base/internal-var-field-address.exp b/gdb/testsuite/gdb.base/internal-var-field-address.exp new file mode 100644 index 00000000000..33c9e94eeee --- /dev/null +++ b/gdb/testsuite/gdb.base/internal-var-field-address.exp @@ -0,0 +1,26 @@ +# Copyright 2009 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 . + +set test internal-var-field-address +set binfile ${test}.x +if { [gdb_compile "${srcdir}/${subdir}/${test}.c" "[standard_output_file ${binfile}]" object {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +clean_restart $binfile + +gdb_test {set $varstruct = staticstruct} +gdb_test {p $varstruct.field} " = 1" diff --git a/gdb/testsuite/gdb.base/largecore-last-address-lock.exp b/gdb/testsuite/gdb.base/largecore-last-address-lock.exp new file mode 100644 index 00000000000..8a597e9b15f --- /dev/null +++ b/gdb/testsuite/gdb.base/largecore-last-address-lock.exp @@ -0,0 +1,49 @@ +# Copyright 2006 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +if $tracelevel then { + strace $tracelevel +} + +# Get things started. + +gdb_exit +gdb_start + +# i386 (32-bit) only: gdb with Red Hat largecore patch did lock up: +# https://enterprise.redhat.com/issue-tracker/?module=issues&action=view&tid=103263 +# https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=210614 + +# i386: Bug exists when the `target_xfer_memory' condition +# `(memaddr + len < region->hi)' operates on 64-bit operands on +# largecore-patched with 32-bit addresses and so it can get `false' with +# arbitrary `len'. + +# x86_64: The bug is not present as the operands and calculations have the same +# bit size. Would would still need to pass there the highest address +# (`memaddr == 0xffffffffffffffff') but we would need to pass `len == 0' +# to make the condition `(memaddr + len < region->hi)' false. +# `len == 0' would get caught eariler. + +# Error in the success case is immediate. +set timeoutold ${timeout} +set timeout 10 + +gdb_test "x/xb 0xffffffff" \ + "Cannot access memory at address 0xffffffff" \ + "Read the last address space byte" + +set timeout ${timeoutold} diff --git a/gdb/testsuite/gdb.base/lineno-makeup-func.c b/gdb/testsuite/gdb.base/lineno-makeup-func.c new file mode 100644 index 00000000000..1a0220ea529 --- /dev/null +++ b/gdb/testsuite/gdb.base/lineno-makeup-func.c @@ -0,0 +1,21 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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 . */ + +void +func (void) +{ +} diff --git a/gdb/testsuite/gdb.base/lineno-makeup.c b/gdb/testsuite/gdb.base/lineno-makeup.c new file mode 100644 index 00000000000..5d4be90999d --- /dev/null +++ b/gdb/testsuite/gdb.base/lineno-makeup.c @@ -0,0 +1,35 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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 . */ + +/* DW_AT_low_pc-DW_AT_high_pc should cover the function without line number + information (.debug_line) so we cannot use an external object file. + + It must not be just a label as it would alias on the next function even for + correct GDB. Therefore some stub data must be placed there. + + We need to provide a real stub function body as at least s390 + (s390_analyze_prologue) would skip the whole body till reaching `main'. */ + +extern void func (void); +asm ("func: .incbin \"" BINFILENAME "\""); + +int +main (void) +{ + func (); + return 0; +} diff --git a/gdb/testsuite/gdb.base/lineno-makeup.exp b/gdb/testsuite/gdb.base/lineno-makeup.exp new file mode 100644 index 00000000000..9e11d78bf9c --- /dev/null +++ b/gdb/testsuite/gdb.base/lineno-makeup.exp @@ -0,0 +1,78 @@ +# Copyright 2009 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 . + +set testfile "lineno-makeup" +set srcfuncfile ${testfile}-func.c +set srcfile ${testfile}.c +set objfuncfile [standard_output_file ${testfile}-func.o] +set binfuncfile [standard_output_file ${testfile}-func.bin] +set binfile [standard_output_file ${testfile}] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfuncfile}" "${objfuncfile}" object {}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +set objcopy [catch "exec objcopy -O binary --only-section .text ${objfuncfile} ${binfuncfile}" output] +verbose -log "objcopy=$objcopy: $output" +if { $objcopy != 0 } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} +set binfuncfilesize [file size $binfuncfile] +verbose -log "file size $binfuncfile = $binfuncfilesize" + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug additional_flags=-DBINFILENAME=\"$binfuncfile\"]] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +set b_addr "" +set test "break func" +gdb_test_multiple $test $test { + -re "Breakpoint \[0-9\]+ at (0x\[0-9a-f\]+)\r\n$gdb_prompt $" { + set b_addr $expect_out(1,string) + pass $test + } + -re "Breakpoint \[0-9\]+ at (0x\[0-9a-f\]+): .*\r\n$gdb_prompt $" { + set b_addr $expect_out(1,string) + fail $test + } +} +verbose -log "b_addr=<$b_addr>" + +set p_addr "" +set test "print func" +gdb_test_multiple $test $test { + -re "\\$\[0-9\]+ = {} (0x\[0-9a-f\]+) \r\n$gdb_prompt $" { + set p_addr $expect_out(1,string) + pass $test + } +} +verbose -log "p_addr=<$p_addr>" + +set test "break address belongs to func" +if {$b_addr == $p_addr} { + pass "$test (exact match)" +} else { + set skip [expr $b_addr - $p_addr] + if {$skip > 0 && $skip < $binfuncfilesize} { + pass "$test (prologue skip by $skip bytes)" + } else { + fail $test + } +} diff --git a/gdb/testsuite/gdb.base/longest-types-64bit.S b/gdb/testsuite/gdb.base/longest-types-64bit.S new file mode 100644 index 00000000000..336d3fdb7a7 --- /dev/null +++ b/gdb/testsuite/gdb.base/longest-types-64bit.S @@ -0,0 +1,249 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2012 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 . */ + + .file "longest-types-64bit.c" + .text +.Ltext0: + .globl main +main: + .comm f,8,8 +.Letext0: + .file 1 "gdb.base/longest-types-64bit.c" + .section .debug_info,"",@progbits +.Ldebug_info0: + .4byte 0x9a /* Length of Compilation Unit Info */ + .2byte 0x2 /* DWARF version number */ + .4byte .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ + .byte 0x8 /* Pointer Size (in bytes) */ + .uleb128 0x1 /* (DIE (0xb) DW_TAG_compile_unit) */ + .4byte .LASF3 /* DW_AT_producer: "GNU C 4.7.3 20121109 (prerelease)" */ + .byte 0x1 /* DW_AT_language */ + .4byte .LASF4 /* DW_AT_name: "gdb.base/longest-types-64bit.c" */ + .4byte .LASF5 /* DW_AT_comp_dir: "" */ + .4byte .Ldebug_line0 /* DW_AT_stmt_list */ + .uleb128 0x2 /* (DIE (0x1d) DW_TAG_structure_type) */ + .ascii "foo\0" /* DW_AT_name */ + .4byte 0xff000002 /* DW_AT_byte_size */ + .byte 0x1 /* DW_AT_decl_file (gdb.base/longest-types-64bit.c) */ + .byte 0x12 /* DW_AT_decl_line */ + .4byte 0x4e /* DW_AT_sibling */ + .uleb128 0x3 /* (DIE (0x2c) DW_TAG_member) */ + .ascii "buf\0" /* DW_AT_name */ + .byte 0x1 /* DW_AT_decl_file (gdb.base/longest-types-64bit.c) */ + .byte 0x14 /* DW_AT_decl_line */ + .4byte 0x4e /* DW_AT_type */ + .byte 0x2 /* DW_AT_data_member_location */ + .byte 0x23 /* DW_OP_plus_uconst */ + .uleb128 0 + .uleb128 0x4 /* (DIE (0x3a) DW_TAG_member) */ + .4byte .LASF0 /* DW_AT_name: "buf2" */ + .byte 0x1 /* DW_AT_decl_file (gdb.base/longest-types-64bit.c) */ + .byte 0x15 /* DW_AT_decl_line */ + .4byte 0x73 /* DW_AT_type */ + .byte 0x7 /* DW_AT_data_member_location */ + .byte 0x23 /* DW_OP_plus_uconst */ + .uleb128 0xffff000000 + .byte 0 /* end of children of DIE 0x1d */ + .uleb128 0x5 /* (DIE (0x4e) DW_TAG_array_type) */ + .4byte 0x6c /* DW_AT_type */ + .4byte 0x65 /* DW_AT_sibling */ + .uleb128 0x6 /* (DIE (0x57) DW_TAG_subrange_type) */ + .4byte 0x65 /* DW_AT_type */ + .quad 0xfffeffffff /* DW_AT_upper_bound */ + .byte 0 /* end of children of DIE 0x4e */ + .uleb128 0x7 /* (DIE (0x65) DW_TAG_base_type) */ + .byte 0x8 /* DW_AT_byte_size */ + .byte 0x7 /* DW_AT_encoding */ + .4byte .LASF1 /* DW_AT_name: "sizetype" */ + .uleb128 0x7 /* (DIE (0x6c) DW_TAG_base_type) */ + .byte 0x1 /* DW_AT_byte_size */ + .byte 0x6 /* DW_AT_encoding */ + .4byte .LASF2 /* DW_AT_name: "char" */ + .uleb128 0x5 /* (DIE (0x73) DW_TAG_array_type) */ + .4byte 0x6c /* DW_AT_type */ + .4byte 0x83 /* DW_AT_sibling */ + .uleb128 0x8 /* (DIE (0x7c) DW_TAG_subrange_type) */ + .4byte 0x65 /* DW_AT_type */ + .byte 0x1 /* DW_AT_upper_bound */ + .byte 0 /* end of children of DIE 0x73 */ + .uleb128 0x9 /* (DIE (0x83) DW_TAG_variable) */ + .ascii "f\0" /* DW_AT_name */ + .byte 0x1 /* DW_AT_decl_file (gdb.base/longest-types-64bit.c) */ + .byte 0x16 /* DW_AT_decl_line */ + .4byte 0x97 /* DW_AT_type */ + .byte 0x1 /* DW_AT_external */ + .byte 0x9 /* DW_AT_location */ + .byte 0x3 /* DW_OP_addr */ + .quad f + .uleb128 0xa /* (DIE (0x97) DW_TAG_pointer_type) */ + .byte 0x8 /* DW_AT_byte_size */ + .4byte 0x1d /* DW_AT_type */ + .byte 0 /* end of children of DIE 0xb */ + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 /* (abbrev code) */ + .uleb128 0x11 /* (TAG: DW_TAG_compile_unit) */ + .byte 0x1 /* DW_children_yes */ + .uleb128 0x25 /* (DW_AT_producer) */ + .uleb128 0xe /* (DW_FORM_strp) */ + .uleb128 0x13 /* (DW_AT_language) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0xe /* (DW_FORM_strp) */ + .uleb128 0x1b /* (DW_AT_comp_dir) */ + .uleb128 0xe /* (DW_FORM_strp) */ + .uleb128 0x10 /* (DW_AT_stmt_list) */ + .uleb128 0x6 /* (DW_FORM_data4) */ + .byte 0 + .byte 0 + .uleb128 0x2 /* (abbrev code) */ + .uleb128 0x13 /* (TAG: DW_TAG_structure_type) */ + .byte 0x1 /* DW_children_yes */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0xb /* (DW_AT_byte_size) */ + .uleb128 0x6 /* (DW_FORM_data4) */ + .uleb128 0x3a /* (DW_AT_decl_file) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3b /* (DW_AT_decl_line) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x1 /* (DW_AT_sibling) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .byte 0 + .byte 0 + .uleb128 0x3 /* (abbrev code) */ + .uleb128 0xd /* (TAG: DW_TAG_member) */ + .byte 0 /* DW_children_no */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x3a /* (DW_AT_decl_file) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3b /* (DW_AT_decl_line) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x38 /* (DW_AT_data_member_location) */ + .uleb128 0xa /* (DW_FORM_block1) */ + .byte 0 + .byte 0 + .uleb128 0x4 /* (abbrev code) */ + .uleb128 0xd /* (TAG: DW_TAG_member) */ + .byte 0 /* DW_children_no */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0xe /* (DW_FORM_strp) */ + .uleb128 0x3a /* (DW_AT_decl_file) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3b /* (DW_AT_decl_line) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x38 /* (DW_AT_data_member_location) */ + .uleb128 0xa /* (DW_FORM_block1) */ + .byte 0 + .byte 0 + .uleb128 0x5 /* (abbrev code) */ + .uleb128 0x1 /* (TAG: DW_TAG_array_type) */ + .byte 0x1 /* DW_children_yes */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x1 /* (DW_AT_sibling) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .byte 0 + .byte 0 + .uleb128 0x6 /* (abbrev code) */ + .uleb128 0x21 /* (TAG: DW_TAG_subrange_type) */ + .byte 0 /* DW_children_no */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x2f /* (DW_AT_upper_bound) */ + .uleb128 0x7 /* (DW_FORM_data8) */ + .byte 0 + .byte 0 + .uleb128 0x7 /* (abbrev code) */ + .uleb128 0x24 /* (TAG: DW_TAG_base_type) */ + .byte 0 /* DW_children_no */ + .uleb128 0xb /* (DW_AT_byte_size) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3e /* (DW_AT_encoding) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0xe /* (DW_FORM_strp) */ + .byte 0 + .byte 0 + .uleb128 0x8 /* (abbrev code) */ + .uleb128 0x21 /* (TAG: DW_TAG_subrange_type) */ + .byte 0 /* DW_children_no */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x2f /* (DW_AT_upper_bound) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .byte 0 + .byte 0 + .uleb128 0x9 /* (abbrev code) */ + .uleb128 0x34 /* (TAG: DW_TAG_variable) */ + .byte 0 /* DW_children_no */ + .uleb128 0x3 /* (DW_AT_name) */ + .uleb128 0x8 /* (DW_FORM_string) */ + .uleb128 0x3a /* (DW_AT_decl_file) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x3b /* (DW_AT_decl_line) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .uleb128 0x3f /* (DW_AT_external) */ + .uleb128 0xc /* (DW_FORM_flag) */ + .uleb128 0x2 /* (DW_AT_location) */ + .uleb128 0xa /* (DW_FORM_block1) */ + .byte 0 + .byte 0 + .uleb128 0xa /* (abbrev code) */ + .uleb128 0xf /* (TAG: DW_TAG_pointer_type) */ + .byte 0 /* DW_children_no */ + .uleb128 0xb /* (DW_AT_byte_size) */ + .uleb128 0xb /* (DW_FORM_data1) */ + .uleb128 0x49 /* (DW_AT_type) */ + .uleb128 0x13 /* (DW_FORM_ref4) */ + .byte 0 + .byte 0 + .byte 0 + .section .debug_aranges,"",@progbits + .4byte 0x1c /* Length of Address Ranges Info */ + .2byte 0x2 /* DWARF Version */ + .4byte .Ldebug_info0 /* Offset of Compilation Unit Info */ + .byte 0x8 /* Size of Address */ + .byte 0 /* Size of Segment Descriptor */ + .2byte 0 /* Pad to 16 byte boundary */ + .2byte 0 + .quad 0 + .quad 0 + .section .debug_line,"",@progbits +.Ldebug_line0: + .section .debug_str,"MS",@progbits,1 +.LASF4: + .string "gdb.base/longest-types-64bit.c" +.LASF3: + .string "GNU C 4.7.3 20121109 (prerelease)" +.LASF0: + .string "buf2" +.LASF1: + .string "sizetype" +.LASF5: + .string "" +.LASF2: + .string "char" + .ident "GCC: (GNU) 4.7.3 20121109 (prerelease)" + .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.base/longest-types-64bit.bz2.uu b/gdb/testsuite/gdb.base/longest-types-64bit.bz2.uu new file mode 100644 index 00000000000..4007da29172 --- /dev/null +++ b/gdb/testsuite/gdb.base/longest-types-64bit.bz2.uu @@ -0,0 +1,67 @@ +begin 755 gdb.base/longest-types-64bit.bz2 +M0EIH.3%!62936<'N#OH`"G/________^______?_Y______//]7SQD5'^/_% +M=VY7?F_[X`F]]SG7531-==V:Z-.FW;M.U7=';:UH@<&FD31,E3]J'HE-/TR@ +M]4_5/32;%/U3]1--HU/U$#$R'I'J,FC0T-,)B'J#:CU,F@]0`/4:>F@CU/4, +MA@$S2>IH!H`TR/0-$$:9`C(&FHU3VE-J;4\%,@>4T:#]49-J/4`>HT!H#3)^ +MJ`!H-``T]0&@-```:'J``&@`:9!`R9,@&3(`#3!#0!H``-#$--`,@``T`T#( +M:`:`&0&@::,0:-```:``-`E-$1#4-3:4]3R9-39(Q/)#3R-30:9#$T!D!H&@ +M,CTGI!H#(#0T`#0``T`T`:``-``T`0,F3(!DR``TP0T`:``#0Q#30#(``-`- +M`R&@&@!D!H&FC$&C0``&@`#0)%)H32>JGZ&!)Z1B1X@)DTVC4>H`&0:``R&@ +M,C0:``T``,C0``!H``#(`T`:#0U^\?]7K8M.96V/2[?M*DC)>WIUF)H7T\$:KKRE&\Q +M..M]L1*,!>D!X)RW,[,1I,9N%X-N&2+*:&)DJY4(VFQG%9K[/?J06WACF6-I +MJ&JJ9,ZK4;X28M@[==%ME(A54:%>+3->MRK(G!8#TY>@E$6DR&<_5:C&/RZE +MI,!E6#`;*8R*E@++*))U)[6=OKFM%'+$-H5\X@1D)_Y*"NKV. +M&\F8?SXW^HQ:Y@(Q[.>PEG=]@^ +M%C"3EZ/1X'H*02ZQH":6"@;8Z0LEW6)> +M6^V=*`FB'5G4MD8L3J5XT#SW;J1]ZO+"SPIS%J(P46+Q=CC2$H-`-B&TD)M` +M&A:066DA%AB0C6,460>M8B+$:-BR&@NM()F`S',,F8+#&0.SMOK@.G<'83N. +MDA"#5-`JVC("1*TA;/M()&8J0+YH%IFV)+OA@4,`E?3M$[$@&Q`3]A!$&A(- +M$PBT+2,@PU+2H9(T-H3N6'(2;""%2T*1I2P@`L?AG8&A!=31J7)1(9FB'8X= +MWJ0S#YEG9K$.#.[L.[CNA"4JSJ^GK2*)UH=MC0.R8+E75'.09[G +MMQ1*[GI:>#>K`_NZS:V6>$K;OX6#!!N'"2413$DTL&]7KY>B<3V5!!C8#X5+ +MF%9X!8NOKM5 +M+"N&P4.75C16!A9Q;:C.6N`WZDV=-]!,5PG]SNP[GV^L?YGI]7_'D8N?XV +M'[7KZJWYVMXGBQS[`!)YI%3:D)I2!;%'R`W&YB<`9O2#F"C/)F;JK9P+@3&( +MAH31[W)=YCODQDUKNM7A"3.C!2%CHTJNZ"Z\+#F-?(DLE>XAC%07B8;$%J_L +MJPK48QC&,916=IM+<1&WRKLB6&Q2O79*!7S$,`7J8*!`!=K:5W550[NH9M#_ +MKL!LT,&;59GZW7S"5Z4%`%&!`9"J9`0:IR&H=MTKT=PEYC$,4K90M9AT'%;_ +MB0HVLE)(W&YWF,C:TURXO:`M[RX(A-GT97456Q4Z*HPU*4J:*[WU-4GD.9UV +MSA#L4X[[*Y+)8IF.EO<.TP4IC2?(4HX)W1#:GOMOD2F;HM1BV#;PH[ +M7:PJ-!#,!6N<3')-0C,>15'IZ>@U^CJJJ+>+>%%)%BBATD\)*F6&BLMIR&?\ +MQ2_?33@"NR1/CN\:)>5DG6`>$;$3QA94'-3]*CU6YG])<=2)'GC"RP-RK&-3 +MZDT-M_)R+F06DS?CR>E@^!,33"U6X<@OXO$Q>U$\T@IU'@T=>K`G7H8K5GLXMS3*^@JLVBHHE'.&?9RKC?Y`&&3J5!/C$++<@U#Q' +M9R3I.$+S`%]-.UO>WH^C73F<&;RIJR+(Q@7(3PP*W[-O,,DD3S7BUK^I@D%* +M`Y<*2TXJ&7;2'6'R.U>]0-="M`K+&N%/==N4U@9%@M1)U&251C($^S"WL"]T +M-XN'D2[II3-$K%+&`3['O)%,8G*E%_8RV6A5B_4(2/?-AIC.\/>,YFJ<(G.8 +MAVP?UN*=ME:7&T!C%)I:&4H:-5>&^!&0>A.O'0G'/6&ZZ964@04&=#DC`%&: +MUNLOS?,?'T:T!8L80='M:96K4;JX)6.('1#J$.1/L)$IS<4/*'2D34 +M/@J\BA(I2T40JS%9G8F!7U5_!#'U!+[7$ES&)@:*QAET-IBX6'_N5^7/#>@V +MN3&,-6(AG[8&!8LV+F_U"W?/)+Y^,;=1K:SW28<0WA2"UPHP^8FG#R$!`Y`, +MLF<`U*NNU\[6N03"*?I8D=K7.Z*H=A_37;S=LVC(BQ,58Q_\#G`'P*_-]T!G4$`V0BS]'S)D/;V7R?.2F?SF)N+2+#P2_G(49TCE&*UIVT-MP808VTVV-$(*`VT<%>%96AHOL`(7%SI2%-R +M#G2F02VQQH-7KT3E05I9Z)E\$Y8ED1KU`(4QHT%B]1$F:F1&8DAN.Q4&*?F@ +M.8D965.$PRHT5HD,G=G!KTF3D +M94"&ZA-F,.19=8`\(Q;A07Q%!19*3#*F9Q+D(0K@V87@O.=7EJIM6`!4`>D! +M)49QHA!BV+:4O@K00$$!5*6>A@2@4D)@R\"%$2F"O:24J*L(RP#N;O4K7I&2 +M[#)KR47H-N[VJ%3>$`9,AF8QID&I3G+D`*]BX98B$2K":A7_\ +M_]7LT!4,$NL5)NE>9[:MK2_/'GO:7"P`=P(\L]O?"-APH(834$,W!IJS+U1F1C.!D$!&KS^-6%F90PQ[F]F=$^QE\X+- +M@.W*LPH_78B>MHH@69RU[*'1J@8QAC\KSV@IG\(;_CUW:ZR2.,0$E3LZ_^P= +M<_DCP"Q<`;+_;YP#^U%&E^#2M%,T?F3UN^>TSH)GFL"\%RF[KNZ+[R+@<&.$ +MC42)B96\1-.O_I).K7)X]W>EQ):4C(XB*+:S%0_37D^EBP+1HU(D?3"%_O2R +M6-#X>AU#<$*!/,W6QC^;O^%]LR&_X'<8X$<3CUU_QFAJ;">H)2443GD4W!4# +?<55!2^6_8J$)-O<>\H0U/6Q^>UG0%W)%.%"0P>X.^@`` +` +end diff --git a/gdb/testsuite/gdb.base/longest-types-64bit.c b/gdb/testsuite/gdb.base/longest-types-64bit.c new file mode 100644 index 00000000000..1394c08bdc5 --- /dev/null +++ b/gdb/testsuite/gdb.base/longest-types-64bit.c @@ -0,0 +1,28 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2012 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 . */ + +struct foo +{ + char buf[0xffff000000]; + char buf2[2]; +} *f; + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.base/longest-types-64bit.exp b/gdb/testsuite/gdb.base/longest-types-64bit.exp new file mode 100644 index 00000000000..4871dec72f4 --- /dev/null +++ b/gdb/testsuite/gdb.base/longest-types-64bit.exp @@ -0,0 +1,59 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2012 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 . + +standard_testfile .c longest-types-64bit.S + +proc test { name } { with_test_prefix $name { + # 64-bit array size should not overflow + gdb_test "print &f->buf" {= \(char \(\*\)\[1099494850560\]\) 0x0} + + # The offset should not overflow + gdb_test "print &f->buf2" {= \(char \(\*\)\[2\]\) 0xffff000000} +}} + + +# Test 64-bit file first as it is not compiled so its compilation never fails. + +set file64bitbz2uu ${srcdir}/${subdir}/${testfile}.bz2.uu +set file64bit [standard_output_file ${testfile}] + +if {[catch "system \"uudecode -o - ${file64bitbz2uu} | bzip2 -dc >${file64bit}\""] != 0} { + untested "failed uudecode or bzip2" + return -1 +} +file stat ${file64bit} file64bitstat +if {$file64bitstat(size) != 9501} { + untested "uudecode or bzip2 produce invalid result" + return -1 +} + +clean_restart ${file64bit} + +#if { [prepare_for_testing ${testfile}.exp ${testfile} $srcfile2 {nodebug}] } { +# return -1 +#} + +test "64bit" + + +# And here is the native build test. + +if { [prepare_for_testing ${testfile}.exp ${testfile} $srcfile {debug quiet}] } { + return -1 +} + +test "native" diff --git a/gdb/testsuite/gdb.base/macscp.exp b/gdb/testsuite/gdb.base/macscp.exp index f8eb750151c..f776602ba57 100644 --- a/gdb/testsuite/gdb.base/macscp.exp +++ b/gdb/testsuite/gdb.base/macscp.exp @@ -25,6 +25,14 @@ if { [test_compiler_info "gcc-*"] || [test_compiler_info "clang-*"] } { lappend options additional_flags=-g3 } +# Workaround ccache making lineno non-zero for command-line definitions. +if {[find_gcc] == "gcc" && [file executable "/usr/bin/gcc"]} { + set result [catch "exec which gcc" output] + if {$result == 0 && [string first "/ccache/" $output] > -1} { + lappend options "compiler=/usr/bin/gcc" + } +} + # Generate the intermediate object file. This is required by Darwin to # have access to the .debug_macinfo section. if {[gdb_compile "${srcdir}/${subdir}/macscp1.c" "${objfile}" \ diff --git a/gdb/testsuite/gdb.base/move-dir.c b/gdb/testsuite/gdb.base/move-dir.c new file mode 100644 index 00000000000..89b65b4b6a7 --- /dev/null +++ b/gdb/testsuite/gdb.base/move-dir.c @@ -0,0 +1,10 @@ +#include +#include +#include "move-dir.h" + +int main() { + const char* hw = "hello world."; + printf ("%s\n", hw);; + other(); +} + diff --git a/gdb/testsuite/gdb.base/move-dir.exp b/gdb/testsuite/gdb.base/move-dir.exp new file mode 100644 index 00000000000..f189ea77b9f --- /dev/null +++ b/gdb/testsuite/gdb.base/move-dir.exp @@ -0,0 +1,57 @@ +# Copyright 2005 +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +set testfile "move-dir" +set srcfile ${testfile}.c +set incfile ${testfile}.h +set binfile [standard_output_file ${testfile}] + +set testdir [standard_output_file incdir] + +remote_exec build "mkdir $testdir" +remote_exec build "cp ${srcdir}/${subdir}/${srcfile} [standard_output_file ${srcfile}]" +remote_exec build "cp ${srcdir}/${subdir}/${incfile} [standard_output_file ${incfile}]" + +set additional_flags "additional_flags=-I${subdir}/incdir" + +if { [gdb_compile [standard_output_file ${srcfile}] "${binfile}" executable [list debug $additional_flags]] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +# Create and source the file that provides information about the compiler +# used to compile the test case. + +if [get_compiler_info ${binfile}] { + return -1; +} + + +set oldtimeout $timeout +set timeout [expr "$timeout + 60"] + +# Start with a fresh gdb. + +gdb_exit +gdb_start +gdb_test "cd ../.." "" "" +gdb_load ${binfile} +gdb_test "list main" ".*hw.*other.*" "found main" +gdb_test "list other" ".*ostring.*" "found include file" + + +set timeout $oldtimeout +return 0 diff --git a/gdb/testsuite/gdb.base/move-dir.h b/gdb/testsuite/gdb.base/move-dir.h new file mode 100644 index 00000000000..4a99725a003 --- /dev/null +++ b/gdb/testsuite/gdb.base/move-dir.h @@ -0,0 +1,7 @@ +#include + +void other() { + const char* ostring = "other"; + printf ("%s\n", ostring);; +} + diff --git a/gdb/testsuite/gdb.base/new-ui-pending-input.exp b/gdb/testsuite/gdb.base/new-ui-pending-input.exp index ae41d396294..891120e9beb 100644 --- a/gdb/testsuite/gdb.base/new-ui-pending-input.exp +++ b/gdb/testsuite/gdb.base/new-ui-pending-input.exp @@ -62,6 +62,7 @@ proc test_command_line_new_ui_pending_input {} { set options "" append options " -iex \"set height 0\"" append options " -iex \"set width 0\"" + append options " -iex \"set build-id-verbose 0\"" append options " -iex \"new-ui console $extra_tty_name\"" append options " -ex \"b $bpline\"" append options " -ex \"run\"" diff --git a/gdb/testsuite/gdb.base/readline-overflow.exp b/gdb/testsuite/gdb.base/readline-overflow.exp new file mode 100644 index 00000000000..5e46816d21c --- /dev/null +++ b/gdb/testsuite/gdb.base/readline-overflow.exp @@ -0,0 +1,126 @@ +# Copyright 2006 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Jan Kratochvil + +# This file is part of the gdb testsuite. + +# +# Tests for readline buffer overflow. +# + +if $tracelevel { + strace $tracelevel +} + +# Don't let a .inputrc file or an existing setting of INPUTRC mess up +# the test results. Even if /dev/null doesn't exist on the particular +# platform, the readline library will use the default setting just by +# failing to open the file. OTOH, opening /dev/null successfully will +# also result in the default settings being used since nothing will be +# read from this file. +global env +if [info exists env(INPUTRC)] { + set old_inputrc $env(INPUTRC) +} +set env(INPUTRC) "/dev/null" + +set oldtimeout1 $timeout +set timeout 600 + +if [info exists env(GDBHISTFILE)] { + set old_gdbhistfile $env(GDBHISTFILE) +} +if [info exists env(HISTSIZE)] { + set old_histsize $env(HISTSIZE) +} +set env(GDBHISTFILE) "${srcdir}/${subdir}/gdb_history" +set env(HISTSIZE) "10" + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir + + +set width 11 +gdb_test "set width $width" \ + "" \ + "Setting width to $width." +#gdb_test "set height 1" \ +# "" \ +# "Setting height to 1." +send_gdb "run X" +set i 0 +# It crashes using `set width 7' on `set total 3560'. +# Sometimes it corrupts screen on `set width 7'. +# Bugreport used `set total 130001': +# https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=214196 +# Check also `timeout' above. +set total 4200 +gdb_expect { + -re X { + incr i + if {$i <= $total} { + send_gdb "X" + exp_continue + } + } + -re "\[ \b\r\n\]" { + exp_continue + } + eof { + fail "gdb sending total $total characters" + note "Failed after sending $i characters, reason: EOF" + gdb_clear_suppressed + } + timeout { + fail "gdb sending total $total characters" + note "Failed after sending $i characters (timeout $timeout), reason: TIMEOUT" + gdb_clear_suppressed + } + default { + fail "gdb sending total $total characters" + note "Failed after sending $i characters, reason: 0=\[$expect_out(0,string)\] buffer=\[$expect_out(buffer)\]" + gdb_clear_suppressed + } +} +send_gdb "\r" +gdb_test "" \ + "No executable file specified..*" \ + "All the characters transferred" + + +# Restore globals modified in this test... +if [info exists old_inputrc] { + set env(INPUTRC) $old_inputrc +} else { + unset env(INPUTRC) +} +if [info exists old_gdbhistfile] { + set env(GDBHISTFILE) $old_gdbhistfile +} else { + unset env(GDBHISTFILE) +} +if [info exists old_histsize] { + set env(HISTSIZE) $old_histsize +} else { + unset env(HISTSIZE) +} +set timeout $oldtimeout1 + diff --git a/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.c b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.c new file mode 100644 index 00000000000..085001d7f3f --- /dev/null +++ b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.c @@ -0,0 +1,33 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2016 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 . */ + +__attribute__((aligned(16))) struct +{ + int var0, var4, var8; +} aligned; + +int +main (void) +{ + aligned.var0 = 1; + aligned.var4 = 2; + aligned.var8 = 3; + + aligned.var4 = aligned.var0; + + return 0; +} diff --git a/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp new file mode 100644 index 00000000000..49bb9756029 --- /dev/null +++ b/gdb/testsuite/gdb.base/rhbz1261564-aarch64-watchpoint.exp @@ -0,0 +1,53 @@ +# Copyright (C) 2016 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 . + +if { [prepare_for_testing rhbz1261564-aarch64-watchpoint.exp "rhbz1261564-aarch64-watchpoint"] } { + return -1 +} + +if { ! [ runto main ] } then { return 0 } + +set test "rwatch aligned.var4" +if [istarget "s390*-*-*"] { + gdb_test $test {Target does not support this type of hardware watchpoint\.} + untested "s390* does not support hw read watchpoint" + return +} +gdb_test $test "Hardware read watchpoint \[0-9\]+: aligned.var4" + +proc checkvar { address } { + global gdb_prompt + + set test "p &aligned.var$address" + gdb_test_multiple $test $test { + -re " = \\(int \\*\\) 0x\[0-9a-f\]+$address \r\n$gdb_prompt $" { + pass $test + } + -re "\r\n$gdb_prompt $" { + untested "$test (unexpected ELF layout)" + return 0 + } + } + return 1 +} +if ![checkvar "0"] { return } +if ![checkvar "4"] { return } +if ![checkvar "8"] { return } + +# Assumes: PPC_PTRACE_GETHWDBGINFO::data_bp_alignment == 8 +# 'lwz' does read only 4 bytes but the hw watchpoint is 8 bytes wide. +setup_xfail "powerpc*-*-*" + +gdb_continue_to_end diff --git a/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp new file mode 100644 index 00000000000..bb70c5cf446 --- /dev/null +++ b/gdb/testsuite/gdb.base/rhbz981154-misleading-yum-install-warning.exp @@ -0,0 +1,97 @@ +# Copyright (C) 2014 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 . + +standard_testfile "normal.c" + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { + return -1 +} + +# Get the build-id of the file +set build_id_debug_file [build_id_debug_filename_get $binfile] +regsub -all ".debug$" $build_id_debug_file "" build_id_without_debug + +# Run to main +if { ![runto_main] } { + return -1 +} + +# We first need to generate a corefile +set escapedfilename [string_to_regexp [standard_output_file gcore.test]] +set core_supported 0 +gdb_test_multiple "gcore [standard_output_file gcore.test]" \ + "save a corefile" \ +{ + -re "Saved corefile ${escapedfilename}\[\r\n\]+$gdb_prompt $" { + pass "save a corefile" + global core_supported + set core_supported 1 + } + -re "Can't create a corefile\[\r\n\]+$gdb_prompt $" { + unsupported "save a corefile" + global core_supported + set core_supported 0 + } +} + +if {!$core_supported} { + return -1 +} + +# Move the binfile to a temporary name +remote_exec build "mv $binfile ${binfile}.old" + +# Reinitialize GDB and see if we get a yum/dnf warning +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir + +with_test_prefix "first run:" { + gdb_test "set build-id-verbose 1" "" \ + "set build-id-verbose" + + gdb_test "set debug-file-directory [file dirname [standard_output_file gcore.test]]" "" \ + "set debug-file-directory" + + gdb_test "core-file [standard_output_file gcore.test]" \ + "Missing separate debuginfo for the main executable file\r\nTry: (yum|dnf) --enablerepo='\\*debug\\*' install [standard_output_file $build_id_without_debug]\r\n.*" \ + "test first yum/dnf warning" +} + +# Now we define and create our .build-id +file mkdir [file dirname [standard_output_file ${build_id_without_debug}]] +# Cannot use "file link" (from TCL) because it requires the target file to +# exist. +remote_exec build "ln -s $binfile [standard_output_file ${build_id_without_debug}]" + +# Reinitialize GDB to get the second yum/dnf warning +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir + +with_test_prefix "second run:" { + gdb_test "set build-id-verbose 1" "" \ + "set build-id-verbose" + + gdb_test "set debug-file-directory [file dirname [standard_output_file gcore.test]]" "" \ + "set debug-file-directory" + + gdb_test "core-file [standard_output_file gcore.test]" \ + "Missing separate debuginfo for the main executable file\r\nTry: (yum|dnf) --enablerepo='\\*debug\\*' install $binfile\r\n.*" \ + "test second yum/dnf warning" +} + +# Leaving the link there will cause breakage in the next run. +remote_exec build "rm -f [standard_output_file ${build_id_without_debug}]" diff --git a/gdb/testsuite/gdb.base/set-solib-absolute-prefix.c b/gdb/testsuite/gdb.base/set-solib-absolute-prefix.c new file mode 100644 index 00000000000..2675a34f1a6 --- /dev/null +++ b/gdb/testsuite/gdb.base/set-solib-absolute-prefix.c @@ -0,0 +1,26 @@ +/* Copyright (C) 2012 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 . */ + +#include +#include + +int +main (int argc, char *argv[]) +{ + printf ("Hello, World.\n"); + abort (); +} diff --git a/gdb/testsuite/gdb.base/set-solib-absolute-prefix.exp b/gdb/testsuite/gdb.base/set-solib-absolute-prefix.exp new file mode 100644 index 00000000000..bb4c8b962b9 --- /dev/null +++ b/gdb/testsuite/gdb.base/set-solib-absolute-prefix.exp @@ -0,0 +1,39 @@ +# Copyright 2012 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 . + +set testfile "set-solib-absolute-prefix" +set srcfile ${testfile}.c + +# It is necessary to verify if the binary is 32-bit, so that the system +# call `__kernel_vsyscall' originates from vDSO. + +if { ![is_ilp32_target] } { + return -1 +} + +if { [prepare_for_testing $testfile.exp $testfile $srcfile] } { + return -1 +} + +if { ![runto_main] } { + return -1 +} + +gdb_test "continue" "Program received signal SIGABRT, Aborted.*" \ + "continue until abort" +gdb_test "set solib-absolute-prefix /BOGUS_DIRECT" \ + ".*warning: Unable to find dynamic linker breakpoint function.*" \ + "set solib-absolute-prefix" +gdb_test "bt" "__kernel_vsyscall.*" "backtrace with __kernel_vsyscall" diff --git a/gdb/testsuite/gdb.base/solib-symbol.exp b/gdb/testsuite/gdb.base/solib-symbol.exp index 94713d3c147..9257bf8b695 100644 --- a/gdb/testsuite/gdb.base/solib-symbol.exp +++ b/gdb/testsuite/gdb.base/solib-symbol.exp @@ -29,6 +29,7 @@ set testfile "solib-symbol-main" set srcfile ${srcdir}/${subdir}/${testfile}.c set binfile [standard_output_file ${testfile}] set bin_flags [list debug shlib=${binfile_lib}] +set executable ${testfile} if [get_compiler_info] { return -1 @@ -72,8 +73,26 @@ gdb_test "br foo2" \ "Breakpoint.*: foo2. .2 locations..*" \ "foo2 in mdlib" -gdb_exit +# Test GDB warns for shared libraris which have not been found. -return 0 +gdb_test "info sharedlibrary" "/${libname}.*" +clean_restart ${executable} +gdb_breakpoint "main" +gdb_run_cmd +set test "no warning for missing libraries" +gdb_test_multiple "" $test { + -re "warning: Could not load shared library symbols for \[0-9\]+ libraries,.*\r\n$gdb_prompt $" { + fail $test + } + -re "Breakpoint \[0-9\]+, main .*\r\n$gdb_prompt $" { + pass $test + } +} +clean_restart ${executable} +gdb_test_no_output "set solib-absolute-prefix /doESnotEXIST" +gdb_breakpoint "main" +gdb_run_cmd +gdb_test "" "warning: Could not load shared library symbols for \[0-9\]+ libraries,.*\r\nBreakpoint \[0-9\]+, main .*" \ + "warning for missing libraries" diff --git a/gdb/testsuite/gdb.base/step-over-trampoline.c b/gdb/testsuite/gdb.base/step-over-trampoline.c new file mode 100644 index 00000000000..a012da1031a --- /dev/null +++ b/gdb/testsuite/gdb.base/step-over-trampoline.c @@ -0,0 +1,28 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2006 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +#include + +int main (void) +{ + puts ("hello world"); + return 0; +} diff --git a/gdb/testsuite/gdb.base/step-over-trampoline.exp b/gdb/testsuite/gdb.base/step-over-trampoline.exp new file mode 100644 index 00000000000..a183e362639 --- /dev/null +++ b/gdb/testsuite/gdb.base/step-over-trampoline.exp @@ -0,0 +1,54 @@ +# Copyright 2006 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +if $tracelevel then { + strace $tracelevel +} + +set testfile step-over-trampoline +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +# Get things started. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# For C programs, "start" should stop in main(). + +gdb_test "start" \ + "main \\(\\) at .*$srcfile.*" \ + "start" + +# main () at hello2.c:5 +# 5 puts("hello world\n"); +# (gdb) next +# 0x100007e0 in call___do_global_ctors_aux () + +gdb_test_multiple "next" "invalid `next' output" { + -re "\nhello world.*return 0;.*" { + pass "stepped over" + } + -re " in call___do_global_ctors_aux \\(\\).*" { + fail "stepped into trampoline" + } +} diff --git a/gdb/testsuite/gdb.base/tab-crash.bz2.uu b/gdb/testsuite/gdb.base/tab-crash.bz2.uu new file mode 100644 index 00000000000..e55ec5011be --- /dev/null +++ b/gdb/testsuite/gdb.base/tab-crash.bz2.uu @@ -0,0 +1,393 @@ +begin 644 /tmp/libgcc_s-6.3.1-20161221.so.1-objcopyR.debug.bz2 +M0EIH.3%!6293622@"44`>Q=_____________________________________ +M________X#\<>SD#OM[7/HAP:R]\H#D"=!/";NP7!]OOJG>U[N;WW'KVV?9I +M[[,[X.\/;%2U``[[NUM7P^T[U617V#12M]6M7W;M7CZU<=!]/8WL[LI=AZZ> +MJ5XW;QP]W]DVHY@]/6RS= +M8[:2][W/F01Z:GIID,IC$GHU-HR$:@T0F +M@$PC($P"`$PF)D9-&IZFCT-4\$TRI^330-$TR>32>FFF@F!H0GJ>TD_*9!E, +MR3Q3/11M-,%#T-3:-3T9(P-3T3TT@;1ZD>C1E,AM0:`@@303"`(Q*>FGHU)Z +MGDFR8FFJ'L5/1C313R3U/*?JF]&35-J!Y3U/TI^1$\IZGFBGJ>HVF4>H])ZA +MZC)ZFT)H>IH]0>H!H&RC0,F0T9E!HT-`TT`)-1(A$R&J?J3T80]313\F0GHC +MU3:90\H]$]3:C93U-!LH\IIZ$]0R>:D>329J--`/4_5'I-`TT9#3U!ZC0>H# +M0])H!H9!Z@#30VH#30-/4T'J`]09%$!4\)A3R,-1'J`S2#0--,$:/$C9-3TG +MH:FR9-(T>D\4],HT'I`/4`>HVFIIZFR:FR:)Y,3*/3*;"FT:(VIYJC:FF)Z: +MCTFAIZCTAH:#U!F*")1`0!`"9#4Q-,FT(R33R-4VFE/U&TU-3RGZ1FJ>&H]2 +M;U38GJ-J3TQ0Q'DU-'J?JF]2&30-'J:>H,FC1HWJ@#RFC0!Z#2-/4T&&4T-/ +M2:&(>D'J,5#"1JH5B["KJTH:1R2I95!0TXN8+PQ'&*+8%8JVQCC/1G1D0A-S +M91MLJJLK];M*G>^]MGIW=W7E>KL +M)MXKMO7VV\M77ANM3H=6LGI)+AR&CF'#<66)4&4S6:;*26:S5DUQGS$+>97< +M!3.,U$LQELITU,X3Y5[GW>0?IM4(5>Z!^AE04E8=:H(X[7T$U.`@QRT\Z]_" +M7?`4-8Q_UDP"AQ@$1,B`G(D*S"^7Z%ABZ-%T6MS+#&8M+G +M)M>_Y9ME3-K"RMO>,UK^9/4HYU5!3:6'45^1-AA23JG7FH&=KT9ZK-!6>?\- +M;_HD;$V3C,[X\-20B*R?`.(:CK$3A&J2!XYI6TW[U*HI*560[F!42LB.:FO9 +MT2S-`KC"H/^S^JJFC(54?*/HIBKH,!73^2++62,G98Y/*,\,%R,Y08$R@$&L +MC#"P#E53*YTZS&>L\]4*"<8&2^]*I?02,46;3.V(P+2P`3$>F+HNTY/(%Z<` +MM.P&I]6,NED[M1J4`O?!J@8`&>?1 +M%!8/]>.7UF-'?ZO,O??);\\L:3X7JN-O^ZWAPV:'ONI*N$I2REEE+$\Q47N6 +M)NB0W\O.LZ)TMD[9VG1NS+?94@_.$$=!P2#U2(8;*%.99OOW:1@#`W]ZV:OR +M1IWEL,R4\*2Y2^>SP[^QB +M_,U-)GY3;9KT/P=Q.GX.7G"Q:>QK&9"$ +M[#-J-&>2W>*T.XDRFC(,4I`"ED(D0(($(R0#&6;D6H(.:&R(R,:JBHZ!54G< +M11T9V@K&&$`@8+T3IN#,:<5@P(RTBD1%(JP%55$2*#^!4E,%ER22`*-**JU6 +MJZII6%N>*+(`*J_?LDI@")%A1D1`@0D?O:UXU=+B+/%.C.3P3935G@9N(=B( +M39SA1$,K(<1`/."P@;M&4XI&*(9N(H[,#92F)PFDD,V:;%@V(`6%EHV(`6$+T`+00*I0;U +M`+6F`+<5+:@OPH!:+<%V-Y:H6@0ST6@@$DQO&U0"]M7&.2N,;AN4`HP8H!<7 +MT;QP4`N;A(R`&`P88BZ-&+V-:04?;20GS/LL>$_B,!&RT)$%@$(*)!"$E!7/ +M#&8("!8N/9=K.,FB'MY.._/VD>C9#^`XS.XJ/S:XR1TI^MMN1AER0/FI,QI< +MI!S/-3&8!4S2B>DK$=5/`G2Z><=$L7)SB`(%.`?MXB?J?H_!K]]%1:Q0>>D5 +M@*,0!$21@`8Q[N?N_7_H;4[#S/![4O,^[NUOC?7F"'Z'YMMYO*;_)-K^K9([W=II7_32_/>'@"M-U3'I3>\5F/7!,>LN:H3*N!L;; +M")']UU7>>-S\,?K65#!/&(542)(!76C2F<92T@@7G-NX#D][M'6*;YS)AF7< +M!W7=#3Y1,RGT_`:&!`EU8>JEM/&JEI"+[5?4O\_]DT0",,XH95*#$@#=L,AO4L+ +M1BB(3Q$X?C1IAS!$AY.>_%4]AI=*'&F6&\>U;\YG,QV14-HP9\BY30H/3].G +MTW36AQ.N"4&8U(-$CSEJ:IAKE6J,KC=.U9$\H:1I/5!WK37"2WTTCL+"6YJD +MVV8?W_`MAI=@)]J^U-YAOBS;:'(S4SPBJP))LEQ'+GK;<]US[@5VN)U.SEI] +M@B6(>WE8&UNN(Z_Y^_U`>?=I*[4=\'V/"\YOXXU=RH7$2P +MZ8AP5/2@#F" +M^(R"5",K@5=:R=P=>/%\_!=LCS0>*ISX$*;G?\$9(P-<"734Z=7:V/E#,EJ3 +MR#)DN].):$0+S";E13Q8UADO"%],GD)5UBLWUDCN34&A3.I3U+69_K:PL#9:%6F) +M[AU5/05TLKLJ2*QB0,US:"U%(#G!9N81MN&'7T1O*J^]%%^#HV->-]LNGN*= +M"C%H8>WG7$,^&0"244E4:#V6Y!289:<&E<<-ZGKH1[>$BW"MUU,#SL;,,),V +M565B6/E!Z,H8E#]WD=(P%@X(,/C7GD0D +MP-:,NZ$0>8GQY;JN=^^\XXXN0&5=W>Z5]AZ1HYC%E&S'8*.!D@5[<8]"EYC) +M7*.I"&7-3RH1V#K4>$VO7@MZ*G*`]>M6049!\$(C%$3O$(">"B@IT'Y=.=H)`'G +MP?T,;OF2.6;FQ;,.#Y<(PT)/0+73.OI!]&#-""F[4ST51A!FJDN2B3PA +MCB(Q@J)!V14/5@R7:FG%FN\:RY!,K%>T32S-L$$!!OM9<,*\;?V9^D]EW* +MBQ6*UR5PQ\J=9&)2U[%%,*&2VK(M$(BHTDQO)TV^76K`\E7:.HV99X,B$L68 +MSG"]BK3]QP^-(JA!,M42_#=-`S`(@)8T4R,S_Y[7P__.8YW/0JJJJJJJNK8X +M-=3PO'T&C*J9)`]F0`%K%$*P$#"""'MX"\OETF6EW>4IT9RN8.;PY_?U:<^? +M*X$4&<5`%`1414BR`"1@4.DH8`QG9@#`TT7)^C&:7C@IA^%"_<3WTX+Q5*-=*7Y#/IE(_)_ +MYYO52X/>^`A8NS+]GQ6$%J!9HFB5*_*22UE#*>TYS.T"1U[AFR44'A(ZIZ$N +M7O')DXRK49/4T!7XG8#F7\)CF+,TPJAPV;\#4,AD7,Z/*?9D2DQDGR.^]LB( +M%[`,/\]CK_:F,LN`#`T>]RT?A*WQ[K='\FN+&[/YKKD[GOG)".MPK9KOE&2> +M4312<,\Y^C:>3=S-OHU-R)^F^*9H5Q"=7^-'_#GT?0V-ZX-3_S"6N2Q?O;7: +M=G#ZR=L/JQG[ +MO\_!J];07#9:XP=/JNC6V$KW5]`_.82T05/S?='X=WG0YS.[I94'X$?S()[N +M#_Y@OQH(_`@/2399*2&\0*8=X^IVZ-3#*-44=7^#1YU#@<+A<&%:']\FNF[I +M29_6J&Z$R.&H/.2,M8LDC$UZC*6*@F7SBW:"GQ3@-&AS/D'%[PAX*Z.!&Q`! +MK?M_?V/CA,ZX91WMR-A0992O)T0BR^HF9=VIA-3&20"GDL&" +M2O*AJJ$K`'3#X"@L61'"0N\_-&J])J,%%(*O_R0A*R3X>_<_]4=+TNCF/6?< +M]IGY%UQ&M/IX7^;)C'TSL++)C1,MUVW257A0K(-$P.$V@S/RDA=MA.W#)`^< +MI.1!C(@-*E;AB)^IQOD_^YWQ:2]K^31Z+%2J$@W$OT7PD.02BH.>E@'022(E +M3@Y$+>HD)''I +MK!<&,1@9T",6@FYM(V?[Q8KX6%]RJ`*8F:0\/6K-)X%%08$0"I?TTOH7J&:2 +MP"RV[FF`@B!MYU]ZA5,A0DG2_Q)37"OW#@@D%P1P53,Y9BTRN'V=+Z4!-QP> +M0Y0QJ(A,6"07X?-ZWOBHFM&@L1]UFNEG^IKIM+R/9>.LI"N99-[D[:+A+S@] +M9SU/\?K]_\Q%2,`!A(D20!4>@D8$G;HBBL(!"(2`J'98-5R/N2MRE[9.N+,! +MO"/VT9Y%Q@(TM(/8\%_VL"*'2P^*D+N2,C?4!XXM?3VL;&:5WJ^+#L>F7!H_,N +MIUM`#L5Y[#M_O]A6"9J&&AI_78:(A$4RYACP^Q[,#B9?EORFBL,[/%'C)]'[ +M.CACW"3O$#=`(=[_-\UU>&,/=25L+C^"'BK/E0!N1^$_"JB+_JPA`*]8CO(: +M`,.^+BG;`ZF7BV09<[-_][:8^4KLHF.(1`0<SWGYJ3I.3K!0![LX-.34%X +MKYZ.+[/.9+T`A+UD=Y@88X+WRYRQ#Z.0GAL_X^DU8%6CXLM.6/V<%ZXA\X\>Z?;"LR((5^)BH[ +M9YVM6QCU[L+>4:^0@[(+A[*2R473>#_#80G05=[MO!0B83]S4Y#69SL\FU;, +MM[%]++>'XGB[M<9CU9H/*ZY^J8LEQ/Y>=4H#=D +M076@OV1*HU!09+VY&I##%336?/5%)M>9>5%%"0;X0^D(!5LP%ZR;J#4AL2A( +MVL=+2L3>4N`V%1T%AG`R@("$$@E`4)0]>@`6#Y_ +M!?KZ5D(#B^G8"OV,(-.'8LE-"R&W?C;5W&U,*%TS9#DQGG02?LI;-V'6_'VD:/[B\[^!BK._+R4O,AIRU>SJ67X@ +M9BGP5'Z*.")D_)5(1^2U>5IE7MC^?6;KS0@W,1]%[_1Q>7T[6YJ6XJQ.^W;Y +M/EBI?KRW$W[U(3Z"^#'K&C9:437[_,^`K\[(S?[&%\T)U''KMU:$5SAVI&?1 +MO)WDB92)(QL1_:14'+!3-4<$"%!A'EL*M:SVOPL/C22OB0/^XF +MK<69BJ[(VD8/"J7=>==O$-;WW//)P10\;N+6!'EH$U.A3!PVG>^?[V.QP)[E +MM#M7!J:JJ5FI.V-&A9([(@[VAQ'!<$'(1S;SN=_.6>^5#L1AQ&_D'TL&-9`/ +M68$)7J_190&=D@#5'\F^+AINR/5:*)DDUZ[PNR9<+9KN3=Z?U+GOLD3<33S= +MITE&9$Q@::(*8DUSZ<4:QI+(U)BWK2;WBIFENWDW[`N'(FMFG:Z>V\N0-.!C +M]U#!U]T8<9HC9P8<^B_][RM5^;"??IE6G\((HDSM:T1.%M7\:[:DU2F*_DM4 +MYS/(B9,$-F_^*?"5:RW^<#:*&>C'":.!%4R6T1D?:_G=$H[JG;^K-&;DAU5X +M&\$R"F*J1F;BV>]?N_E7K/--@V7(QI0@&I.NR=19-&!(=T.&_,X7T=/'`?1* +M%W!R_DXWII`J:7?>BE$CIAWG*'YBZ$Q'_%_<27$JIQGYCU"!+X5C(PDS@W[\ +M7\*E`_CB_W[+#`2HNE+Z5(.40BX]1`,]W]9L2=-5S\JMIA,-W<&@; +M^[8^O76V>0CBYD0'SW%)\GD[WPO%X,)C%,*J;0T`C:JCB'+92>O:H';H,-[R +M=DRZ#I]-'NVA`SO3(FDOZW8P4EL?@9A=5^0Y7FCDLWBFFUTVRG&%.[D2V^=` +M5#K.+)QE0NXQY^M7*(C1-,N?>U93STMV@CGTY>&R$>RPK3'2R2*?5I5(24S/ +M3K0$S`PJ(?/0Q9_SG%)RTTU3HP8:\7'A72DJ57`^O/MG`YY><>SSD?WAH=M: +M"RO5HS+T!`\:(`9QAYB=#3-8"F2'/%UT1%Q3?D&F$[TQ2-M#%>'(OH`!2E./ +M)389QV:(LHH6GG+(3N1L[?82L*K4K0&9XD2X6@M+0N,)U%K,T-":?/Y]\MK5 +MK_Z:_I>'2UZ7+0:AKH\.K%VYPA6E!DHVG,PO?KU25M)+DT,P/AGJ<1$85R9% +MPF!G=#T]U45@%VRRB)A-TW^ZQ(Q_ZZED+F:K/ +M%[7I:0$4UD$#WL$0]Y40\#A.AW7;\'O>+#S^/JY/1OZ/3K>4XW>>[AD]#5PU +M:AAQU[/W.(AMMJ>4Q`29&#B9U_*;%>_:VI]+:'MP6ICV=R&`\X8;_^^!.GMS +M[CNN,)<#02E3:J,LVK(;7-QHKD@J'][T+:HKY^3V'XE@FQ3YWDML=KUMVS9T +M--UE*6'ES*\2LIZ+T;BH^&&6:[X%`OG)G&&W,6 +M)H$T1"14@OL:/PY6'YT^RE4`/70$D`%\6*J_[>]LELD`/3H$FC6R':]3T>]R:N[G/F>L^-Z8W(@05",604",9-Y"A3TN;K^7U_D?5 +M]+)>,!C#_7R<;\D\CX1PL]S$^X[C@`P,/0"-31'T61;6DR@][DZ>GRX>I6>`E\3;J]#&J;J-QZDEZ +MN`Z"S<>Q9D;G8V4DQ'4T:78NL=:(*1TE&S_R-!0N)EE'3[0&B*! +MXQ*NL=1!1^MME#CP3"#Z\>EWS"6?=]^))"@K:@'@@WDG:-N)I=7TH:&]V:HU#$8H@2H7&5C!B8/< +M>+*R`ZN=[,`1\>^V(NU#+I]][;J]J$$)=@@8!C&8F38Z2ZYW@!C;&*7UJH?S +MQ*8,+&MJ!D'$H2WJ"=:##R1L!V.SV:FBB#KMJZ-A8U=P'F)%DBD+Y(]`W<76 +M0"B`P'7/I#2C1W`Q//G]JRCF4N!U6V.,:6B(^'F_PM]?37_I^G\>W:F,#`!L +M#$,?SLN]D@92+./&PT_IX_D\#C]]P.?H=A[GX8-3>EHG#-5Y:9#51"%*"@8, +MR,#P4(,M6C4*U0!009;_,O-S^;=Q%1U4]/RN)VFLJGPB`SJ%?B]A6)UT%0>\ +M7?CM)8U>&P!P_@=A7"`%&/ZL=2/B:J/Z>/Q_QN./XO]HL>FR%6\R]CX<7IV1 +MM0K6BSY&M4Q1/\^R5ZB<#`'BZ1KJHV!@LE\&)<,`$827-VNZ1PXSI0/%T;N2 +M:'A7:2NQC\#-SZFY*DG.9SA'QL/C0XYFJ`..@)-DDV29VD5#RDE>]G8Q^3VW +ML)IY;;C3C--_D9B/%?0-[\A)B^]1S.A,'R5))?(UTRN%AZ[R=7^#1>8QD6;? +M\\>9'WS7+Q2MMQB$4G'&LKKE_5:P6VHX=!IXC/A?V!&;E12BA`S"D%5]>PD& +MLS[;Q-_NX\>E1,6!J!`.E>BKU-7><]ML_>YUY`*]=J1"%3^'=ZG#M`_=FP\5 +M_1@U\L5HC!6/M^AK=6RKL$<4WMRZ#=/)WD-JE[^K[$5:2F,WF$W:PM9.*M4Y +M,1F3/&3Z4AKF[0P[+OYJE&NVX5N("$H-U)M)Q]U1O+/^/[+5!F0AOSIW)JO1 +M-W"XB@\FPFF^^+'I5<9E=\R":I,J$XM:0Y$V!"D*0/[J>C4]94.6F>7>N3E^ +MZS4N7`.VR=BDAPI]W\W2SM;LA4L[C%P*HES%0]GNJ_4,L#<[Z^]\A0P/G_9< +M-GJDQ,;U!M7+G$4.Q774HG@<3ZR^,@.(C5#=9R1V,1BJ>G;B^X1G8:0*J9PI +M0O;M#TOG'I,BH@=IM=C3M.?3S+JKI7#,9^+T0K`E=MSFF.*<'F(&]5Y[G99G +M$Q0MHQB/4_,W&S73.T(4?>X?VDZ)REP[?IQJS%,A"CV=$(_EC6+=\=C[AZ^L +MT6_?WU:<<"*P,*F!BTVR-7-UZ8R*<(0Z,?*JV<():T68@T1[:_##<>AN:?DT +MFK>X6UN;;41]M,=73:_5`8T)T.!>[ADD@M$)!&9DX4_BU5+'$2![3L[L]J^Z +MNB>(E(74J3W"%&E0J0Z!0A1"@K/[XD5C,*BGM#&WV3BL+08N0>"'P6\JH&%[ +M_'ONYQUCK5P8Z@\6BSVU0/@G(./1*RH.1^?4F$S2GX":4R%3D!X_,0:@()!, +MX.-/LI6"D^5H9QOY(BMN;Y[FTCO5U^=_V]-005[^R6@N"H]!I"@*J2I9445_ +M?LM+4&A$:4*A`@3/(K`5895(TB768N-]$Y",C9W-PTE8>7<6FSV_800?X^2Q +ML6'"\!JHI4"AC#]EJ"+343WC0"P%!X6Z=Z+>/#;E\:3H +M*J9Z)ZHG?FL$!@@([X%`13X]*>3\4W=4+!:?80*1;@X_:7`V2$",%O%+Y;NW +MSK?IH.1]7FZJ%F6T;`NP\"[HC>M:RB9@9CM +MN5V'C^C]SZ+:[B[]+=^EM]A+]F_!\*>SA;M^^UT*,[^Z802/D8,&I$20.*F'Q/!Z_P-@_2/8^OT^"0@))K'@?MU`W<04B($7/6DU3`./KY +M:1.?^/Y_JBD3"%"(29.P4)IHI_DA+0R?6Z%LR#'D>>-RY]_<[&]";4S'N9LZ +M"Y_Z2\H5#%Z.7J?>2_*H\+?3*3@?E2>)5$*M1;0//-@K!L7>5:>)F4[WO4.>,LM,94O5/E$SMAZ>H +M\![?H>XT]I?,L*YE4(_XY&?7:=O,PS0::.'M8IM8F#)34%%76)^HW?:5.S=Y6&,4AE,AE@%G2V47(DXEPJT)0 +M..PL_..*EQ-^+I,4 +M56.:ST1Q#2EAT>"]%8+(?\>5O`*'!.B37T7>L6.7PW*[?5@`6%UD\A!('2L+ +M.$R'/6!C>GKC#<5U,GN3M%F9WZDL`#J-4OYO1/K#W'8/.+L-B!CG +MX>C5+"2X.U^#\@\X%#M@H7^B?UMO@_`IC<6<>OX?O"ZMQ?_D-P]Z(A[$]Z_% +M+`/EE#J)UQ1L@*%@C[$1"K]>"A+B&;O@8'Q?I;)U?/;1OP=SD7X(0+@/D`C +M/D>5DIGL#VVM`4V40(D($48(AZH0`3N`(J^_Z7C^-$K2C]+3I-44+?CE2BE: +M#.]`(@$(E,*(A?*OS&D'J%0$X>>2#.C>W]UAB?==P[^@X@.USAH$4HVQ5N0` +MZODUS#,W(T.=7,.=4Z"1PJ7D&>!D_"SMO9HN>!IEBHY@LWU&4`A2C*%!*P@F +M8:NPEZZ1OJ+8!2PM4`I5D,(BM2`%DHF4@!@-D)G$G;9"2$@VMR@%5`*C5O"T +M4`BYZ*`8%I9>WMXV(`8>GP<;"C@H!&EW$,0`H)-61KVF4`"BE8`&6*P(T5MY +M[,,;ND@P0:%;$:!6,4@"?R*`@&(I`?/V.OR$P*:HNV,TP%#5A;Z`2JI_A9J' +M][V!`!.$/:?0EGVF8TSR<_YI`4.0%0RB(=X"A!$/`!0OJ`)50["B$$0M!0I0 +M2"H11'R04*J-04+S-FYJBAX210"0]YV;I/?,69?B1'DF7D;]MP`1`).+&>KUBK4B?4=S:MC<=XWW$U4KM[G[J2EVCN; +M/@/-;<73F[?O[4P!0W`4.`%#R=[`2!W.O9K37>X]!V]56Z^)X;I9Q1+C!41$ +MA)"20]?3*9`AEP?L?*3)N`Q3!3D0`LC0"E*)%1I%>]!0VP4.J"ALW`8GBTD@ +M#L^)$P#&[CW_!W%E/`IFIAB>S2DGPA)&9)!F9F`A"*L=/@R,)LXZQI19P9&2 +M15")D#(0,00(D`:\P,X<1RJ9G3.Q+U&^0G`B'FW@#<8A8&_T9K"I@@00;!0V +MFV+(\9;GZW-.K6N_:8*<.7D+*!;[0KZ.DM+/;Q1#DO]1P=U0K$SDMIB"0,=)TI=B1D1`&1@9+]015`AUX.G%YCZTQSMP&.NF[Q2D +MLFF^%S/`X*6,"GT/\-3\I.+EJ[:-C*DVU%JVK?RT55HA5M +M=IL\W`ZX8X'%R6G6UJ($"HG#NPH6)[9)5#I>#661&#'.,(R#0BA?#,(=4P<9 +MC849O*SG1$]L9,1UH*!1HCV=J7?)NP'\_L2T\!H*$(67:P!AE18K\Z$!Z8K# +M3**H"OOKTP&`WF3K!\@2',QTC=T"G1R-J+][XLV +M(+8U@=`1MFP\,V/E5"&F8=JAMA>ST4A8R]DFB-V.8J;>MYL^"G(IU)_!1T1S +M1ZKUQC]A"6W+L==(4)^N[[/IW.W'V>OI3ZQ3I)5#=,;"[4`WYH:H"EIO#QP] +MSLR@!H'@:TL;M]IPBL<^H8]HE8\TV##;I=QSPY_]QF;P +MM/>O"3T)[*80=VMJ@'7HE+(S=H(%<+PY^)\@S]_< +M;HPZ-X4BF#W(*'(0`K;8HF.\+K,J(@7U(\$0%_L?>;GX@ZBQQ8+SQM-(KZ,T +M9C:"/-1$LP6-!UB!H'J`"Z[BU1&&*B])JICY7IM$"$[=1A]Z(`N00(;F^!CC +M5^P%&$;?H8DTT347F=$+184JBY0.(9!0,+$N[M:9UZ'XN^`PG`&KU$+X:VQP^/6EA!K$],NI#&V[..-H-1%"/>\UILE?@CGDZ_->"R,B!V.L@$ +M\&)YAC4=[_/OLTGHN.\HM45P\AYL%3UTXX8UK89FA0IA!,I6./VBK\XR="PY +MX$>0E!].'NBXP53HL[#=M+887P^KJ$O*\J%%R3%HS53F3>PW"W)RE^0XP`&B +MX5S4FXKO7KFF=!'B*40SE(LCGE4:[%<'28D=N(EZTAK?KT,J8/+0;J:&KD4Q +MB[OTEDH1OBO+GDKUP8>/$/I/K&79VH!DW(/A#%O11Q,@?43>'>UDD\ER#*FT +M')J(=2J>5.VW66K+2X(DT)IN(PK1W!R2F&OY&3M18,?"*L,:G@I^8P.Q>&WF +M#.EZ:?20E*9N80_^%7)T'JNIOAM2U8J7U%SQ!5SP<%>O\CD:[T#9,"[%5=`GHARQIT +M%\QD4*(FQ4)1^"94)MT,<05.QG++X<\&]/K$6S/WCS493!P1"*-:=F<4IPIN +M/+HA_?]9K12Z4?9#B^ZG``&8)YPC&'J`:.$+6*I=A&GX74>)[[HP]&G1Q'WD +M&I$34#4[D:E&0X>6!PZ:3'B0^W>(,D=*^/92`7Q>Q9-VAPUEQY3OTL_HZO#; +M>#LA+:6P2J`"-2V,RA8$1Z7F[]*K)3,'CQHY$78K\B']@`8P%]=;,/U'E7#N +M*&)X?MY1EQ%FK,8H:9K>;;!S?'N^@'EQ,87%WG+>)!%3C>! +MPG)6ZNZG!P'@4%04Y;)`BM,$\7AB]3RL4:\XW7W00(".LJFSTKGT*M2TN^L7 +M%@0`B`(A<`$"(1N!QX5FD\?@KO;H<;O.81WCXCX0Q*/U9@/0C +M%(`V()O@A7*8\:4@&#F)EC0I05R7\PBCBCE#2XF,#"KCFN@W +M>X>>N2Q1:\ZY(2F0,Q?:''2/&A[N9<9W,W"C.BFA"X6`#S/>PH?FQ$NZU?L5 +M:%KJY31\`:46RYB8I12>4+@=KUF'V84*AZ9)<=+3`TMQSW!&4&1 +MOVK3F)P\F'+M>@6I@UR)FR&V&]@54]WN43U=;>HIBQ14'9V"IBLL3##*Q],) +M]QWNQWGS@"VU^,'ZK(O"&XX73+[$P:JK;=PJN[)=#R\,!3RVIIE4%#$M#M:[T;+*^L[L\_E->?;7GBTF.WV'SA^,C +MI_(U5I*^F0K_A\E2M,7C("1S"";,76BQS-J0\@"(!@A7K8LPYTN8I$"81B%1 +M`2=VC#?M08HPA"!^5`AU)@H2LH%WI7IIQW$(44H5I@A&_(*0&2]9BH$/S424 +MA[ID(4F0PG+%CL8%'F96&M\T#-$984"5((`GI9O\^J`G)"3 +MF$F&UPO%T7I"-_4@?=<7448N.,D(T:\SOC/B0Q[.&;'-BYP3#<._R"(7]"@2 +MB;[:-2ACE"YUZ)"\@RP@*&P7C0%#GO?PG1Z($QPJPJX;0J% +MM77KK\]``=R#J10T14"4D%<\6L+ME\?UG3^>^5U.OD!0]L0`3B!0@@KR<9-P +MXQ-;L=B_?>*S;KP@@@<.\Z#.-M"Q%IPM$S$,EA?"(H)'AE%@E>(`38$0KENH +M]!A=)P]Y_=LLSAE$R%+").Z_8;-;K9`DT\WCWG0Y"P]#];[*TR"=W$V,V91A +M71,P*$:G9H`TMG,HETJ\/!38KNF;OK\P*&5H!OJJO>I!4(\(*&-IF"F@%#?: +MYPX,&FHI(<=[S*;`*%BV3+ +M@P&<#C!ZMB!2%%`=4,*!O.H4S#`@H%NK\B\5#*>?XGQMCF8W'\*G4SGM?J3$ +M.[`K2U%`44!BQ&16V,KX'0*3KCCC(@8G90&TX@*';F\]9.BEPZ+322R/-M10 +MR5`$IZ@@N9>,I984,W=;)`QC)JX*%>Y?0&'-AM15=<-%!(&;ZK>!O.*&]IL/,LNP44\D;(=EVWGN. +M<:*;Y.R9TN"O:[A73N%1/,)PN)6#(&+%6B&Y"2A!;:[G-0( +M^-\(=F/B/>'L(+-)POFTHV%?R5\SNC[ABBN!J7%-YELS%@L5(H5@58P5D`B` +MQ/D!-HQ7,::HBH&,@RH3&"0PAK<0`BHRSV)WVT<&3@">YM+7(7/6<0U33JH% +MFYS:'!VWP`!*]J2!E)"0B0B*((HQ$11B/WIB!1L2$UPD9"-3(1C`4W^Z@.T2 +M$RV=VM%5165C3(]7JSZ`N=#Z<"=NM9G/\83I['_K/4_HWCFKHWV:J:Y?Y'7A +M?DI$1`BM`$0%(``A]#ENPDS3Z^)MN7]3\W6%.*Z'<&R.8+:@@0!@(0% +M"09`0($!0@H)Q;WT=+2$%0GCY,%V.FV#8+C555,5:JE1I*&A64J4TRPD#?A"`A7A?E=V;H^5^.-Z +M6;9:`B>RV7/ZWMF<\GFAL7@"0.W=<"A9CT-E%!,43[^,@)S]'FB,H9"!IZQH +MH1S!EM)#>P@B%+J@H=P:#%`(H!&-^E\:4(U/%V"IIP!0VP4,!8N3#&7E(4*% +M)0E+QR`H8:"X`T;-Y?41POCSN=O=DYGW<]63['4"AD9$])!#N0$%Y%49R1H] +M6*"?%YJ!HJ9E39'VPG`9;O/EH#D8L95,.A8F&DHX/>60794`1,M0S,&B"%^> +M[P>L"]1T,P1:P($'TD0"Y41OAU@4,@*&P>W@],!U&R'%CMFQ:HY5&CU!-N[: +M:`]:H6HH)F;`H[WL[.Z[\^9ZZ[8.CHFX(ZCAF4T3E@H1&D:F)3>UXW%).3O] +MRT3:,VU>!F(A42\]S]WA?`OT/W'0ZPB&3&:)2,V*VM25/IZA($,I-Z0HI"08 +M-.R5&JC:35G(%UE`@`EGDP"BC`(HW^#4+@4(!-L%"/8+F@V"(0E!$*(9H2M" +MHPD"AN&[" +MHYN6'+C&PP%&S;A:II;HDMNP,&X`2"C@&373*.8%#/6+@=`;!$.`>9,UQMY*T*=9H'VFCSJY7!1 +MH?-G*%!;>7G+:^;0H7;MI8I6M-//XE"IS@R@H7E +MY\2C1W-"$VZCS`4,FYEC"$C)Q.UJUX'2_3P_3?C7Y81 +MP,^I,KDUEX*'2RG3Z1TR=K[S57UI`^G-6<@AIA:KW**=FLHRLF,>RE9I:;CV +M4C_OU2_?Z=CQ.71PKA'F+1J.K@V'#!L0F\Q=I##\/`0="-8S0ZE_`R/TQF'CHT4`W8<[TPTZU!0+[.[FW,VK1354`PU6:N@I$Y +M1)%S)K0='IB5-T]&)5RK!@S/9"_3E$4!NNR>F!0@9T1/(CV^`DDA/[34!0RQ +M%#(P6<\X#56L2%-:EHOT6QP7!X.0;!#X&/ASC>:8LLPWEBS*LKKB9-)5-!59 +M;6UU`W:U?"X$VMI5J-"JJM33NIPX&OL!*OGM;9XNSKN6C=V;OA4M:TIL8[8* +M%^J)980DA-L3E:P4-XO,2W1]3!ORDA(8FT"AA0@TH(;+`IJ,.ZW.(-U!^J\((H=5D)E'S]CYGC\FGS[,.=D#, +M(@6/J18(LK%TQ`B`(48]'1WW<%0RDAXIVF(Y#P3)VT/;XM?VC8[E<)6]2F'B^O^_4N,>`RGOW`@G[W'RU`?#%[PDA$DU(]^8A?^ +MDQ/MS"1D8>ER,>3H3/'H7"ZZZZZ8`23.A,Z?;PB*/NR+C\>IA[S;IO[X\L(U +M*8+6$!40?^>X!1K^-^)7O8>D0_%NKYCSHZS]:)( +M#/7AQ%$8&:1AS>,M=[MMCGM6%&D&#F`2`,8!0\5[J>,"A_;L#]"=R+AE/7]C +M8_=MCV(DO(2>>\_GL\JRX/G?045JAA`"?.G7@>0?@4#[;Q3V6/>^I+CR_SZ/ +M,QH'S_0_0J>U@>)/_$/5:-1JY7&7'UTX3B"P`2@J&]3PK1Y37045.-[&RU@C +MRZE!QRM1S7R%'CX/#[_R-&9Z3/H$A9[*ITAY+H87N/MQ^XRSN=4GN]8J"*9T +M4R?\IT_Z'OD_W1@',I\5%O.?>V!^_>KA%_VPS55;10&&]E*IK?KLI,/7_/>L +M^UO:R&]I_AK"3J+\;_ +M27^:>[[K:'0_IRO#AY]*0D\W_]V,W?7WO7[;][\4N]4J;74]OKR#I("ZF)[\D.+7[JW<1M_S+T\R07]^.GHN2N_V9W^UAH/?M6L(]G=;K8`^ +MNGF*OQV7S(P>`QF$K9K.8#_/:_`86%)Q#=W]L'PKE*TZ/Q/>W0X:[]Z!=MVAGZ3XE^R4@7Z<;!&Y2#\_ +MZ)!2!?*E\$B%&8XI)1DC5[YX0Q.D!U5!X>T_#9.<7W8\W8*\2(#[7OKPL/%P +MMCZ'U_NJ)T\='S>((D_7A^ELI=U(3,[P-9[+TT'PWDE'"$\!X=_\_).ROW^? +MC=.S-W,8.>T2CBVG&3T>S'H/R==M"JX)?-VOP7GM- +M?2\':;;5N;OB<3>9^20W4&3S:/LW:AARVH-G6TXL +MDV\!)L(@OU(`.H@8<80FQRK)$PE(T\YV=T-QZICXH'U:!W.%:XYY4M:_.D`5 +M6YB":A=D94"H`(#`W"$#%A,')0]-U:>&S":X@W%\BOH3^V+%,$"HQKE""HB- +M0A!C@V((WR@$O#G3>I#[/G[2P@U&5UR47BO1?WMZ5$;Y`0%V0?IONU7!O;OQ +M$->N4W#HL,OL_MU_I-KT.>\Z;3O>4:*LX#Q,&CM7">7Z$\6]4ZMY7I=NTYM% +MZ)IY48P2K*WEJ^2V-(B`/`IKS(?6MQ2E'=>U[*5&>8($I,!YRH*,FI%59T3G +MCT@9#11"[,IUXXTZJ=+@L^BO,#!,@8`B,,'D:[,(IRKJN!N(PCUN7ETFMNQ> +MT.M,<5L4#9FB*%?$W!57FM?/^ZBA@2T-7E"Z%F;\[:8XR0<6)_+$E*H!FF8. +M-XG<(8#8^U:S%08IU0*`6B3A$>0E<[+JG_>:@;>-`Y1E`&`8=(RYUE')]1`TYY(A:#RB0FG3$PE+)8S +MGU.@!,R[6^+K@E&1>47'U:5Y9^H"9N$SLJ5J?%:_%JV9"PQ"#C%I;C:?MTG) +M<_+^*U#T[J#O`$?NA$H`J5@CT><;M?J"+89:J5'/N15EU7F7>F1"I0/G+">Y +M3+-@8%+J^"D)LAGHE1:IW4%D>L70=!S'KQZ=T/&:X3,<[QS#1;Q0:L.Y4(WR +MIS8('-XK,_=EA`C,5^$HZS9@[X!)(&TP;5L0+F9IIL:86^R:&;<$8IY<9"=$ +M980D2B%BWIQ8MF1**D]I;;CK69[X^A0WPLO@0K_*(X]F;<'PTXE7 +M=W36:V(H)-CY_U'(8WEH]4NH>1WYRQ+BR@4% +M$1U.K,)S+4!]61]+Q!Q];=1<:0H&&9F^&`@320!JS8'6STZ[:=E*IZ;&BDC7 +M0Z/7-5O>MY:IK*BM/5>;X56^9&U^#42.H)OFI54HV1)`TJC7_B33GAVXJ]7O +M;?1"OI([IPP,[MV,/M;SJ$X)F]1/8&A&510:&ID)5D![*U)9=_1^5X(."9$3 +MAKAD3Q"G(58]/R>7K9'EWM'SQL4<(VSXPXG5&YKMU-_C3ND*S57\G4:0+B9, +MJ5UN=Z]5!0TZS\:=[S.J>H-)[0]6K0B-@S.BC387!M +M$S)!YJMA-!`JT[;'[Z^+^[0R-)::%H%GHKM=7G#8VW_]:.U^;<&A9&M/6UP?W""!BY%` +M#![EE,U-#7?W49=0ZXLS<=KZ:P-?Z3.X9G9?7W,9U.N2TLZ.@I-#Z@G7\7TV +MWHSA0AEJ*,1,`G^Y-'RV*AEKF,/?,:P^UZ&F<"J&#J0NMG0&<\V@F>9R#G`8 +M8"2$M4:2?X:&&W[K8\*=>CQHL8G]'<]@CN1F#'"X-ZO8\(=;X+BJT=]2+C:H +M4PL_D99">XRIU6^@S@B;6=;A"S6J!DD&;F8.@CY3\G*1J,;%1,\3U?C65;#&*>6OE! +MFVJJJM,IDRO),/K661%M4\6#1,IBT04O9HXN64;!]\FH*H#<46AK6%-'LCF9 +MR+1L24TY4/W_$$4`;*4R6-)=-<[!3VX70!7=GKY%5A/>5U.!KP4`/^X".'H%Q?;P',T8(,[(O1T\\K!%">*#TZ3L)AZ$/:3# +MN#L_''38,`!CF+]:(8[7>H+[G4L`8'8$'2;(;A-TB>Y-?`Z0SHGO<-&]>=?1 +M.%\D]#]-"\?6"0!S,$=]"\WZJKFWW+0,KN8@H5#,P4JO+2[I8+)K.GE;OZ'7 +MW6^-;6=X]"-%4;W@V9C.#*N(]M'VAWIC7&N_#'E;W?3^T'>]-2-X=9B^4;U\ +MT'*-(H-.>>8:,Q(3.V46OUD]TQT7D-PM+!C5]1&$A5_.0$FU.WL(&AB[^J(W +MC9_.U;3@%I%C#)%M;R_(%(ZBT`U7Z%$^2K53FF"->R$&0GTQ1HJCRC*ZNL1@ +M;F!0>FK6OK[E(YYHF^=GYS,F>9DC+2@>J2@N@/>\BL^-6Z=!H*-?OLIAZ_NK +MLDN"E,GB8]*I2!;=UH7JBS.6AF88^:>-ZOR=_N7A"M\B,YE=CKV?B(2%+;-$FTH0P@=0=)7(@D5HIYCOV$EW.MZP_:HB +M&,OED]W=BZGUITM#NKAC8,`1SO"V/<*,?4Q+AGF/V=O(_QZ9Q08'TG;(.%W> +M3QI"^R0+9F25\+`V81V6@)V/X&8HAATY-]YTO.V[=I1-2`X6_"5%@0JCBP0? +M!4@"!(7#-S*G*12#Q7ISP]OR(^?&&48%!EP>;\@B($4F'_XNY(IPH2!)0!** +` +end diff --git a/gdb/testsuite/gdb.base/tab-crash.exp b/gdb/testsuite/gdb.base/tab-crash.exp new file mode 100644 index 00000000000..91c45aa366d --- /dev/null +++ b/gdb/testsuite/gdb.base/tab-crash.exp @@ -0,0 +1,43 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2017 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if { ![istarget x86_64-*-* ] || ![is_lp64_target] } { + return +} + +standard_testfile + +# gcc-base-debuginfo-6.3.1-1.fc25.x86_64 +# /usr/lib/debug/lib64/libgcc_s-6.3.1-20161221.so.1.debug +# objcopy -R .debug_loc -R .debug_ranges -R .debug_info -R .debug_abbrev -R .debug_aranges -R .debug_str -R .comment ... + +set debugfilebz2uu ${srcdir}/${subdir}/${testfile}.bz2.uu +set debugfile [standard_output_file ${testfile}] + +if {[catch "system \"uudecode -o - ${debugfilebz2uu} | bzip2 -dc >${debugfile}\""] != 0} { + untested "failed uudecode or bzip2" + return -1 +} +file stat ${debugfile} debugfilestat +if {$debugfilestat(size) != 71936} { + untested "uudecode or bzip2 produce invalid result" + return -1 +} + +clean_restart ${debugfile} + +gdb_test "complete p si" "complete p si\r\np size_of_encoded_value" diff --git a/gdb/testsuite/gdb.base/tracefork-zombie.exp b/gdb/testsuite/gdb.base/tracefork-zombie.exp new file mode 100644 index 00000000000..5807040840d --- /dev/null +++ b/gdb/testsuite/gdb.base/tracefork-zombie.exp @@ -0,0 +1,75 @@ +# Copyright 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +# are we on a target board +if [is_remote target] then { + return 0 +} + +# Start the program running and then wait for a bit, to be sure +# that it can be attached to. + +gdb_exit +gdb_start +gdb_load sleep + +set gdb_pid [exp_pid -i [board_info host fileid]] +set test "identified the child GDB" +if {$gdb_pid != "" && $gdb_pid > 0} { + pass $test + verbose -log "Child GDB PID $gdb_pid" +} else { + fail $test +} + +set testpid [eval exec sleep 10 &] +exec sleep 2 + +set test "attach" +gdb_test_multiple "attach $testpid" "$test" { + -re "Attaching to program.*`?.*'?, process $testpid..*$gdb_prompt $" { + pass "$test" + } + -re "Attaching to program.*`?.*\.exe'?, process $testpid.*\[Switching to thread $testpid\..*\].*$gdb_prompt $" { + # Response expected on Cygwin + pass "$test" + } +} + +# Some time to let GDB spawn its testing child. +exec sleep 2 + +set found none +foreach procpid [glob -directory /proc -type d {[0-9]*}] { + if {[catch {open $procpid/status} statusfi]} { + continue + } + set status [read $statusfi] + close $statusfi + if {1 + && [regexp -line {^Name:\tgdb$} $status] + && [regexp -line {^PPid:\t1$} $status] + && [regexp -line "^TracerPid:\t$gdb_pid$" $status]} { + set found $procpid + verbose -log "Found linux_test_for_tracefork zombie PID $procpid" + } +} +set test "linux_test_for_tracefork leaves no zombie" +if {$found eq {none}} { + pass $test +} else { + fail $test +} diff --git a/gdb/testsuite/gdb.base/unwind-leak.c b/gdb/testsuite/gdb.base/unwind-leak.c new file mode 100644 index 00000000000..58e34fb2647 --- /dev/null +++ b/gdb/testsuite/gdb.base/unwind-leak.c @@ -0,0 +1,29 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +#include + +int main() +{ + for (;;) + alarm (0); + return 0; +} diff --git a/gdb/testsuite/gdb.base/unwind-leak.exp b/gdb/testsuite/gdb.base/unwind-leak.exp new file mode 100644 index 00000000000..098962a57c0 --- /dev/null +++ b/gdb/testsuite/gdb.base/unwind-leak.exp @@ -0,0 +1,83 @@ +# Copyright 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +set testfile unwind-leak +set srcfile ${testfile}.c +set shfile [standard_output_file ${testfile}-gdb.sh] +set binfile [standard_output_file ${testfile}] +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +# Get things started. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +set pid [exp_pid -i [board_info host fileid]] + +# For C programs, "start" should stop in main(). + +gdb_test "start" \ + "main \\(\\) at .*$srcfile.*" \ + "start" + +set loc [gdb_get_line_number "alarm"] +gdb_breakpoint $loc + +proc memory_get {} { + global pid + set fd [open "/proc/$pid/statm"] + gets $fd line + close $fd + # number of pages of data/stack + scan $line "%*d%*d%*d%*d%*d%d" drs + return $drs +} + +set cycles 100 +# For 100 cycles it was 1308: from = 363 KB, to = 1671 KB +set permit_kb 100 +verbose -log "cycles = $cycles, permit_kb = $permit_kb" + +set fail 0 +set test "breakpoint stop/continue cycles" +for {set i $cycles} {$i > 0} {set i [expr {$i - 1}]} { + gdb_test_multiple "continue" $test { + -re "Breakpoint 2, main .*alarm .*.*${gdb_prompt} $" { + } + -re "Segmentation fault" { + fail $test + set i 0 + set fail 1 + } + } + if ![info exists from] { + set from [memory_get] + } +} +set to [memory_get] +if {!$fail} { + verbose -log "from = $from KB, to = $to KB" + if {$from > 0 && $to > 10 && $to < $from + $permit_kb} { + pass $test + } else { + fail $test + } +} diff --git a/gdb/testsuite/gdb.base/vla-frame.c b/gdb/testsuite/gdb.base/vla-frame.c new file mode 100644 index 00000000000..5750f68b3d0 --- /dev/null +++ b/gdb/testsuite/gdb.base/vla-frame.c @@ -0,0 +1,31 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2011 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 . */ + +#include + +int +main (int argc, char **argv) +{ + char s[2 + argc]; + void (*f) (char *) = 0; + + memset (s, 0, sizeof (s)); + s[0] = 'X'; + + f (s); + return 0; +} diff --git a/gdb/testsuite/gdb.base/vla-frame.exp b/gdb/testsuite/gdb.base/vla-frame.exp new file mode 100644 index 00000000000..47736c7625d --- /dev/null +++ b/gdb/testsuite/gdb.base/vla-frame.exp @@ -0,0 +1,38 @@ +# Copyright 2011 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 . + +set testfile vla-frame +set executable ${testfile} + +if { [prepare_for_testing ${testfile}.exp ${executable}] } { + return -1 +} + +if ![runto_main] { + return -1 +} + +set test "continue" +gdb_test_multiple $test $test { + -re "Continuing\\.\r\n\r\nProgram received signal SIGSEGV, Segmentation fault\\.\r\n0x0+ in \\?\\? \\(\\)\r\n$gdb_prompt $" { + pass $test + } + -re "\r\n$gdb_prompt $" { + untested ${testfile}.exp + return + } +} + +gdb_test "bt full" "\r\n +s = \"X\\\\000\"\r\n.*" diff --git a/gdb/testsuite/gdb.base/vla-overflow.c b/gdb/testsuite/gdb.base/vla-overflow.c new file mode 100644 index 00000000000..c5d5ee0bb93 --- /dev/null +++ b/gdb/testsuite/gdb.base/vla-overflow.c @@ -0,0 +1,30 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008 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 . */ + +#include + +int +main (int argc, char **argv) +{ + int array[argc]; + + array[0] = array[0]; + + abort (); + + return 0; +} diff --git a/gdb/testsuite/gdb.base/vla-overflow.exp b/gdb/testsuite/gdb.base/vla-overflow.exp new file mode 100644 index 00000000000..43a5825979d --- /dev/null +++ b/gdb/testsuite/gdb.base/vla-overflow.exp @@ -0,0 +1,109 @@ +# Copyright 2008 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 . + +# We could crash in: +# #0 block_linkage_function (bl=0x0) at ../../gdb/block.c:69 +# #1 in dwarf_block_get_frame_base (...) at ../../gdb/dwarf2block.c:97 +# 97 framefunc = block_linkage_function (get_frame_block (frame, NULL)); +# #2 in execute_stack_op (...) at ../../gdb/dwarf2expr.c:496 +# #3 in dwarf_block_exec_core () at ../../gdb/dwarf2block.c:156 +# #4 dwarf_block_exec (...) at ../../gdb/dwarf2block.c:206 +# #5 in range_type_count_bound_internal (...) at ../../gdb/gdbtypes.c:1430 +# #6 in create_array_type (...) at ../../gdb/gdbtypes.c:840 +# ... +# #21 in psymtab_to_symtab (...) at ../../gdb/symfile.c:292 +# ... +# #29 in backtrace_command_1 () at ../../gdb/stack.c:1273 + +set testfile vla-overflow +set shfile [standard_output_file ${testfile}-gdb.sh] +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +set f [open "|getconf PAGESIZE" "r"] +gets $f pagesize +close $f + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +set pid_of_gdb [exp_pid -i [board_info host fileid]] + +if { [runto_main] < 0 } { + untested vla-overflow + return -1 +} + +# Get the GDB memory size when we stay at main. + +proc memory_v_pages_get {} { + global pid_of_gdb pagesize + set fd [open "/proc/$pid_of_gdb/statm"] + gets $fd line + close $fd + # number of pages of virtual memory + scan $line "%d" drs + return $drs +} + +set pages_found [memory_v_pages_get] + +# s390x with glibc-debuginfo.s390x installed used approx. 16MB. +set mb_reserve 40 +verbose -log "pages_found = $pages_found, mb_reserve = $mb_reserve" +set kb_found [expr $pages_found * $pagesize / 1024] +set kb_permit [expr $kb_found + 1 * 1024 + $mb_reserve * 1024] +verbose -log "kb_found = $kb_found, kb_permit = $kb_permit" + +# Create the ulimit wrapper. +set f [open $shfile "w"] +puts $f "#! /bin/sh" +puts $f "ulimit -v $kb_permit" +puts $f "exec $GDB \"\$@\"" +close $f +remote_exec host "chmod +x $shfile" + +gdb_exit +set GDBold $GDB +set GDB "$shfile" +gdb_start +set GDB $GDBold + +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +set pid_of_gdb [exp_pid -i [board_info host fileid]] + +# Check the size again after the second run. +# We must not stop in main as it would cache `array' and never crash later. + +gdb_run_cmd + +verbose -log "kb_found before abort() = [expr [memory_v_pages_get] * $pagesize / 1024]" + +gdb_test "" "Program received signal SIGABRT, Aborted..*" "Enter abort()" + +verbose -log "kb_found in abort() = [expr [memory_v_pages_get] * $pagesize / 1024]" + +# `abort' can get expressed as `*__GI_abort'. +gdb_test "bt" "in \[^ \]*abort \\(.* in main \\(.*" "Backtrace after abort()" + +verbose -log "kb_found in bt after abort() = [expr [memory_v_pages_get] * $pagesize / 1024]" diff --git a/gdb/testsuite/gdb.base/vla.c b/gdb/testsuite/gdb.base/vla.c new file mode 100644 index 00000000000..e1f3ed17801 --- /dev/null +++ b/gdb/testsuite/gdb.base/vla.c @@ -0,0 +1,55 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008 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 . */ + +#include + +void +marker (void) +{ +} + +void +bar (char *a, char *b, char *c, int size) +{ + memset (a, '1', size); + memset (b, '2', size); + memset (c, '3', 48); +} + +void +foo (int size) +{ + char temp1[size]; + char temp3[48]; + + temp1[size - 1] = '\0'; + { + char temp2[size]; + + bar (temp1, temp2, temp3, size); + + marker (); /* break-here */ + } +} + +int +main (void) +{ + foo (26); + foo (78); + return 0; +} diff --git a/gdb/testsuite/gdb.base/vla.exp b/gdb/testsuite/gdb.base/vla.exp new file mode 100644 index 00000000000..71fe6372727 --- /dev/null +++ b/gdb/testsuite/gdb.base/vla.exp @@ -0,0 +1,62 @@ +# Copyright 2008 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 . + +set testfile vla +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] { + untested vla + return -1 +} + +gdb_breakpoint [gdb_get_line_number "break-here"] + +gdb_continue_to_breakpoint "break-here" + +gdb_test "whatis temp1" "type = char \\\[26\\\]" "first: whatis temp1" +gdb_test "whatis temp2" "type = char \\\[26\\\]" "first: whatis temp2" +gdb_test "whatis temp3" "type = char \\\[48\\\]" "first: whatis temp3" + +gdb_test "ptype temp1" "type = char \\\[26\\\]" "first: ptype temp1" +gdb_test "ptype temp2" "type = char \\\[26\\\]" "first: ptype temp2" +gdb_test "ptype temp3" "type = char \\\[48\\\]" "first: ptype temp3" + +gdb_test "p temp1" " = '1' " "first: print temp1" +gdb_test "p temp2" " = '2' " "first: print temp2" +gdb_test "p temp3" " = '3' " "first: print temp3" + +gdb_continue_to_breakpoint "break-here" + +gdb_test "whatis temp1" "type = char \\\[78\\\]" "second: whatis temp1" +gdb_test "whatis temp2" "type = char \\\[78\\\]" "second: whatis temp2" +gdb_test "whatis temp3" "type = char \\\[48\\\]" "second: whatis temp3" + +gdb_test "ptype temp1" "type = char \\\[78\\\]" "second: ptype temp1" +gdb_test "ptype temp2" "type = char \\\[78\\\]" "second: ptype temp2" +gdb_test "ptype temp3" "type = char \\\[48\\\]" "second: ptype temp3" + +gdb_test "p temp1" " = '1' " "second: print temp1" +gdb_test "p temp2" " = '2' " "second: print temp2" +gdb_test "p temp3" " = '3' " "second: print temp3" diff --git a/gdb/testsuite/gdb.base/watchpoint-cond.c b/gdb/testsuite/gdb.base/watchpoint-cond.c new file mode 100644 index 00000000000..d4ec581946c --- /dev/null +++ b/gdb/testsuite/gdb.base/watchpoint-cond.c @@ -0,0 +1,31 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008 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 . + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +int +main (int argc, char **argv) +{ + static int i = 0; /* `static' to start initialized. */ + int j = 2; + + for (j = 0; j < 30; j++) + i = 30 - j; + + return 0; +} diff --git a/gdb/testsuite/gdb.base/watchpoint-cond.exp b/gdb/testsuite/gdb.base/watchpoint-cond.exp new file mode 100644 index 00000000000..31d5b602aaf --- /dev/null +++ b/gdb/testsuite/gdb.base/watchpoint-cond.exp @@ -0,0 +1,37 @@ +# Copyright 2008 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 . + +set testfile watchpoint-cond +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +# Get things started. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if { [runto_main] < 0 } { + untested watchpoint-cond + return -1 +} + +gdb_test "watch i if i < 20" "atchpoint \[0-9\]+: i" +gdb_test "cont" "atchpoint \[0-9\]+: i.*Old value = 20.*New value = 19.*" diff --git a/gdb/testsuite/gdb.base/watchpoint-during-step.c b/gdb/testsuite/gdb.base/watchpoint-during-step.c new file mode 100644 index 00000000000..107eae45a07 --- /dev/null +++ b/gdb/testsuite/gdb.base/watchpoint-during-step.c @@ -0,0 +1,30 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +static int var; + +int main() +{ + var = 1; + var = 2; + var = 3; + return 0; +} diff --git a/gdb/testsuite/gdb.base/watchpoint-during-step.exp b/gdb/testsuite/gdb.base/watchpoint-during-step.exp new file mode 100644 index 00000000000..12ba99f1a9f --- /dev/null +++ b/gdb/testsuite/gdb.base/watchpoint-during-step.exp @@ -0,0 +1,44 @@ +# Copyright 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +set testfile watchpoint-during-step +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +# Get things started. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +runto_main + +gdb_breakpoint [gdb_get_line_number "var = 2"] +gdb_continue_to_breakpoint "Find the first var set" + +gdb_test "step" ".*var = 3;" "Step to the next var set" + +gdb_test "watch var" "atchpoint .*: var" "Set the watchpoint" + +# Here is the target point. Be careful to not have breakpoint set on the line +# we step from as in this case it is a valid upstream KFAIL gdb/38 + +gdb_test "step" ".*Old value = 2.*New value = 3.*" "Catch the watchpoint" diff --git a/gdb/testsuite/gdb.base/watchpoint-hw-before-run.exp b/gdb/testsuite/gdb.base/watchpoint-hw-before-run.exp new file mode 100644 index 00000000000..4ce9997e4a4 --- /dev/null +++ b/gdb/testsuite/gdb.base/watchpoint-hw-before-run.exp @@ -0,0 +1,40 @@ +# Copyright 2009, 2010 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 . + +# Arch not supporting hw watchpoints does not imply no_hardware_watchpoints set. +if {(![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"] + && ![istarget "ia64-*-*"]) + || [target_info exists gdb,no_hardware_watchpoints]} then { + verbose "Skipping watchpoint-hw-before-run test." + return +} + +set test watchpoint-hw-before-run +set srcfile watchpoint-hw-hit-once.c +if { [prepare_for_testing ${test}.exp ${test} ${srcfile}] } { + return -1 +} + +gdb_test "rwatch watchee" "ardware read watchpoint 1: watchee" + +# `runto_main' or `runto main' would delete the watchpoint created above. + +if { [gdb_start_cmd] < 0 } { + untested start + return -1 +} +gdb_test "" "main .* at .*" "start" + +gdb_test "continue" "Continuing.\r\n\r\nHardware read watchpoint \[0-9\]+: watchee\r\n\r\nValue = 0\r\n.*" diff --git a/gdb/testsuite/gdb.cp/b146835.cc b/gdb/testsuite/gdb.cp/b146835.cc new file mode 100644 index 00000000000..4161d523f5d --- /dev/null +++ b/gdb/testsuite/gdb.cp/b146835.cc @@ -0,0 +1,32 @@ +#include "b146835.h" +#include + +class F : public C { + +protected: + + virtual void funcA (unsigned long a, B *b); + virtual void funcB (E *e); + virtual void funcC (unsigned long x, bool y); + + char *s1, *s2; + bool b1; + int k; + +public: + void foo() { + std::cout << "foo" << std::endl; + } +}; + + +void F::funcA (unsigned long a, B *b) {} +void F::funcB (E *e) {} +void F::funcC (unsigned long x, bool y) {} + +int main() +{ + F f; + f.foo(); +} + diff --git a/gdb/testsuite/gdb.cp/b146835.exp b/gdb/testsuite/gdb.cp/b146835.exp new file mode 100644 index 00000000000..d03815bcff6 --- /dev/null +++ b/gdb/testsuite/gdb.cp/b146835.exp @@ -0,0 +1,47 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2005 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Check that GDB can properly print an inherited member variable +# (Bugzilla 146835) + +set testfile "b146835" +set srcfile ${testfile}.cc +set srcfile2 ${testfile}b.cc +set binfile [standard_output_file ${testfile}] +if {[gdb_compile "${srcdir}/${subdir}/${srcfile} ${srcdir}/${subdir}/${srcfile2}" "${binfile}" executable {debug c++}] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# +# Run to `main' where we begin our tests. +# + +if ![runto_main] then { + gdb_suppress_tests +} + +gdb_test "break 'F::foo()'" "" +gdb_continue_to_breakpoint "First line foo" + +# Verify that we can access the inherited member d +gdb_test "p d" " = \\(D \\*\\) *0x0" "Verify inherited member d accessible" diff --git a/gdb/testsuite/gdb.cp/b146835.h b/gdb/testsuite/gdb.cp/b146835.h new file mode 100644 index 00000000000..48df7a2935f --- /dev/null +++ b/gdb/testsuite/gdb.cp/b146835.h @@ -0,0 +1,36 @@ + +class A { + +protected: + + virtual void funcA (unsigned long a, class B *b) = 0; + virtual void funcB (class E *e) = 0; + virtual void funcC (unsigned long x, bool y) = 0; + + void funcD (class E *e, class D* d); + virtual void funcE (E *e, D *d); + virtual void funcF (unsigned long x, D *d); +}; + + +class C : public A { + +protected: + + int x; + class K *k; + class H *h; + + D *d; + + class W *w; + class N *n; + class L *l; + unsigned long *r; + +public: + + C(); + int z (char *s); + virtual ~C(); +}; diff --git a/gdb/testsuite/gdb.cp/b146835b.cc b/gdb/testsuite/gdb.cp/b146835b.cc new file mode 100644 index 00000000000..1853c1fa380 --- /dev/null +++ b/gdb/testsuite/gdb.cp/b146835b.cc @@ -0,0 +1,11 @@ +#include "b146835.h" + +C::C() { d = 0; x = 3; } + +int C::z (char *s) { return 0; } + +C::~C() {} + +void A::funcD (class E *e, class D *d) {} +void A::funcE (E *e, D *d) {} +void A::funcF (unsigned long x, D *d) {} diff --git a/gdb/testsuite/gdb.cp/constructortest.cc b/gdb/testsuite/gdb.cp/constructortest.cc new file mode 100644 index 00000000000..9ac8793e502 --- /dev/null +++ b/gdb/testsuite/gdb.cp/constructortest.cc @@ -0,0 +1,99 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2005 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +class A +{ + public: + A(); + ~A(); + int k; + private: + int x; +}; + +class B: public A +{ + public: + B(); + private: + int y; +}; + +/* C and D are for the $delete destructor. */ + +class C +{ + public: + C(); + virtual ~C(); + private: + int x; +}; + +class D: public C +{ + public: + D(); + private: + int y; +}; + +int main(int argc, char *argv[]) +{ + A* a = new A; + B* b = new B; + D* d = new D; + delete a; + delete b; + delete d; + return 0; +} + +A::A() /* Constructor A */ +{ + x = 1; /* First line A */ + k = 4; /* Second line A */ +} + +A::~A() /* Destructor A */ +{ + x = 3; /* First line ~A */ + k = 6; /* Second line ~A */ +} + +B::B() +{ + y = 2; /* First line B */ + k = 5; +} + +C::C() /* Constructor C */ +{ + x = 1; /* First line C */ +} + +C::~C() /* Destructor C */ +{ + x = 3; /* First line ~C */ +} + +D::D() +{ + y = 2; /* First line D */ +} diff --git a/gdb/testsuite/gdb.cp/constructortest.exp b/gdb/testsuite/gdb.cp/constructortest.exp new file mode 100644 index 00000000000..341f6c99ad5 --- /dev/null +++ b/gdb/testsuite/gdb.cp/constructortest.exp @@ -0,0 +1,130 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2005, 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Check that GDB can break at multiple forms of constructors. + +set testfile "constructortest" +set srcfile ${testfile}.cc +set binfile [standard_output_file ${testfile}] +# PIE is required for testing proper BREAKPOINT_RE_SET of the multiple-PC +# breakpoints. +if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++ "additional_flags=-fpie -pie"}] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# +# Run to `main' where we begin our tests. +# + +if ![runto_main] then { + gdb_suppress_tests +} + +# Break on the various forms of the A::A constructor. +# " (2 locations)" is displayed depending on G++ version. +gdb_test "break A\:\:A" "Breakpoint 2 at .*" "breaking on A::A" + +# Verify that we break for the A constructor two times +# Once for new A and once for new B +gdb_continue_to_breakpoint "First line A" +gdb_test "bt" "#0.*A.*#1.*main.*" "Verify in in-charge A::A" +gdb_continue_to_breakpoint "First line A" +gdb_test "bt" "#0.*A.*#1.*B.*#2.*main.*" "Verify in not-in-charge A::A" + +# Now do the same for destructors +gdb_test "break 'A::~A()'" "" + +# Verify that we break for the A destructor two times +# Once for delete a and once for delete b +gdb_continue_to_breakpoint "First line ~A" +gdb_test "bt" "#0.*~A.*#1.*main.*" "Verify in in-charge A::~A" +gdb_continue_to_breakpoint "First line ~A" +gdb_test "bt" "#0.*~A.*#1.*~B.*#2.*main.*" "Verify in not-in-charge A::~A" + + +# Verify that we can break by line number in a constructor and find +# both occurrences +runto_main +gdb_test "break 'A::A()'" "" "break in constructor A 2" +gdb_continue_to_breakpoint "First line A" +set second_line [gdb_get_line_number "Second line A"] +# " (2 locations)" is displayed depending on G++ version. +gdb_test "break $second_line" "Breakpoint .*, line $second_line\\..*" "break by line in constructor" +gdb_continue_to_breakpoint "Second line A" +gdb_test "bt" "#0.*A.*#1.*main.*" "Verify in in-charge A::A second line" +gdb_continue_to_breakpoint "Second line A" +gdb_test "bt" "#0.*A.*#1.*B.*#2.*main.*" "Verify in not-in-charge A::A second line" + +# Verify that we can break by line number in a destructor and find +# both occurrences +gdb_test "break 'A::~A()'" "" "break in constructor ~A 2" +gdb_continue_to_breakpoint "First line ~A" +set second_line_dtor [gdb_get_line_number "Second line ~A"] +# " (2 locations)" is displayed depending on G++ version. +gdb_test "break $second_line_dtor" "Breakpoint .*, line $second_line_dtor\\..*" "break by line in destructor" +gdb_continue_to_breakpoint "Second line ~A" +gdb_test "bt" "#0.*A.*#1.*main.*" "Verify in in-charge A::~A second line" +# FIXME: Analyse this case better. +gdb_continue_to_breakpoint "Second line ~A" +gdb_test "bt" "#0.*A.*#1.*main.*" "Verify in A::~A second line #2" +gdb_continue_to_breakpoint "Second line ~A" +gdb_test "bt" "#0.*A.*#1.*B.*#2.*main.*" "Verify in not-in-charge A::~A second line" + + +# Test now the $delete destructors. + +gdb_load ${binfile} +runto_main + +set first_line_dtor [gdb_get_line_number "First line ~C"] +set define_line_dtor [gdb_get_line_number "Destructor C"] +# Break on the various forms of the C::~C destructor +# " ([23] locations)" is displayed depending on G++ version. +gdb_test "break C\:\:~C" "Breakpoint .*: C::~C\\. \\(2 locations\\)" "breaking on C::~C" +gdb_continue_to_breakpoint "First line ~C" + +# Verify that we can break by line number in a destructor and find +# the $delete occurence + +gdb_load ${binfile} +delete_breakpoints + +# " (3 locations)" is displayed depending on G++ version. +gdb_test "break $first_line_dtor" "Breakpoint .*, line $first_line_dtor\\..*" "break by line in destructor" + +# Run to `main' where we begin our tests. +# Set the breakpoints first to test PIE multiple-PC BREAKPOINT_RE_SET. +# RUNTO_MAIN or RUNTO MAIN are not usable here as it runs DELETE_BREAKPOINTS. + +if ![gdb_breakpoint main] { + gdb_suppress_tests +} +gdb_run_cmd +set test "running to main" +gdb_test_multiple "" $test { + -re "Breakpoint \[0-9\]*, main .*$gdb_prompt $" { + pass $test + } +} + +gdb_continue_to_breakpoint "First line ~C" diff --git a/gdb/testsuite/gdb.cp/cxxexec.cc b/gdb/testsuite/gdb.cp/cxxexec.cc new file mode 100644 index 00000000000..48fd63e9d3d --- /dev/null +++ b/gdb/testsuite/gdb.cp/cxxexec.cc @@ -0,0 +1,25 @@ +/* This test script is part of GDB, the GNU debugger. + + Copyright 2010 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 . */ + +#include + +int +main() +{ + execlp ("true", "true", NULL); + return 1; +} diff --git a/gdb/testsuite/gdb.cp/cxxexec.exp b/gdb/testsuite/gdb.cp/cxxexec.exp new file mode 100644 index 00000000000..c85dd0129d8 --- /dev/null +++ b/gdb/testsuite/gdb.cp/cxxexec.exp @@ -0,0 +1,51 @@ +# Copyright 2010 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 . + +if { [skip_cplus_tests] } { continue } + +set testfile cxxexec +if { [prepare_for_testing ${testfile}.exp ${testfile} ${testfile}.cc {c++ debug}] } { + return -1 +} + +runto_main + +# We could stop after `continue' again at `main'. +delete_breakpoints + +set test "p _Unwind_DebugHook" +gdb_test_multiple $test $test { + -re " = .* 0x\[0-9a-f\].*\r\n$gdb_prompt $" { + pass $test + } + -re "\r\nNo symbol .*\r\n$gdb_prompt $" { + xfail $test + untested ${testfile}.exp + return -1 + } +} + +set test continue +gdb_test_multiple $test $test { + -re "Cannot access memory at address 0x\[0-9a-f\]+\r\n$gdb_prompt $" { + fail $test + } + -re "\r\n$gdb_prompt $" { + pass $test + } +} + +# `info inferiors' can show on older GDBs. +gdb_test "info threads" "info threads" "program finished" diff --git a/gdb/testsuite/gdb.cp/gdb-rhbz1186476-internal-error-unqualified-name-re-set-main.cc b/gdb/testsuite/gdb.cp/gdb-rhbz1186476-internal-error-unqualified-name-re-set-main.cc new file mode 100644 index 00000000000..1c9f8eabc1d --- /dev/null +++ b/gdb/testsuite/gdb.cp/gdb-rhbz1186476-internal-error-unqualified-name-re-set-main.cc @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2015 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +int +main (int argc, char *argv[]) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.cp/gdb-rhbz1186476-internal-error-unqualified-name-re-set.cc b/gdb/testsuite/gdb.cp/gdb-rhbz1186476-internal-error-unqualified-name-re-set.cc new file mode 100644 index 00000000000..007854b0c46 --- /dev/null +++ b/gdb/testsuite/gdb.cp/gdb-rhbz1186476-internal-error-unqualified-name-re-set.cc @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2015 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +class C + { + public: + C () {} + C (int x) {} + }; + +C a; +C b (1); diff --git a/gdb/testsuite/gdb.cp/gdb-rhbz1186476-internal-error-unqualified-name-re-set.exp b/gdb/testsuite/gdb.cp/gdb-rhbz1186476-internal-error-unqualified-name-re-set.exp new file mode 100644 index 00000000000..19b25309692 --- /dev/null +++ b/gdb/testsuite/gdb.cp/gdb-rhbz1186476-internal-error-unqualified-name-re-set.exp @@ -0,0 +1,51 @@ +# Copyright 2015 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if { [skip_cplus_tests] } { continue } +if { [skip_shlib_tests] } { continue } +if { [is_remote target] } { continue } +if { [target_info exists use_gdb_stub] } { continue } + +set testfile gdb-rhbz1186476-internal-error-unqualified-name-re-set-main +set srcfile $testfile.cc +set executable $testfile +set binfile [standard_output_file $executable] + +set libtestfile gdb-rhbz1186476-internal-error-unqualified-name-re-set +set libsrcfile $libtestfile.cc +set sofile [standard_output_file lib$libtestfile.so] + +# Create and source the file that provides information about the compiler +# used to compile the test case. +if [get_compiler_info "c++"] { + return -1 +} + +if { [gdb_compile_shlib $srcdir/$subdir/$libsrcfile $sofile {debug c++ "additional_flags=-fPIC"}] != "" + || [gdb_compile $srcdir/$subdir/$srcfile $binfile executable [list additional_flags=-Wl,-rpath,[file dirname ${sofile}] "c++" shlib=${sofile} ]] != ""} { + untested $libtestfile.exp + return -1 +} + +clean_restart $executable + +gdb_test_no_output "set breakpoint pending on" +# gdb_breakpoint would print a failure because of some warning messages +gdb_test "break C::C" "Breakpoint $decimal \\(C::C\\) pending." + +#gdb_test "run" "warning: Found more than one location for breakpoint #$decimal; only the first location will be used.(\r\n)+Breakpoint $decimal, C::C.*" +gdb_test "run" + +gdb_test "info break" " in C::C\\(\\) at .* in C::C\\(int\\) at .*" diff --git a/gdb/testsuite/gdb.cp/gdb9593.cc b/gdb/testsuite/gdb.cp/gdb9593.cc new file mode 100644 index 00000000000..783c9622a8d --- /dev/null +++ b/gdb/testsuite/gdb.cp/gdb9593.cc @@ -0,0 +1,180 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008, 2009 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 . + */ +#include + +using namespace std; + +class NextOverThrowDerivates +{ + +public: + + + // Single throw an exception in this function. + void function1() + { + throw 20; + } + + // Throw an exception in another function. + void function2() + { + function1(); + } + + // Throw an exception in another function, but handle it + // locally. + void function3 () + { + { + try + { + function1 (); + } + catch (...) + { + cout << "Caught and handled function1 exception" << endl; + } + } + } + + void rethrow () + { + try + { + function1 (); + } + catch (...) + { + throw; + } + } + + void finish () + { + // We use this to test that a "finish" here does not end up in + // this frame, but in the one above. + try + { + function1 (); + } + catch (int x) + { + } + function1 (); // marker for until + } + + void until () + { + function1 (); + function1 (); // until here + } + +}; +NextOverThrowDerivates next_cases; + + +int main () +{ + try + { + next_cases.function1 (); + } + catch (...) + { + // Discard + } + + try + { + next_cases.function2 (); + } + catch (...) + { + // Discard + } + + try + { + // This is duplicated so we can next over one but step into + // another. + next_cases.function2 (); + } + catch (...) + { + // Discard + } + + next_cases.function3 (); + + try + { + next_cases.rethrow (); + } + catch (...) + { + // Discard + } + + try + { + // Another duplicate so we can test "finish". + next_cases.function2 (); + } + catch (...) + { + // Discard + } + + // Another test for "finish". + try + { + next_cases.finish (); + } + catch (...) + { + } + + // Test of "until". + try + { + next_cases.finish (); + } + catch (...) + { + } + + // Test of "until" with an argument. + try + { + next_cases.until (); + } + catch (...) + { + } + + // Test of "advance". + try + { + next_cases.until (); + } + catch (...) + { + } +} + diff --git a/gdb/testsuite/gdb.cp/gdb9593.exp b/gdb/testsuite/gdb.cp/gdb9593.exp new file mode 100644 index 00000000000..ef404244028 --- /dev/null +++ b/gdb/testsuite/gdb.cp/gdb9593.exp @@ -0,0 +1,182 @@ +# Copyright 2008, 2009 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 . + + +if $tracelevel then { + strace $tracelevel +} + +if { [skip_cplus_tests] } { continue } + +set testfile "gdb9593" +set srcfile ${testfile}.cc +set binfile [standard_output_file $testfile] + +# Create and source the file that provides information about the compiler +# used to compile the test case. +if [get_compiler_info "c++"] { + untested gdb9593.exp + return -1 +} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { + untested gdb9593.exp + return -1 +} + +# Some targets can't do function calls, so don't even bother with this +# test. +if [target_info exists gdb,cannot_call_functions] { + setup_xfail "*-*-*" 9593 + fail "This target can not call functions" + continue +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto_main] then { + perror "couldn't run to main" + continue +} + +# See whether we have the needed unwinder hooks. +set ok 1 +gdb_test_multiple "print _Unwind_DebugHook" "check for unwinder hook" { + -re "= .*_Unwind_DebugHook.*\r\n$gdb_prompt $" { + pass "check for unwinder hook" + } + -re "No symbol .* in current context.\r\n$gdb_prompt $" { + # Pass the test so we don't get bogus fails in the results. + pass "check for unwinder hook" + set ok 0 + } +} +if {!$ok} { + untested gdb9593.exp + return -1 +} + +# See http://sourceware.org/bugzilla/show_bug.cgi?id=9593 + +gdb_test "next" \ + ".*catch (...).*" \ + "next over a throw 1" + +gdb_test "next" \ + ".*next_cases.function2.*" \ + "next past catch 1" + +gdb_test "next" \ + ".*catch (...).*" \ + "next over a throw 2" + +gdb_test "next" \ + ".*next_cases.function2.*" \ + "next past catch 2" + +gdb_test "step" \ + ".*function1().*" \ + "step into function2 1" + +gdb_test "next" \ + ".*catch (...).*" \ + "next over a throw 3" + +gdb_test "next" \ + ".*next_cases.function3.*" \ + "next past catch 3" + +gdb_test "next" \ + ".*next_cases.rethrow.*" \ + "next over a throw 4" + +gdb_test "next" \ + ".*catch (...).*" \ + "next over a rethrow" + +gdb_test "next" \ + ".*next_cases.function2.*" \ + "next after a rethrow" + +gdb_test "step" \ + ".*function1().*" \ + "step into function2 2" + +gdb_test "finish" \ + ".*catch (...).*" \ + "finish 1" + +gdb_test "next" \ + ".*next_cases.finish ().*" \ + "next past catch 4" + +gdb_test "step" \ + ".*function1 ().*" \ + "step into finish method" + +gdb_test "finish" \ + ".*catch (...).*" \ + "finish 2" + +gdb_test "next" \ + ".*next_cases.finish ().*" \ + "next past catch 5" + +gdb_test "step" \ + ".*function1 ().*" \ + "step into finish, for until" + +gdb_test "until" \ + ".*function1 ().*" \ + "until with no argument 1" + +set line [gdb_get_line_number "marker for until" $testfile.cc] + +gdb_test "until $line" \ + ".*function1 ().*" \ + "next past catch 6" + +gdb_test "until" \ + ".*catch (...).*" \ + "until with no argument 2" + +set line [gdb_get_line_number "until here" $testfile.cc] + +gdb_test "next" \ + ".*next_cases.until ().*" \ + "next past catch 6" + +gdb_test "step" \ + ".*function1 ().*" \ + "step into until" + +gdb_test "until $line" \ + ".*catch (...).*" \ + "until-over-throw" + +gdb_test "next" \ + ".*next_cases.until ().*" \ + "next past catch 7" + +gdb_test "step" \ + ".*function1 ().*" \ + "step into until, for advance" + +gdb_test "advance $line" \ + ".*catch (...).*" \ + "advance-over-throw" diff --git a/gdb/testsuite/gdb.cp/namespace-nested-imports.cc b/gdb/testsuite/gdb.cp/namespace-nested-imports.cc new file mode 100644 index 00000000000..9723f874d94 --- /dev/null +++ b/gdb/testsuite/gdb.cp/namespace-nested-imports.cc @@ -0,0 +1,36 @@ +namespace A +{ + namespace B + { + int ab = 11; + } +} + +namespace C +{ + namespace D + { + using namespace A::B; + + int + second() + { + ab; + return 0; + } + } + + int + first() + { + //ab; + return D::second(); + } +} + +int +main() +{ + //ab; + return C::first(); +} diff --git a/gdb/testsuite/gdb.cp/namespace-nested-imports.exp b/gdb/testsuite/gdb.cp/namespace-nested-imports.exp new file mode 100644 index 00000000000..a606c43cb3d --- /dev/null +++ b/gdb/testsuite/gdb.cp/namespace-nested-imports.exp @@ -0,0 +1,50 @@ +# Copyright 2008 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 . + +set testfile namespace-nested-imports +set srcfile ${testfile}.cc +set binfile [standard_output_file ${testfile}] +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +# Get things started. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +############################################ +if ![runto_main] then { + perror "couldn't run to breakpoint main" + continue +} + +gdb_test "print ab" "No symbol .* in current context." + +############################################ +gdb_breakpoint C::first +gdb_continue_to_breakpoint "C::first" + +gdb_test "print ab" "No symbol .* in current context." +gdb_test "print C::D::ab" "= 11" + +############################################ +gdb_breakpoint C::D::second +gdb_continue_to_breakpoint "C::D::second" + +gdb_test "print ab" "= 11" diff --git a/gdb/testsuite/gdb.cp/namespace-no-imports.cc b/gdb/testsuite/gdb.cp/namespace-no-imports.cc new file mode 100644 index 00000000000..d1c68abaeac --- /dev/null +++ b/gdb/testsuite/gdb.cp/namespace-no-imports.cc @@ -0,0 +1,37 @@ + +namespace A +{ + int _a = 11; + + namespace B{ + + int ab = 22; + + namespace C{ + + int abc = 33; + + int second(){ + return 0; + } + + } + + int first(){ + _a; + ab; + C::abc; + return C::second(); + } + } +} + + +int +main() +{ + A::_a; + A::B::ab; + A::B::C::abc; + return A::B::first(); +} diff --git a/gdb/testsuite/gdb.cp/namespace-no-imports.exp b/gdb/testsuite/gdb.cp/namespace-no-imports.exp new file mode 100644 index 00000000000..a4ae9b3cd28 --- /dev/null +++ b/gdb/testsuite/gdb.cp/namespace-no-imports.exp @@ -0,0 +1,69 @@ +# Copyright 2008 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 . + +set testfile namespace-no-imports +set srcfile ${testfile}.cc +set binfile [standard_output_file ${testfile}] +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug c++}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +# Get things started. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +############################################ +if ![runto_main] then { + perror "couldn't run to breakpoint main" + continue +} + +gdb_test "print A::_a" "= 11" +gdb_test "print A::B::ab" "= 22" +gdb_test "print A::B::C::abc" "= 33" + +gdb_test "print _a" "No symbol .* in current context." +gdb_test "print ab" "No symbol .* in current context." +gdb_test "print abc" "No symbol .* in current context." + +############################################ +gdb_breakpoint A::B::first +gdb_continue_to_breakpoint "A::B::first" + +gdb_test "print A::_a" "= 11" +gdb_test "print A::B::ab" "= 22" +gdb_test "print A::B::C::abc" "= 33" + +gdb_test "print _a" "= 11" +gdb_test "print ab" "= 22" +gdb_test "print C::abc" "= 33" + +gdb_test "print abc" "No symbol .* in current context." + +############################################ +gdb_breakpoint A::B::C::second +gdb_continue_to_breakpoint "A::B::C::second" + +gdb_test "print A::_a" "= 11" +gdb_test "print A::B::ab" "= 22" +gdb_test "print A::B::C::abc" "= 33" + +gdb_test "print _a" "= 11" +gdb_test "print ab" "= 22" +gdb_test "print abc" "= 33" diff --git a/gdb/testsuite/gdb.cp/pr11734-1.cc b/gdb/testsuite/gdb.cp/pr11734-1.cc new file mode 100644 index 00000000000..f3480ce977b --- /dev/null +++ b/gdb/testsuite/gdb.cp/pr11734-1.cc @@ -0,0 +1,30 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2010 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 . + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@gnu.org */ + +#include "pr11734.h" + +int +main () +{ + pr11734 *p = new pr11734; + p->foo (); + return 0; +} + diff --git a/gdb/testsuite/gdb.cp/pr11734-2.cc b/gdb/testsuite/gdb.cp/pr11734-2.cc new file mode 100644 index 00000000000..dbebe8281a3 --- /dev/null +++ b/gdb/testsuite/gdb.cp/pr11734-2.cc @@ -0,0 +1,27 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2010 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 . + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@gnu.org */ + +#include "pr11734.h" + +void +pr11734::foo(void) +{ +} + diff --git a/gdb/testsuite/gdb.cp/pr11734-3.cc b/gdb/testsuite/gdb.cp/pr11734-3.cc new file mode 100644 index 00000000000..faaeffc9dde --- /dev/null +++ b/gdb/testsuite/gdb.cp/pr11734-3.cc @@ -0,0 +1,27 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2010 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 . + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@gnu.org */ + +#include "pr11734.h" + +void +pr11734::foo (int a) +{ +} + diff --git a/gdb/testsuite/gdb.cp/pr11734-4.cc b/gdb/testsuite/gdb.cp/pr11734-4.cc new file mode 100644 index 00000000000..6edf8110f12 --- /dev/null +++ b/gdb/testsuite/gdb.cp/pr11734-4.cc @@ -0,0 +1,27 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2010 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 . + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@gnu.org */ + +#include "pr11734.h" + +void +pr11734::foo (char *a) +{ +} + diff --git a/gdb/testsuite/gdb.cp/pr11734.exp b/gdb/testsuite/gdb.cp/pr11734.exp new file mode 100644 index 00000000000..e731d422f60 --- /dev/null +++ b/gdb/testsuite/gdb.cp/pr11734.exp @@ -0,0 +1,55 @@ +# Copyright 2010 Free Software Foundation, Inc. +# +# Contributed by Red Hat, originally written by Keith Seitz. +# +# 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 . + +# This file is part of the gdb testsuite. + +if { [skip_cplus_tests] } { continue } + +set testfile "pr11734" +set class $testfile + +set srcfiles {} +for {set i 1} {$i < 5} {incr i} { + lappend srcfiles $testfile-$i.cc +} + +prepare_for_testing pr11734 $testfile $srcfiles {c++ debug} + +if {![runto_main]} { + perror "couldn't run to breakpoint" + continue +} + +# An array holding the overload types for the method pr11734::foo. The +# first element is the overloaded method parameter. The second element +# is the expected source file number, e.g. "pr11734-?.cc". +array set tests { + "char*" 4 + "int" 3 + "" 2 +} + +# Test each overload instance twice: once quoted, once unquoted +foreach ovld [array names tests] { + set method "${class}::foo\($ovld\)" + set result "Breakpoint (\[0-9\]).*file .*/$class-$tests($ovld).*" + gdb_test "break $method" $result + gdb_test "break '$method'" $result +} + +gdb_exit +return 0 diff --git a/gdb/testsuite/gdb.cp/pr11734.h b/gdb/testsuite/gdb.cp/pr11734.h new file mode 100644 index 00000000000..7f6e72a6855 --- /dev/null +++ b/gdb/testsuite/gdb.cp/pr11734.h @@ -0,0 +1,28 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2010 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 . + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@gnu.org */ + +class pr11734 +{ + public: + void foo (); + void foo (int); + void foo (char *); +}; + diff --git a/gdb/testsuite/gdb.cp/pr12273.cc b/gdb/testsuite/gdb.cp/pr12273.cc new file mode 100644 index 00000000000..79dd7bad741 --- /dev/null +++ b/gdb/testsuite/gdb.cp/pr12273.cc @@ -0,0 +1,37 @@ +/* This test case is part of GDB, the GNU debugger. + + Copyright 2010 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 . */ + +template +class GDB +{ + public: + static int simple (void) { return 0; } + static int harder (T a) { return 1; } + template + static X even_harder (T a) { return static_cast (a); } + int operator == (GDB const& other) + { return 1; } +}; + +int main(int argc, char **argv) +{ + GDB a, b; + if (a == b) + return GDB::harder('a') + GDB::harder(3) + + GDB::even_harder ('a'); + return GDB::simple (); +} diff --git a/gdb/testsuite/gdb.cp/pr12273.exp b/gdb/testsuite/gdb.cp/pr12273.exp new file mode 100644 index 00000000000..9d71482742b --- /dev/null +++ b/gdb/testsuite/gdb.cp/pr12273.exp @@ -0,0 +1,46 @@ +# Copyright 2010 Free Software Foundation, Inc. +# +# Contributed by Red Hat, originally written by Keith Seitz. +# +# 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 . + +# This file is part of the gdb testsuite. + +if {[skip_cplus_tests]} { continue } + +set testfile "pr12273" +# Do NOT compile with debug flag. +prepare_for_testing pr12273 $testfile $testfile.cc {c++} + +gdb_test_no_output "set language c++" + +# A list of minimal symbol names to check. +# Note that GDB::even_harder(char) is quoted and includes +# the return type. This is necessary because this is the demangled name +# of the minimal symbol. +set min_syms [list \ + "GDB::operator ==" \ + "GDB::operator==(GDB const&)" \ + "GDB::harder(char)" \ + "GDB::harder(int)" \ + {"int GDB::even_harder(char)"} \ + "GDB::simple()"] + +foreach sym $min_syms { + if {[gdb_breakpoint $sym]} { + pass "setting breakpoint at $sym" + } +} + +gdb_exit diff --git a/gdb/testsuite/gdb.cp/vla-cxx.cc b/gdb/testsuite/gdb.cp/vla-cxx.cc index 04c09fd91d2..fb6e72161ef 100644 --- a/gdb/testsuite/gdb.cp/vla-cxx.cc +++ b/gdb/testsuite/gdb.cp/vla-cxx.cc @@ -15,6 +15,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +extern "C" { +#include +} + struct container; struct element @@ -40,11 +44,16 @@ int main(int argc, char **argv) typedef typeof (vla) &vlareftypedef; vlareftypedef vlaref2 (vla); container c; + typeof (vla) *ptr = NULL; + + // Before pointer assignment + ptr = &vla; for (int i = 0; i < z; ++i) vla[i] = 5 + 2 * i; // vlas_filled vla[0] = 2 * vla[0]; + return vla[2]; } diff --git a/gdb/testsuite/gdb.cp/vla-cxx.exp b/gdb/testsuite/gdb.cp/vla-cxx.exp index 70a7fdac190..084ef476c0f 100644 --- a/gdb/testsuite/gdb.cp/vla-cxx.exp +++ b/gdb/testsuite/gdb.cp/vla-cxx.exp @@ -23,6 +23,12 @@ if ![runto_main] { return -1 } +gdb_breakpoint [gdb_get_line_number "Before pointer assignment"] +gdb_continue_to_breakpoint "Before pointer assignment" +gdb_test "ptype ptr" "int \\(\\*\\)\\\[variable length\\\]" "ptype ptr, Before pointer assignment" +gdb_test "print ptr" "\\(int \\(\\*\\)\\\[variable length\\\]\\) 0x0" "print ptr, Before pointer assignment" +gdb_test "print *ptr" "Cannot access memory at address 0x0" "print *ptr, Before pointer assignment" + gdb_breakpoint [gdb_get_line_number "vlas_filled"] gdb_continue_to_breakpoint "vlas_filled" @@ -33,3 +39,6 @@ gdb_test "print vlaref" " = \\(int \\(&\\)\\\[3\\\]\\) @$hex: \\{5, 7, 9\\}" # bug being tested, it's better not to depend on the exact spelling. gdb_test "print vlaref2" " = \\(.*\\) @$hex: \\{5, 7, 9\\}" gdb_test "print c" " = \\{e = \\{c = @$hex\\}\\}" +gdb_test "ptype ptr" "int \\(\\*\\)\\\[3\\\]" +gdb_test "print ptr" "\\(int \\(\\*\\)\\\[3\\\]\\) $hex" +gdb_test "print *ptr" " = \\{5, 7, 9\\}" diff --git a/gdb/testsuite/gdb.dwarf2/dw2-aranges.S b/gdb/testsuite/gdb.dwarf2/dw2-aranges.S new file mode 100644 index 00000000000..d5b9ca5a3c6 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-aranges.S @@ -0,0 +1,140 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2004, 2007, 2008, 2009 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 . */ + +/* Test .debug_aranges containing zero address_size. */ + +/* Dummy function to provide debug information for. */ + + .text +.Lbegin_text1: + .globl main + .type main, %function +main: +.Lbegin_main: + .int 0 +.Lend_main: + .size main, .-main +.Lend_text1: + +/* Debug information */ + + .section .debug_info +.Lcu1_begin: + /* CU header */ + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */ +.Lcu1_start: + .2byte 2 /* DWARF Version */ + .4byte .Labbrev1_begin /* Offset into abbrev section */ + .byte 4 /* Pointer size */ + + /* CU die */ + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ + .4byte .Lend_text1 /* DW_AT_high_pc */ + .4byte .Lbegin_text1 /* DW_AT_low_pc */ + .ascii "file1.txt\0" /* DW_AT_name */ + .ascii "GNU C 3.3.3\0" /* DW_AT_producer */ + .byte 1 /* DW_AT_language (C) */ + + /* main */ + .uleb128 2 /* Abbrev: DW_TAG_subprogram */ + .byte 1 /* DW_AT_external */ + .byte 1 /* DW_AT_decl_file */ + .byte 2 /* DW_AT_decl_line */ + .ascii "main\0" /* DW_AT_name */ + .4byte .Ltype_int-.Lcu1_begin /* DW_AT_type */ + .4byte .Lbegin_main /* DW_AT_low_pc */ + .4byte .Lend_main /* DW_AT_high_pc */ + .byte 1 /* DW_AT_frame_base: length */ + .byte 0x55 /* DW_AT_frame_base: DW_OP_reg5 */ + +.Ltype_int: + .uleb128 3 /* Abbrev: DW_TAG_base_type */ + .ascii "int\0" /* DW_AT_name */ + .byte 4 /* DW_AT_byte_size */ + .byte 5 /* DW_AT_encoding */ + + .byte 0 /* End of children of CU */ + +.Lcu1_end: + +/* Abbrev table */ + .section .debug_abbrev +.Labbrev1_begin: + .uleb128 1 /* Abbrev code */ + .uleb128 0x11 /* DW_TAG_compile_unit */ + .byte 1 /* has_children */ + .uleb128 0x12 /* DW_AT_high_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .uleb128 0x11 /* DW_AT_low_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x25 /* DW_AT_producer */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x13 /* DW_AT_language */ + .uleb128 0xb /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 2 /* Abbrev code */ + .uleb128 0x2e /* DW_TAG_subprogram */ + .byte 0 /* has_children */ + .uleb128 0x3f /* DW_AT_external */ + .uleb128 0xc /* DW_FORM_flag */ + .uleb128 0x3a /* DW_AT_decl_file */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x3b /* DW_AT_decl_line */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x11 /* DW_AT_low_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .uleb128 0x12 /* DW_AT_high_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .uleb128 0x40 /* DW_AT_frame_base */ + .uleb128 0xa /* DW_FORM_block1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 3 /* Abbrev code */ + .uleb128 0x24 /* DW_TAG_base_type */ + .byte 0 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0xb /* DW_AT_byte_size */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x3e /* DW_AT_encoding */ + .uleb128 0xb /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + +/* aranges table */ + .section .debug_aranges + .long .Laranges_end - 1f +1: + .2byte 2 /* aranges Version */ + .4byte .Lcu1_begin - .debug_info /* Offset into .debug_info section */ + /* The GDB crasher is this zero value. */ + .byte 0 /* aranges address_size */ + .byte 0 /* aranges segment_size */ + +.Laranges_end: diff --git a/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp b/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp new file mode 100644 index 00000000000..f95bde4c358 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-aranges.exp @@ -0,0 +1,40 @@ +# Copyright 2004, 2005, 2007, 2008, 2009 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 . + +# Test .debug_aranges containing zero address_size. + +# This test can only be run on targets which support DWARF-2 and use gas. +# For now pick a sampling of likely targets. +if {![istarget *-*-linux*] + && ![istarget *-*-gnu*] + && ![istarget *-*-elf*] + && ![istarget *-*-openbsd*] + && ![istarget arm-*-eabi*] + && ![istarget powerpc-*-eabi*]} { + return 0 +} + +set testfile "dw2-aranges" +set srcfile ${testfile}.S +set binfile [standard_output_file ${testfile}] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {nodebug}] != "" } { + return -1 +} + +clean_restart $testfile + +# Failed gdb_load would abort the testcase execution earlier. +pass "file loaded" diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.S b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.S new file mode 100644 index 00000000000..aac3baad8a1 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.S @@ -0,0 +1,246 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2010 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 . */ + +/* Debug information */ + +/* We will `break *main' at the very first instruction. */ +#define main_length 1 + + .section .data +vardata: + /* See DW_OP_lit3 + 1 (0-based). */ + .string "seennotseen" + + .section .debug_info +.Lcu1_begin: + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */ +.Lcu1_start: + .2byte 2 /* DWARF version number */ + .4byte .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ + .byte 4 /* Pointer Size (in bytes) */ + + /* CU die */ + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ + .4byte .Lproducer /* DW_AT_producer */ + /* Use C++ to exploit a bug in parsing DW_AT_name "". */ + .byte 4 /* DW_AT_language (C++) - */ + .4byte main /* DW_AT_low_pc */ + .byte main_length /* DW_AT_high_pc */ + +.Larray_type: + .uleb128 2 /* Abbrev: DW_TAG_array_type */ + .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */ + + .uleb128 3 /* Abbrev: DW_TAG_subrange_type */ + .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */ + .byte 0 /* DW_AT_lower_bound */ + .4byte .Llen_var-.Lcu1_begin /* DW_AT_upper_bound */ + .byte 0 /* End of children of die */ + + /* DW_AT_upper_bound is referencing an optimized-out variable. */ +.Larrayb_type: + .uleb128 2 /* Abbrev: DW_TAG_array_type */ + .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */ + + .uleb128 3 /* Abbrev: DW_TAG_subrange_type */ + .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */ + .byte 0 /* DW_AT_lower_bound */ + .4byte .Llenb_var-.Lcu1_begin /* DW_AT_upper_bound */ + .byte 0 /* End of children of die */ + + /* DW_AT_upper_bound is referencing register. */ +.Larrayreg_type: + .uleb128 2 /* Abbrev: DW_TAG_array_type */ + .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */ + + .uleb128 8 /* Abbrev: DW_TAG_subrange_type with block */ + .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */ + .byte 0 /* DW_AT_lower_bound */ + .byte 2f - 1f /* DW_AT_upper_bound */ +1: .byte 0x50 /* DW_OP_reg0 */ +2: + .byte 0 /* End of children of die */ + +.Luint_type: + .uleb128 4 /* Abbrev: DW_TAG_base_type */ + .4byte .Luint_str /* DW_AT_name */ + .byte 4 /* DW_AT_byte_size */ + .byte 7 /* DW_AT_encoding */ + +.Lchar_type: + .uleb128 4 /* Abbrev: DW_TAG_base_type */ + .4byte .Lchar_str /* DW_AT_name */ + .byte 1 /* DW_AT_byte_size */ + .byte 6 /* DW_AT_encoding */ + +.Llen_var: + .uleb128 5 /* Abbrev: DW_TAG_variable artificial */ + .byte 1 /* DW_AT_artificial */ + .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */ + .4byte .Llen_loclist-.Lloclist /* DW_AT_location */ + + /* optimized-out variable for b_string. */ +.Llenb_var: + .uleb128 7 /* Abbrev: DW_TAG_variable artificial no DW_AT_location */ + .byte 1 /* DW_AT_artificial */ + .4byte .Luint_type-.Lcu1_begin /* DW_AT_type */ + + .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */ + .string "a_string" /* DW_AT_name */ + .4byte .Larray_type-.Lcu1_begin /* DW_AT_type */ + .byte 2f - 1f /* DW_AT_location */ +1: .byte 3 /* DW_OP_addr */ + .4byte vardata /* */ +2: + + /* DW_AT_upper_bound is referencing an optimized-out variable. */ + .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */ + .string "b_string" /* DW_AT_name */ + .4byte .Larrayb_type-.Lcu1_begin /* DW_AT_type */ + .byte 2f - 1f /* DW_AT_location */ +1: .byte 3 /* DW_OP_addr */ + .4byte vardata /* */ +2: + + /* DW_AT_upper_bound is referencing register. */ + .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */ + .string "reg_string" /* DW_AT_name */ + .4byte .Larrayreg_type-.Lcu1_begin /* DW_AT_type */ + .byte 2f - 1f /* DW_AT_location */ +1: .byte 3 /* DW_OP_addr */ + .4byte vardata /* */ +2: + + .byte 0 /* End of children of CU */ +.Lcu1_end: + + .section .debug_loc +.Lloclist: +.Llen_loclist: + .4byte 0 # Location list begin address + .4byte main_length # Location list end address + .value 2f-1f # Location expression size +1: .byte 0x33 # DW_OP_lit3 + .byte 0x9f # DW_OP_stack_value +2: + .quad 0x0 # Location list terminator begin (*.LLST2) + .quad 0x0 # Location list terminator end (*.LLST2) + + .section .debug_abbrev +.Ldebug_abbrev0: + .uleb128 1 /* Abbrev code */ + .uleb128 0x11 /* DW_TAG_compile_unit */ + .byte 0x1 /* has_children */ + .uleb128 0x25 /* DW_AT_producer */ + .uleb128 0xe /* DW_FORM_strp */ + .uleb128 0x13 /* DW_AT_language */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x11 /* DW_AT_low_pc */ + .uleb128 0x1 /* DW_FORM_addr */ + .uleb128 0x12 /* DW_AT_high_pc */ + .uleb128 0xb /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 2 /* Abbrev code */ + .uleb128 0x1 /* TAG: DW_TAG_array_type */ + .byte 0x1 /* DW_children_yes */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 3 /* Abbrev code */ + .uleb128 0x21 /* DW_TAG_subrange_type */ + .byte 0x0 /* no children */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x22 /* DW_AT_lower_bound */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x2f /* DW_AT_upper_bound */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 4 /* Abbrev code */ + .uleb128 0x24 /* DW_TAG_base_type */ + .byte 0x0 /* no_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0xe /* DW_FORM_strp */ + .uleb128 0xb /* DW_AT_byte_size */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x3e /* DW_AT_encoding */ + .uleb128 0xb /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 5 /* Abbrev code */ + .uleb128 0x34 /* DW_TAG_variable */ + .byte 0x0 /* no_children */ + .uleb128 0x34 /* DW_AT_artificial */ + .uleb128 0x0c /* DW_FORM_flag */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x02 /* DW_AT_location */ + .uleb128 0x06 /* DW_FORM_data4 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 6 /* Abbrev code */ + .uleb128 0x34 /* DW_TAG_variable */ + .byte 0x0 /* no_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x2 /* DW_AT_location */ + .uleb128 0xa /* DW_FORM_block1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 7 /* Abbrev code */ + .uleb128 0x34 /* DW_TAG_variable */ + .byte 0x0 /* no_children */ + .uleb128 0x34 /* DW_AT_artificial */ + .uleb128 0x0c /* DW_FORM_flag */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 8 /* Abbrev code */ + .uleb128 0x21 /* DW_TAG_subrange_type with block */ + .byte 0x0 /* no children */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x22 /* DW_AT_lower_bound */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x2f /* DW_AT_upper_bound */ + .uleb128 0xa /* DW_FORM_block1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .byte 0x0 /* Terminator */ + +/* String table */ + .section .debug_str +.Lproducer: + .string "GNU C 3.3.3" +.Lchar_str: + .string "char" +.Luint_str: + .string "unsigned int" diff --git a/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.exp b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.exp new file mode 100644 index 00000000000..39e69b470f3 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-bound-loclist.exp @@ -0,0 +1,66 @@ +# Copyright 2010 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 . + +# Test printing variable with dynamic bounds which reference a different +# (artificial in the GCC case) variable containing loclist as its location. +# This testcase uses value (not address) of the referenced variable: +# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43762 + +# This test can only be run on targets which support DWARF-2 and use gas. +# For now pick a sampling of likely targets. +if {![istarget *-*-linux*] + && ![istarget *-*-gnu*] + && ![istarget *-*-elf*] + && ![istarget *-*-openbsd*] + && ![istarget arm-*-eabi*] + && ![istarget powerpc-*-eabi*]} { + return 0 +} + +set testfile dw2-bound-loclist +if { [prepare_for_testing ${testfile}.exp ${testfile} [list ${testfile}.S main.c] {}] } { + return -1 +} + +# Verify it behaves at least as an unbound array without inferior. + +# FIXME: FSF GDB crashes due to !has_stack_frames (). +# But in practice that should not happen. +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43762 +#set test "p a_string" +#gdb_test_multiple $test $test { +# -re " = 0x\[0-9a-f\]+ \"seennotseen\"\r\n$gdb_prompt $" { +# pass $test +# } +# -re "No registers\\.\r\n$gdb_prompt $" { +# kfail "vlaregression" $test +# } +#} +# +#gdb_test "ptype a_string" {type = char \[variable length\]} + +# Not runto_main as dw2-bound-loclist.S handles only the first byte of main. +if ![runto "*main"] { + return -1 +} + +gdb_test "p a_string" { = "seen"} +gdb_test "ptype a_string" {type = char \[4\]} + +gdb_test "p b_string" { = (0x[0-9a-f]+ )?"seennotseen"} +gdb_test "ptype b_string" {type = char \[\]} + +# The register contains unpredictable value - the array size. +gdb_test "ptype reg_string" {type = char \[-?[0-9]+\]} diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno.c b/gdb/testsuite/gdb.dwarf2/dw2-errno.c new file mode 100644 index 00000000000..7bd10d09786 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-errno.c @@ -0,0 +1,28 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2005, 2007 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 . + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +#include + +int main() +{ + errno = 42; + + return 0; /* breakpoint */ +} diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno.exp b/gdb/testsuite/gdb.dwarf2/dw2-errno.exp new file mode 100644 index 00000000000..1f13cc13236 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-errno.exp @@ -0,0 +1,60 @@ +# Copyright 2007 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 . + +set testfile dw2-errno +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] + +proc prep {} { + global srcdir subdir binfile + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + runto_main + + gdb_breakpoint [gdb_get_line_number "breakpoint"] + gdb_continue_to_breakpoint "breakpoint" +} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "additional_flags=-g2"] != "" } { + untested "Couldn't compile test program" + return -1 +} +prep +gdb_test "print errno" ".* = 42" "errno with macros=N threads=N" + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "additional_flags=-g3"] != "" } { + untested "Couldn't compile test program" + return -1 +} +prep +gdb_test "print errno" ".* = 42" "errno with macros=Y threads=N" + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "additional_flags=-g2"] != "" } { + return -1 +} +prep +gdb_test "print errno" ".* = 42" "errno with macros=N threads=Y" + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "additional_flags=-g3"] != "" } { + return -1 +} +prep +gdb_test "print errno" ".* = 42" "errno with macros=Y threads=Y" + +# TODO: Test the error on resolving ERRNO with only libc loaded. +# Just how to find the current libc filename? diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno2.c b/gdb/testsuite/gdb.dwarf2/dw2-errno2.c new file mode 100644 index 00000000000..7bd10d09786 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-errno2.c @@ -0,0 +1,28 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2005, 2007 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 . + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +#include + +int main() +{ + errno = 42; + + return 0; /* breakpoint */ +} diff --git a/gdb/testsuite/gdb.dwarf2/dw2-errno2.exp b/gdb/testsuite/gdb.dwarf2/dw2-errno2.exp new file mode 100644 index 00000000000..0f6e66870b7 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-errno2.exp @@ -0,0 +1,71 @@ +# Copyright 2007 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 . + +set testfile dw2-errno2 +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] + +proc prep { message {do_xfail 0} } { with_test_prefix $message { + global srcdir subdir binfile variant + gdb_exit + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile}${variant} + + runto_main + + gdb_breakpoint [gdb_get_line_number "breakpoint"] + gdb_continue_to_breakpoint "breakpoint" + + gdb_test "gcore ${binfile}${variant}.core" "\r\nSaved corefile .*" "gcore $variant" + + gdb_test "print errno" ".* = 42" + + gdb_test "kill" ".*" "kill" {Kill the program being debugged\? \(y or n\) } "y" + gdb_test "core-file ${binfile}${variant}.core" "\r\nCore was generated by .*" "core-file" + if $do_xfail { + setup_xfail "*-*-*" + } + gdb_test "print (int) errno" ".* = 42" "print errno for core" +}} + +set variant g2thrN +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}${variant}" executable "additional_flags=-g2"] != "" } { + untested "Couldn't compile test program" + return -1 +} +prep "macros=N threads=N" 1 + +set variant g3thrN +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}${variant}" executable "additional_flags=-g3"] != "" } { + untested "Couldn't compile test program" + return -1 +} +prep "macros=Y threads=N" 1 + +set variant g2thrY +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}${variant}" executable "additional_flags=-g2"] != "" } { + return -1 +} +prep "macros=N threads=Y" + +set variant g3thrY +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}${variant}" executable "additional_flags=-g3"] != "" } { + return -1 +} +prep "macros=Y threads=Y" 1 + +# TODO: Test the error on resolving ERRNO with only libc loaded. +# Just how to find the current libc filename? diff --git a/gdb/testsuite/gdb.dwarf2/dw2-included.c b/gdb/testsuite/gdb.dwarf2/dw2-included.c new file mode 100644 index 00000000000..28e54fb932b --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-included.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2006 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +#include "dw2-included.h" + +int +main() +{ + return 0; +} diff --git a/gdb/testsuite/gdb.dwarf2/dw2-included.exp b/gdb/testsuite/gdb.dwarf2/dw2-included.exp new file mode 100644 index 00000000000..ce83ea50f0b --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-included.exp @@ -0,0 +1,47 @@ +# Copyright 2006 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Minimal DWARF-2 unit test + +# This test can only be run on targets which support DWARF-2. +# For now pick a sampling of likely targets. +if {![istarget *-*-linux*] + && ![istarget *-*-gnu*] + && ![istarget *-*-elf*] + && ![istarget *-*-openbsd*] + && ![istarget arm-*-eabi*] + && ![istarget powerpc-*-eabi*]} { + return 0 +} + +set testfile "dw2-included" +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +gdb_test "set listsize 1" "" +gdb_test "list integer" "int integer;\r" +gdb_test "ptype integer" "type = int\r" +# Path varies depending on the build location. +gdb_test "info variables integer" "\r\nFile \[^\r\n\]*/gdb.dwarf2/dw2-included.h:\r\n${decimal}:.*int integer;\r" diff --git a/gdb/testsuite/gdb.dwarf2/dw2-included.h b/gdb/testsuite/gdb.dwarf2/dw2-included.h new file mode 100644 index 00000000000..f31348ab4f3 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-included.h @@ -0,0 +1,20 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2006 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +int integer; diff --git a/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-func.S b/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-func.S new file mode 100644 index 00000000000..442c4d00a17 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-func.S @@ -0,0 +1,328 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008 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 . */ + +/* +#include + +void +func (void) +{ + int i; + + abort (); +} +*/ + .file "dw2-loclist-prelinked.c" + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .section .debug_line,"",@progbits +.Ldebug_line0: + .text +.Ltext0: +.globl func + .type func, @function +func: +.LFB2: + .file 1 "dw2-loclist-prelinked.c" + .loc 1 5 0 + pushl %ebp +.LCFI0: + movl %esp, %ebp +.LCFI1: + subl $24, %esp +.LCFI2: + .loc 1 8 0 + call abort +.LFE2: + .size func, .-func + .section .debug_frame,"",@progbits +.Lframe0: + .long .LECIE0-.LSCIE0 +.LSCIE0: + .long 0xffffffff + .byte 0x1 + .string "" + .uleb128 0x1 + .sleb128 -4 + .byte 0x8 + .byte 0xc + .uleb128 0x4 + .uleb128 0x4 + .byte 0x88 + .uleb128 0x1 + .align 4 +.LECIE0: +.LSFDE0: + .long .LEFDE0-.LASFDE0 +.LASFDE0: + .long .Lframe0 + .long .LFB2 + .long .LFE2-.LFB2 + .byte 0x4 + .long .LCFI0-.LFB2 + .byte 0xe + .uleb128 0x8 + .byte 0x85 + .uleb128 0x2 + .byte 0x4 + .long .LCFI1-.LCFI0 + .byte 0xd + .uleb128 0x5 + .align 4 +.LEFDE0: + .text +.Letext0: + .section .debug_loc,"",@progbits +.Ldebug_loc0: +.LLST0: + .long .LFB2-.Ltext0 + .long .LCFI0-.Ltext0 + .value 0x2 + .byte 0x74 + .sleb128 4 + .long .LCFI0-.Ltext0 + .long .LCFI1-.Ltext0 + .value 0x2 + .byte 0x74 + .sleb128 8 + .long .LCFI1-.Ltext0 + .long .LFE2-.Ltext0 + .value 0x2 + .byte 0x75 + .sleb128 8 + .long 0x0 + .long 0x0 + .section .debug_info + .long 0x94 + .value 0x2 + .long .Ldebug_abbrev0 + .byte 0x4 + .uleb128 0x1 + .long .LASF10 + .byte 0x1 + .long .LASF11 + .long .LASF12 + .long .Ltext0 + .long .Letext0 + .long .Ldebug_line0 + .uleb128 0x2 + .byte 0x4 + .byte 0x7 + .long .LASF0 + .uleb128 0x3 + .byte 0x4 + .byte 0x5 + .string "int" + .uleb128 0x2 + .byte 0x4 + .byte 0x5 + .long .LASF1 + .uleb128 0x2 + .byte 0x1 + .byte 0x8 + .long .LASF2 + .uleb128 0x2 + .byte 0x2 + .byte 0x7 + .long .LASF3 + .uleb128 0x2 + .byte 0x4 + .byte 0x7 + .long .LASF4 + .uleb128 0x2 + .byte 0x1 + .byte 0x6 + .long .LASF5 + .uleb128 0x2 + .byte 0x2 + .byte 0x5 + .long .LASF6 + .uleb128 0x2 + .byte 0x8 + .byte 0x5 + .long .LASF7 + .uleb128 0x2 + .byte 0x8 + .byte 0x7 + .long .LASF8 + .uleb128 0x4 + .byte 0x4 + .byte 0x7 + .uleb128 0x2 + .byte 0x1 + .byte 0x6 + .long .LASF9 + .uleb128 0x5 + .byte 0x1 + .long .LASF13 + .byte 0x1 + .byte 0x5 + .byte 0x1 + .long .LFB2 + .long .LFE2 + .long .LLST0 + .uleb128 0x6 + .string "i" + .byte 0x1 + .byte 0x6 + .long 0x2c + .byte 0x2 + .byte 0x91 + .sleb128 -12 + .byte 0x0 + .byte 0x0 + .section .debug_abbrev + .uleb128 0x1 + .uleb128 0x11 + .byte 0x1 + .uleb128 0x25 + .uleb128 0xe + .uleb128 0x13 + .uleb128 0xb + .uleb128 0x3 + .uleb128 0xe + .uleb128 0x1b + .uleb128 0xe + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x1 + .uleb128 0x10 + .uleb128 0x6 + .byte 0x0 + .byte 0x0 + .uleb128 0x2 + .uleb128 0x24 + .byte 0x0 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x3e + .uleb128 0xb + .uleb128 0x3 + .uleb128 0xe + .byte 0x0 + .byte 0x0 + .uleb128 0x3 + .uleb128 0x24 + .byte 0x0 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x3e + .uleb128 0xb + .uleb128 0x3 + .uleb128 0x8 + .byte 0x0 + .byte 0x0 + .uleb128 0x4 + .uleb128 0x24 + .byte 0x0 + .uleb128 0xb + .uleb128 0xb + .uleb128 0x3e + .uleb128 0xb + .byte 0x0 + .byte 0x0 + .uleb128 0x5 + .uleb128 0x2e + .byte 0x1 + .uleb128 0x3f + .uleb128 0xc + .uleb128 0x3 + .uleb128 0xe + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x27 + .uleb128 0xc + .uleb128 0x11 + .uleb128 0x1 + .uleb128 0x12 + .uleb128 0x1 + .uleb128 0x40 + .uleb128 0x6 + .byte 0x0 + .byte 0x0 + .uleb128 0x6 + .uleb128 0x34 + .byte 0x0 + .uleb128 0x3 + .uleb128 0x8 + .uleb128 0x3a + .uleb128 0xb + .uleb128 0x3b + .uleb128 0xb + .uleb128 0x49 + .uleb128 0x13 + .uleb128 0x2 + .uleb128 0xa + .byte 0x0 + .byte 0x0 + .byte 0x0 + .section .debug_pubnames,"",@progbits + .long 0x17 + .value 0x2 + .long .Ldebug_info0 + .long 0x98 + .long 0x75 + .string "func" + .long 0x0 + .section .debug_aranges,"",@progbits + .long 0x1c + .value 0x2 + .long .Ldebug_info0 + .byte 0x4 + .byte 0x0 + .value 0x0 + .value 0x0 + .long .Ltext0 + .long .Letext0-.Ltext0 + .long 0x0 + .long 0x0 + .section .debug_str,"MS",@progbits,1 +.LASF7: + .string "long long int" +.LASF0: + .string "unsigned int" +.LASF11: + .string "dw2-loclist-prelinked.c" +.LASF12: + .string "gdb-6.8/gdb/testsuite/gdb.dwarf2" +.LASF4: + .string "long unsigned int" +.LASF8: + .string "long long unsigned int" +.LASF2: + .string "unsigned char" +.LASF9: + .string "char" +.LASF1: + .string "long int" +.LASF3: + .string "short unsigned int" +.LASF5: + .string "signed char" +.LASF10: + .string "GNU C 4.3.2 20081007 (Red Hat 4.3.2-6)" +.LASF13: + .string "func" +.LASF6: + .string "short int" + .ident "GCC: (GNU) 4.3.2 20081007 (Red Hat 4.3.2-6)" + .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-main.c b/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-main.c new file mode 100644 index 00000000000..57386999cef --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-main.c @@ -0,0 +1,26 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2008 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 . */ + +/* dw2-loclist-prelinked-func.S */ +extern void func (void); + +int +main (void) +{ + func (); + return 0; +} diff --git a/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked.exp b/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked.exp new file mode 100644 index 00000000000..30d04733362 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked.exp @@ -0,0 +1,102 @@ +# Copyright 2008 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Minimal DWARF-2 unit test + +# This test can only be run on i386/x86_64 targets which support DWARF-2. +# For now pick a sampling of likely targets. +if {(![istarget *-*-linux*] + && ![istarget *-*-gnu*] + && ![istarget *-*-elf*] + && ![istarget *-*-openbsd*]) + || (![istarget "i?86-*-*"] && ![istarget "x86_64-*-*"])} { + return 0 +} + +set testfile "dw2-loclist-prelinked" +set srcfuncfile ${testfile}-func.S +set binsharedfuncfile [standard_output_file ${testfile}.so] +set srcmainfile ${testfile}-main.c +set binfile [standard_output_file ${testfile}] + +remote_exec build "rm -f ${binfile}" + +# get the value of gcc_compiled +if [get_compiler_info ${binfile}] { + return -1 +} + +# This test can only be run on gcc as we use additional_flags=FIXME +if {$gcc_compiled == 0} { + return 0 +} + +if { [gdb_compile_shlib "${srcdir}/${subdir}/${srcfuncfile}" "${binsharedfuncfile}" {debug additional_flags=-m32}] != "" } { + untested "Couldn't compile test library" + return -1 +} + +# The new separate debug info file will be stored in the .debug subdirectory. + +if [gdb_gnu_strip_debug ${binsharedfuncfile}] { + # check that you have a recent version of strip and objcopy installed + unsupported "cannot produce separate debug info files" + return -1 +} + +if {[catch "system \"/usr/sbin/prelink -qNR --no-exec-shield ${binsharedfuncfile}\""] != 0} { + # Maybe we don't have prelink. + return -1 +} + +if { [gdb_compile "${srcdir}/${subdir}/${srcmainfile}" \ + "${binfile}" executable [list debug additional_flags=-m32 shlib=${binsharedfuncfile}]] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +gdb_run_cmd + +gdb_test "" "Program received signal SIGABRT, Aborted..*" "Enter abort()" + +# Incorrect: +# #0 0x00110430 in __kernel_vsyscall () +# No symbol table info available. +# #1 0x003d44c0 in raise () from /lib/libc.so.6 +# No symbol table info available. +# #2 0x003d5e88 in abort () from /lib/libc.so.6 +# No symbol table info available. +# #3 0x44f10437 in func () at dw2-loclist-prelinked.c:8 +# i = Could not find the frame base for "func". + +# Correct: +# #0 0x00110430 in __kernel_vsyscall () +# No symbol table info available. +# #1 0x003d44c0 in raise () from /lib/libc.so.6 +# No symbol table info available. +# #2 0x003d5e88 in abort () from /lib/libc.so.6 +# No symbol table info available. +# #3 0x4ae36437 in func () at dw2-loclist-prelinked.c:8 +# i = 3827288 +# #4 0x0804851a in main () at ../../../gdb/testsuite/gdb.dwarf2/dw2-loclist-prelinked-main.c:24 +# No locals. + +# `abort' can get expressed as `*__GI_abort'. +gdb_test "bt full" "in \[^ \]*abort \\(.*in func \\(.*\r\n\[\t \]+i = -?\[0-9\].*in main \\(.*" "Backtrace after abort()" diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.c b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c new file mode 100644 index 00000000000..1f02d90eebc --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.c @@ -0,0 +1,42 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2004 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + + +/* The function `func1' traced into must have debug info on offset > 0; + (DW_UNSND (attr)). This is the reason of `func0' existence. */ + +void +func0(int a, int b) +{ +} + +/* `func1' being traced into must have some arguments to dump. */ + +void +func1(int a, int b) +{ + func0 (a,b); +} + +int +main(void) +{ + func1 (1, 2); + return 0; +} diff --git a/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp new file mode 100644 index 00000000000..9336e031577 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-stripped.exp @@ -0,0 +1,79 @@ +# Copyright 2006 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Minimal DWARF-2 unit test + +# This test can only be run on targets which support DWARF-2. +# For now pick a sampling of likely targets. +if {![istarget *-*-linux*] + && ![istarget *-*-gnu*] + && ![istarget *-*-elf*] + && ![istarget *-*-openbsd*] + && ![istarget arm-*-eabi*] + && ![istarget powerpc-*-eabi*]} { + return 0 +} + +set testfile "dw2-stripped" +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}.x] + +remote_exec build "rm -f ${binfile}" + +# get the value of gcc_compiled +if [get_compiler_info ${binfile}] { + return -1 +} + +# This test can only be run on gcc as we use additional_flags=FIXME +if {$gcc_compiled == 0} { + return 0 +} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-ggdb3}] != "" } { + return -1 +} + +remote_exec build "objcopy -R .debug_loc ${binfile}" +set strip_output [remote_exec build "objdump -h ${binfile}"] + +set test "stripping test file preservation" +if [ regexp ".debug_info " $strip_output] { + pass "$test (.debug_info preserved)" +} else { + fail "$test (.debug_info got also stripped)" +} + +set test "stripping test file functionality" +if [ regexp ".debug_loc " $strip_output] { + fail "$test (.debug_loc still present)" +} else { + pass "$test (.debug_loc stripped)" +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# For C programs, "start" should stop in main(). + +gdb_test "start" \ + ".*main \\(\\) at .*" \ + "start" +gdb_test "step" \ + "func.* \\(.*\\) at .*" \ + "step" diff --git a/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S new file mode 100644 index 00000000000..5fcdd849863 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.S @@ -0,0 +1,83 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 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 . */ + +/* Debug information */ + + .section .debug_info +.Lcu1_begin: + /* CU header */ + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */ +.Lcu1_start: + .2byte 2 /* DWARF Version */ + .4byte .Labbrev1_begin /* Offset into abbrev section */ + .byte 4 /* Pointer size */ + + /* CU die */ + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ + .ascii "dw2-struct-member-data-location.c\0" /* DW_AT_name */ + .ascii "GNU C 4.3.2\0" /* DW_AT_producer */ + .byte 1 /* DW_AT_language (C) */ + +.Ltype_uchar: + .uleb128 2 /* Abbrev: DW_TAG_structure_type */ + .ascii "some_struct\0" /* DW_AT_name */ + + .uleb128 3 /* Abbrev: DW_TAG_member */ + .ascii "field\0" /* DW_AT_name */ + .byte 0 /* DW_AT_data_member_location */ + + .byte 0 /* End of children of some_struct */ + + .byte 0 /* End of children of CU */ + +.Lcu1_end: + +/* Abbrev table */ + .section .debug_abbrev +.Labbrev1_begin: + .uleb128 1 /* Abbrev code */ + .uleb128 0x11 /* DW_TAG_compile_unit */ + .byte 1 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x25 /* DW_AT_producer */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x13 /* DW_AT_language */ + .uleb128 0xb /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 2 /* Abbrev code */ + .uleb128 0x13 /* DW_TAG_structure_type */ + .byte 1 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 3 /* Abbrev code */ + .uleb128 0x0d /* DW_TAG_member */ + .byte 0 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x38 /* DW_AT_data_member_location */ + .uleb128 0x0b /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ diff --git a/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp new file mode 100644 index 00000000000..bc35209fe59 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-struct-member-data-location.exp @@ -0,0 +1,37 @@ +# Copyright 2009 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 . + +# This test can only be run on targets which support DWARF-2 and use gas. +# For now pick a sampling of likely targets. +if {![istarget *-*-linux*] + && ![istarget *-*-gnu*] + && ![istarget *-*-elf*] + && ![istarget *-*-openbsd*] + && ![istarget arm-*-eabi*] + && ![istarget powerpc-*-eabi*]} { + return 0 +} + +set testfile "dw2-struct-member-data-location" +set srcfile ${testfile}.S +set binfile ${testfile}.x + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "[standard_output_file ${binfile}]" object {nodebug}] != "" } { + return -1 +} + +clean_restart $binfile + +gdb_test "ptype struct some_struct" "type = struct some_struct {\[\r\n \t\]*void field;\[\r\n \t\]*}" diff --git a/gdb/testsuite/gdb.dwarf2/dw2-subrange-no-type.S b/gdb/testsuite/gdb.dwarf2/dw2-subrange-no-type.S new file mode 100644 index 00000000000..9dbbf3c3e13 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-subrange-no-type.S @@ -0,0 +1,121 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2012 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 . */ + +/* Debug information */ + + .section .data +vardata: + .rept 129 + .ascii "x" + .endr + .ascii "UNSEEN\0" + + .section .debug_info +.Lcu1_begin: + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */ +.Lcu1_start: + .2byte 2 /* DWARF version number */ + .4byte .Ldebug_abbrev0 /* Offset Into Abbrev. Section */ + .byte 4 /* Pointer Size (in bytes) */ + + /* CU die */ + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ + .ascii "GNU C 3.3.3\0" /* DW_AT_producer */ + .byte 2 /* DW_AT_language (C) - */ + +.Larray_type: + .uleb128 2 /* Abbrev: DW_TAG_array_type */ + .4byte .Lchar_type-.Lcu1_begin /* DW_AT_type */ + + .uleb128 8 /* Abbrev: DW_TAG_subrange_type without DW_AT_type */ + .byte 0 /* DW_AT_lower_bound */ + .byte 128 /* DW_AT_upper_bound */ + + .byte 0 /* End of children of die */ + +.Lchar_type: + .uleb128 4 /* Abbrev: DW_TAG_base_type */ + .ascii "char\0" /* DW_AT_name */ + .byte 1 /* DW_AT_byte_size */ + .byte 6 /* DW_AT_encoding */ + + .uleb128 6 /* Abbrev: DW_TAG_variable DW_FORM_string */ + .ascii "notype_string\0" /* DW_AT_name */ + .4byte .Larray_type-.Lcu1_begin /* DW_AT_type */ + .byte 2f - 1f /* DW_AT_location */ +1: .byte 3 /* DW_OP_addr */ + .4byte vardata /* */ +2: + + .byte 0 /* End of children of CU */ +.Lcu1_end: + + .section .debug_abbrev +.Ldebug_abbrev0: + .uleb128 1 /* Abbrev code */ + .uleb128 0x11 /* DW_TAG_compile_unit */ + .byte 0x1 /* has_children */ + .uleb128 0x25 /* DW_AT_producer */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x13 /* DW_AT_language */ + .uleb128 0xb /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 2 /* Abbrev code */ + .uleb128 0x1 /* TAG: DW_TAG_array_type */ + .byte 0x1 /* DW_children_yes */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 4 /* Abbrev code */ + .uleb128 0x24 /* DW_TAG_base_type */ + .byte 0x0 /* no_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0xb /* DW_AT_byte_size */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x3e /* DW_AT_encoding */ + .uleb128 0xb /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 6 /* Abbrev code */ + .uleb128 0x34 /* DW_TAG_variable */ + .byte 0x0 /* no_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x2 /* DW_AT_location */ + .uleb128 0xa /* DW_FORM_block1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 8 /* Abbrev code */ + .uleb128 0x21 /* DW_TAG_subrange_type without DW_AT_type */ + .byte 0x0 /* no children */ + .uleb128 0x22 /* DW_AT_lower_bound */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x2f /* DW_AT_upper_bound */ + .uleb128 0xb /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .byte 0x0 /* Terminator */ diff --git a/gdb/testsuite/gdb.dwarf2/dw2-subrange-no-type.exp b/gdb/testsuite/gdb.dwarf2/dw2-subrange-no-type.exp new file mode 100644 index 00000000000..cec673cd399 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/dw2-subrange-no-type.exp @@ -0,0 +1,39 @@ +# Copyright 2012 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 . +load_lib dwarf.exp + +# https://bugzilla.redhat.com/show_bug.cgi?id=806920 +# read_subrange_type reinitialization +# of BASE_TYPE was done too late, it affects DW_TAG_subrange_type without +# specified DW_AT_type, present only in XLF produced code. + +# This test can only be run on targets which support DWARF-2 and use gas. +if {![dwarf2_support]} { + return 0 +} + +set testfile dw2-subrange-no-type +set srcfile ${testfile}.S +set executable ${testfile}.x +set binfile [standard_output_file ${executable}] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {}] != "" } { + return -1 +} + +clean_restart $executable + +gdb_test "ptype notype_string" {type = char \[129\]} +gdb_test "p notype_string" " = 'x' " diff --git a/gdb/testsuite/gdb.dwarf2/rh-dwarf4-x86_64.S b/gdb/testsuite/gdb.dwarf2/rh-dwarf4-x86_64.S new file mode 100644 index 00000000000..48b1bbf3e19 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/rh-dwarf4-x86_64.S @@ -0,0 +1,167 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2010 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 . */ + + .file "rh-dwarf4-x86_64.c" + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .section .debug_line,"",@progbits +.Ldebug_line0: + .text +.Ltext0: +.globl main + .type main, @function +main: +.LFB0: + .file 1 "gdb.dwarf2/rh-dwarf4-x86_64.c" + # gdb.dwarf2/rh-dwarf4-x86_64.c:20 + .loc 1 20 0 + .cfi_startproc + # basic block 2 + pushq %rbp + .cfi_def_cfa_offset 16 + movq %rsp, %rbp + .cfi_offset 6, -16 + .cfi_def_cfa_register 6 + # gdb.dwarf2/rh-dwarf4-x86_64.c:21 + .loc 1 21 0 + movl $0, %eax + # gdb.dwarf2/rh-dwarf4-x86_64.c:22 + .loc 1 22 0 + leave + .cfi_def_cfa 7, 8 + ret + .cfi_endproc +.LFE0: + .size main, .-main +.Letext0: + .section .debug_info + .long 0x4e # Length of Compilation Unit Info + .value 0x4 # DWARF version number + .long .Ldebug_abbrev0 # Offset Into Abbrev. Section + .byte 0x8 # Pointer Size (in bytes) + .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit) + .long .LASF0 # DW_AT_producer: "GNU C 4.4.4 20100503 (Red Hat 4.4.4-2)" + .byte 0x1 # DW_AT_language + .long .LASF1 # DW_AT_name: "gdb.dwarf2/rh-dwarf4-x86_64.c" + .long .LASF2 # DW_AT_comp_dir + .quad .Ltext0 # DW_AT_low_pc + .quad .Letext0 # DW_AT_high_pc + .long .Ldebug_line0 # DW_AT_stmt_list + .uleb128 0x2 # (DIE (0x2d) DW_TAG_subprogram) + # DW_AT_external + .long .LASF3 # DW_AT_name: "main" + .byte 0x1 # DW_AT_decl_file (gdb.dwarf2/rh-dwarf4-x86_64.c) + .byte 0x13 # DW_AT_decl_line + # DW_AT_prototyped + .long 0x4a # DW_AT_type + .quad .LFB0 # DW_AT_low_pc + .quad .LFE0 # DW_AT_high_pc + .uleb128 0x1 # DW_AT_frame_base + .byte 0x9c # DW_OP_call_frame_cfa + .uleb128 0x3 # (DIE (0x4a) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x5 # DW_AT_encoding + .ascii "int\0" # DW_AT_name + .byte 0x0 # end of children of DIE 0xb + .section .debug_abbrev + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x10 # (DW_AT_stmt_list) + .uleb128 0x17 # (DW_FORM_sec_offset) + .byte 0x0 + .byte 0x0 + .uleb128 0x2 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x0 # DW_children_no + .uleb128 0x3f # (DW_AT_external) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x27 # (DW_AT_prototyped) + .uleb128 0x19 # (DW_FORM_flag_present) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x18 # (DW_FORM_exprloc) + .byte 0x0 + .byte 0x0 + .uleb128 0x3 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0x0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .byte 0x0 + .byte 0x0 + .byte 0x0 + .section .debug_pubnames,"",@progbits + .long 0x17 # Length of Public Names Info + .value 0x2 # DWARF Version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .long 0x52 # Compilation Unit Length + .long 0x2d # DIE offset + .ascii "main\0" # external name + .long 0x0 + .section .debug_aranges,"",@progbits + .long 0x2c # Length of Address Ranges Info + .value 0x2 # DWARF Version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .byte 0x8 # Size of Address + .byte 0x0 # Size of Segment Descriptor + .value 0x0 # Pad to 16 byte boundary + .value 0x0 + .quad .Ltext0 # Address + .quad .Letext0-.Ltext0 # Length + .quad 0x0 + .quad 0x0 + .section .debug_str,"MS",@progbits,1 +.LASF2: + .string "." +.LASF0: + .string "GNU C 4.4.4 20100503 (Red Hat 4.4.4-2)" +.LASF1: + .string "gdb.dwarf2/rh-dwarf4-x86_64.c" +.LASF3: + .string "main" + .ident "GCC: (GNU) 4.4.4 20100503 (Red Hat 4.4.4-2)" + .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.dwarf2/rh-dwarf4-x86_64.c b/gdb/testsuite/gdb.dwarf2/rh-dwarf4-x86_64.c new file mode 100644 index 00000000000..46fcd120f49 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/rh-dwarf4-x86_64.c @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2010 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 . */ + +int +main (void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.dwarf2/rh-dwarf4-x86_64.exp b/gdb/testsuite/gdb.dwarf2/rh-dwarf4-x86_64.exp new file mode 100644 index 00000000000..a728f9c5ed5 --- /dev/null +++ b/gdb/testsuite/gdb.dwarf2/rh-dwarf4-x86_64.exp @@ -0,0 +1,42 @@ +# Copyright 2010 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 . + +# This test can only be run on targets which support DWARF-2 and use gas. +# For now pick a sampling of likely targets. +if {![istarget *-*-linux*] + && ![istarget *-*-gnu*] + && ![istarget *-*-elf*] + && ![istarget *-*-openbsd*] + && ![istarget arm-*-eabi*] + && ![istarget powerpc-*-eabi*]} { + return 0 +} + +if {![istarget x86_64-*]} { + return 0 +} + +set testfile "rh-dwarf4-x86_64" +set srcfile ${testfile}.S +set executable ${testfile}.x +set binfile [standard_output_file ${executable}] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {}] != "" } { + return -1 +} + +clean_restart $executable + +gdb_test "ptype main" {type = int \(void\)} diff --git a/gdb/testsuite/gdb.fortran/array-bounds.S b/gdb/testsuite/gdb.fortran/array-bounds.S new file mode 100644 index 00000000000..463a4276508 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/array-bounds.S @@ -0,0 +1,529 @@ +/* Copyright 2012 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 . + + This file is part of the gdb testsuite. */ + + .file "array-bounds.f" + .text +.Ltext0: + .type MAIN__, @function +MAIN__: +.LFB0: + .file 1 "gdb.fortran/array-bounds.f" + # gdb.fortran/array-bounds.f:16 + .loc 1 16 0 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushl %ebp +.LCFI0: + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp +.LCFI1: + .cfi_def_cfa_register 5 + subl $40, %esp +.LBB2: +# SUCC: 3 (FALLTHRU) + # gdb.fortran/array-bounds.f:18 + .loc 1 18 0 + movl $-1, %eax +# BLOCK 3 seq:1 +# PRED: 2 (FALLTHRU) 4 [100.0%] +.L3: + # gdb.fortran/array-bounds.f:18 + .loc 1 18 0 is_stmt 0 discriminator 1 + testl %eax, %eax +# SUCC: 5 4 (FALLTHRU) + jg .L2 +# BLOCK 4 seq:2 +# PRED: 3 (FALLTHRU) + # gdb.fortran/array-bounds.f:18 + .loc 1 18 0 discriminator 2 + leal 1(%eax), %ecx + movl .LC0, %edx + movl %edx, -16(%ebp,%ecx,4) + addl $1, %eax +# SUCC: 3 [100.0%] + jmp .L3 +# BLOCK 5 seq:3 +# PRED: 3 +.L2: +.LBE2: + # gdb.fortran/array-bounds.f:19 + .loc 1 19 0 is_stmt 1 + movl -16(%ebp), %eax + movl -12(%ebp), %edx + movl %eax, -24(%ebp) + movl %edx, -20(%ebp) + # gdb.fortran/array-bounds.f:20 + .loc 1 20 0 + movl $0, 4(%esp) + movl $0, (%esp) +# SUCC: + call _gfortran_stop_string + .cfi_endproc +.LFE0: + .size MAIN__, .-MAIN__ + .globl main + .type main, @function +main: +.LFB1: + # gdb.fortran/array-bounds.f:21 + .loc 1 21 0 + .cfi_startproc +# BLOCK 2 seq:0 +# PRED: ENTRY (FALLTHRU) + pushl %ebp +.LCFI2: + .cfi_def_cfa_offset 8 + .cfi_offset 5, -8 + movl %esp, %ebp +.LCFI3: + .cfi_def_cfa_register 5 + andl $-16, %esp + subl $16, %esp + # gdb.fortran/array-bounds.f:21 + .loc 1 21 0 + movl 12(%ebp), %eax + movl %eax, 4(%esp) + movl 8(%ebp), %eax + movl %eax, (%esp) + call _gfortran_set_args + movl $options.1.1824, 4(%esp) + movl $7, (%esp) + call _gfortran_set_options + call MAIN__ + movl $0, %eax + leave +.LCFI4: + .cfi_restore 5 + .cfi_def_cfa 4, 4 +# SUCC: EXIT [100.0%] + ret + .cfi_endproc +.LFE1: + .size main, .-main + .section .rodata + .align 4 + .type options.1.1824, @object + .size options.1.1824, 28 +options.1.1824: + .long 68 + .long 1023 + .long 0 + .long 0 + .long 1 + .long 1 + .long 0 + .align 4 +.LC0: + .long 1109917696 + .text +.Letext0: + .section .debug_info,"",@progbits +.Ldebug_info0: + .long 2f - 1f # Length of Compilation Unit Info +1: + .value 0x2 # DWARF version number + .long .Ldebug_abbrev0 # Offset Into Abbrev. Section + .byte 0x4 # Pointer Size (in bytes) +dieb: .uleb128 0x1 # (DIE (0xb) DW_TAG_compile_unit) + .long .LASF5 # DW_AT_producer: "GNU Fortran 4.8.0 20121015 (experimental) -ffixed-form -m32 -mtune=generic -march=x86-64 -g -gdwarf-2 -fintrinsic-modules-path .../gcchead-root/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/finclude" + .byte 0xe # DW_AT_language + .byte 0x2 # DW_AT_identifier_case + .long .LASF6 # DW_AT_name: "gdb.fortran/array-bounds.f" + .long .LASF7 # DW_AT_comp_dir: "" + .long .Ltext0 # DW_AT_low_pc + .long .Letext0 # DW_AT_high_pc + .long .Ldebug_line0 # DW_AT_stmt_list +die26: .uleb128 0x2 # (DIE (0x26) DW_TAG_subprogram) + .long .LASF8 # DW_AT_name: "MAIN__" + .byte 0x1 # DW_AT_decl_file (gdb.fortran/array-bounds.f) + .byte 0x10 # DW_AT_decl_line + .long .LFB0 # DW_AT_low_pc + .long .LFE0 # DW_AT_high_pc + .long .LLST0 # DW_AT_frame_base + .byte 0x1 # DW_AT_GNU_all_tail_call_sites + .byte 0x1 # DW_AT_main_subprogram + .byte 0x2 # DW_AT_calling_convention + .long die66 - .Ldebug_info0 # DW_AT_sibling +die40: .uleb128 0x3 # (DIE (0x40) DW_TAG_variable) + .ascii "bar\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (gdb.fortran/array-bounds.f) + .byte 0x11 # DW_AT_decl_line + .long die66 - .Ldebug_info0 # DW_AT_type + .byte 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -24 +die4e: .uleb128 0x3 # (DIE (0x4e) DW_TAG_variable) + .ascii "foo\0" # DW_AT_name + .byte 0x1 # DW_AT_decl_file (gdb.fortran/array-bounds.f) + .byte 0x10 # DW_AT_decl_line + .long die88 - .Ldebug_info0 # DW_AT_type + .byte 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 -32 +die5c: .uleb128 0x4 # (DIE (0x5c) DW_TAG_lexical_block) + .long .LBB2 # DW_AT_low_pc + .long .LBE2 # DW_AT_high_pc + .byte 0 # end of children of DIE 0x26 +die66: .uleb128 0x5 # (DIE (0x66) DW_TAG_array_type) + .long die81 - .Ldebug_info0 # DW_AT_type + .long die7a - .Ldebug_info0 # DW_AT_sibling +die6f: .uleb128 0x6 # (DIE (0x6f) DW_TAG_subrange_type) + .long die7a - .Ldebug_info0 # DW_AT_type +#if 0 + .long 0xffffffff # DW_AT_lower_bound + .byte 0 # DW_AT_upper_bound +#else + .quad 0xfffffffeffffffff # DW_AT_lower_bound + .quad 0xffffffff00000000 # DW_AT_upper_bound +#endif + .byte 0 # end of children of DIE 0x66 +die7a: .uleb128 0x7 # (DIE (0x7a) DW_TAG_base_type) +#if 0 + .byte 0x4 # DW_AT_byte_size +#else + .byte 0x8 # DW_AT_byte_size +#endif + .byte 0x5 # DW_AT_encoding + .long .LASF0 # DW_AT_name: "integer(kind=4)" +die81: .uleb128 0x7 # (DIE (0x81) DW_TAG_base_type) + .byte 0x4 # DW_AT_byte_size + .byte 0x4 # DW_AT_encoding + .long .LASF1 # DW_AT_name: "real(kind=4)" +die88: .uleb128 0x5 # (DIE (0x88) DW_TAG_array_type) + .long die81 - .Ldebug_info0 # DW_AT_type + .long die99 - .Ldebug_info0 # DW_AT_sibling +die91: .uleb128 0x8 # (DIE (0x91) DW_TAG_subrange_type) + .long die7a - .Ldebug_info0 # DW_AT_type +#if 0 + .byte 0 # DW_AT_lower_bound + .byte 0x1 # DW_AT_upper_bound +#else + .quad 0x100000000 # DW_AT_lower_bound + .quad 0x100000001 # DW_AT_upper_bound +#endif + .byte 0 # end of children of DIE 0x88 +die99: .uleb128 0x9 # (DIE (0x99) DW_TAG_subprogram) + .byte 0x1 # DW_AT_external + .long .LASF9 # DW_AT_name: "main" + .byte 0x1 # DW_AT_decl_file (gdb.fortran/array-bounds.f) + .byte 0x15 # DW_AT_decl_line + .long die7a - .Ldebug_info0 # DW_AT_type + .long .LFB1 # DW_AT_low_pc + .long .LFE1 # DW_AT_high_pc + .long .LLST1 # DW_AT_frame_base + .byte 0x1 # DW_AT_GNU_all_tail_call_sites + .long died4 - .Ldebug_info0 # DW_AT_sibling +dieb6: .uleb128 0xa # (DIE (0xb6) DW_TAG_formal_parameter) + .long .LASF2 # DW_AT_name: "argc" + .byte 0x1 # DW_AT_decl_file (gdb.fortran/array-bounds.f) + .byte 0x15 # DW_AT_decl_line + .long died4 - .Ldebug_info0 # DW_AT_type + .byte 0x2 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 0 +diec4: .uleb128 0xa # (DIE (0xc4) DW_TAG_formal_parameter) + .long .LASF3 # DW_AT_name: "argv" + .byte 0x1 # DW_AT_decl_file (gdb.fortran/array-bounds.f) + .byte 0x15 # DW_AT_decl_line + .long died9 - .Ldebug_info0 # DW_AT_type + .byte 0x3 # DW_AT_location + .byte 0x91 # DW_OP_fbreg + .sleb128 4 + .byte 0x6 # DW_OP_deref + .byte 0 # end of children of DIE 0x99 +died4: .uleb128 0xb # (DIE (0xd4) DW_TAG_const_type) + .long die7a - .Ldebug_info0 # DW_AT_type +died9: .uleb128 0xc # (DIE (0xd9) DW_TAG_pointer_type) + .byte 0x4 # DW_AT_byte_size + .long diedf - .Ldebug_info0 # DW_AT_type +diedf: .uleb128 0x7 # (DIE (0xdf) DW_TAG_base_type) + .byte 0x1 # DW_AT_byte_size + .byte 0x8 # DW_AT_encoding + .long .LASF4 # DW_AT_name: "character(kind=1)" + .byte 0 # end of children of DIE 0xb +2: + .section .debug_abbrev,"",@progbits +.Ldebug_abbrev0: + .uleb128 0x1 # (abbrev code) + .uleb128 0x11 # (TAG: DW_TAG_compile_unit) + .byte 0x1 # DW_children_yes + .uleb128 0x25 # (DW_AT_producer) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x13 # (DW_AT_language) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x42 # (DW_AT_identifier_case) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x1b # (DW_AT_comp_dir) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x10 # (DW_AT_stmt_list) + .uleb128 0x6 # (DW_FORM_data4) + .byte 0 + .byte 0 + .uleb128 0x2 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x2116 # (DW_AT_GNU_all_tail_call_sites) + .uleb128 0xc # (DW_FORM_flag) + .uleb128 0x6a # (DW_AT_main_subprogram) + .uleb128 0xc # (DW_FORM_flag) + .uleb128 0x36 # (DW_AT_calling_convention) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x3 # (abbrev code) + .uleb128 0x34 # (TAG: DW_TAG_variable) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0x8 # (DW_FORM_string) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0xa # (DW_FORM_block1) + .byte 0 + .byte 0 + .uleb128 0x4 # (abbrev code) + .uleb128 0xb # (TAG: DW_TAG_lexical_block) + .byte 0 # DW_children_no + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x1 # (DW_FORM_addr) + .byte 0 + .byte 0 + .uleb128 0x5 # (abbrev code) + .uleb128 0x1 # (TAG: DW_TAG_array_type) + .byte 0x1 # DW_children_yes + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0x6 # (abbrev code) + .uleb128 0x21 # (TAG: DW_TAG_subrange_type) + .byte 0 # DW_children_no + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) +#if 0 + .uleb128 0x22 # (DW_AT_lower_bound) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x2f # (DW_AT_upper_bound) + .uleb128 0xb # (DW_FORM_data1) +#else + .uleb128 0x22 # (DW_AT_lower_bound) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x2f # (DW_AT_upper_bound) + .uleb128 0x7 # (DW_FORM_data8) +#endif + .byte 0 + .byte 0 + .uleb128 0x7 # (abbrev code) + .uleb128 0x24 # (TAG: DW_TAG_base_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3e # (DW_AT_encoding) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .byte 0 + .byte 0 + .uleb128 0x8 # (abbrev code) + .uleb128 0x21 # (TAG: DW_TAG_subrange_type) + .byte 0 # DW_children_no + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) +#if 0 + .uleb128 0x22 # (DW_AT_lower_bound) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x2f # (DW_AT_upper_bound) + .uleb128 0xb # (DW_FORM_data1) +#else + .uleb128 0x22 # (DW_AT_lower_bound) + .uleb128 0x7 # (DW_FORM_data8) + .uleb128 0x2f # (DW_AT_upper_bound) + .uleb128 0x7 # (DW_FORM_data8) +#endif + .byte 0 + .byte 0 + .uleb128 0x9 # (abbrev code) + .uleb128 0x2e # (TAG: DW_TAG_subprogram) + .byte 0x1 # DW_children_yes + .uleb128 0x3f # (DW_AT_external) + .uleb128 0xc # (DW_FORM_flag) + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x11 # (DW_AT_low_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x12 # (DW_AT_high_pc) + .uleb128 0x1 # (DW_FORM_addr) + .uleb128 0x40 # (DW_AT_frame_base) + .uleb128 0x6 # (DW_FORM_data4) + .uleb128 0x2116 # (DW_AT_GNU_all_tail_call_sites) + .uleb128 0xc # (DW_FORM_flag) + .uleb128 0x1 # (DW_AT_sibling) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0xa # (abbrev code) + .uleb128 0x5 # (TAG: DW_TAG_formal_parameter) + .byte 0 # DW_children_no + .uleb128 0x3 # (DW_AT_name) + .uleb128 0xe # (DW_FORM_strp) + .uleb128 0x3a # (DW_AT_decl_file) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x3b # (DW_AT_decl_line) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .uleb128 0x2 # (DW_AT_location) + .uleb128 0xa # (DW_FORM_block1) + .byte 0 + .byte 0 + .uleb128 0xb # (abbrev code) + .uleb128 0x26 # (TAG: DW_TAG_const_type) + .byte 0 # DW_children_no + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .uleb128 0xc # (abbrev code) + .uleb128 0xf # (TAG: DW_TAG_pointer_type) + .byte 0 # DW_children_no + .uleb128 0xb # (DW_AT_byte_size) + .uleb128 0xb # (DW_FORM_data1) + .uleb128 0x49 # (DW_AT_type) + .uleb128 0x13 # (DW_FORM_ref4) + .byte 0 + .byte 0 + .byte 0 + .section .debug_loc,"",@progbits +.Ldebug_loc0: +.LLST0: + .long .LFB0-.Ltext0 # Location list begin address (*.LLST0) + .long .LCFI0-.Ltext0 # Location list end address (*.LLST0) + .value 0x2 # Location expression size + .byte 0x74 # DW_OP_breg4 + .sleb128 4 + .long .LCFI0-.Ltext0 # Location list begin address (*.LLST0) + .long .LCFI1-.Ltext0 # Location list end address (*.LLST0) + .value 0x2 # Location expression size + .byte 0x74 # DW_OP_breg4 + .sleb128 8 + .long .LCFI1-.Ltext0 # Location list begin address (*.LLST0) + .long .LFE0-.Ltext0 # Location list end address (*.LLST0) + .value 0x2 # Location expression size + .byte 0x75 # DW_OP_breg5 + .sleb128 8 + .long 0 # Location list terminator begin (*.LLST0) + .long 0 # Location list terminator end (*.LLST0) +.LLST1: + .long .LFB1-.Ltext0 # Location list begin address (*.LLST1) + .long .LCFI2-.Ltext0 # Location list end address (*.LLST1) + .value 0x2 # Location expression size + .byte 0x74 # DW_OP_breg4 + .sleb128 4 + .long .LCFI2-.Ltext0 # Location list begin address (*.LLST1) + .long .LCFI3-.Ltext0 # Location list end address (*.LLST1) + .value 0x2 # Location expression size + .byte 0x74 # DW_OP_breg4 + .sleb128 8 + .long .LCFI3-.Ltext0 # Location list begin address (*.LLST1) + .long .LCFI4-.Ltext0 # Location list end address (*.LLST1) + .value 0x2 # Location expression size + .byte 0x75 # DW_OP_breg5 + .sleb128 8 + .long .LCFI4-.Ltext0 # Location list begin address (*.LLST1) + .long .LFE1-.Ltext0 # Location list end address (*.LLST1) + .value 0x2 # Location expression size + .byte 0x74 # DW_OP_breg4 + .sleb128 4 + .long 0 # Location list terminator begin (*.LLST1) + .long 0 # Location list terminator end (*.LLST1) + .section .debug_aranges,"",@progbits + .long 0x1c # Length of Address Ranges Info + .value 0x2 # DWARF Version + .long .Ldebug_info0 # Offset of Compilation Unit Info + .byte 0x4 # Size of Address + .byte 0 # Size of Segment Descriptor + .value 0 # Pad to 8 byte boundary + .value 0 + .long .Ltext0 # Address + .long .Letext0-.Ltext0 # Length + .long 0 + .long 0 + .section .debug_line,"",@progbits +.Ldebug_line0: + .section .debug_str,"MS",@progbits,1 +.LASF4: + .string "character(kind=1)" +.LASF5: + .string "GNU Fortran 4.8.0 20121015 (experimental) -ffixed-form -m32 -mtune=generic -march=x86-64 -g -gdwarf-2 -fintrinsic-modules-path .../gcchead-root/lib/gcc/x86_64-unknown-linux-gnu/4.8.0/finclude" +.LASF7: + .string "" +.LASF0: +#if 0 + .string "integer(kind=4)" +#else + .string "integer(kind=8)" +#endif +.LASF9: + .string "main" +.LASF8: + .string "MAIN__" +.LASF6: + .string "gdb.fortran/array-bounds.f" +.LASF2: + .string "argc" +.LASF1: + .string "real(kind=4)" +.LASF3: + .string "argv" + .ident "GCC: (GNU) 4.8.0 20121015 (experimental)" + .section .note.GNU-stack,"",@progbits diff --git a/gdb/testsuite/gdb.fortran/array-bounds.exp b/gdb/testsuite/gdb.fortran/array-bounds.exp index e18530c75ed..2eb3df38466 100644 --- a/gdb/testsuite/gdb.fortran/array-bounds.exp +++ b/gdb/testsuite/gdb.fortran/array-bounds.exp @@ -25,7 +25,21 @@ if {[prepare_for_testing $testfile.exp $testfile $srcfile {f90 debug}]} { return -1 } -if {![runto MAIN__]} { +if { [is_ilp32_target] && ([istarget "i\[34567\]86-*-linux*"] + || [istarget "x86_64-*-linux*"]) } { + set srcfile ${testfile}.S + set opts {nodebug f90} +} else { + set srcfile ${testfile}.f + set opts {debug f90} +} + +if {[prepare_for_testing $testfile.exp $testfile $srcfile $opts]} { + print "compile failed" + return -1 +} + +if { ![runto MAIN__] } { perror "Could not run to breakpoint `MAIN__'." continue } diff --git a/gdb/testsuite/gdb.fortran/array-bounds.f b/gdb/testsuite/gdb.fortran/array-bounds.f new file mode 100644 index 00000000000..78b36e6c27e --- /dev/null +++ b/gdb/testsuite/gdb.fortran/array-bounds.f @@ -0,0 +1,22 @@ +c Copyright 2012 Free Software Foundation, Inc. + +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 3 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program. If not, see . + + dimension foo(4294967296_8:4294967297_8) + dimension bar(-4294967297_8:-4294967296_8) + bar = 42 + foo=bar + stop + end + diff --git a/gdb/testsuite/gdb.fortran/dwarf-stride.exp b/gdb/testsuite/gdb.fortran/dwarf-stride.exp new file mode 100644 index 00000000000..d7b8bea8dbb --- /dev/null +++ b/gdb/testsuite/gdb.fortran/dwarf-stride.exp @@ -0,0 +1,42 @@ +# Copyright 2009 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# This file was written by Jan Kratochvil . + +# This file is part of the gdb testsuite. Array element stride must not be +# specified in the number of elements but in a number of bytes instead. +# Original problem: +# (gdb) p c40pt(1) +# $1 = '0-hello', ' ' +# (gdb) p c40pt(2) +# warning: Fortran array stride not divisible by the element size + +set testfile dwarf-stride +set srcfile ${testfile}.f90 + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f90}] } { + return -1 +} + +if ![runto MAIN__] then { + perror "couldn't run to breakpoint MAIN__" + continue +} + +gdb_breakpoint [gdb_get_line_number "break-here"] +gdb_continue_to_breakpoint "break-here" ".*break-here.*" +gdb_test "p c40pt(1)" " = '0-hello.*" +gdb_test "p c40pt(2)" " = '1-hello.*" diff --git a/gdb/testsuite/gdb.fortran/dwarf-stride.f90 b/gdb/testsuite/gdb.fortran/dwarf-stride.f90 new file mode 100644 index 00000000000..e492b3af42e --- /dev/null +++ b/gdb/testsuite/gdb.fortran/dwarf-stride.f90 @@ -0,0 +1,40 @@ +! Copyright 2009 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 2 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, write to the Free Software +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +! +! File written by Alan Matsuoka. + +program repro + + type small_stride + character*40 long_string + integer small_pad + end type small_stride + + type(small_stride), dimension (20), target :: unpleasant + character*40, pointer, dimension(:):: c40pt + + integer i + + do i = 0,19 + unpleasant(i+1)%small_pad = i+1 + unpleasant(i+1)%long_string = char (ichar('0') + i) // '-hello' + end do + + c40pt => unpleasant%long_string + + print *, c40pt ! break-here + +end program repro diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90 b/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90 new file mode 100644 index 00000000000..261ce17ae50 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame-stub.f90 @@ -0,0 +1,24 @@ +! Copyright 2010 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 2 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, write to the Free Software +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +! +! Ihis file is the Fortran source file for dynamic.exp. +! Original file written by Jakub Jelinek . +! Modified for the GDB testcase by Jan Kratochvil . + +subroutine bar + real :: dummy + dummy = 1 +end subroutine bar diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp b/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp new file mode 100644 index 00000000000..570a28ca652 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame.exp @@ -0,0 +1,39 @@ +# Copyright 2010 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +set testfile "dynamic-other-frame" +set srcfile1 ${testfile}.f90 +set srcfile2 ${testfile}-stub.f90 +set objfile2 [standard_output_file ${testfile}-stub.o] +set executable ${testfile} +set binfile [standard_output_file ${executable}] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${objfile2}" object {f90}] != "" + || [gdb_compile "${srcdir}/${subdir}/${srcfile1} ${objfile2}" "${binfile}" executable {debug f90}] != "" } { + untested "Couldn't compile ${srcfile1} or ${srcfile2}" + return -1 +} + +clean_restart ${executable} + +gdb_test_no_output "set print frame-arguments all" + +if ![runto bar_] then { + perror "couldn't run to bar_" + continue +} + +gdb_test "bt" {foo \(string='hello'.*} diff --git a/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90 b/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90 new file mode 100644 index 00000000000..2bc637db49b --- /dev/null +++ b/gdb/testsuite/gdb.fortran/dynamic-other-frame.f90 @@ -0,0 +1,36 @@ +! Copyright 2010 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 2 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, write to the Free Software +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +! +! Ihis file is the Fortran source file for dynamic.exp. +! Original file written by Jakub Jelinek . +! Modified for the GDB testcase by Jan Kratochvil . + +subroutine foo (string) + interface + subroutine bar + end subroutine + end interface + character string*(*) + call bar ! stop-here +end subroutine foo +program test + interface + subroutine foo (string) + character string*(*) + end subroutine + end interface + call foo ('hello') +end diff --git a/gdb/testsuite/gdb.fortran/dynamic.exp b/gdb/testsuite/gdb.fortran/dynamic.exp new file mode 100644 index 00000000000..37d435f799d --- /dev/null +++ b/gdb/testsuite/gdb.fortran/dynamic.exp @@ -0,0 +1,154 @@ +# Copyright 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# This file was written by Jan Kratochvil . + +# This file is part of the gdb testsuite. It contains tests for dynamically +# allocated Fortran arrays. +# It depends on the GCC dynamic Fortran arrays DWARF support: +# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22244 + +set testfile "dynamic" +set srcfile ${testfile}.f90 +set binfile [standard_output_file ${testfile}] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f90 quiet}] != "" } { + untested "Couldn't compile ${srcfile}" + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto MAIN__] then { + perror "couldn't run to breakpoint MAIN__" + continue +} + +gdb_breakpoint [gdb_get_line_number "varx-init"] +gdb_continue_to_breakpoint "varx-init" + +# http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html#5 +# Do not: gdb_test "p varx" "\\$\[0-9\]* = " "p varx unallocated" +# Do not: gdb_test "ptype varx" {type = real\(kind=4\) \(:,:,:\)} "ptype varx unallocated" +# Do not: gdb_test "p varx(1,5,17)" {no such vector element \(vector not allocated\)} "p varx(1,5,17) unallocated" +# Do not: gdb_test "p varx(1,5,17)=1" {no such vector element \(vector not allocated\)} "p varx(1,5,17)=1 unallocated" +# Do not: gdb_test "ptype varx(1,5,17)" {no such vector element \(vector not allocated\)} "ptype varx(1,5,17) unallocated" + +gdb_breakpoint [gdb_get_line_number "varx-allocated"] +gdb_continue_to_breakpoint "varx-allocated" +# $1 = (( ( 0, 0, 0, 0, 0, 0) ( 0, 0, 0, 0, 0, 0) --- , 0) ) ( ( 0, 0, ...) ...) ...) +gdb_test "ptype varx" "type = real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)" "ptype varx allocated" +# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1. +gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)" "p l if varx allocated" + +gdb_breakpoint [gdb_get_line_number "varx-filled"] +gdb_continue_to_breakpoint "varx-filled" +gdb_test "p varx(2, 5, 17)" "\\$\[0-9\]* = 6" +gdb_test "p varx(1, 5, 17)" "\\$\[0-9\]* = 7" +gdb_test "p varx(2, 6, 18)" "\\$\[0-9\]* = 8" +gdb_test "p varx(6, 15, 28)" "\\$\[0-9\]* = 9" +# http://www.cs.rpi.edu/~szymansk/OOF90/bugs.html#5 +# Do not: gdb_test "p varv" "\\$\[0-9\]* = " "p varv unassociated" +# Do not: gdb_test "ptype varv" {type = real\(kind=4\) \(:,:,:\)} "ptype varv unassociated" + +set test "output varx" +gdb_test_multiple $test $test { + -re "^output varx\r\n\[() ,6789.\]*$gdb_prompt $" { + pass $test + } +} + +gdb_breakpoint [gdb_get_line_number "varv-associated"] +gdb_continue_to_breakpoint "varv-associated" +gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 6" "p varx(3, 7, 19) with varv associated" +gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 6" "p varv(3, 7, 19) associated" +# Intel Fortran Compiler 10.1.008 uses -1 there, GCC uses 1. +gdb_test "p l" "\\$\[0-9\]* = (\\.TRUE\\.|4294967295)" "p l if varv associated" +gdb_test "ptype varx" "type = real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)" "ptype varx with varv associated" +# Intel Fortran Compiler 10.1.008 uses the pointer type. +gdb_test "ptype varv" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(6,5:15,17:28\\)\\)?" "ptype varv associated" + +gdb_breakpoint [gdb_get_line_number "varv-filled"] +gdb_continue_to_breakpoint "varv-filled" +gdb_test "p varx(3, 7, 19)" "\\$\[0-9\]* = 10" "p varx(3, 7, 19) with varv filled" +gdb_test "p varv(3, 7, 19)" "\\$\[0-9\]* = 10" "p varv(3, 7, 19) filled" + +gdb_breakpoint [gdb_get_line_number "varv-deassociated"] +gdb_continue_to_breakpoint "varv-deassociated" +# The latter one is for the Intel Fortran Compiler 10.1.008 pointer type. +gdb_test "p varv" "\\$\[0-9\]* = (|.*(Cannot access it|Unable to access the object) because the object is not associated.)" "p varv deassociated" +gdb_test "ptype varv" {type = real\(kind=4\) \(:,:,:\)} "ptype varv deassociated" +gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\." "p l if varv deassociated" +gdb_test "p varv(1,5,17)" {no such vector element \(vector not associated\)} +gdb_test "ptype varv(1,5,17)" {no such vector element \(vector not associated\)} + +gdb_breakpoint [gdb_get_line_number "varx-deallocated"] +gdb_continue_to_breakpoint "varx-deallocated" +gdb_test "p varx" "\\$\[0-9\]* = " "p varx deallocated" +gdb_test "ptype varx" {type = real\(kind=4\) \(:,:,:\)} "ptype varx deallocated" +gdb_test "p l" "\\$\[0-9\]* = \\.FALSE\\." "p l if varx deallocated" +gdb_test "p varx(1,5,17)" {no such vector element \(vector not allocated\)} "p varx(1,5,17) deallocated" +gdb_test "ptype varx(1,5,17)" {no such vector element \(vector not allocated\)} "ptype varx(1,5,17) deallocated" + +gdb_breakpoint [gdb_get_line_number "vary-passed"] +gdb_continue_to_breakpoint "vary-passed" +# $1 = (( ( 1, 1, 1, 1, 1, 1) ( 1, 1, 1, 1, 1, 1) --- , 1) ) ( ( 1, 1, ...) ...) ...) +gdb_test "p vary" "\\$\[0-9\]* = \\(\[()1, .\]*\\)" + +gdb_breakpoint [gdb_get_line_number "vary-filled"] +gdb_continue_to_breakpoint "vary-filled" +gdb_test "ptype vary" "type = real(\\(kind=4\\)|\\*4) \\(10,10\\)" +gdb_test "p vary(1, 1)" "\\$\[0-9\]* = 8" +gdb_test "p vary(2, 2)" "\\$\[0-9\]* = 9" +gdb_test "p vary(1, 3)" "\\$\[0-9\]* = 10" +# $1 = (( ( 3, 3, 3, 3, 3, 3) ( 3, 3, 3, 3, 3, 3) --- , 3) ) ( ( 3, 3, ...) ...) ...) +gdb_test "p varw" "\\$\[0-9\]* = \\(\[()3, .\]*\\)" + +gdb_breakpoint [gdb_get_line_number "varw-almostfilled"] +gdb_continue_to_breakpoint "varw-almostfilled" +gdb_test "ptype varw" "type = real(\\(kind=4\\)|\\*4) \\(5,4,3\\)" +gdb_test "p varw(3,1,1)=1" "\\$\[0-9\]* = 1" +# $1 = (( ( 6, 5, 1, 5, 5, 5) ( 5, 5, 5, 5, 5, 5) --- , 5) ) ( ( 5, 5, ...) ...) ...) +gdb_test "p varw" "\\$\[0-9\]* = \\( *\\( *\\( *6, *5, *1,\[()5, .\]*\\)" "p varw filled" +# "up" works with GCC but other Fortran compilers may copy the values into the +# outer function only on the exit of the inner function. +# We need both variants as depending on the arch we optionally may still be +# executing the caller line or not after `finish'. +gdb_test "finish" ".*(call bar \\(y, x\\)|call foo \\(x, z\\(2:6, 4:7, 6:8\\)\\))" +gdb_test "p z(2,4,5)" "\\$\[0-9\]* = 3" +gdb_test "p z(2,4,6)" "\\$\[0-9\]* = 6" +gdb_test "p z(2,4,7)" "\\$\[0-9\]* = 5" +gdb_test "p z(4,4,6)" "\\$\[0-9\]* = 1" + +gdb_breakpoint [gdb_get_line_number "varz-almostfilled"] +gdb_continue_to_breakpoint "varz-almostfilled" +# GCC uses the pointer type here, Intel Fortran Compiler 10.1.008 does not. +gdb_test "ptype varz" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(\\*\\)\\)?" +# Intel Fortran Compiler 10.1.008 has a bug here - (2:11,7:7) +# as it produces DW_AT_lower_bound == DW_AT_upper_bound == 7. +gdb_test "ptype vart" "type = (PTR TO -> \\( )?real(\\(kind=4\\)|\\*4) \\(2:11,7:\\*\\)\\)?" +gdb_test "p varz" "\\$\[0-9\]* = \\(\\)" +gdb_test "p vart" "\\$\[0-9\]* = \\(\\)" +gdb_test "p varz(3)" "\\$\[0-9\]* = 4" +# maps to foo::vary(1,1) +gdb_test "p vart(2,7)" "\\$\[0-9\]* = 8" +# maps to foo::vary(2,2) +gdb_test "p vart(3,8)" "\\$\[0-9\]* = 9" +# maps to foo::vary(1,3) +gdb_test "p vart(2,9)" "\\$\[0-9\]* = 10" diff --git a/gdb/testsuite/gdb.fortran/dynamic.f90 b/gdb/testsuite/gdb.fortran/dynamic.f90 new file mode 100644 index 00000000000..0f43564378f --- /dev/null +++ b/gdb/testsuite/gdb.fortran/dynamic.f90 @@ -0,0 +1,98 @@ +! Copyright 2007 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 2 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, write to the Free Software +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +! +! Ihis file is the Fortran source file for dynamic.exp. +! Original file written by Jakub Jelinek . +! Modified for the GDB testcase by Jan Kratochvil . + +subroutine baz + real, target, allocatable :: varx (:, :, :) + real, pointer :: varv (:, :, :) + real, target :: varu (1, 2, 3) + logical :: l + allocate (varx (1:6, 5:15, 17:28)) ! varx-init + l = allocated (varx) + varx(:, :, :) = 6 ! varx-allocated + varx(1, 5, 17) = 7 + varx(2, 6, 18) = 8 + varx(6, 15, 28) = 9 + varv => varx ! varx-filled + l = associated (varv) + varv(3, 7, 19) = 10 ! varv-associated + varv => null () ! varv-filled + l = associated (varv) + deallocate (varx) ! varv-deassociated + l = allocated (varx) + varu(:, :, :) = 10 ! varx-deallocated + allocate (varv (1:6, 5:15, 17:28)) + l = associated (varv) + varv(:, :, :) = 6 + varv(1, 5, 17) = 7 + varv(2, 6, 18) = 8 + varv(6, 15, 28) = 9 + deallocate (varv) + l = associated (varv) + varv => varu + varv(1, 1, 1) = 6 + varv(1, 2, 3) = 7 + l = associated (varv) +end subroutine baz +subroutine foo (vary, varw) + real :: vary (:, :) + real :: varw (:, :, :) + vary(:, :) = 4 ! vary-passed + vary(1, 1) = 8 + vary(2, 2) = 9 + vary(1, 3) = 10 + varw(:, :, :) = 5 ! vary-filled + varw(1, 1, 1) = 6 + varw(2, 2, 2) = 7 ! varw-almostfilled +end subroutine foo +subroutine bar (varz, vart) + real :: varz (*) + real :: vart (2:11, 7:*) + varz(1:3) = 4 + varz(2) = 5 ! varz-almostfilled + vart(2,7) = vart(2,7) +end subroutine bar +program test + interface + subroutine foo (vary, varw) + real :: vary (:, :) + real :: varw (:, :, :) + end subroutine + end interface + interface + subroutine bar (varz, vart) + real :: varz (*) + real :: vart (2:11, 7:*) + end subroutine + end interface + real :: x (10, 10), y (5), z(8, 8, 8) + x(:,:) = 1 + y(:) = 2 + z(:,:,:) = 3 + call baz + call foo (x, z(2:6, 4:7, 6:8)) + call bar (y, x) + if (x (1, 1) .ne. 8 .or. x (2, 2) .ne. 9 .or. x (1, 2) .ne. 4) call abort + if (x (1, 3) .ne. 10) call abort + if (z (2, 4, 6) .ne. 6 .or. z (3, 5, 7) .ne. 7 .or. z (2, 4, 7) .ne. 5) call abort + if (any (y .ne. (/4, 5, 4, 2, 2/))) call abort + call foo (transpose (x), z) + if (x (1, 1) .ne. 8 .or. x (2, 2) .ne. 9 .or. x (1, 2) .ne. 4) call abort + if (x (3, 1) .ne. 10) call abort +end diff --git a/gdb/testsuite/gdb.fortran/fortran-frame-string.exp b/gdb/testsuite/gdb.fortran/fortran-frame-string.exp new file mode 100644 index 00000000000..7114afd440e --- /dev/null +++ b/gdb/testsuite/gdb.fortran/fortran-frame-string.exp @@ -0,0 +1,36 @@ +# Copyright 2014 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +standard_testfile .f90 +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f90}] } { + return -1 +} + +if ![runto MAIN__] then { + perror "couldn't run to breakpoint MAIN__" + continue +} + +gdb_breakpoint [gdb_get_line_number "s = s"] +gdb_continue_to_breakpoint "s = s" + +gdb_test "ptype s" {type = character\*3} +gdb_test "p s" " = 'foo'" + +# Fix rejected upstream: +# https://sourceware.org/ml/gdb-patches/2014-07/msg00768.html +setup_kfail "rejected" *-*-* +gdb_test "frame" { \(s='foo', .*} diff --git a/gdb/testsuite/gdb.fortran/fortran-frame-string.f90 b/gdb/testsuite/gdb.fortran/fortran-frame-string.f90 new file mode 100644 index 00000000000..3d1576fb1fc --- /dev/null +++ b/gdb/testsuite/gdb.fortran/fortran-frame-string.f90 @@ -0,0 +1,28 @@ +! Copyright 2014 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 2 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, write to the Free Software +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +! +! Ihis file is the Fortran source file for dynamic.exp. +! Original file written by Jakub Jelinek . +! Modified for the GDB testcase by Jan Kratochvil . + + subroutine f(s) + character*3 s + s = s + end + + program main + call f ('foo') + end diff --git a/gdb/testsuite/gdb.fortran/omp-step.exp b/gdb/testsuite/gdb.fortran/omp-step.exp new file mode 100644 index 00000000000..66440a7507f --- /dev/null +++ b/gdb/testsuite/gdb.fortran/omp-step.exp @@ -0,0 +1,31 @@ +# Copyright 2009 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 . + +set testfile "omp-step" +set srcfile ${testfile}.f90 +if { [prepare_for_testing $testfile.exp $testfile $srcfile {debug f90 additional_flags=-fopenmp}] } { + return -1 +} + +if ![runto [gdb_get_line_number "start-here"]] { + perror "Couldn't run to start-here" + return 0 +} + +gdb_test "next" {!\$omp parallel} "step closer" +gdb_test "next" {a\(omp_get_thread_num\(\) \+ 1\) = 1} "step into omp" + +gdb_breakpoint [gdb_get_line_number "success"] +gdb_continue_to_breakpoint "success" ".*success.*" diff --git a/gdb/testsuite/gdb.fortran/omp-step.f90 b/gdb/testsuite/gdb.fortran/omp-step.f90 new file mode 100644 index 00000000000..a0cfb370144 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/omp-step.f90 @@ -0,0 +1,32 @@ +! Copyright 2009 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 . + + use omp_lib + integer nthreads, i, a(1000) + nthreads = omp_get_num_threads() + if (nthreads .gt. 1000) call abort + + do i = 1, nthreads + a(i) = 0 + end do + print *, "start-here" +!$omp parallel + a(omp_get_thread_num() + 1) = 1 +!$omp end parallel + do i = 1, nthreads + if (a(i) .ne. 1) call abort + end do + print *, "success" + end diff --git a/gdb/testsuite/gdb.fortran/pointers.exp b/gdb/testsuite/gdb.fortran/pointers.exp new file mode 100644 index 00000000000..67cf99989d8 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/pointers.exp @@ -0,0 +1,143 @@ +# Copyright 2016 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 . + +standard_testfile "pointers.f90" +load_lib fortran.exp + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ + {debug f90 quiet}] } { + return -1 +} + +if ![runto_main] { + untested "could not run to main" + return -1 +} + +# Depending on the compiler being used, the type names can be printed differently. +set logical [fortran_logical4] +set real [fortran_real4] +set int [fortran_int4] +set complex [fortran_complex4] + + +gdb_breakpoint [gdb_get_line_number "Before pointer assignment"] +gdb_continue_to_breakpoint "Before pointer assignment" +gdb_test "print logp" "= \\(PTR TO -> \\( $logical \\)\\) 0x0" "print logp, not associated" +gdb_test "print *logp" "Cannot access memory at address 0x0" "print *logp, not associated" +gdb_test "print comp" "= \\(PTR TO -> \\( $complex \\)\\) 0x0" "print comp, not associated" +gdb_test "print *comp" "Cannot access memory at address 0x0" "print *comp, not associated" +gdb_test "print charp" "= \\(PTR TO -> \\( character\\*1 \\)\\) 0x0" "print charp, not associated" +gdb_test "print *charp" "Cannot access memory at address 0x0" "print *charp, not associated" +gdb_test "print charap" "= \\(PTR TO -> \\( character\\*3 \\)\\) 0x0" "print charap, not associated" +gdb_test "print *charap" "Cannot access memory at address 0x0" "print *charap, not associated" +gdb_test "print intp" "= \\(PTR TO -> \\( $int \\)\\) 0x0" "print intp, not associated" +gdb_test "print *intp" "Cannot access memory at address 0x0" "print *intp, not associated" +set test "print intap, not associated" +gdb_test_multiple "print intap" $test { + -re " = \\(PTR TO -> \\( $int \\(:,:\\)\\)\\) \r\n$gdb_prompt $" { + pass $test + } + -re " = \r\n$gdb_prompt $" { + pass $test + } +} +gdb_test "print realp" "= \\(PTR TO -> \\( $real \\)\\) 0x0" "print realp, not associated" +gdb_test "print *realp" "Cannot access memory at address 0x0" "print *realp, not associated" +gdb_test "print \$my_var = intp" "= \\(PTR TO -> \\( $int \\)\\) 0x0" +set test "print cyclicp1, not associated" +gdb_test_multiple "print cyclicp1" $test { + -re "= \\( i = -?\\d+, p = 0x0 \\)\r\n$gdb_prompt $" { + pass $test + } + -re "= \\( i = -?\\d+, p = \\)\r\n$gdb_prompt $" { + pass $test + } +} +set test "print cyclicp1%p, not associated" +gdb_test_multiple "print cyclicp1%p" $test { + -re "= \\(PTR TO -> \\( Type typewithpointer \\)\\) 0x0\r\n$gdb_prompt $" { + pass $test + } + -re "= \\(PTR TO -> \\( Type typewithpointer \\)\\) \r\n$gdb_prompt $" { + pass $test + } +} + + +gdb_breakpoint [gdb_get_line_number "Before value assignment"] +gdb_continue_to_breakpoint "Before value assignment" +gdb_test "print *(twop)%ivla2" "= " + + +gdb_breakpoint [gdb_get_line_number "After value assignment"] +gdb_continue_to_breakpoint "After value assignment" +gdb_test "print logp" "= \\(PTR TO -> \\( $logical \\)\\) $hex\( <.*>\)?" +gdb_test "print *logp" "= \\.TRUE\\." +gdb_test "print comp" "= \\(PTR TO -> \\( $complex \\)\\) $hex\( <.*>\)?" +gdb_test "print *comp" "= \\(1,2\\)" +gdb_test "print charp" "= \\(PTR TO -> \\( character\\*1 \\)\\) $hex\( <.*>\)?" +gdb_test "print *charp" "= 'a'" +gdb_test "print charap" "= \\(PTR TO -> \\( character\\*3 \\)\\) $hex\( <.*>\)?" +gdb_test "print *charap" "= 'abc'" +gdb_test "print intp" "= \\(PTR TO -> \\( $int \\)\\) $hex\( <.*>\)?" +gdb_test "print *intp" "= 10" +set test_name "print intap, associated" +gdb_test_multiple "print intap" $test_name { + -re "= \\(\\( 1, 1, 3(, 1){7}\\) \\( 1(, 1){9}\\) \\)\r\n$gdb_prompt $" { + pass $test_name + } + -re "= \\(PTR TO -> \\( $int \\(10,2\\)\\)\\) $hex\( <.*>\)?\r\n$gdb_prompt $" { + gdb_test "print *intap" "= \\(\\( 1, 1, 3(, 1){7}\\) \\( 1(, 1){9}\\) \\)" + pass $test_name + } +} +set test_name "print intvlap, associated" +gdb_test_multiple "print intvlap" $test_name { + -re "= \\(2, 2, 2, 4(, 2){6}\\)\r\n$gdb_prompt $" { + pass $test_name + } + -re "= \\(PTR TO -> \\( $int \\(10\\)\\)\\) $hex\( <.*>\)?\r\n$gdb_prompt $" { + gdb_test "print *intvlap" "= \\(2, 2, 2, 4(, 2){6}\\)" + pass $test_name + } +} +gdb_test "print realp" "= \\(PTR TO -> \\( $real \\)\\) $hex\( <.*>\)?" +gdb_test "print *realp" "= 3\\.14000\\d+" +gdb_test "print arrayOfPtr(2)%p" "= \\(PTR TO -> \\( Type two \\)\\) $hex\( <.*>\)?" +gdb_test "print *(arrayOfPtr(2)%p)" "= \\( ivla1 = \\(11, 12, 13\\), ivla2 = \\(\\( 211, 221\\) \\( 212, 222\\) \\) \\)" +set test_name "print arrayOfPtr(3)%p" +gdb_test_multiple $test_name $test_name { + -re "= \\(PTR TO -> \\( Type two \\)\\) \r\n$gdb_prompt $" { + pass $test_name + } + -re "= \\(PTR TO -> \\( Type two \\)\\) 0x0\r\n$gdb_prompt $" { + pass $test_name + } +} +set test_name "print *(arrayOfPtr(3)%p), associated" +gdb_test_multiple "print *(arrayOfPtr(3)%p)" $test_name { + -re "Cannot access memory at address 0x0\r\n$gdb_prompt $" { + pass $test_name + } + -re "Attempt to take contents of a not associated pointer.\r\n$gdb_prompt $" { + pass $test_name + } +} +gdb_test "print cyclicp1" "= \\( i = 1, p = $hex\( <.*>\)? \\)" +gdb_test "print cyclicp1%p" "= \\(PTR TO -> \\( Type typewithpointer \\)\\) $hex\( <.*>\)?" +gdb_test "print *((integer*) &inta + 2)" "= 3" "print temporary pointer, array" +gdb_test "print *((integer*) &intvla + 3)" "= 4" "print temporary pointer, allocated vla" +gdb_test "print \$pc" "= \\(PTR TO -> \\( void \\(\\)\\(\\)\\)\\) $hex " "Print program counter" diff --git a/gdb/testsuite/gdb.fortran/pointers.f90 b/gdb/testsuite/gdb.fortran/pointers.f90 new file mode 100644 index 00000000000..6240c87988e --- /dev/null +++ b/gdb/testsuite/gdb.fortran/pointers.f90 @@ -0,0 +1,109 @@ +! Copyright 2016 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 . + +program pointers + + type :: two + integer, allocatable :: ivla1 (:) + integer, allocatable :: ivla2 (:, :) + end type two + + type :: typeWithPointer + integer i + type(typeWithPointer), pointer:: p + end type typeWithPointer + + type :: twoPtr + type (two), pointer :: p + end type twoPtr + + logical, target :: logv + complex, target :: comv + character, target :: charv + character (len=3), target :: chara + integer, target :: intv + integer, target, dimension (10,2) :: inta + integer, target, allocatable, dimension (:) :: intvla + real, target :: realv + type(two), target :: twov + type(twoPtr) :: arrayOfPtr (3) + type(typeWithPointer), target:: cyclicp1,cyclicp2 + + logical, pointer :: logp + complex, pointer :: comp + character, pointer:: charp + character (len=3), pointer:: charap + integer, pointer :: intp + integer, pointer, dimension (:,:) :: intap + integer, pointer, dimension (:) :: intvlap + real, pointer :: realp + type(two), pointer :: twop + + nullify (logp) + nullify (comp) + nullify (charp) + nullify (charap) + nullify (intp) + nullify (intap) + nullify (intvlap) + nullify (realp) + nullify (twop) + nullify (arrayOfPtr(1)%p) + nullify (arrayOfPtr(2)%p) + nullify (arrayOfPtr(3)%p) + nullify (cyclicp1%p) + nullify (cyclicp2%p) + + logp => logv ! Before pointer assignment + comp => comv + charp => charv + charap => chara + intp => intv + intap => inta + intvlap => intvla + realp => realv + twop => twov + arrayOfPtr(2)%p => twov + cyclicp1%i = 1 + cyclicp1%p => cyclicp2 + cyclicp2%i = 2 + cyclicp2%p => cyclicp1 + + logv = associated(logp) ! Before value assignment + comv = cmplx(1,2) + charv = "a" + chara = "abc" + intv = 10 + inta(:,:) = 1 + inta(3,1) = 3 + allocate (intvla(10)) + intvla(:) = 2 + intvla(4) = 4 + intvlap => intvla + realv = 3.14 + + allocate (twov%ivla1(3)) + allocate (twov%ivla2(2,2)) + twov%ivla1(1) = 11 + twov%ivla1(2) = 12 + twov%ivla1(3) = 13 + twov%ivla2(1,1) = 211 + twov%ivla2(2,1) = 221 + twov%ivla2(1,2) = 212 + twov%ivla2(2,2) = 222 + + intv = intv + 1 ! After value assignment + +end program pointers diff --git a/gdb/testsuite/gdb.fortran/print_type.exp b/gdb/testsuite/gdb.fortran/print_type.exp new file mode 100644 index 00000000000..45b4968f6c2 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/print_type.exp @@ -0,0 +1,100 @@ +# Copyright 2016 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 . + +standard_testfile "pointers.f90" +load_lib fortran.exp + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ + {debug f90 quiet}] } { + return -1 +} + + +if ![runto_main] { + untested "could not run to main" + return -1 +} + +# Depending on the compiler being used, the type names can be printed differently. +set logical [fortran_logical4] +set real [fortran_real4] +set int [fortran_int4] +set complex [fortran_complex4] + +gdb_breakpoint [gdb_get_line_number "Before pointer assignment"] +gdb_continue_to_breakpoint "Before pointer assignment" +gdb_test "ptype logp" "type = PTR TO -> \\( $logical \\)" "ptype logp, not associated" +gdb_test "ptype comp" "type = PTR TO -> \\( $complex \\)" "ptype comp, not associated" +gdb_test "ptype charp" "type = PTR TO -> \\( character\\*1 \\)" "ptype charp, not associated" +gdb_test "ptype charap" "type = PTR TO -> \\( character\\*3 \\)" "ptype charap, not associated" +gdb_test "ptype intp" "type = PTR TO -> \\( $int \\)" "ptype intp, not associated" +set test "ptype intap, not associated" +gdb_test_multiple "ptype intap" $test { + -re "type = PTR TO -> \\( $int \\(:,:\\)\\)\r\n$gdb_prompt $" { + pass $test + } + -re "type = $int \\(:,:\\)\r\n$gdb_prompt $" { + pass $test + } +} +gdb_test "ptype realp" "type = PTR TO -> \\( $real \\)" "ptype realp, not associated" +gdb_test "ptype twop" \ + [multi_line "type = PTR TO -> \\( Type two" \ + " $int :: ivla1\\(:\\)" \ + " $int :: ivla2\\(:,:\\)" \ + "End Type two \\)"] \ + "ptype twop, not associated" +gdb_test "ptype two" \ + [multi_line "type = Type two" \ + " $int :: ivla1\\(:\\)" \ + " $int :: ivla2\\(:,:\\)" \ + "End Type two"] + + +gdb_breakpoint [gdb_get_line_number "Before value assignment"] +gdb_continue_to_breakpoint "Before value assignment" +gdb_test "ptype twop" \ + [multi_line "type = PTR TO -> \\( Type two" \ + " $int :: ivla1\\(:\\)" \ + " $int :: ivla2\\(:,:\\)" \ + "End Type two \\)"] + + +gdb_breakpoint [gdb_get_line_number "After value assignment"] +gdb_continue_to_breakpoint "After value assignment" +gdb_test "ptype logv" "type = $logical" +gdb_test "ptype comv" "type = $complex" +gdb_test "ptype charv" "type = character\\*1" +gdb_test "ptype chara" "type = character\\*3" +gdb_test "ptype intv" "type = $int" +gdb_test "ptype inta" "type = $int \\(10,2\\)" +gdb_test "ptype realv" "type = $real" + + +gdb_test "ptype logp" "type = PTR TO -> \\( $logical \\)" +gdb_test "ptype comp" "type = PTR TO -> \\( $complex \\)" +gdb_test "ptype charp" "type = PTR TO -> \\( character\\*1 \\)" +gdb_test "ptype charap" "type = PTR TO -> \\( character\\*3 \\)" +gdb_test "ptype intp" "type = PTR TO -> \\( $int \\)" +set test "ptype intap" +gdb_test_multiple $test $test { + -re "type = $int \\(10,2\\)\r\n$gdb_prompt $" { + pass $test + } + -re "type = PTR TO -> \\( $int \\(10,2\\)\\)\r\n$gdb_prompt $" { + pass $test + } +} +gdb_test "ptype realp" "type = PTR TO -> \\( $real \\)" diff --git a/gdb/testsuite/gdb.fortran/printing-types.exp b/gdb/testsuite/gdb.fortran/printing-types.exp index 2f6be4ec249..a1875c7e64c 100644 --- a/gdb/testsuite/gdb.fortran/printing-types.exp +++ b/gdb/testsuite/gdb.fortran/printing-types.exp @@ -29,7 +29,7 @@ if {![runto MAIN__]} then { gdb_breakpoint [gdb_get_line_number "write"] gdb_continue_to_breakpoint "write" -gdb_test "print oneByte" " = 1" +gdb_test "print oneByte" " = 1 \'\\\\001\'" gdb_test "print twobytes" " = 2" gdb_test "print chvalue" " = \'a\'" gdb_test "print logvalue" " = \.TRUE\." diff --git a/gdb/testsuite/gdb.fortran/static-arrays.exp b/gdb/testsuite/gdb.fortran/static-arrays.exp new file mode 100644 index 00000000000..cc9ecc04ab6 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/static-arrays.exp @@ -0,0 +1,421 @@ +# Copyright 2015 Free Software Foundation, Inc. +# +# Contributed by Intel Corp. +# +# 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 . + +standard_testfile static-arrays.f90 + +if { [prepare_for_testing $testfile.exp $testfile $srcfile {debug f90}] } { + return -1 +} + +if ![runto MAIN__] then { + perror "couldn't run to breakpoint MAIN__" + continue +} + +gdb_breakpoint [gdb_get_line_number "BP1"] +gdb_continue_to_breakpoint "BP1" ".*BP1.*" + +# Tests subarrays of one dimensional arrays with subrange variations +gdb_test "print ar1" "\\$\[0-9\]+ = \\(1, 2, 3, 4, 5, 6, 7, 8, 9\\)" \ + "print ar1." +gdb_test "print ar1\(4:7\)" "\\$\[0-9\]+ = \\(4, 5, 6, 7\\)" \ + "print ar1\(4:7\)" +gdb_test "print ar1\(8:\)" "\\$\[0-9\]+ = \\(8, 9\\).*" \ + "print ar1\(8:\)" +gdb_test "print ar1\(:3\)" "\\$\[0-9\]+ = \\(1, 2, 3\\).*" \ + "print ar1\(:3\)" +gdb_test "print ar1\(:\)" "\\$\[0-9\]+ = \\(1, 2, 3, 4, 5, 6, 7, 8, 9\\)" \ + "print ar1\(:\)" + +# Check assignment +gdb_test_no_output "set \$my_ary = ar1\(3:8\)" +gdb_test "print \$my_ary" \ + "\\$\[0-9\]+ = \\(3, 4, 5, 6, 7, 8\\)" \ + "Assignment of subarray to variable" +gdb_test_no_output "set ar1\(5\) = 42" + gdb_test "print ar1\(3:8\)" \ + "\\$\[0-9\]+ = \\(3, 4, 42, 6, 7, 8\\)" \ + "print ar1\(3:8\) after assignment" +gdb_test "print \$my_ary" \ + "\\$\[0-9\]+ = \\(3, 4, 5, 6, 7, 8\\)" \ + "Assignment of subarray to variable after original array changed" + +# Test for subarrays of one dimensional arrays with literals + gdb_test "print ar1\(3\)" "\\$\[0-9\]+ = 3" \ + "print ar1\(3\)" + +# Tests for subranges of 2 dimensional arrays with subrange variations +gdb_test "print ar2\(2:3, 3:4\)" \ + "\\$\[0-9\]+ = \\(\\( 23, 33\\) \\( 24, 34\\) \\)" \ + "print ar2\(2:3, 3:4\)." +gdb_test "print ar2\(8:9,8:\)" \ + "\\$\[0-9\]+ = \\(\\( 88, 98\\) \\( 89, 99\\) \\)" \ + "print ar2\(8:9,8:\)" +gdb_test "print ar2\(8:9,:2\)" \ + "\\$\[0-9\]+ = \\(\\( 81, 91\\) \\( 82, 92\\) \\)" \ + "print ar2\(8:9,:2\)" + +gdb_test "print ar2\(8:,8:9\)" \ + "\\$\[0-9\]+ = \\(\\( 88, 98\\) \\( 89, 99\\) \\)" \ + "print ar2\(8:,8:9\)" +gdb_test "print ar2\(8:,8:\)" \ + "\\$\[0-9\]+ = \\(\\( 88, 98\\) \\( 89, 99\\) \\)" \ + "print ar2\(8:,8:\)" +gdb_test "print ar2\(8:,:2\)" \ + "\\$\[0-9\]+ = \\(\\( 81, 91\\) \\( 82, 92\\) \\)" \ + "print ar2\(8:,:2\)" + +gdb_test "print ar2\(:2,2:3\)" \ + "\\$\[0-9\]+ = \\(\\( 12, 22\\) \\( 13, 23\\) \\)" \ + "print ar2\(:2,2:3\)" +gdb_test "print ar2\(:2,8:\)" \ + "\\$\[0-9\]+ = \\(\\( 18, 28\\) \\( 19, 29\\) \\)" \ + "print ar2\(:2,8:\)" +gdb_test "print ar2\(:2,:2\)" \ + "\\$\[0-9\]+ = \\(\\( 11, 21\\) \\( 12, 22\\) \\)" \ + "print ar2\(:2,:2\)" + +# Test subranges of 2 dimensional arrays with literals and subrange variations +gdb_test "print ar2\(7, 3:6\)" \ + "\\$\[0-9\]+ = \\(73, 74, 75, 76\\)" \ + "print ar2\(7, 3:6\)" +gdb_test "print ar2\(7,8:\)" \ + "\\$\[0-9\]+ = \\(78, 79\\)" \ + "print ar2\(7,8:\)" +gdb_test "print ar2\(7,:2\)" \ + "\\$\[0-9\]+ = \\(71, 72\\)" \ + "print ar2\(7,:2\)" + +gdb_test "print ar2\(7:8,4\)" \ + "\\$\[0-9\]+ = \\(74, 84\\)" \ + "print ar2(7:8,4\)" +gdb_test "print ar2\(8:,4\)" \ + "\\$\[0-9\]+ = \\(84, 94\\)" \ + "print ar2\(8:,4\)" +gdb_test "print ar2\(:2,4\)" \ + "\\$\[0-9\]+ = \\(14, 24\\)" \ + "print ar2\(:2,4\)" +gdb_test "print ar2\(3,4\)" \ + "\\$\[0-9\]+ = 34" \ + "print ar2\(3,4\)" + +# Test subarrays of 3 dimensional arrays with literals and subrange variations +gdb_test "print ar3\(2:4,3:4,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 237, 337, 437\\) \\( 247, 347, 447\\)\ + \\) \\( \\( 238, 338, 438\\) \\( 248, 348, 448\\) \\) \\)" \ + "print ar3\(2:4,3:4,7:8\)" +gdb_test "print ar3\(2:3,4:5,8:\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 248, 348\\) \\( 258, 358\\) \\) \\(\ + \\( 249, 349\\) \\( 259, 359\\) \\) \\)" \ + "print ar3\(2:3,4:5,8:\)" +gdb_test "print ar3\(2:3,4:5,:2\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 241, 341\\) \\( 251, 351\\) \\) \\(\ + \\( 242, 342\\) \\( 252, 352\\) \\) \\)" \ + "print ar3\(2:3,4:5,:2\)" + +gdb_test "print ar3\(2:3,8:,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 287, 387\\) \\( 297, 397\\) \\) \\(\ + \\( 288, 388\\) \\( 298, 398\\) \\) \\)" \ + "print ar3\(2:3,8:,7:8\)" +gdb_test "print ar3\(2:3,8:,8:\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 288, 388\\) \\( 298, 398\\) \\) \\(\ + \\( 289, 389\\) \\( 299, 399\\) \\) \\)" \ + "print ar3\(2:3,8:,8:\)" +gdb_test "print ar3\(2:3,8:,:2\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 281, 381\\) \\( 291, 391\\) \\) \\(\ + \\( 282, 382\\) \\( 292, 392\\) \\) \\)" \ + "print ar3\(2:3,8:,:2\)" + +gdb_test "print ar3\(2:3,:2,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 217, 317\\) \\( 227, 327\\) \\) \\(\ + \\( 218, 318\\) \\( 228, 328\\) \\) \\)" \ + "print ar3\(2:3,:2,7:8\)" +gdb_test "print ar3\(2:3,:2,8:\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 218, 318\\) \\( 228, 328\\) \\) \\(\ + \\( 219, 319\\) \\( 229, 329\\) \\) \\)" \ + "print ar3\(2:3,:2,8:\)" +gdb_test "print ar3\(2:3,:2,:2\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 211, 311\\) \\( 221, 321\\) \\) \\(\ + \\( 212, 312\\) \\( 222, 322\\) \\) \\)" \ + "print ar3\(2:3,:2,:2\)" + +gdb_test "print ar3\(8:,3:4,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 837, 937\\) \\( 847, 947\\) \\) \\(\ + \\( 838, 938\\) \\( 848, 948\\) \\) \\)" \ + "print ar3\(8:,3:4,7:8\)" +gdb_test "print ar3\(8:,4:5,8:\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 848, 948\\) \\( 858, 958\\) \\) \\(\ + \\( 849, 949\\) \\( 859, 959\\) \\) \\)" \ + "print ar3\(8:,4:5,8:\)" +gdb_test "print ar3\(8:,4:5,:2\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 841, 941\\) \\( 851, 951\\) \\) \\(\ + \\( 842, 942\\) \\( 852, 952\\) \\) \\)" \ + "print ar3\(8:,4:5,:2\)" + +gdb_test "print ar3\(8:,8:,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 887, 987\\) \\( 897, 997\\) \\) \\(\ + \\( 888, 988\\) \\( 898, 998\\) \\) \\)" \ + "print ar3\(8:,8:,7:8\)" +gdb_test "print ar3\(8:,8:,8:\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 888, 988\\) \\( 898, 998\\) \\) \\(\ + \\( 889, 989\\) \\( 899, 999\\) \\) \\)" \ + "print ar3\(8:,8:,8:\)" +gdb_test "print ar3\(8:,8:,:2\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 881, 981\\) \\( 891, 991\\) \\) \\(\ + \\( 882, 982\\) \\( 892, 992\\) \\) \\)" \ + "print ar3\(8:,8:,:2\)" + +gdb_test "print ar3\(8:,:2,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 817, 917\\) \\( 827, 927\\) \\) \\(\ + \\( 818, 918\\) \\( 828, 928\\) \\) \\)" \ + "print ar3\(8:,:2,7:8\)" +gdb_test "print ar3\(8:,:2,8:\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 818, 918\\) \\( 828, 928\\) \\) \\(\ + \\( 819, 919\\) \\( 829, 929\\) \\) \\)" \ + "print ar3\(8:,:2,8:\)" +gdb_test "print ar3\(8:,:2,:2\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 811, 911\\) \\( 821, 921\\) \\) \\(\ + \\( 812, 912\\) \\( 822, 922\\) \\) \\)" \ + "print ar3\(8:,:2,:2\)" + + +gdb_test "print ar3\(:2,3:4,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 137, 237\\) \\( 147, 247\\) \\) \\(\ + \\( 138, 238\\) \\( 148, 248\\) \\) \\)" \ + "print ar3 \(:2,3:4,7:8\)." +gdb_test "print ar3\(:2,3:4,8:\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 138, 238\\) \\( 148, 248\\) \\) \\(\ + \\( 139, 239\\) \\( 149, 249\\) \\) \\)" \ + "print ar3\(:2,3:4,8:\)" +gdb_test "print ar3\(:2,3:4,:2\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 131, 231\\) \\( 141, 241\\) \\) \\(\ + \\( 132, 232\\) \\( 142, 242\\) \\) \\)" \ + "print ar3\(:2,3:4,:2\)" + +gdb_test "print ar3\(:2,8:,7:8\)" "\\$\[0-9\]+ = \\(\\( \\( 187, 287\\) \\(\ + 197, 297\\) \\) \\( \\( 188, 288\\) \\( 198, 298\\) \\) \\)" \ + "print ar3\(:2,8:,7:8\)" +gdb_test "print ar3\(:2,8:,8:\)" "\\$\[0-9\]+ = \\(\\( \\( 188, 288\\) \\( 198,\ + 298\\) \\) \\( \\( 189, 289\\) \\( 199, 299\\) \\) \\)" \ + "print ar3\(:2,8:,8:\)" +gdb_test "print ar3\(:2,8:,:2\)" "\\$\[0-9\]+ = \\(\\( \\( 181, 281\\) \\( 191,\ + 291\\) \\) \\( \\( 182, 282\\) \\( 192, 292\\) \\) \\)" \ + "print ar3\(:2,8:,:2\)" + +gdb_test "print ar3\(:2,:2,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 117, 217\\) \\( 127, 227\\) \\) \\(\ + \\( 118, 218\\) \\( 128, 228\\) \\) \\)" \ + "print ar3\(:2,:2,7:8\)" +gdb_test "print ar3\(:2,:2,8:\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 118, 218\\) \\( 128, 228\\) \\) \\(\ + \\( 119, 219\\) \\( 129, 229\\) \\) \\)" \ + "print ar3\(:2,:2,8:\)" +gdb_test "print ar3\(:2,:2,:2\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 111, 211\\) \\( 121, 221\\) \\) \\(\ + \\( 112, 212\\) \\( 122, 222\\) \\) \\)" \ + "print ar3\(:2,:2,:2\)" + +#Tests for subarrays of 3 dimensional arrays with literals and subranges +gdb_test "print ar3\(3,3:4,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( 337, 347\\) \\( 338, 348\\) \\)" \ + "print ar3\(3,3:4,7:8\)" +gdb_test "print ar3\(3,4:5,8:\)" \ + "\\$\[0-9\]+ = \\(\\( 348, 358\\) \\( 349, 359\\) \\)" \ + "print ar3\(3,4:5,8:\)" +gdb_test "print ar3\(3,4:5,:2\)" \ + "\\$\[0-9\]+ = \\(\\( 341, 351\\) \\( 342, 352\\) \\)" \ + "print ar3\(3,4:5,:2\)" +gdb_test "print ar3\(3,4:5,3\)" \ + "\\$\[0-9\]+ = \\(343, 353\\)" \ + "print ar3\(3,4:5,3\)" + +gdb_test "print ar3\(2,8:,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( 287, 297\\) \\( 288, 298\\) \\)" \ + "print ar3\(2,8:,7:8\)" +gdb_test "print ar3\(2,8:,8:\)" \ + "\\$\[0-9\]+ = \\(\\( 288, 298\\) \\( 289, 299\\) \\)" \ + "print ar3\(2,8:,8:\)" +gdb_test "print ar3\(2,8:,:2\)"\ + "\\$\[0-9\]+ = \\(\\( 281, 291\\) \\( 282, 292\\) \\)" \ + "print ar3\(2,8:,:2\)" +gdb_test "print ar3\(2,8:,3\)" \ + "\\$\[0-9\]+ = \\(283, 293\\)" \ + "print ar3\(2,8:,3\)" + +gdb_test "print ar3\(2,:2,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( 217, 227\\) \\( 218, 228\\) \\)" \ + "print ar3\(2,:2,7:8\)" +gdb_test "print ar3\(2,:2,8:\)" \ + "\\$\[0-9\]+ = \\(\\( 218, 228\\) \\( 219, 229\\) \\)" \ + "print ar3\(2,:2,8:\)" +gdb_test "print ar3\(2,:2,:2\)" \ + "\\$\[0-9\]+ = \\(\\( 211, 221\\) \\( 212, 222\\) \\)" \ + "print ar3\(2,:2,:2\)" +gdb_test "print ar3\(2,:2,3\)" \ + "\\$\[0-9\]+ = \\(213, 223\\)" \ + "print ar3\(2,:2,3\)" + +gdb_test "print ar3\(3,4,7:8\)" \ + "\\$\[0-9\]+ = \\(347, 348\\)" \ + "print ar3\(3,4,7:8\)" +gdb_test "print ar3\(3,4,8:\)" \ + "\\$\[0-9\]+ = \\(348, 349\\)" \ +i "print ar3\(3,4,8:\)" +gdb_test "print ar3\(3,4,:2\)" \ + "\\$\[0-9\]+ = \\(341, 342\\)" \ + "print ar3\(3,4,:2\)" +gdb_test "print ar3\(5,6,7\)" \ + "\\$\[0-9\]+ = 567" \ + "print ar3\(5,6,7\)" + +gdb_test "print ar3\(3:4,6,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( 367, 467\\) \\( 368, 468\\) \\)" \ + "print ar3\(3:4,6,7:8\)" +gdb_test "print ar3\(3:4,6,8:\)" \ + "\\$\[0-9\]+ = \\(\\( 368, 468\\) \\( 369, 469\\) \\)" \ + "print ar3\(3:4,6,8:\)" +gdb_test "print ar3\(3:4,6,:2\)" \ + "\\$\[0-9\]+ = \\(\\( 361, 461\\) \\( 362, 462\\) \\)" \ + "print ar3\(3:4,6,:2\)" +gdb_test "print ar3\(3:4,6,5\)" \ + "\\$\[0-9\]+ = \\(365, 465\\)" \ + "print ar3\(3:4,6,5\)" + +gdb_test "print ar3\(8:,6,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( 867, 967\\) \\( 868, 968\\) \\)" \ + "print ar3\(8:,6,7:8\)" +gdb_test "print ar3\(8:,6,8:\)" \ + "\\$\[0-9\]+ = \\(\\( 868, 968\\) \\( 869, 969\\) \\)" \ + "print ar3\(8:,6,8:\)" +gdb_test "print ar3\(8:,6,:2\)" \ + "\\$\[0-9\]+ = \\(\\( 861, 961\\) \\( 862, 962\\) \\)" \ + "print ar3\(8:,6,:2\)" +gdb_test "print ar3\(8:,6,5\)" \ + "\\$\[0-9\]+ = \\(865, 965\\)" \ + "print ar3\(8:,6,5\)" + +gdb_test "print ar3\(:2,6,7:8\)" \ + "\\$\[0-9\]+ = \\(\\( 167, 267\\) \\( 168, 268\\) \\)" \ + "print ar3\(:2,6,7:8\)" +gdb_test "print ar3\(:2,6,8:\)" \ + "\\$\[0-9\]+ = \\(\\( 168, 268\\) \\( 169, 269\\) \\)" \ + "print ar3\(:2,6,8:\)" +gdb_test "print ar3\(:2,6,:2\)" \ + "\\$\[0-9\]+ = \\(\\( 161, 261\\) \\( 162, 262\\) \\)" \ + "print ar3\(:2,6,:2\)" +gdb_test "print ar3\(:2,6,5\)" \ + "\\$\[0-9\]+ = \\(165, 265\\)" \ + "print ar3\(:2,6,5\)" + +gdb_test "print ar3\(3:4,5:6,4\)" \ + "\\$\[0-9\]+ = \\(\\( 354, 454\\) \\( 364, 464\\) \\)" \ + "print ar2\(3:4,5:6,4\)" +gdb_test "print ar3\(8:,5:6,4\)" \ + "\\$\[0-9\]+ = \\(\\( 854, 954\\) \\( 864, 964\\) \\)" \ + "print ar2\(8:,5:6,4\)" +gdb_test "print ar3\(:2,5:6,4\)" \ + "\\$\[0-9\]+ = \\(\\( 154, 254\\) \\( 164, 264\\) \\)" \ + "print ar2\(:2,5:6,4\)" + +# Stride > 1 +gdb_test "print ar1\(2:6:2\)" \ + "\\$\[0-9\]+ = \\(2, 4, 6\\)" \ + "print ar1\(2:6:2\)" +gdb_test "print ar2\(2:6:2,3:4\)" \ + "\\$\[0-9\]+ = \\(\\( 23, 43, 63\\) \\( 24, 44, 64\\) \\)" \ + "print ar2\(2:6:2,3:4\)" +gdb_test "print ar2\(2:6:2,3\)" \ + "\\$\[0-9\]+ = \\(23, 43, 63\\)" \ + "print ar2\(2:6:2,3\)" +gdb_test "print ar3\(2:6:2,3:5:2,4:7:3\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 234, 434, 634\\) \\( 254, 454, 654\\)\ + \\) \\( \\( 237, 437, 637\\) \\( 257, 457, 657\\) \\) \\)" \ + "print ar3\(2:6:2,3:5:2,4:7:3\)" +gdb_test "print ar3\(2:6:2,5,4:7:3\)" \ + "\\$\[0-9\]+ = \\(\\( 254, 454, 654\\) \\( 257, 457, 657\\)\ + \\)" \ + "print ar3\(2:6:2,5,4:7:3\)" + +# Stride < 0 +gdb_test "print ar1\(8:2:-2\)" \ + "\\$\[0-9\]+ = \\(8, 6, 4, 2\\)" \ + "print ar1\(8:2:-2\)" +gdb_test "print ar2\(8:2:-2,3:4\)" \ + "\\$\[0-9\]+ = \\(\\( 83, 63, 43, 23\\) \\( 84, 64, 44, 24\\)\ + \\)" \ + "print ar2\(8:2:-2,3:4\)" +gdb_test "print ar2\(2:6:2,3\)" \ + "\\$\[0-9\]+ = \\(23, 43, 63\\)" \ + "print ar2\(2:6:2,3\)" +gdb_test "print ar3\(2:3,7:3:-4,4:7:3\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 274, 374\\) \\( 234, 334\\) \\) \\(\ + \\( 277, 377\\) \\( 237, 337\\) \\) \\)" \ + "print ar3\(2:3,7:3:-4,4:7:3\)" +gdb_test "print ar3\(2:6:2,5,7:4:-3\)" \ + "\\$\[0-9\]+ = \\(\\( 257, 457, 657\\) \\( 254, 454, 654\\)\ + \\)" \ + "print ar3\(2:6:2,5,7:4:-3\)" + +# Tests with negative and mixed indices +gdb_test "p ar4\(2:4, -2:1, -15:-14\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 261, 361, 461\\) \\( 271, 371, 471\\)\ + \\( 281, 381, 481\\) \\( 291, 391, 491\\) \\) \\( \\( 262,\ + 362, 462\\) \\( 272, 372, 472\\) \\( 282, 382, 482\\) \\( 292,\ + 392, 492\\) \\) \\)" \ + "print ar4(2:4, -2:1, -15:-14)" + +gdb_test "p ar4\(7,-6:2:3,-7\)" \ + "\\$\[0-9\]+ = \\(729, 759, 789\\)" \ + "print ar4(7,-6:2:3,-7)" + +gdb_test "p ar4\(9:2:-2, -6:2:3, -6:-15:-3\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 930, 730, 530, 330\\) \\( 960, 760,\ + 560, 360\\) \\( 990, 790, 590, 390\\) \\) \\( \\( 927, 727,\ + 527, 327\\) \\( 957, 757, 557, 357\\) \\( 987, 787, 587,\ + 387\\) \\) \\( \\( 924, 724, 524, 324\\) \\( 954, 754, 554,\ + 354\\) \\( 984, 784, 584, 384\\) \\) \\( \\( 921, 721, 521,\ + 321\\) \\( 951, 751, 551, 351\\) \\( 981, 781, 581, 381\\) \\)\ + \\)" \ + "print ar4(9:2:-2, -6:2:3, -6:-15:-3)" + +gdb_test "p ar4\(:,:,:\)" \ + "\\$\[0-9\]+ = \\(\\( \\( 111, 211, 311, 411, 511, 611, 711,\ + 811, .*" \ + "print ar4(:,:,:)" + +# Provoke error messages for bad user input +gdb_test "print ar1\(0:4\)" \ + "provided bound\\(s\\) outside array bound\\(s\\)" \ + "print ar1\(0:4\)" +gdb_test "print ar1\(8:12\)" \ + "provided bound\\(s\\) outside array bound\\(s\\)" \ + "print ar1\(8:12\)" +gdb_test "print ar1\(8:2:\)" \ + "A syntax error in expression, near `\\)'." \ + "print ar1\(8:2:\)" +gdb_test "print ar1\(8:2:2\)" \ + "Wrong value provided for stride and boundaries" \ + "print ar1\(8:2:2\)" +gdb_test "print ar1\(2:8:-2\)" \ + "Wrong value provided for stride and boundaries" \ + "print ar1\(2:8:-2\)" +gdb_test "print ar1\(2:7:0\)" \ + "Stride must not be 0" \ + "print ar1\(2:7:0\)" +gdb_test "print ar1\(3:7\) = 42" \ + "Invalid cast." \ + "Assignment of value to subarray" diff --git a/gdb/testsuite/gdb.fortran/static-arrays.f90 b/gdb/testsuite/gdb.fortran/static-arrays.f90 new file mode 100644 index 00000000000..f22fcbe1244 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/static-arrays.f90 @@ -0,0 +1,55 @@ +! Copyright 2015 Free Software Foundation, Inc. +! +! Contributed by Intel Corp. +! +! 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 . + +subroutine sub + integer, dimension(9) :: ar1 + integer, dimension(9,9) :: ar2 + integer, dimension(9,9,9) :: ar3 + integer, dimension(10,-7:3, -15:-5) :: ar4 + integer :: i,j,k + + ar1 = 1 + ar2 = 1 + ar3 = 1 + ar4 = 4 + + ! Resulting array ar3 looks like ((( 111, 112, 113, 114,...))) + do i = 1, 9, 1 + ar1(i) = i + do j = 1, 9, 1 + ar2(i,j) = i*10 + j + do k = 1, 9, 1 + ar3(i,j,k) = i*100 + j*10 + k + end do + end do + end do + + do i = 1, 10, 1 + do j = -7, 3, 1 + do k = -15, -5, 1 + ar4(i,j,k) = i*100 + (j+8)*10 + (k+16) + end do + end do + end do + + ar1(1) = 11 !BP1 + return +end + +program testprog + call sub +end diff --git a/gdb/testsuite/gdb.fortran/string.exp b/gdb/testsuite/gdb.fortran/string.exp new file mode 100644 index 00000000000..1b7c0dbf73e --- /dev/null +++ b/gdb/testsuite/gdb.fortran/string.exp @@ -0,0 +1,59 @@ +# Copyright 2008 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# This file was written by Jan Kratochvil . + +# This file is part of the gdb testsuite. It contains tests for Fortran +# strings with dynamic length. + +set testfile "string" +set srcfile ${testfile}.f90 +set binfile [standard_output_file ${testfile}] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug f90 quiet}] != "" } { + untested "Couldn't compile ${srcfile}" + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if ![runto MAIN__] then { + perror "couldn't run to breakpoint MAIN__" + continue +} + +gdb_breakpoint [gdb_get_line_number "var-init"] +gdb_continue_to_breakpoint "var-init" +gdb_test "ptype c" "type = character(\\(kind=1\\)|\\*1)" +gdb_test "ptype d" "type = character(\\(kind=8\\)|\\*8)" +gdb_test "ptype e" "type = character(\\(kind=4\\)|\\*4)" +gdb_test "ptype f" "type = character(\\(kind=4\\)|\\*4) \\(7,8:10\\)" +gdb_test "ptype *e" "Attempt to take contents of a non-pointer value." +gdb_test "ptype *f" "type = character(\\(kind=4\\)|\\*4) \\(7\\)" +gdb_test "p c" "\\$\[0-9\]* = 'c'" +gdb_test "p d" "\\$\[0-9\]* = 'd '" +gdb_test "p e" "\\$\[0-9\]* = 'g '" +gdb_test "p f" "\\$\[0-9\]* = \\(\\( 'h ', 'h ', 'h ', 'h ', 'h ', 'h ', 'h '\\) \\( 'h ', 'h ', 'h ', 'h ', 'h ', 'h ', 'h '\\) \\( 'h ', 'h ', 'h ', 'h ', 'h ', 'h ', 'h '\\) \\)" +gdb_test "p *e" "Attempt to take contents of a non-pointer value." +gdb_test "p *f" "Attempt to take contents of a non-pointer value." + +gdb_breakpoint [gdb_get_line_number "var-finish"] +gdb_continue_to_breakpoint "var-finish" +gdb_test "p e" "\\$\[0-9\]* = 'e '" "p e re-set" +gdb_test "p f" "\\$\[0-9\]* = \\(\\( 'f ', 'f ', 'f ', 'f ', 'f ', 'f ', 'f '\\) \\( 'f2 ', 'f ', 'f ', 'f ', 'f ', 'f ', 'f '\\) \\( 'f ', 'f ', 'f ', 'f ', 'f ', 'f ', 'f '\\) \\)" "p *f re-set" diff --git a/gdb/testsuite/gdb.fortran/string.f90 b/gdb/testsuite/gdb.fortran/string.f90 new file mode 100644 index 00000000000..226dc5d0fff --- /dev/null +++ b/gdb/testsuite/gdb.fortran/string.f90 @@ -0,0 +1,37 @@ +! Copyright 2008 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 2 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, write to the Free Software +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +! +! Ihis file is the Fortran source file for dynamic.exp. +! Original file written by Jakub Jelinek . +! Modified for the GDB testcase by Jan Kratochvil . + +subroutine foo (e, f) + character (len=1) :: c + character (len=8) :: d + character (len=*) :: e + character (len=*) :: f (1:7, 8:10) + c = 'c' + d = 'd' + e = 'e' ! var-init + f = 'f' + f(1,9) = 'f2' + c = 'c' ! var-finish +end subroutine foo + character (len=4) :: g, h (1:7, 8:10) + g = 'g' + h = 'h' + call foo (g, h) +end diff --git a/gdb/testsuite/gdb.fortran/subrange.exp b/gdb/testsuite/gdb.fortran/subrange.exp new file mode 100644 index 00000000000..c121ab97512 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/subrange.exp @@ -0,0 +1,72 @@ +# Copyright 2011 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 . + +if { [skip_fortran_tests] } { return -1 } + +set testfile "subrange" +set srcfile ${testfile}.f90 +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} {debug f90}] } { + return -1 +} + +if ![runto MAIN__] { + perror "Couldn't run to MAIN__" + continue +} + +# Depending on the compiler version being used, the name of the 4-byte integer +# and real types can be printed differently. For instance, gfortran-4.1 uses +# "int4" whereas gfortran-4.3 uses "int(kind=4)". +set int4 "(int4|integer\\(kind=4\\))" + +gdb_breakpoint [gdb_get_line_number "break-static"] +gdb_continue_to_breakpoint "break-static" ".*break-static.*" + +foreach var {a alloc ptr} { + global pf_prefix + set old_prefix $pf_prefix + lappend pf_prefix "$var:" + + setup_kfail "*-*-*" "vlaregression/9999" + gdb_test "p $var (2, 2:3)" { = \(22, 32\)} + setup_kfail "*-*-*" "vlaregression/9999" + gdb_test "p $var (2:3, 3)" { = \(32, 33\)} + setup_kfail "*-*-*" "vlaregression/9999" + gdb_test "p $var (1, 2:)" { = \(21, 31\)} + setup_kfail "*-*-*" "vlaregression/9999" + gdb_test "p $var (2, :2)" { = \(12, 22\)} + setup_kfail "*-*-*" "vlaregression/9999" + gdb_test "p $var (3, 2:2)" { = \(23\)} + setup_kfail "*-*-*" "vlaregression/9999" + gdb_test "ptype $var (3, 2:2)" " = $int4 \\(2:2\\)" + setup_kfail "*-*-*" "vlaregression/9999" + gdb_test "p $var (4, :)" { = \(14, 24, 34\)} + setup_kfail "*-*-*" "vlaregression/9999" + gdb_test "p $var (:, :)" { = \(\( *11, 12, 13, 14\) \( *21, 22, 23, 24\) \( *31, 32, 33, 34\) *\)} + setup_kfail "*-*-*" "vlaregression/9999" + gdb_test "ptype $var (:, :)" " = $int4 \\(4,3\\)" + setup_kfail "*-*-*" "vlaregression/9999" + gdb_test "p $var (:)" "Wrong number of subscripts" + setup_kfail "*-*-*" "vlaregression/9999" + gdb_test "p $var (:, :, :)" "Wrong number of subscripts" + + set pf_prefix $old_prefix +} + +gdb_test_no_output {set $a=a} +delete_breakpoints +gdb_unload +setup_kfail "*-*-*" "vlaregression/9999" +gdb_test {p $a (3, 2:2)} { = \(23\)} diff --git a/gdb/testsuite/gdb.fortran/subrange.f90 b/gdb/testsuite/gdb.fortran/subrange.f90 new file mode 100644 index 00000000000..4747ea9746f --- /dev/null +++ b/gdb/testsuite/gdb.fortran/subrange.f90 @@ -0,0 +1,28 @@ +! Copyright 2011 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 . + +program test + integer, target :: a (4, 3) + integer, allocatable :: alloc (:, :) + integer, pointer :: ptr (:, :) + do 1 i = 1, 4 + do 1 j = 1, 3 + a (i, j) = j * 10 + i +1 continue + allocate (alloc (4, 3)) + alloc = a + ptr => a + write (*,*) a ! break-static +end diff --git a/gdb/testsuite/gdb.fortran/vla-func.exp b/gdb/testsuite/gdb.fortran/vla-func.exp new file mode 100644 index 00000000000..f0f236bef07 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/vla-func.exp @@ -0,0 +1,61 @@ +# Copyright 2014 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 . + +standard_testfile ".f90" + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ + {debug f90 quiet}] } { + return -1 +} + +if ![runto MAIN__] then { + perror "couldn't run to breakpoint MAIN__" + continue +} + +# Check VLA passed to first Fortran function. +gdb_breakpoint [gdb_get_line_number "func1-vla-passed"] +gdb_continue_to_breakpoint "func1-vla-passed" +gdb_test "print vla" " = \\( *\\( *22, *22, *22,\[()22, .\]*\\)" \ + "print vla (func1)" +gdb_test "ptype vla" "type = integer\\\(kind=4\\\) \\\(10,10\\\)" \ + "ptype vla (func1)" + +gdb_breakpoint [gdb_get_line_number "func1-vla-modified"] +gdb_continue_to_breakpoint "func1-vla-modified" +gdb_test "print vla(5,5)" " = 55" "print vla(5,5) (func1)" +gdb_test "print vla(7,7)" " = 77" "print vla(5,5) (func1)" + +# Check if the values are correct after returning from func1 +gdb_breakpoint [gdb_get_line_number "func1-returned"] +gdb_continue_to_breakpoint "func1-returned" +gdb_test "print ret" " = .TRUE." "print ret after func1 returned" + +# Check VLA passed to second Fortran function +gdb_breakpoint [gdb_get_line_number "func2-vla-passed"] +gdb_continue_to_breakpoint "func2-vla-passed" +gdb_test "print vla" \ + " = \\\(44, 44, 44, 44, 44, 44, 44, 44, 44, 44\\\)" \ + "print vla (func2)" +gdb_test "ptype vla" "type = integer\\\(kind=4\\\) \\\(10\\\)" \ + "ptype vla (func2)" + +# Check if the returned VLA has the correct values and ptype. +gdb_breakpoint [gdb_get_line_number "func2-returned"] +gdb_continue_to_breakpoint "func2-returned" +gdb_test "print vla3" " = \\\(1, 2, 44, 4, 44, 44, 44, 8, 44, 44\\\)" \ + "print vla3 (after func2)" +gdb_test "ptype vla3" "type = integer\\\(kind=4\\\) \\\(10\\\)" \ + "ptype vla3 (after func2)" diff --git a/gdb/testsuite/gdb.fortran/vla-func.f90 b/gdb/testsuite/gdb.fortran/vla-func.f90 new file mode 100644 index 00000000000..7540f54dbbc --- /dev/null +++ b/gdb/testsuite/gdb.fortran/vla-func.f90 @@ -0,0 +1,71 @@ +! Copyright 2014 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 2 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, write to the Free Software +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +logical function func1 (vla) + implicit none + integer, allocatable :: vla (:, :) + func1 = allocated(vla) + vla(5,5) = 55 ! func1-vla-passed + vla(7,7) = 77 + return ! func1-vla-modified +end function func1 + +function func2(vla) + implicit none + integer :: vla (:) + integer :: func2(size(vla)) + integer :: k + + vla(1) = 1 ! func2-vla-passed + vla(2) = 2 + vla(4) = 4 + vla(8) = 8 + + func2 = vla +end function func2 + +program vla_func + implicit none + interface + logical function func1 (vla) + integer, allocatable :: vla (:, :) + end function + end interface + interface + function func2 (vla) + integer :: vla (:) + integer func2(size(vla)) + end function + end interface + + logical :: ret + integer, allocatable :: vla1 (:, :) + integer, allocatable :: vla2 (:) + integer, allocatable :: vla3 (:) + + ret = .FALSE. + + allocate (vla1 (10,10)) + vla1(:,:) = 22 + + allocate (vla2 (10)) + vla2(:) = 44 + + ret = func1(vla1) + vla3 = func2(vla2) ! func1-returned + + ret = .TRUE. ! func2-returned +end program vla_func diff --git a/gdb/testsuite/gdb.fortran/vla-ptype.exp b/gdb/testsuite/gdb.fortran/vla-ptype.exp index a40ad917da5..9111082076e 100644 --- a/gdb/testsuite/gdb.fortran/vla-ptype.exp +++ b/gdb/testsuite/gdb.fortran/vla-ptype.exp @@ -32,9 +32,9 @@ set real [fortran_real4] # Check the ptype of various VLA states and pointer to VLA's. gdb_breakpoint [gdb_get_line_number "vla1-init"] gdb_continue_to_breakpoint "vla1-init" -gdb_test "ptype vla1" "type = " "ptype vla1 not initialized" -gdb_test "ptype vla2" "type = " "ptype vla2 not initialized" -gdb_test "ptype pvla" "type = " "ptype pvla not initialized" +gdb_test "ptype vla1" "type = $real \\(:,:,:\\)" "ptype vla1 not initialized" +gdb_test "ptype vla2" "type = $real \\(:,:,:\\)" "ptype vla2 not initialized" +gdb_test "ptype pvla" "type = $real \\(:,:,:\\)" "ptype pvla not initialized" gdb_test "ptype vla1(3, 6, 9)" "no such vector element \\\(vector not allocated\\\)" \ "ptype vla1(3, 6, 9) not initialized" gdb_test "ptype vla2(5, 45, 20)" \ @@ -81,20 +81,24 @@ gdb_test "ptype vla2(5, 45, 20)" "type = $real" \ gdb_breakpoint [gdb_get_line_number "pvla-deassociated"] gdb_continue_to_breakpoint "pvla-deassociated" -gdb_test "ptype pvla" "type = " "ptype pvla deassociated" +gdb_test "ptype pvla" "type = $real \\(:,:,:\\)" "ptype pvla deassociated" gdb_test "ptype pvla(5, 45, 20)" \ "no such vector element \\\(vector not associated\\\)" \ "ptype pvla(5, 45, 20) not associated" gdb_breakpoint [gdb_get_line_number "vla1-deallocated"] gdb_continue_to_breakpoint "vla1-deallocated" -gdb_test "ptype vla1" "type = " "ptype vla1 not allocated" +gdb_test "ptype vla1" "type = $real \\(:,:,:\\)" "ptype vla1 not allocated" gdb_test "ptype vla1(3, 6, 9)" "no such vector element \\\(vector not allocated\\\)" \ "ptype vla1(3, 6, 9) not allocated" gdb_breakpoint [gdb_get_line_number "vla2-deallocated"] gdb_continue_to_breakpoint "vla2-deallocated" -gdb_test "ptype vla2" "type = " "ptype vla2 not allocated" +gdb_test "ptype vla2" "type = $real \\(:,:,:\\)" "ptype vla2 not allocated" gdb_test "ptype vla2(5, 45, 20)" \ "no such vector element \\\(vector not allocated\\\)" \ "ptype vla2(5, 45, 20) not allocated" + +gdb_breakpoint [gdb_get_line_number "vla1-neg-bounds"] +gdb_continue_to_breakpoint "vla1-neg-bounds" +gdb_test "ptype vla1" "type = $real \\(-2:1,-5:4,-3:-1\\)" "ptype vla1 negative bounds" diff --git a/gdb/testsuite/gdb.fortran/vla-sizeof.exp b/gdb/testsuite/gdb.fortran/vla-sizeof.exp index 7f74a699d76..f4965082687 100644 --- a/gdb/testsuite/gdb.fortran/vla-sizeof.exp +++ b/gdb/testsuite/gdb.fortran/vla-sizeof.exp @@ -44,3 +44,7 @@ gdb_test "print sizeof(pvla)" " = 0" "print sizeof non-associated pvla" gdb_breakpoint [gdb_get_line_number "pvla-associated"] gdb_continue_to_breakpoint "pvla-associated" gdb_test "print sizeof(pvla)" " = 4000" "print sizeof associated pvla" + +gdb_breakpoint [gdb_get_line_number "vla1-neg-bounds"] +gdb_continue_to_breakpoint "vla1-neg-bounds" +gdb_test "print sizeof(vla1)" " = 480" "print sizeof vla1 negative bounds" diff --git a/gdb/testsuite/gdb.fortran/vla-stride.exp b/gdb/testsuite/gdb.fortran/vla-stride.exp new file mode 100644 index 00000000000..dcf15e5dafa --- /dev/null +++ b/gdb/testsuite/gdb.fortran/vla-stride.exp @@ -0,0 +1,44 @@ +# Copyright 2016 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 . + +standard_testfile ".f90" + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ + {debug f90 quiet}] } { + return -1 +} + +if ![runto MAIN__] then { + perror "couldn't run to breakpoint MAIN__" + continue +} + +gdb_breakpoint [gdb_get_line_number "re-reverse-elements"] +gdb_continue_to_breakpoint "re-reverse-elements" +gdb_test "print pvla" " = \\\(1, 2, 3, 4, 5, 6, 7, 8, 9, 10\\\)" \ + "print re-reverse-elements" +gdb_test "print pvla(1)" " = 1" "print first re-reverse-element" +gdb_test "print pvla(10)" " = 10" "print last re-reverse-element" + +gdb_breakpoint [gdb_get_line_number "odd-elements"] +gdb_continue_to_breakpoint "odd-elements" +gdb_test "print pvla" " = \\\(1, 3, 5, 7, 9\\\)" "print odd-elements" +gdb_test "print pvla(1)" " = 1" "print first odd-element" +gdb_test "print pvla(5)" " = 9" "print last odd-element" + +gdb_breakpoint [gdb_get_line_number "single-element"] +gdb_continue_to_breakpoint "single-element" +gdb_test "print pvla" " = \\\(5\\\)" "print single-element" +gdb_test "print pvla(1)" " = 5" "print one single-element" diff --git a/gdb/testsuite/gdb.fortran/vla-stride.f90 b/gdb/testsuite/gdb.fortran/vla-stride.f90 new file mode 100644 index 00000000000..8d2425222e5 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/vla-stride.f90 @@ -0,0 +1,29 @@ +! Copyright 2016 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 . + +program vla_stride + integer, target, allocatable :: vla (:) + integer, pointer :: pvla (:) + + allocate(vla(10)) + vla = (/ (I, I = 1,10) /) + + pvla => vla(10:1:-1) + pvla => pvla(10:1:-1) + pvla => vla(1:10:2) ! re-reverse-elements + pvla => vla(5:4:-2) ! odd-elements + + pvla => null() ! single-element +end program vla_stride diff --git a/gdb/testsuite/gdb.fortran/vla-strings.exp b/gdb/testsuite/gdb.fortran/vla-strings.exp new file mode 100644 index 00000000000..484fdcb652a --- /dev/null +++ b/gdb/testsuite/gdb.fortran/vla-strings.exp @@ -0,0 +1,103 @@ +# Copyright 2016 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 . + +standard_testfile ".f90" + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ + {debug f90 quiet}] } { + return -1 +} + +# check that all fortran standard datatypes will be +# handled correctly when using as VLA's + +if ![runto_main] { + untested "could not run to main" + return -1 +} + +gdb_breakpoint [gdb_get_line_number "var_char-allocated-1"] +gdb_continue_to_breakpoint "var_char-allocated-1" +set test "whatis var_char first time" +gdb_test_multiple "whatis var_char" $test { + -re "type = PTR TO -> \\( character\\*10 \\)\r\n$gdb_prompt $" { + pass $test + } + -re "type = character\\*10\r\n$gdb_prompt $" { + pass $test + } +} +set test "ptype var_char first time" +gdb_test_multiple "ptype var_char" $test { + -re "type = PTR TO -> \\( character\\*10 \\)\r\n$gdb_prompt $" { + pass $test + } + -re "type = character\\*10\r\n$gdb_prompt $" { + pass $test + } +} + + +gdb_test "next" "\\d+.*var_char = 'foo'.*" \ + "next to allocation status of var_char" +gdb_test "print l" " = \\.TRUE\\." "print allocation status first time" + + +gdb_breakpoint [gdb_get_line_number "var_char-filled-1"] +gdb_continue_to_breakpoint "var_char-filled-1" +set test "print var_char, var_char-filled-1" +gdb_test_multiple "print var_char" $test { + -re "= \\(PTR TO -> \\( character\\*3 \\)\\) $hex\r\n$gdb_prompt $" { + gdb_test "print *var_char" "= 'foo'" "print *var_char, var_char-filled-1" + pass $test + } + -re "= 'foo'\r\n$gdb_prompt $" { + pass $test + } +} +set test "ptype var_char, var_char-filled-1" +gdb_test_multiple "ptype var_char" $test { + -re "type = PTR TO -> \\( character\\*3 \\)\r\n$gdb_prompt $" { + pass $test + } + -re "type = character\\*3\r\n$gdb_prompt $" { + pass $test + } +} +gdb_test "print var_char(1)" " = 102 'f'" "print var_char(1)" +gdb_test "print var_char(3)" " = 111 'o'" "print var_char(3)" + + +gdb_breakpoint [gdb_get_line_number "var_char-filled-2"] +gdb_continue_to_breakpoint "var_char-filled-2" +set test "print var_char, var_char-filled-2" +gdb_test_multiple "print var_char" $test { + -re "= \\(PTR TO -> \\( character\\*6 \\)\\) $hex\r\n$gdb_prompt $" { + gdb_test "print *var_char" "= 'foobar'" "print *var_char, var_char-filled-2" + pass $test + } + -re "= 'foobar'\r\n$gdb_prompt $" { + pass $test + } +} +set test "ptype var_char, var_char-filled-2" +gdb_test_multiple "ptype var_char" $test { + -re "type = PTR TO -> \\( character\\*6 \\)\r\n$gdb_prompt $" { + pass $test + } + -re "type = character\\*6\r\n$gdb_prompt $" { + pass $test + } +} diff --git a/gdb/testsuite/gdb.fortran/vla-strings.f90 b/gdb/testsuite/gdb.fortran/vla-strings.f90 new file mode 100644 index 00000000000..3c22735fdbe --- /dev/null +++ b/gdb/testsuite/gdb.fortran/vla-strings.f90 @@ -0,0 +1,39 @@ +! Copyright 2016 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 . + +program vla_strings + character(len=:), target, allocatable :: var_char + character(len=:), pointer :: var_char_p + logical :: l + + allocate(character(len=10) :: var_char) + l = allocated(var_char) ! var_char-allocated-1 + var_char = 'foo' + deallocate(var_char) ! var_char-filled-1 + l = allocated(var_char) ! var_char-deallocated + allocate(character(len=42) :: var_char) + l = allocated(var_char) + var_char = 'foobar' + var_char = '' ! var_char-filled-2 + var_char = 'bar' ! var_char-empty + deallocate(var_char) + allocate(character(len=21) :: var_char) + l = allocated(var_char) ! var_char-allocated-3 + var_char = 'johndoe' + var_char_p => var_char + l = associated(var_char_p) ! var_char_p-associated + var_char_p => null() + l = associated(var_char_p) ! var_char_p-not-associated +end program vla_strings diff --git a/gdb/testsuite/gdb.fortran/vla-stringsold.exp b/gdb/testsuite/gdb.fortran/vla-stringsold.exp new file mode 100644 index 00000000000..c1bf7ef763a --- /dev/null +++ b/gdb/testsuite/gdb.fortran/vla-stringsold.exp @@ -0,0 +1,101 @@ +# Copyright 2014 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 . + +standard_testfile ".f90" + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile} \ + {debug f90 quiet}] } { + return -1 +} + +# check that all fortran standard datatypes will be +# handled correctly when using as VLA's + +if ![runto MAIN__] then { + perror "couldn't run to breakpoint MAIN__" + continue +} + +gdb_breakpoint [gdb_get_line_number "var_char-allocated-1"] +gdb_continue_to_breakpoint "var_char-allocated-1" +gdb_test "print var_char" \ + " = \\(PTR TO -> \\( character\\*10 \\)\\) ${hex}" \ + "print var_char after allocated first time" +gdb_test "whatis var_char" "type = PTR TO -> \\( character\\*10 \\)" \ + "whatis var_char first time" +gdb_test "ptype var_char" "type = PTR TO -> \\( character\\*10 \\)" \ + "ptype var_char first time" +gdb_test "next" "\\d+.*var_char = 'foo'.*" \ + "next to allocation status of var_char" +gdb_test "print l" " = .TRUE." "print allocation status first time" + +gdb_breakpoint [gdb_get_line_number "var_char-filled-1"] +gdb_continue_to_breakpoint "var_char-filled-1" +gdb_test "print var_char" \ + " = \\(PTR TO -> \\( character\\*3 \\)\\) ${hex}" \ + "print var_char after filled first time" +gdb_test "print *var_char" " = 'foo'" \ + "print *var_char after filled first time" +gdb_test "whatis var_char" "type = PTR TO -> \\( character\\*3 \\)" \ + "whatis var_char after filled first time" +gdb_test "ptype var_char" "type = PTR TO -> \\( character\\*3 \\)" \ + "ptype var_char after filled first time" +gdb_test "print var_char(1)" " = 102 'f'" "print var_char(1)" +gdb_test "print var_char(3)" " = 111 'o'" "print var_char(3)" + +gdb_breakpoint [gdb_get_line_number "var_char-filled-2"] +gdb_continue_to_breakpoint "var_char-filled-2" +gdb_test "print var_char" \ + " = \\(PTR TO -> \\( character\\*6 \\)\\) ${hex}" \ + "print var_char after allocated second time" +gdb_test "print *var_char" " = 'foobar'" \ + "print *var_char after allocated second time" +gdb_test "whatis var_char" "type = PTR TO -> \\( character\\*6 \\)" \ + "whatis var_char second time" +gdb_test "ptype var_char" "type = PTR TO -> \\( character\\*6 \\)" \ + "ptype var_char second time" + +gdb_breakpoint [gdb_get_line_number "var_char-empty"] +gdb_continue_to_breakpoint "var_char-empty" +gdb_test "print var_char" \ + " = \\(PTR TO -> \\( character\\*0 \\)\\) ${hex}" \ + "print var_char after set empty" +gdb_test "print *var_char" " = \"\"" "print *var_char after set empty" +gdb_test "whatis var_char" "type = PTR TO -> \\( character\\*0 \\)" \ + "whatis var_char after set empty" +gdb_test "ptype var_char" "type = PTR TO -> \\( character\\*0 \\)" \ + "ptype var_char after set empty" + +gdb_breakpoint [gdb_get_line_number "var_char-allocated-3"] +gdb_continue_to_breakpoint "var_char-allocated-3" +gdb_test "print var_char" \ + " = \\(PTR TO -> \\( character\\*21 \\)\\) ${hex}" \ + "print var_char after allocated third time" +gdb_test "whatis var_char" "type = PTR TO -> \\( character\\*21 \\)" \ + "whatis var_char after allocated third time" +gdb_test "ptype var_char" "type = PTR TO -> \\( character\\*21 \\)" \ + "ptype var_char after allocated third time" + +gdb_breakpoint [gdb_get_line_number "var_char_p-associated"] +gdb_continue_to_breakpoint "var_char_p-associated" +gdb_test "print var_char_p" \ + " = \\(PTR TO -> \\( character\\*7 \\)\\) ${hex}" \ + "print var_char_p after associated" +gdb_test "print *var_char_p" " = 'johndoe'" \ + "print *var_char_ after associated" +gdb_test "whatis var_char_p" "type = PTR TO -> \\( character\\*7 \\)" \ + "whatis var_char_p after associated" +gdb_test "ptype var_char_p" "type = PTR TO -> \\( character\\*7 \\)" \ + "ptype var_char_p after associated" diff --git a/gdb/testsuite/gdb.fortran/vla-stringsold.f90 b/gdb/testsuite/gdb.fortran/vla-stringsold.f90 new file mode 100644 index 00000000000..0a1d5221d08 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/vla-stringsold.f90 @@ -0,0 +1,40 @@ +! Copyright 2014 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 2 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, write to the Free Software +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +program vla_strings + character(len=:), target, allocatable :: var_char + character(len=:), pointer :: var_char_p + logical :: l + + allocate(character(len=10) :: var_char) + l = allocated(var_char) ! var_char-allocated-1 + var_char = 'foo' + deallocate(var_char) ! var_char-filled-1 + l = allocated(var_char) ! var_char-deallocated + allocate(character(len=42) :: var_char) + l = allocated(var_char) + var_char = 'foobar' + var_char = '' ! var_char-filled-2 + var_char = 'bar' ! var_char-empty + deallocate(var_char) + allocate(character(len=21) :: var_char) + l = allocated(var_char) ! var_char-allocated-3 + var_char = 'johndoe' + var_char_p => var_char + l = associated(var_char_p) ! var_char_p-associated + var_char_p => null() + l = associated(var_char_p) ! var_char_p-not-associated +end program vla_strings diff --git a/gdb/testsuite/gdb.fortran/vla-type.exp b/gdb/testsuite/gdb.fortran/vla-type.exp index 407a447a851..5be19f19969 100755 --- a/gdb/testsuite/gdb.fortran/vla-type.exp +++ b/gdb/testsuite/gdb.fortran/vla-type.exp @@ -132,7 +132,10 @@ gdb_test "ptype fivearr(2)%tone" \ "End Type one" ] # Check allocation status of dynamic array and it's dynamic members -gdb_test "ptype fivedynarr" "type = " +gdb_test "ptype fivedynarr" \ + [multi_line "type = Type five" \ + " Type one :: tone" \ + "End Type five \\(:\\)" ] gdb_test "next" "" gdb_test "ptype fivedynarr(2)" \ [multi_line "type = Type five" \ @@ -141,7 +144,7 @@ gdb_test "ptype fivedynarr(2)" \ "ptype fivedynarr(2), tone is not allocated" gdb_test "ptype fivedynarr(2)%tone" \ [multi_line "type = Type one" \ - " $int :: ivla\\(\\)" \ + " $int :: ivla\\(:,:,:\\)" \ "End Type one" ] \ "ptype fivedynarr(2)%tone, not allocated" diff --git a/gdb/testsuite/gdb.fortran/vla-value.exp b/gdb/testsuite/gdb.fortran/vla-value.exp index 3582d47c946..bfd0ca9b3e9 100644 --- a/gdb/testsuite/gdb.fortran/vla-value.exp +++ b/gdb/testsuite/gdb.fortran/vla-value.exp @@ -35,7 +35,7 @@ gdb_breakpoint [gdb_get_line_number "vla1-init"] gdb_continue_to_breakpoint "vla1-init" gdb_test "print vla1" " = " "print non-allocated vla1" gdb_test "print &vla1" \ - " = \\\(PTR TO -> \\\( $real \\\(\\\)\\\)\\\) $hex" \ + " = \\\(PTR TO -> \\\( $real \\\(:,:,:\\\)\\\)\\\) $hex" \ "print non-allocated &vla1" gdb_test "print vla1(1,1,1)" "no such vector element \\\(vector not allocated\\\)" \ "print member in non-allocated vla1 (1)" @@ -76,7 +76,7 @@ gdb_test "print vla1(9, 9, 9)" " = 999" \ # Try to access values in undefined pointer to VLA (dangling) gdb_test "print pvla" " = " "print undefined pvla" gdb_test "print &pvla" \ - " = \\\(PTR TO -> \\\( $real \\\(\\\)\\\)\\\) $hex" \ + " = \\\(PTR TO -> \\\( $real \\\(:,:,:\\\)\\\)\\\) $hex" \ "print non-associated &pvla" gdb_test "print pvla(1, 3, 8)" "no such vector element \\\(vector not associated\\\)" \ "print undefined pvla(1,3,8)" diff --git a/gdb/testsuite/gdb.fortran/vla.f90 b/gdb/testsuite/gdb.fortran/vla.f90 index 5bc608744b3..51c6f479af7 100644 --- a/gdb/testsuite/gdb.fortran/vla.f90 +++ b/gdb/testsuite/gdb.fortran/vla.f90 @@ -54,4 +54,14 @@ program vla allocate (vla3 (2,2)) ! vla2-deallocated vla3(:,:) = 13 + + allocate (vla1 (-2:1, -5:4, -3:-1)) + l = allocated(vla1) + + vla1(:, :, :) = 1 + vla1(-2, -3, -1) = -231 + + deallocate (vla1) ! vla1-neg-bounds + l = allocated(vla1) + end program vla diff --git a/gdb/testsuite/gdb.fortran/xlf-variable.S b/gdb/testsuite/gdb.fortran/xlf-variable.S new file mode 100644 index 00000000000..e826c844c77 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/xlf-variable.S @@ -0,0 +1,638 @@ +/* Copyright (C) 2012 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 . */ + +/* This file has been generated from the file named `xlf-variable.f', which + should be present in this directory. The command used to generate this + file was: + + xlf -qnoopt -g9 -S xlf-variable.f -o xlf-variable.S + + After issuing this command, you must hand-edit this file and remove the + mentions for `_xlfExit', since it is only present in XLF-specific + libraries. You must also make sure to remove the file named `mod1.mod' + which will be created in the compilation directory. + + In order to generated this file, the following XLF package was used: + + xlf.14.1.0.0.linux.eval.tar.gz + + These instructions may be different for different versions of the XLF + compiler. */ + +.set r0,0; .set SP,1; .set RTOC,2; .set r3,3; .set r4,4 +.set r5,5; .set r6,6; .set r7,7; .set r8,8; .set r9,9 +.set r10,10; .set r11,11; .set r12,12; .set r13,13; .set r14,14 +.set r15,15; .set r16,16; .set r17,17; .set r18,18; .set r19,19 +.set r20,20; .set r21,21; .set r22,22; .set r23,23; .set r24,24 +.set r25,25; .set r26,26; .set r27,27; .set r28,28; .set r29,29 +.set r30,30; .set r31,31 +.set fp0,0; .set fp1,1; .set fp2,2; .set fp3,3; .set fp4,4 +.set fp5,5; .set fp6,6; .set fp7,7; .set fp8,8; .set fp9,9 +.set fp10,10; .set fp11,11; .set fp12,12; .set fp13,13; .set fp14,14 +.set fp15,15; .set fp16,16; .set fp17,17; .set fp18,18; .set fp19,19 +.set fp20,20; .set fp21,21; .set fp22,22; .set fp23,23; .set fp24,24 +.set fp25,25; .set fp26,26; .set fp27,27; .set fp28,28; .set fp29,29 +.set fp30,30; .set fp31,31 +.set v0,0; .set v1,1; .set v2,2; .set v3,3; .set v4,4 +.set v5,5; .set v6,6; .set v7,7; .set v8,8; .set v9,9 +.set v10,10; .set v11,11; .set v12,12; .set v13,13; .set v14,14 +.set v15,15; .set v16,16; .set v17,17; .set v18,18; .set v19,19 +.set v20,20; .set v21,21; .set v22,22; .set v23,23; .set v24,24 +.set v25,25; .set v26,26; .set v27,27; .set v28,28; .set v29,29 +.set v30,30; .set v31,31 +.set q0,0; .set q1,1; .set q2,2; .set q3,3; .set q4,4 +.set q5,5; .set q6,6; .set q7,7; .set q8,8; .set q9,9 +.set q10,10; .set q11,11; .set q12,12; .set q13,13; .set q14,14 +.set q15,15; .set q16,16; .set q17,17; .set q18,18; .set q19,19 +.set q20,20; .set q21,21; .set q22,22; .set q23,23; .set q24,24 +.set q25,25; .set q26,26; .set q27,27; .set q28,28; .set q29,29 +.set q30,30; .set q31,31 +.set MQ,0; .set XER,1; .set FROM_RTCU,4; .set FROM_RTCL,5; .set FROM_DEC,6 +.set LR,8; .set CTR,9; .set TID,17; .set DSISR,18; .set DAR,19; .set TO_RTCU,20 +.set TO_RTCL,21; .set TO_DEC,22; .set SDR_0,24; .set SDR_1,25; .set SRR_0,26 +.set SRR_1,27 +.set BO_dCTR_NZERO_AND_NOT,0; .set BO_dCTR_NZERO_AND_NOT_1,1 +.set BO_dCTR_ZERO_AND_NOT,2; .set BO_dCTR_ZERO_AND_NOT_1,3 +.set BO_IF_NOT,4; .set BO_IF_NOT_1,5; .set BO_IF_NOT_2,6 +.set BO_IF_NOT_3,7; .set BO_dCTR_NZERO_AND,8; .set BO_dCTR_NZERO_AND_1,9 +.set BO_dCTR_ZERO_AND,10; .set BO_dCTR_ZERO_AND_1,11; .set BO_IF,12 +.set BO_IF_1,13; .set BO_IF_2,14; .set BO_IF_3,15; .set BO_dCTR_NZERO,16 +.set BO_dCTR_NZERO_1,17; .set BO_dCTR_ZERO,18; .set BO_dCTR_ZERO_1,19 +.set BO_ALWAYS,20; .set BO_ALWAYS_1,21; .set BO_ALWAYS_2,22 +.set BO_ALWAYS_3,23; .set BO_dCTR_NZERO_8,24; .set BO_dCTR_NZERO_9,25 +.set BO_dCTR_ZERO_8,26; .set BO_dCTR_ZERO_9,27; .set BO_ALWAYS_8,28 +.set BO_ALWAYS_9,29; .set BO_ALWAYS_10,30; .set BO_ALWAYS_11,31 +.set CR0_LT,0; .set CR0_GT,1; .set CR0_EQ,2; .set CR0_SO,3 +.set CR1_FX,4; .set CR1_FEX,5; .set CR1_VX,6; .set CR1_OX,7 +.set CR2_LT,8; .set CR2_GT,9; .set CR2_EQ,10; .set CR2_SO,11 +.set CR3_LT,12; .set CR3_GT,13; .set CR3_EQ,14; .set CR3_SO,15 +.set CR4_LT,16; .set CR4_GT,17; .set CR4_EQ,18; .set CR4_SO,19 +.set CR5_LT,20; .set CR5_GT,21; .set CR5_EQ,22; .set CR5_SO,23 +.set CR6_LT,24; .set CR6_GT,25; .set CR6_EQ,26; .set CR6_SO,27 +.set CR7_LT,28; .set CR7_GT,29; .set CR7_EQ,30; .set CR7_SO,31 +.set TO_LT,16; .set TO_GT,8; .set TO_EQ,4; .set TO_LLT,2; .set TO_LGT,1 + + .file "xlf-variable.f" + .globl __mod1_NMOD_____mod1 + .type __mod1_NMOD_____mod1,@function + .size __mod1_NMOD_____mod1,32 + .globl main + .type main,@function + .size main,68 + .globl __mod1_NMOD_sub1 + .type __mod1_NMOD_sub1,@function + .size __mod1_NMOD_sub1,136 + .globl _main + .type _main,@function + .size _main,68 + + .section ".text" + .align 7 +.LC.text: +__mod1_NMOD_____mod1: + stwu SP,-32(SP) + stw r31,28(SP) + or r31,SP,SP + b $+0x4 + addi r11,r31,32 + lwz r31,-4(r11) + or SP,r11,r11 + bclr BO_ALWAYS,CR0_LT +.LC.text32: + +__mod1_NMOD_sub1: + stwu SP,-32(SP) + stw r31,28(SP) + stw r30,24(SP) + or r31,SP,SP + addis r30,r0,.const_dr@ha + addi r30,r30,.const_dr@l + addis r3,r0,__N_mod1@ha + addi r3,r3,__N_mod1@l + addi r0,r0,1 + stb r0,4(r3) + addi r4,r0,14 + stb r4,5(r3) + stb r0,7(r3) + addis r5,r0,__N__mod1@ha + addi r5,r5,__N__mod1@l + stw r5,0(r3) + lbz r5,6(r3) + rlwinm r5,r5,0,25,25 + ori r5,r5,0x0040 + stb r5,6(r3) + lwz r5,0(r3) + lfs fp0,0(r30) + stfs fp0,0(r5) + stb r0,4(r3) + stb r4,5(r3) + addi r4,r0,0 + stb r4,6(r3) + stb r0,7(r3) + b $+0x4 + addi r11,r31,32 + lwz r30,-8(r11) + lwz r31,-4(r11) + or SP,r11,r11 + bclr BO_ALWAYS,CR0_LT +.LC.text168: + .long 0 + .skip 0x54 +.LC.text256: + +main: +_main: + mfspr r0,LR + stwu SP,-32(SP) + stw r31,28(SP) + stw r0,36(SP) + or r31,SP,SP + bl __mod1_NMOD_sub1 + addi r3,r0,0 +.LC.text288: + + tw TO_EQ,r14,r14 + addi r3,r0,0 + b $+0x4 + addi r11,r31,32 + lwz r31,-4(r11) + lwz r0,4(r11) + mtspr LR,r0 + or SP,r11,r11 + bclr BO_ALWAYS,CR0_LT +.LC.text324: + + + .section ".rodata","a" + .align 2 +.LC.rodata: + .type .const_dr,@object + .size .const_dr,4 +.const_dr: + .long 0x40400000 + + .section ".eh_frame","wa" + .align 2 +.LC.eh_frame: + .long 0x0000000c + .long 0x00000000 + .long 0x0100047c + .long 0x410c0100 + .long 0x0000001c + .long 0x00000014 + .long .LC.text + .long 0x00000020 + .long 0x410e2041 + .long 0x9f01410d + .long 0x1f410a42 + .long 0xdf420b00 + .long 0x00000020 + .long 0x00000034 + .long .LC.text32 + .long 0x00000088 + .long 0x410e2041 + .long 0x9f01419e + .long 0x02410d1f + .long 0x590a42de + .long 0x41df420b + .long 0x0000000c + .long 0x00000000 + .long 0x0100047c + .long 0x410c0100 + .long 0x00000020 + .long 0x00000014 + .long .LC.text256 + .long 0x00000044 + .long 0x420e2041 + .long 0x9f014111 + .long 0x417f410d + .long 0x1f460a42 + .long 0xdf440b00 + + .section ".data","wa" + .align 4 +.LC.data: + .globl __N_mod1 + .type __N_mod1,@object + .size __N_mod1,8 +__N_mod1: + .long 0x00000000 + .long 0x01000001 + + .section ".except.1","wa" + .align 1 +.LC.except.1: + .long .LC.text288 + .byte 0x01 + .byte 0x09 + + .ident "Fri Jun 15 16:35:45 2012 .IBM XL Fortran for Linux, V14.1 (5765-J05, 5725-C75) Version 14.01.0000.0000.Fri Jun 15 16:35:45 2012 .IBM XL Fortran for Linux, V14.1 (5765-J05, 5725-C75) Version 14.01.0000.0000." + + .section ".debug_aranges" + .align 0 +.LC.debug_aranges: + .long 0x0000001c + .byte 0x00 + .byte 0x02 + .long .LC.debug_info + .long 0x04000000 + .byte 0x00 + .byte 0x00 + .long .LC.text + .long 0x000000a8 + .long 0x00000000 + .long 0x00000000 + .long 0x0000001c + .byte 0x00 + .byte 0x02 + .long .LC.debug_info273 + .long 0x04000000 + .byte 0x00 + .byte 0x00 + .long .LC.text256 + .long 0x00000044 + .long 0x00000000 + .long 0x00000000 + + .section ".debug_pubnames" + .align 0 +.LC.debug_pubnames: + .long 0x0000002f + .byte 0x00 + .byte 0x02 + .long .LC.debug_info + .long 0x00000111 + .long 0x000000dc + .long 0x79000000 + .long 0x00ec7a00 + .long 0x000000fc + .long 0x5f5f6d6f + .long 0x64315f4e + .long 0x4d4f445f + .long 0x73756231 + .long 0x00000000 + .long 0x00000000 + .byte 0x18 + .byte 0x00 + .byte 0x02 + .long .LC.debug_info273 + .long 0x00000127 + .long 0x0000010f + .long 0x5f6d6169 + .long 0x6e000000 + .byte 0x00 + .byte 0x00 + + .section ".debug_info" + .align 0 +.LC.debug_info: + .long 0x0000010d + .byte 0x00 + .byte 0x02 + .long .LC.debug_abbrev + .long 0x0401786c + .long 0x662d7661 + .long 0x72696162 + .long 0x6c652e66 + .byte 0x00 + .long .LC.debug_line + .long .LC.text + .long .LC.text168 + .long 0x082f726f + .long 0x6f742f73 + .long 0x65726769 + .long 0x6f646a2f + .long 0x6764622d + .long 0x372e302e + .long 0x312d3432 + .long 0x2e656c35 + .long 0x2f676462 + .long 0x2d372e30 + .long 0x2e312f67 + .long 0x64622f74 + .long 0x65737473 + .long 0x75697465 + .long 0x2f676462 + .long 0x2e666f72 + .long 0x7472616e + .long 0x0049424d + .long 0x20584c20 + .long 0x466f7274 + .long 0x72616e20 + .long 0x666f7220 + .long 0x4c696e75 + .long 0x782c2056 + .long 0x31342e31 + .long 0x20283537 + .long 0x36352d4a + .long 0x30352c20 + .long 0x35373235 + .long 0x2d433735 + .long 0x29205665 + .long 0x7273696f + .long 0x6e203134 + .long 0x2e30312e + .long 0x30303030 + .long 0x2e303030 + .long 0x30000249 + .long 0x4e544547 + .long 0x45520004 + .long 0x05030005 + .long 0x02524541 + .long 0x4c000404 + .long 0x04050000 + .long 0x0000c706 + .long 0x6d6f6431 + .long 0x00070503 + .long __N_mod1 + .long 0x79000100 + .long 0x01000000 + .long 0xd0070503 + .long __N__mod1 + .long 0x7a000100 + .long 0x01000000 + .long 0xc7087375 + .byte 0x62 + .byte 0x31 + .byte 0x00 + .long .LC.text32 + .long .LC.text168 + .long 0x01180101 + .byte 0x6f + .byte 0x00 + .byte 0x00 +.LC.debug_info273: + .long 0x00000123 + .byte 0x00 + .byte 0x02 + .long .LC.debug_abbrev97 + .long 0x0401786c + .long 0x662d7661 + .long 0x72696162 + .long 0x6c652e66 + .byte 0x00 + .long .LC.debug_line98 + .long .LC.text256 + .long .LC.text324 + .long 0x082f726f + .long 0x6f742f73 + .long 0x65726769 + .long 0x6f646a2f + .long 0x6764622d + .long 0x372e302e + .long 0x312d3432 + .long 0x2e656c35 + .long 0x2f676462 + .long 0x2d372e30 + .long 0x2e312f67 + .long 0x64622f74 + .long 0x65737473 + .long 0x75697465 + .long 0x2f676462 + .long 0x2e666f72 + .long 0x7472616e + .long 0x0049424d + .long 0x20584c20 + .long 0x466f7274 + .long 0x72616e20 + .long 0x666f7220 + .long 0x4c696e75 + .long 0x782c2056 + .long 0x31342e31 + .long 0x20283537 + .long 0x36352d4a + .long 0x30352c20 + .long 0x35373235 + .long 0x2d433735 + .long 0x29205665 + .long 0x7273696f + .long 0x6e203134 + .long 0x2e30312e + .long 0x30303030 + .long 0x2e303030 + .long 0x30000249 + .long 0x4e544547 + .long 0x45520004 + .long 0x05030005 + .long 0x02524541 + .long 0x4c000404 + .long 0x04000000 + .long 0xb9050000 + .long 0x0000c706 + .long 0x000000f4 + .long 0x26264e26 + .long 0x6d6f6431 + .long 0x00080779 + .long 0x00022300 + .long 0x000000d4 + .long 0x00060000 + .long 0x010f2626 + .long 0x4e26266d + .long 0x6f643100 + .long 0x04077a00 + .long 0x02230000 + .long 0x0000c700 + .long 0x085f6d61 + .byte 0x69 + .byte 0x6e + .byte 0x00 + .long .LC.text256 + .long .LC.text324 + .long 0x0201016f + .long 0x000000b9 + .byte 0x00 + + .section ".debug_abbrev" + .align 0 +.LC.debug_abbrev: + .long 0x01110103 + .long 0x08100611 + .long 0x01120113 + .long 0x0b1b0825 + .long 0x08000002 + .long 0x24000308 + .long 0x0b0b3e0b + .long 0x00000324 + .long 0x000b0b3e + .long 0x0b000004 + .long 0x15000000 + .long 0x050f0033 + .long 0x0b491300 + .long 0x00061e01 + .long 0x03080000 + .long 0x07340002 + .long 0x0a03083a + .long 0x0b3b0b3f + .long 0x0c491300 + .long 0x00082e00 + .long 0x03081101 + .long 0x12013a0b + .long 0x3b0b3f0c + .long 0x400a0000 + .byte 0x00 +.LC.debug_abbrev97: + .long 0x01110103 + .long 0x08100611 + .long 0x01120113 + .long 0x0b1b0825 + .long 0x08000002 + .long 0x24000308 + .long 0x0b0b3e0b + .long 0x00000324 + .long 0x000b0b3e + .long 0x0b000004 + .long 0x15004913 + .long 0x0000050f + .long 0x00330b49 + .long 0x13000006 + .long 0x13010113 + .long 0x03080b0b + .long 0x0000070d + .long 0x00030838 + .long 0x0a491300 + .long 0x00082e00 + .long 0x03081101 + .long 0x1201360b + .long 0x3f0c400a + .long 0x49130000 + .byte 0x00 + + .section ".debug_line" + .align 0 +.LC.debug_line: + .long 0x0000005e + .long 0x00020000 + .long 0x00220101 + .long 0x9cdc0a00 + .long 0x01010101 + .long 0x00000001 + .long 0x00786c66 + .long 0x2d766172 + .long 0x6961626c + .long 0x652e6600 + .long 0x00000000 + .long 0x04010005 + .byte 0x02 + .long .LC.text + .long 0x03130109 + .long 0x000c0309 + .long 0x01090014 + .long 0x037b0109 + .long 0x00180301 + .long 0x01090038 + .long 0x03010109 + .long 0x000c0301 + .long 0x01090014 + .long 0x03010109 + .long 0x00180001 + .byte 0x01 +.LC.debug_line98: + .long 0x00000046 + .long 0x00020000 + .long 0x00220101 + .long 0x9cdc0a00 + .long 0x01010101 + .long 0x00000001 + .long 0x00786c66 + .long 0x2d766172 + .long 0x6961626c + .long 0x652e6600 + .long 0x00000000 + .long 0x04010005 + .byte 0x02 + .long .LC.text256 + .long 0x031f0109 + .long 0x00140300 + .long 0x01090004 + .long 0x03010109 + .long 0x002c0001 + .byte 0x01 + + .section ".debug_frame" + .align 0 +.LC.debug_frame: + .long 0x0000000c + .long 0xffffffff + .long 0x0100047c + .long 0x410c0100 + .long 0x0000001c + .long .LC.debug_frame + .long .LC.text + .long 0x00000020 + .long 0x410e2041 + .long 0x9f01410d + .long 0x1f410a42 + .long 0xdf420b00 + .long 0x00000020 + .long .LC.debug_frame + .long .LC.text32 + .long 0x00000088 + .long 0x410e2041 + .long 0x9f01419e + .long 0x02410d1f + .long 0x590a42de + .long 0x41df420b +.LC.debug_frame84: + .long 0x0000000c + .long 0xffffffff + .long 0x0100047c + .long 0x410c0100 + .long 0x00000020 + .long .LC.debug_frame84 + .long .LC.text256 + .long 0x00000044 + .long 0x420e2041 + .long 0x9f014111 + .long 0x417f410d + .long 0x1f460a42 + .long 0xdf440b00 + + .section ".debug_pubtypes" + .align 0 +.LC.debug_pubtypes: + .long 0x00000023 + .byte 0x00 + .byte 0x02 + .long .LC.debug_info + .long 0x00000111 + .long 0x000000b9 + .long 0x494e5445 + .long 0x47455200 + .long 0x000000c7 + .long 0x5245414c + .long 0x00000000 + .long 0x00000000 + .byte 0x3e + .byte 0x00 + .byte 0x02 + .long .LC.debug_info273 + .long 0x00000127 + .long 0x000000b9 + .long 0x494e5445 + .long 0x47455200 + .long 0x000000c7 + .long 0x5245414c + .long 0x00000000 + .long 0xda26264e + .long 0x266d6f64 + .long 0x31000000 + .long 0x00f42626 + .long 0x4e26266d + .long 0x6f643100 + .long 0x00000000 + + .comm __N__mod1,4,16 diff --git a/gdb/testsuite/gdb.fortran/xlf-variable.exp b/gdb/testsuite/gdb.fortran/xlf-variable.exp new file mode 100644 index 00000000000..085da125670 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/xlf-variable.exp @@ -0,0 +1,37 @@ +# Copyright 2012 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 . + +# This test can only be run on PPC64 machines. + +if { ![istarget powerpc64-*] || ![is_ilp32_target] } { + return -1 +} + +set testfile "xlf-variable" +set srcfile ${testfile}.S + +if { [prepare_for_testing $testfile.exp $testfile $srcfile] } { + return -1 +} + +if { ![runto_main] } { + return -1 +} + +gdb_test "step" ".*y => z.*" "y => z" +gdb_test "step" ".*y = 3\.0.*" "y = 3.0" +gdb_test "step" ".*nullify \\(y\\).*" "nullify (y)" +gdb_test "print z" "= 3" "z = 3" +gdb_test "ptype z" "= REAL" "z is REAL" diff --git a/gdb/testsuite/gdb.fortran/xlf-variable.f b/gdb/testsuite/gdb.fortran/xlf-variable.f new file mode 100644 index 00000000000..0b458f8b0c4 --- /dev/null +++ b/gdb/testsuite/gdb.fortran/xlf-variable.f @@ -0,0 +1,33 @@ +c Copyright 2012 Free Software Foundation, Inc. +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 3 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program. If not, see . + +c This file is the Fortran source file for xlf-variable.f. +c It was used to generate the assembly output called xlf-variable.S, +c which was generated using IBM's XLF compiler. + + module mod1 + real, pointer :: y + real, target :: z + contains + subroutine sub1 + y => z + y = 3.0 + nullify (y) + end subroutine + end module + + use mod1 + call sub1 + end diff --git a/gdb/testsuite/gdb.gdb/selftest.exp b/gdb/testsuite/gdb.gdb/selftest.exp index 7fdb3b226e1..5c812137f09 100644 --- a/gdb/testsuite/gdb.gdb/selftest.exp +++ b/gdb/testsuite/gdb.gdb/selftest.exp @@ -53,6 +53,9 @@ proc test_with_self { } { -re ".\[0-9\]+ = +.+ +0x.*\[0-9.\]+.*$gdb_prompt $" { pass "printed version with cast" } + -re ".\[0-9\]+ = .(Fedora|Red Hat Enterprise Linux) \[\\(\\)0-9.a-z\\-\]+.*$gdb_prompt $" { + pass "printed version Fedora or Red Hat Enterprise Linux only" + } } # start the "xgdb" process @@ -110,9 +113,25 @@ proc test_with_self { } { } set description "send SIGINT signal to child process" - gdb_test "signal SIGINT" \ - "Continuing with signal SIGINT.*" \ - "$description" + gdb_test_multiple "signal SIGINT" "$description" { + -re "^signal SIGINT\r\nContinuing with signal SIGINT.\r\nQuit\r\n" { + pass "$description" + } + } + + set description "send ^C to child process again" + send_gdb "\003" + gdb_expect { + -re "(Thread .*|Program) received signal SIGINT.*$gdb_prompt $" { + pass "$description" + } + -re ".*$gdb_prompt $" { + fail "$description" + } + timeout { + fail "$description (timeout)" + } + } # Switch back to the GDB thread if Guile support is linked in. # "signal SIGINT" could also switch the current thread. diff --git a/gdb/testsuite/gdb.mi/mi-cli.exp b/gdb/testsuite/gdb.mi/mi-cli.exp index cb654dabc4a..76fdef51bd2 100644 --- a/gdb/testsuite/gdb.mi/mi-cli.exp +++ b/gdb/testsuite/gdb.mi/mi-cli.exp @@ -199,7 +199,7 @@ mi_expect_stop "breakpoint-hit" "main" "" ".*basics.c" \ # Test that the token is output even for CLI commands # Also test that *stopped includes frame information. mi_gdb_test "34 next" \ - ".*34\\\^running.*\\*running,thread-id=\"all\"" \ + ".*34\\\^running.*\\*running,thread-id=\"1\"" \ "34 next: run" # Test that the new current source line is output to the console diff --git a/gdb/testsuite/gdb.mi/mi-console.exp b/gdb/testsuite/gdb.mi/mi-console.exp index 6b024c6de24..294b3393a63 100644 --- a/gdb/testsuite/gdb.mi/mi-console.exp +++ b/gdb/testsuite/gdb.mi/mi-console.exp @@ -60,6 +60,9 @@ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {deb mi_run_to_main +# thread-id=\"all\" vs. thread-id=\"1\" below: +mi_gdb_test "210-gdb-set scheduler-locking off" "210\\^done" "set scheduler-locking off" + # The output we get from the target depends on how it is hosted. If # we are semihosted (e.g., the sim or a remote target that supports # the File I/O remote protocol extension), we see the target I/O diff --git a/gdb/testsuite/gdb.mi/mi-logging.exp b/gdb/testsuite/gdb.mi/mi-logging.exp index 1a5f67342a6..c23a365e020 100644 --- a/gdb/testsuite/gdb.mi/mi-logging.exp +++ b/gdb/testsuite/gdb.mi/mi-logging.exp @@ -53,7 +53,7 @@ close $chan set mi_log_prompt "\[(\]gdb\[)\] \[\r\n\]+" -if [regexp "\\^done\[\r\n\]+$mi_log_prompt\\^running\[\r\n\]+\\*running,thread-id=\"all\"\[\r\n\]+$mi_log_prompt\\*stopped,reason=\"end-stepping-range\",.*\[\r\n\]+$mi_log_prompt\\^running\[\r\n\]+\\*running,thread-id=\"all\"\[\r\n\]+$mi_log_prompt\\*stopped,reason=\"end-stepping-range\",.*\[\r\n\]+$mi_log_prompt" $logcontent] { +if [regexp "\\^done\[\r\n\]+$mi_log_prompt\\^running\[\r\n\]+\\*running,thread-id=\"1\"\[\r\n\]+$mi_log_prompt\\*stopped,reason=\"end-stepping-range\",.*\[\r\n\]+$mi_log_prompt\\^running\[\r\n\]+\\*running,thread-id=\"1\"\[\r\n\]+$mi_log_prompt\\*stopped,reason=\"end-stepping-range\",.*\[\r\n\]+$mi_log_prompt" $logcontent] { pass "log file contents" } else { fail "log file contents" @@ -76,7 +76,7 @@ set chan [open $milogfile] set logcontent [read $chan] close $chan -if [regexp "1001\\^done\[\r\n\]+$mi_log_prompt.*1002\\^running\[\r\n\]+\\*running,thread-id=\"all\"\[\r\n\]+$mi_log_prompt\\*stopped,reason=\"end-stepping-range\",.*\[\r\n\]+$mi_log_prompt.*1003\\^running\[\r\n\]+\\*running,thread-id=\"all\"\[\r\n\]+$mi_log_prompt\\*stopped,reason=\"end-stepping-range\",.*\[\r\n\]+$mi_log_prompt" $logcontent] { +if [regexp "1001\\^done\[\r\n\]+$mi_log_prompt.*1002\\^running\[\r\n\]+\\*running,thread-id=\"1\"\[\r\n\]+$mi_log_prompt\\*stopped,reason=\"end-stepping-range\",.*\[\r\n\]+$mi_log_prompt.*1003\\^running\[\r\n\]+\\*running,thread-id=\"1\"\[\r\n\]+$mi_log_prompt\\*stopped,reason=\"end-stepping-range\",.*\[\r\n\]+$mi_log_prompt" $logcontent] { pass "redirect log file contents" } else { fail "redirect log file contents" diff --git a/gdb/testsuite/gdb.mi/mi-vla-fortran.exp b/gdb/testsuite/gdb.mi/mi-vla-fortran.exp index bf65bf914cf..537221f84fb 100644 --- a/gdb/testsuite/gdb.mi/mi-vla-fortran.exp +++ b/gdb/testsuite/gdb.mi/mi-vla-fortran.exp @@ -51,10 +51,10 @@ mi_expect_stop "breakpoint-hit" "vla" "" ".*vla.f90" "$bp_lineno" \ mi_gdb_test "500-data-evaluate-expression vla1" \ "500\\^done,value=\"\"" "evaluate not allocated vla, before allocation" -mi_create_varobj_checked vla1_not_allocated vla1 "" \ +mi_create_varobj_checked vla1_not_allocated vla1 "$real \\(:\\)" \ "create local variable vla1_not_allocated" mi_gdb_test "501-var-info-type vla1_not_allocated" \ - "501\\^done,type=\"\"" \ + "501\\^done,type=\"$real \\(:\\)\"" \ "info type variable vla1_not_allocated" mi_gdb_test "502-var-show-format vla1_not_allocated" \ "502\\^done,format=\"natural\"" \ @@ -146,10 +146,10 @@ gdb_expect { -re "580\\^done,value=\"\".*${mi_gdb_prompt}$" { pass $test - mi_create_varobj_checked pvla2_not_associated pvla2 "" \ + mi_create_varobj_checked pvla2_not_associated pvla2 "$real \\(:,:\\)" \ "create local variable pvla2_not_associated" mi_gdb_test "581-var-info-type pvla2_not_associated" \ - "581\\^done,type=\"\"" \ + "581\\^done,type=\"$real \\(:,:\\)\"" \ "info type variable pvla2_not_associated" mi_gdb_test "582-var-show-format pvla2_not_associated" \ "582\\^done,format=\"natural\"" \ diff --git a/gdb/testsuite/gdb.mi/mi2-var-stale-type.c b/gdb/testsuite/gdb.mi/mi2-var-stale-type.c new file mode 100644 index 00000000000..ebced3c0427 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi2-var-stale-type.c @@ -0,0 +1,26 @@ +/* Copyright 2011 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 . */ + +int +main (int argc, char **argv) +{ + char vla[argc]; + + vla[0] = 0; /* break-here */ + + return 0; +} diff --git a/gdb/testsuite/gdb.mi/mi2-var-stale-type.exp b/gdb/testsuite/gdb.mi/mi2-var-stale-type.exp new file mode 100644 index 00000000000..88326c03903 --- /dev/null +++ b/gdb/testsuite/gdb.mi/mi2-var-stale-type.exp @@ -0,0 +1,57 @@ +# Copyright 2011 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 . + +load_lib mi-support.exp +set MIFLAGS "-i=mi2" + +gdb_exit +if [mi_gdb_start] { + continue +} + +set testfile "mi2-var-stale-type" +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +if {[build_executable ${testfile}.exp $testfile $srcfile] == -1} { + return -1 +} + +mi_delete_breakpoints +mi_gdb_reinitialize_dir $srcdir/$subdir +mi_gdb_load ${binfile} + +mi_gdb_test {-interpreter-exec console "maintenance set internal-error quit yes"} \ + {\^done} \ + "maintenance set internal-error quit yes" + +mi_gdb_test {-interpreter-exec console "maintenance set internal-error corefile yes"} \ + {\^done} \ + "maintenance set internal-error corefile yes" + +set line [gdb_get_line_number "break-here"] +set func "main" + +mi_gdb_test "-break-insert -t $srcfile:$line" \ + "\\^done,bkpt=\{number=\"\[0-9\]+\",type=\"breakpoint\",disp=\"del\",enabled=\"y\",addr=\"$hex\",func=\"$func\(\\\(.*\\\)\)?\",file=\".*\",fullname=\".*\",line=\"$line\",\[^\r\n\]*,original-location=\".*\"\}" \ + "breakpoint at $func" + +if { [mi_run_cmd] < 0 } { + return -1 +} +mi_expect_stop "breakpoint-hit" $func ".*" ".*" "\[0-9\]+" { "" "disp=\"del\"" } "stop after initializing vla" + +mi_create_varobj "vla" "vla" "create local variable vla" + +mi_gdb_test "-var-update *" "\\^done,changelist=.*" "-var-update *" diff --git a/gdb/testsuite/gdb.opt/array-from-register-func.c b/gdb/testsuite/gdb.opt/array-from-register-func.c new file mode 100644 index 00000000000..729f457c823 --- /dev/null +++ b/gdb/testsuite/gdb.opt/array-from-register-func.c @@ -0,0 +1,22 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2009 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 . */ + +int +func (int *arr) +{ + return arr[0]; +} diff --git a/gdb/testsuite/gdb.opt/array-from-register.c b/gdb/testsuite/gdb.opt/array-from-register.c new file mode 100644 index 00000000000..3090e7e6311 --- /dev/null +++ b/gdb/testsuite/gdb.opt/array-from-register.c @@ -0,0 +1,28 @@ +/* This file is part of GDB, the GNU debugger. + + Copyright 2009 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 . */ + +extern int func (int *arr); + +int +main (void) +{ + int arr[] = { 42 }; + + func (arr); + + return 0; +} diff --git a/gdb/testsuite/gdb.opt/array-from-register.exp b/gdb/testsuite/gdb.opt/array-from-register.exp new file mode 100644 index 00000000000..f2de718bc39 --- /dev/null +++ b/gdb/testsuite/gdb.opt/array-from-register.exp @@ -0,0 +1,33 @@ +# Copyright 2009 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# This file is part of the gdb testsuite. + +if { [prepare_for_testing array-from-register.exp "array-from-register" \ + {array-from-register.c array-from-register-func.c} \ + {debug optimize=-O2}] } { + return -1 +} + +if ![runto func] then { + return -1 +} + +gdb_test "p arr" "\\$\[0-9\]+ = \\(int \\*\\) *0x\[0-9a-f\]+" + +# Seen regression: +# Address requested for identifier "arr" which is in register $rdi +gdb_test "p arr\[0\]" "\\$\[0-9\]+ = 42" diff --git a/gdb/testsuite/gdb.opt/fortran-string.exp b/gdb/testsuite/gdb.opt/fortran-string.exp new file mode 100644 index 00000000000..90a2bdf2120 --- /dev/null +++ b/gdb/testsuite/gdb.opt/fortran-string.exp @@ -0,0 +1,39 @@ +# Copyright 2009 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# This file was written by Jan Kratochvil . + +# Test GDB can cope with Fortran strings having their length present in a CPU +# register. With -O0 the string length is passed on the stack. To make this +# test meaningful the follow assertion should pass. It is not being checked +# here as the "_s" symbol is compiler dependent: +# (gdb) info address _s +# Symbol "_s" is a variable in register XX. + +set test fortran-string +set srcfile ${test}.f90 +if { [prepare_for_testing ${test}.exp ${test} ${srcfile} {debug f90 additional_flags=-O2}] } { + return -1 +} + +if ![runto $srcfile:[gdb_get_line_number "s = s"]] then { + perror "couldn't run to breakpoint MAIN__" + continue +} + +gdb_test "frame" ".*s='foo'.*" +gdb_test "ptype s" "type = character\\*3" +gdb_test "p s" "\\$\[0-9\]* = 'foo'" diff --git a/gdb/testsuite/gdb.opt/fortran-string.f90 b/gdb/testsuite/gdb.opt/fortran-string.f90 new file mode 100644 index 00000000000..e48d5200854 --- /dev/null +++ b/gdb/testsuite/gdb.opt/fortran-string.f90 @@ -0,0 +1,28 @@ +! Copyright 2009 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 2 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, write to the Free Software +! Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +! +! Ihis file is the Fortran source file for dynamic.exp. +! Original file written by Jakub Jelinek . +! Modified for the GDB testcase by Jan Kratochvil . + + subroutine f(s) + character*(*) s + s = s + end + + program main + call f ('foo') + end diff --git a/gdb/testsuite/gdb.opt/inline-cmds.exp b/gdb/testsuite/gdb.opt/inline-cmds.exp index 40e45a26aae..0c10d5bf2d8 100644 --- a/gdb/testsuite/gdb.opt/inline-cmds.exp +++ b/gdb/testsuite/gdb.opt/inline-cmds.exp @@ -331,7 +331,7 @@ proc mi_cli_step {cli_output_re message} { send_gdb "interpreter-exec console \"step\"\n" gdb_expect { - -re "\\^running\r\n\\*running,thread-id=\"all\"\r\n${mi_gdb_prompt}${cli_output_re}" { + -re "\\^running\r\n\\*running,thread-id=\"1\"\r\n${mi_gdb_prompt}${cli_output_re}" { pass $message } timeout { diff --git a/gdb/testsuite/gdb.pascal/arrays.exp b/gdb/testsuite/gdb.pascal/arrays.exp new file mode 100644 index 00000000000..22acdb86d87 --- /dev/null +++ b/gdb/testsuite/gdb.pascal/arrays.exp @@ -0,0 +1,104 @@ +# Copyright 2008, 2009 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 . + +if $tracelevel then { + strace $tracelevel +} + +load_lib "pascal.exp" + +set testfile "arrays" +set srcfile ${testfile}.pas +set binfile [standard_output_file ${testfile}$EXEEXT] + +# These tests only work with fpc, using the -gw3 compile-option +pascal_init +if { $pascal_compiler_is_fpc != 1 } { + return -1 +} + +# Detect if the fpc version is below 2.3.0 +set fpc_generates_dwarf_for_dynamic_arrays 1 +if { ($fpcversion_major < 2) || ( ($fpcversion_major == 2) && ($fpcversion_minor < 3))} { + set fpc_generates_dwarf_for_dynamic_arrays 0 +} + + +if {[gdb_compile_pascal "-gw3 ${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug ]] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} +set bp_location1 [gdb_get_line_number "set breakpoint 1 here"] +set bp_location2 [gdb_get_line_number "set breakpoint 2 here"] + + +if { [gdb_breakpoint ${srcfile}:${bp_location1}] } { + pass "setting breakpoint 1" +} +if { [gdb_breakpoint ${srcfile}:${bp_location2}] } { + pass "setting breakpoint 2" +} + +# Verify that "start" lands inside the right procedure. +if { [gdb_start_cmd] < 0 } { + untested start + return -1 +} + +gdb_test "" ".* at .*${srcfile}.*" "start" + +gdb_test "cont" "Breakpoint .*:${bp_location1}.*" "Going to first breakpoint" + +gdb_test "print StatArrInt" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61\\}" "Print static array of integer type" +gdb_test "print StatArrInt_" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61\\}" "Print static array of integer" + +gdb_test "cont" "Breakpoint .*:${bp_location2}.*" "Going to second breakpoint" + +gdb_test "print StatArrChar" ".* = 'abcdefghijkl'" "Print static array of char" +gdb_test "print Stat2dArrInt" ".* = \\{\\{0, 1, 2, 3, 4\\}, \\{1, 2, 3, 4, 5\\}, \\{2, 3, 4, 5, 6\\}, \\{3, 4, 5, 6, 7\\}, \\{4, 5, 6, 7, 8\\}, \\{5, 6, 7, 8, 9\\}, \\{6, 7, 8, 9, 10\\}, \\{7, 8, 9, 10, 11\\}, \\{8, 9, 10, 11, 12\\}, \\{9, 10, 11, 12, 13\\}, \\{10, 11, 12, 13, 14\\}, \\{11, 12, 13, 14, 15\\}\\}" "Print static 2-dimensional array of integer" + +if { $fpc_generates_dwarf_for_dynamic_arrays == 0} { + setup_xfail "*-*-*" +} +gdb_test "print DynArrInt" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62\\}" "Print dynamic array of integer type" +if { $fpc_generates_dwarf_for_dynamic_arrays == 0} { + setup_xfail "*-*-*" +} +gdb_test "print DynArrInt_" ".* = \\{50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62\\}" "Print dynamic array of integer" + +if { $fpc_generates_dwarf_for_dynamic_arrays == 0} { + setup_xfail "*-*-*" +} +gdb_test "print s" ".* = 'test'#0'string'" "Print string containing null-char" + +if { $fpc_generates_dwarf_for_dynamic_arrays == 0} { + setup_xfail "*-*-*" +} +gdb_test "print DynArrStr" ".* = \\{'dstr0', 'dstr1', 'dstr2', 'dstr3', 'dstr4', 'dstr5', 'dstr6', 'dstr7', 'dstr8', 'dstr9', 'dstr10', 'dstr11', 'dstr12'\\}" "Print dynamic array of string" + +if { $fpc_generates_dwarf_for_dynamic_arrays == 0} { + setup_xfail "*-*-*" +} +gdb_test "print StatArrStr" ".* = \\{'str0', 'str1', 'str2', 'str3', 'str4', 'str5', 'str6', 'str7', 'str8', 'str9', 'str10', 'str11', 'str12'\\}" "Print static array of string" + +if { $fpc_generates_dwarf_for_dynamic_arrays == 0} { + setup_xfail "*-*-*" +} +gdb_test "print DynArrChar" ".* = 'abcdefghijklm'" "Print dynamic array of char" + diff --git a/gdb/testsuite/gdb.pascal/arrays.pas b/gdb/testsuite/gdb.pascal/arrays.pas new file mode 100644 index 00000000000..295602d68ca --- /dev/null +++ b/gdb/testsuite/gdb.pascal/arrays.pas @@ -0,0 +1,82 @@ +{ + Copyright 2008, 2009 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 . +} + +program arrays; + +{$mode objfpc}{$h+} + +uses sysutils; + +type TStatArrInt= array[0..11] of integer; + TDynArrInt= array of integer; + TStatArrStr= array[0..12] of string; + TDynArrStr= array of string; + TDynArrChar = array of char; + TStatArrChar = array [0..11] of char; + + TStat2dArrInt = array[0..11,0..4] of integer; + +var StatArrInt: TStatArrInt; + StatArrInt_: Array[0..11] of integer; + DynArrInt: TDynArrInt; + DynArrInt_: Array of integer; + StatArrStr: TStatArrStr; + DynArrStr: TDynArrStr; + StatArrChar: TStatArrChar; + DynArrChar: TDynArrChar; + + Stat2dArrInt: TStat2dArrInt; + + s: string; + + i,j : integer; + +begin + for i := 0 to 11 do + begin + StatArrInt[i]:= i+50; + StatArrInt_[i]:= i+50; + StatArrChar[i]:= chr(ord('a')+i); + for j := 0 to 4 do + Stat2dArrInt[i,j]:=i+j; + end; + writeln(StatArrInt_[0]); + writeln(StatArrInt[0]); { set breakpoint 1 here } + writeln(StatArrChar[0]); + writeln(Stat2dArrInt[0,0]); + + setlength(DynArrInt,13); + setlength(DynArrInt_,13); + setlength(DynArrStr,13); + setlength(DynArrChar,13); + for i := 0 to 12 do + begin + DynArrInt[i]:= i+50; + DynArrInt_[i]:= i+50; + DynArrChar[i]:= chr(ord('a')+i); + StatArrStr[i]:='str'+inttostr(i); + DynArrStr[i]:='dstr'+inttostr(i); + end; + writeln(DynArrInt_[1]); + writeln(DynArrInt[1]); + writeln(DynArrStr[1]); + writeln(StatArrStr[1]); + writeln(DynArrChar[1]); + + s := 'test'#0'string'; + writeln(s); { set breakpoint 2 here } +end. diff --git a/gdb/testsuite/gdb.pie/attach.c b/gdb/testsuite/gdb.pie/attach.c new file mode 100644 index 00000000000..0041b4732d2 --- /dev/null +++ b/gdb/testsuite/gdb.pie/attach.c @@ -0,0 +1,20 @@ +/* This program is intended to be started outside of gdb, and then + attached to by gdb. Thus, it simply spins in a loop. The loop + is exited when & if the variable 'should_exit' is non-zero. (It + is initialized to zero in this program, so the loop will never + exit unless/until gdb sets the variable to non-zero.) + */ +#include + +int should_exit = 0; + +int main () +{ + int local_i = 0; + + while (! should_exit) + { + local_i++; + } + return 0; +} diff --git a/gdb/testsuite/gdb.pie/attach.exp b/gdb/testsuite/gdb.pie/attach.exp new file mode 100644 index 00000000000..648c92608c3 --- /dev/null +++ b/gdb/testsuite/gdb.pie/attach.exp @@ -0,0 +1,416 @@ +# Copyright 1997, 1999, 2002 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +# On HP-UX 11.0, this test is causing a process running the program +# "attach" to be left around spinning. Until we figure out why, I am +# commenting out the test to avoid polluting tiamat (our 11.0 nightly +# test machine) with these processes. RT +# +# Setting the magic bit in the target app should work. I added a +# "kill", and also a test for the R3 register warning. JB +if { [istarget "hppa*-*-hpux*"] } { + return 0 +} + +# are we on a target board +if [is_remote target] then { + return 0 +} + +set testfile "attach" +set srcfile ${testfile}.c +set srcfile2 ${testfile}2.c +set binfile [standard_output_file ${testfile}] +set binfile2 [standard_output_file ${testfile}2] +set escapedbinfile [string_to_regexp [standard_output_file ${testfile}]] +set cleanupfile [standard_output_file ${testfile}.awk] + +#execute_anywhere "rm -f ${binfile} ${binfile2}" +remote_exec build "rm -f ${binfile} ${binfile2}" +# For debugging this test +# +#log_user 1 + +# Clean out any old files from past runs. +# +remote_exec build "${cleanupfile}" + +# build the first test case +# +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug "additional_flags= -fpie -pie"}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +# Build the in-system-call test + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable {debug "additional_flags= -fpie -pie"}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +if [get_compiler_info ${binfile}] { + return -1 +} + +proc do_attach_tests {} { + global gdb_prompt + global binfile + global escapedbinfile + global srcfile + global testfile + global subdir + global timeout + + # Start the program running and then wait for a bit, to be sure + # that it can be attached to. + # + set testpid [eval exec $binfile &] + exec sleep 2 + + # Verify that we cannot attach to nonsense. + # + send_gdb "attach abc\n" + gdb_expect { + -re ".*Illegal process-id: abc.*$gdb_prompt $"\ + {pass "attach to nonsense is prohibited"} + -re "Attaching to.*, process .*couldn't open /proc file.*$gdb_prompt $"\ + { + # Response expected from /proc-based systems. + pass "attach to nonsense is prohibited" + } + -re "Attaching to.*$gdb_prompt $"\ + {fail "attach to nonsense is prohibited (bogus pid allowed)"} + -re "$gdb_prompt $" {fail "attach to nonsense is prohibited"} + timeout {fail "(timeout) attach to nonsense is prohibited"} + } + + # Verify that we cannot attach to what appears to be a valid + # process ID, but is a process that doesn't exist. Traditionally, + # most systems didn't have a process with ID 0, so we take that as + # the default. However, there are a few exceptions. + # + set boguspid 0 + if { [istarget "*-*-*bsd*"] } { + # In FreeBSD 5.0, PID 0 is used for "swapper". Use -1 instead + # (which should have the desired effect on any version of + # FreeBSD, and probably other *BSD's too). + set boguspid -1 + } + send_gdb "attach $boguspid\n" + gdb_expect { + -re "Attaching to.*, process $boguspid.*No such process.*$gdb_prompt $"\ + { + # Response expected on ptrace-based systems (i.e. HP-UX 10.20). + pass "attach to nonexistent process is prohibited" + } + -re "Attaching to.*, process $boguspid failed.*Hint.*$gdb_prompt $"\ + { + # Response expected on ttrace-based systems (i.e. HP-UX 11.0). + pass "attach to nonexistent process is prohibited" + } + -re "Attaching to.*, process $boguspid.*denied.*$gdb_prompt $"\ + {pass "attach to nonexistent process is prohibited"} + -re "Attaching to.*, process $boguspid.*not permitted.*$gdb_prompt $"\ + {pass "attach to nonexistent process is prohibited"} + -re "Attaching to.*, process .*couldn't open /proc file.*$gdb_prompt $"\ + { + # Response expected from /proc-based systems. + pass "attach to nonexistent process is prohibited" + } + -re "$gdb_prompt $" {fail "attach to nonexistent process is prohibited"} + timeout { + fail "(timeout) attach to nonexistent process is prohibited" + } + } + + # Verify that we can attach to the process by first giving its + # executable name via the file command, and using attach with + # the process ID. + # + # (Actually, the test system appears to do this automatically + # for us. So, we must also be prepared to be asked if we want + # to discard an existing set of symbols.) + # + send_gdb "file $binfile\n" + gdb_expect { + -re "Load new symbol table from.*y or n.*$" { + send_gdb "y\n" + gdb_expect { + -re "Reading symbols from $escapedbinfile\.\.\.*done.*$gdb_prompt $"\ + {pass "(re)set file, before attach1"} + -re "$gdb_prompt $" {fail "(re)set file, before attach1"} + timeout {fail "(timeout) (re)set file, before attach1"} + } + } + -re "Reading symbols from $escapedbinfile\.\.\.*done.*$gdb_prompt $"\ + {pass "set file, before attach1"} + -re "$gdb_prompt $" {fail "set file, before attach1"} + timeout {fail "(timeout) set file, before attach1"} + } + + send_gdb "attach $testpid\n" + gdb_expect { + -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*main.*at .*$srcfile:.*$gdb_prompt $"\ + {pass "attach1, after setting file"} + -re "$gdb_prompt $" {fail "attach1, after setting file"} + timeout {fail "(timeout) attach1, after setting file"} + } + + # Verify that we can "see" the variable "should_exit" in the + # program, and that it is zero. + # + send_gdb "print should_exit\n" + gdb_expect { + -re ".* = 0.*$gdb_prompt $"\ + {pass "after attach1, print should_exit"} + -re "$gdb_prompt $" {fail "after attach1, print should_exit"} + timeout {fail "(timeout) after attach1, print should_exit"} + } + + # Detach the process. + # + send_gdb "detach\n" + gdb_expect { + -re "Detaching from program: .*$escapedbinfile.*$gdb_prompt $"\ + {pass "attach1 detach"} + -re "$gdb_prompt $" {fail "attach1 detach"} + timeout {fail "(timeout) attach1 detach"} + } + + # Wait a bit for gdb to finish detaching + # + exec sleep 5 + + # Purge the symbols from gdb's brain. (We want to be certain + # the next attach, which won't be preceded by a "file" command, + # is really getting the executable file without our help.) + # + set old_timeout $timeout + set timeout 15 + send_gdb "file\n" + gdb_expect { + -re ".*gdb internal error.*$" { + fail "Internal error, prob. Memory corruption" + } + -re "No executable file now.*Discard symbol table.*y or n.*$" { + send_gdb "y\n" + gdb_expect { + -re "No symbol file now.*$gdb_prompt $"\ + {pass "attach1, purging symbols after detach"} + -re "$gdb_prompt $" {fail "attach1, purging symbols after detach"} + timeout {fail "(timeout) attach1, purging symbols after detach"} + } + } + -re "$gdb_prompt $" {fail "attach1, purging file after detach"} + timeout { + fail "(timeout) attach1, purging file after detach" + } + } + set timeout $old_timeout + + # Verify that we can attach to the process just by giving the + # process ID. + # + send_gdb "attach $testpid\n" + gdb_expect { + -re "Attaching to process $testpid.*Reading symbols from $escapedbinfile.*main.*at .*$gdb_prompt $"\ + {pass "attach2"} + -re "$gdb_prompt $" {fail "attach2"} + timeout {fail "(timeout) attach2"} + } + + # Verify that we can modify the variable "should_exit" in the + # program. + # + send_gdb "set should_exit=1\n" + gdb_expect { + -re "$gdb_prompt $" {pass "after attach2, set should_exit"} + timeout {fail "(timeout) after attach2, set should_exit"} + } + + # Verify that the modification really happened. + # + send_gdb "tbreak 19\n" + gdb_expect { + -re "reakpoint .*at.*$srcfile, line 19.*$gdb_prompt $"\ + {pass "after attach2, set tbreak postloop"} + -re "$gdb_prompt $" {fail "after attach2, set tbreak postloop"} + timeout {fail "(timeout) after attach2, set tbreak postloop"} + } + send_gdb "continue\n" + gdb_expect { + -re "main.*at.*$srcfile:19.*$gdb_prompt $"\ + {pass "after attach2, reach tbreak postloop"} + -re "$gdb_prompt $" {fail "after attach2, reach tbreak postloop"} + timeout {fail "(timeout) after attach2, reach tbreak postloop"} + } + + # Allow the test process to exit, to cleanup after ourselves. + # + gdb_test "continue" {\[Inferior .* exited normally\]} "after attach2, exit" + + # Make sure we don't leave a process around to confuse + # the next test run (and prevent the compile by keeping + # the text file busy), in case the "set should_exit" didn't + # work. + # + remote_exec build "kill -9 ${testpid}" + # Start the program running and then wait for a bit, to be sure + # that it can be attached to. + # + set testpid [eval exec $binfile &] + exec sleep 2 + + # Verify that we can attach to the process, and find its a.out + # when we're cd'd to some directory that doesn't contain the + # a.out. (We use the source path set by the "dir" command.) + # + send_gdb "dir [file dirname [standard_output_file ${testfile}]]\n" + gdb_expect { + -re ".*Source directories searched: .*$gdb_prompt $"\ + {pass "set source path"} + -re "$gdb_prompt $" {fail "set source path"} + timeout {fail "(timeout) set source path"} + } + + send_gdb "cd /tmp\n" + gdb_expect { + -re ".*Working directory /tmp.*$gdb_prompt $"\ + {pass "cd away from process' a.out"} + -re "$gdb_prompt $" {fail "cd away from process' a.out"} + timeout {fail "(timeout) cd away from process' a.out"} + } + + # Explicitly flush out any knowledge of the previous attachment. + send_gdb "symbol\n" + gdb_expect { + -re ".*Discard symbol table from.*y or n. $"\ + {send_gdb "y\n" + gdb_expect { + -re ".*No symbol file now.*$gdb_prompt $"\ + {pass "before attach3, flush symbols"} + -re "$gdb_prompt $" {fail "before attach3, flush symbols"} + timeout {fail "(timeout) before attach3, flush symbols"} + } + } + -re ".*No symbol file now.*$gdb_prompt $"\ + {pass "before attach3, flush symbols"} + -re "$gdb_prompt $" {fail "before attach3, flush symbols"} + timeout {fail "(timeout) before attach3, flush symbols"} + } + send_gdb "exec\n" + gdb_expect { + -re ".*No executable file now.*$gdb_prompt $"\ + {pass "before attach3, flush exec"} + -re "$gdb_prompt $" {fail "before attach3, flush exec"} + timeout {fail "(timeout) before attach3, flush exec"} + } + + send_gdb "attach $testpid\n" + gdb_expect { + -re "Attaching to process $testpid.*Reading symbols from $escapedbinfile.*main.*at .*$gdb_prompt $"\ + {pass "attach when process' a.out not in cwd"} + -re "$gdb_prompt $" {fail "attach when process' a.out not in cwd"} + timeout {fail "(timeout) attach when process' a.out not in cwd"} + } + + send_gdb "kill\n" + gdb_expect { + -re ".*Kill the program being debugged.*y or n. $"\ + {send_gdb "y\n" + gdb_expect { + -re "$gdb_prompt $" {pass "after attach3, exit"} + timeout {fail "(timeout) after attach3, exit"} + } + } + -re "$gdb_prompt $" {fail "after attach3, exit"} + timeout {fail "(timeout) after attach3, exit"} + } + + # Another "don't leave a process around" + remote_exec build "kill -9 ${testpid}" +} + +proc do_call_attach_tests {} { + global gdb_prompt + global binfile2 + + # Start the program running and then wait for a bit, to be sure + # that it can be attached to. + # + set testpid [eval exec $binfile2 &] + exec sleep 2 + + # Attach + # + gdb_test "file $binfile2" ".*" "force switch to gdb64, if necessary" + send_gdb "attach $testpid\n" + gdb_expect { + -re ".*warning: reading register.*I.*O error.*$gdb_prompt $" { + fail "attach call, read register 3 error" + } + -re "Attaching to.*process $testpid.*$gdb_prompt $" { + # libc is relocated, not relocated, therefore not printed. + pass "attach call" + } + -re "$gdb_prompt $" {fail "attach call"} + timeout {fail "(timeout) attach call"} + } + + # See if other registers are problems + # + send_gdb "i r r3\n" + gdb_expect { + -re ".*warning: reading register.*$gdb_prompt $" { + pass "CHFts23490: known bug" + } + -re ".*r3.*$gdb_prompt $" { + pass "Bug fixed, Yayyy!" + } + timeout { fail "timeout on info reg" } + } + + # Get rid of the process + # + gdb_test "p should_exit = 1" ".*" + gdb_test "c" {\[Inferior .* exited normally\]} + + # Be paranoid + # + remote_exec build "kill -9 ${testpid}" + +} + + +# Start with a fresh gdb +# +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# This is a test of gdb's ability to attach to a running process. +# +do_attach_tests + +# Test attaching when the target is inside a system call +# +gdb_exit +gdb_start + +gdb_reinitialize_dir $srcdir/$subdir +do_call_attach_tests + +return 0 diff --git a/gdb/testsuite/gdb.pie/attach2.c b/gdb/testsuite/gdb.pie/attach2.c new file mode 100644 index 00000000000..a78037ed387 --- /dev/null +++ b/gdb/testsuite/gdb.pie/attach2.c @@ -0,0 +1,24 @@ +/* This program is intended to be started outside of gdb, and then + attached to by gdb. Thus, it simply spins in a loop. The loop + is exited when & if the variable 'should_exit' is non-zero. (It + is initialized to zero in this program, so the loop will never + exit unless/until gdb sets the variable to non-zero.) + */ +#include +#include +#include + +int should_exit = 0; + +int main () +{ + int local_i = 0; + + sleep( 10 ); /* System call causes register fetch to fail */ + /* This is a known HPUX "feature" */ + while (! should_exit) + { + local_i++; + } + return (0); +} diff --git a/gdb/testsuite/gdb.pie/break.c b/gdb/testsuite/gdb.pie/break.c new file mode 100644 index 00000000000..bf398fcca91 --- /dev/null +++ b/gdb/testsuite/gdb.pie/break.c @@ -0,0 +1,146 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 1992, 1993, 1994, 1995, 1999, 2002, 2003 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +#ifdef vxworks + +# include + +/* VxWorks does not supply atoi. */ +static int +atoi (z) + char *z; +{ + int i = 0; + + while (*z >= '0' && *z <= '9') + i = i * 10 + (*z++ - '0'); + return i; +} + +/* I don't know of any way to pass an array to VxWorks. This function + can be called directly from gdb. */ + +vxmain (arg) +char *arg; +{ + char *argv[2]; + + argv[0] = ""; + argv[1] = arg; + main (2, argv, (char **) 0); +} + +#else /* ! vxworks */ +# include +# include +#endif /* ! vxworks */ + +#ifdef PROTOTYPES +extern int marker1 (void); +extern int marker2 (int a); +extern void marker3 (char *a, char *b); +extern void marker4 (long d); +#else +extern int marker1 (); +extern int marker2 (); +extern void marker3 (); +extern void marker4 (); +#endif + +/* + * This simple classical example of recursion is useful for + * testing stack backtraces and such. + */ + +#ifdef PROTOTYPES +int factorial(int); + +int +main (int argc, char **argv, char **envp) +#else +int +main (argc, argv, envp) +int argc; +char *argv[], **envp; +#endif +{ +#ifdef usestubs + set_debug_traps(); /* set breakpoint 5 here */ + breakpoint(); +#endif + if (argc == 12345) { /* an unlikely value < 2^16, in case uninited */ /* set breakpoint 6 here */ + fprintf (stderr, "usage: factorial \n"); + return 1; + } + printf ("%d\n", factorial (atoi ("6"))); /* set breakpoint 1 here */ + /* set breakpoint 12 here */ + marker1 (); /* set breakpoint 11 here */ + marker2 (43); /* set breakpoint 20 here */ + marker3 ("stack", "trace"); /* set breakpoint 21 here */ + marker4 (177601976L); + argc = (argc == 12345); /* This is silly, but we can step off of it */ /* set breakpoint 2 here */ + return argc; /* set breakpoint 10 here */ +} + +#ifdef PROTOTYPES +int factorial (int value) +#else +int factorial (value) +int value; +#endif +{ + if (value > 1) { /* set breakpoint 7 here */ + value *= factorial (value - 1); + } + return (value); /* set breakpoint 19 here */ +} + +#ifdef PROTOTYPES +int multi_line_if_conditional (int a, int b, int c) +#else +int multi_line_if_conditional (a, b, c) + int a, b, c; +#endif +{ + if (a /* set breakpoint 3 here */ + && b + && c) + return 0; + else + return 1; +} + +#ifdef PROTOTYPES +int multi_line_while_conditional (int a, int b, int c) +#else +int multi_line_while_conditional (a, b, c) + int a, b, c; +#endif +{ + while (a /* set breakpoint 4 here */ + && b + && c) + { + a--, b--, c--; + } + return 0; +} diff --git a/gdb/testsuite/gdb.pie/break.exp b/gdb/testsuite/gdb.pie/break.exp new file mode 100644 index 00000000000..97b87397c27 --- /dev/null +++ b/gdb/testsuite/gdb.pie/break.exp @@ -0,0 +1,954 @@ +# Copyright 1988, 1990, 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2002, 2003, 2004 +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +# This file was written by Rob Savoye. (rob@cygnus.com) + +# Test the same stuff but with PIE executables + +set testfile "break" +set srcfile ${testfile}.c +set srcfile1 ${testfile}1.c +set binfile [standard_output_file ${testfile}] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}0.o" object {debug "additional_flags=-w -fpie -pie"}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile}1.o" object {debug "additional_flags=-w -fpie -pie"}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +if { [gdb_compile "${binfile}0.o ${binfile}1.o" "${binfile}" executable {debug "additional_flags=-w -fpie -pie"}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +if [get_compiler_info ${binfile}] { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +if [target_info exists gdb_stub] { + gdb_step_for_stub; +} +# +# test simple breakpoint setting commands +# + +# Test deleting all breakpoints when there are none installed, +# GDB should not prompt for confirmation. +# Note that gdb-init.exp provides a "delete_breakpoints" proc +# for general use elsewhere. + +send_gdb "delete breakpoints\n" +gdb_expect { + -re "Delete all breakpoints.*$" { + send_gdb "y\n" + gdb_expect { + -re "$gdb_prompt $" { + fail "Delete all breakpoints when none (unexpected prompt)" + } + timeout { fail "Delete all breakpoints when none (timeout after unexpected prompt)" } + } + } + -re ".*$gdb_prompt $" { pass "Delete all breakpoints when none" } + timeout { fail "Delete all breakpoints when none (timeout)" } +} + +# +# test break at function +# +gdb_test "break main" \ + "Breakpoint.*at.* file .*$srcfile, line.*" \ + "breakpoint function" + +# +# test break at quoted function +# +gdb_test "break \"marker2\"" \ + "Breakpoint.*at.* file .*$srcfile1, line.*" \ + "breakpoint quoted function" + +# +# test break at function in file +# +gdb_test "break $srcfile:factorial" \ + "Breakpoint.*at.* file .*$srcfile, line.*" \ + "breakpoint function in file" + +set bp_location1 [gdb_get_line_number "set breakpoint 1 here"] + +# +# test break at line number +# +# Note that the default source file is the last one whose source text +# was printed. For native debugging, before we've executed the +# program, this is the file containing main, but for remote debugging, +# it's wherever the processor was stopped when we connected to the +# board. So, to be sure, we do a list command. +# +gdb_test "list main" \ + ".*main \\(argc, argv, envp\\).*" \ + "use `list' to establish default source file" +gdb_test "break $bp_location1" \ + "Breakpoint.*at.* file .*$srcfile, line $bp_location1\\." \ + "breakpoint line number" + +# +# test duplicate breakpoint +# +gdb_test "break $bp_location1" \ + "Note: breakpoint \[0-9\]+ also set at pc.*Breakpoint \[0-9\]+ at.* file .*$srcfile, line $bp_location1\\." \ + "breakpoint duplicate" + +set bp_location2 [gdb_get_line_number "set breakpoint 2 here"] + +# +# test break at line number in file +# +gdb_test "break $srcfile:$bp_location2" \ + "Breakpoint.*at.* file .*$srcfile, line $bp_location2\\." \ + "breakpoint line number in file" + +set bp_location3 [gdb_get_line_number "set breakpoint 3 here"] +set bp_location4 [gdb_get_line_number "set breakpoint 4 here"] + +# +# Test putting a break at the start of a multi-line if conditional. +# Verify the breakpoint was put at the start of the conditional. +# +gdb_test "break multi_line_if_conditional" \ + "Breakpoint.*at.* file .*$srcfile, line $bp_location3\\." \ + "breakpoint at start of multi line if conditional" + +gdb_test "break multi_line_while_conditional" \ + "Breakpoint.*at.* file .*$srcfile, line $bp_location4\\." \ + "breakpoint at start of multi line while conditional" + +set bp_location5 [gdb_get_line_number "set breakpoint 5 here"] +set bp_location6 [gdb_get_line_number "set breakpoint 6 here"] + +# +# check to see what breakpoints are set +# +if [target_info exists gdb_stub] { + set main_line $bp_location5 +} else { + set main_line $bp_location6 +} + +set proto "" + +set bp_location7 [gdb_get_line_number "set breakpoint 7 here"] +set bp_location8 [gdb_get_line_number "set breakpoint 8 here" $srcfile1] +set bp_location9 [gdb_get_line_number "set breakpoint 9 here" $srcfile1] + +# Test a pending breakpoint in PIE executable does not crash later GDB. +gdb_breakpoint "non_existent_function" allow-pending + +gdb_test "info break" \ + "Num\[ \]+Type\[ \]+Disp Enb Address\[ \]+What.* +\[0-9\]+\[\t \]+breakpoint keep y.* in main at .*$srcfile:$main_line.* +\[0-9\]+\[\t \]+breakpoint keep y.* in marker2 at .*$srcfile1:($bp_location8|$bp_location9).* +\[0-9\]+\[\t \]+breakpoint keep y.* in factorial$proto at .*$srcfile:$bp_location7.* +\[0-9\]+\[\t \]+breakpoint keep y.* in main at .*$srcfile:$bp_location1.* +\[0-9\]+\[\t \]+breakpoint keep y.* in main at .*$srcfile:$bp_location1.* +\[0-9\]+\[\t \]+breakpoint keep y.* in main at .*$srcfile:$bp_location2.* +\[0-9\]+\[\t \]+breakpoint keep y.* in multi_line_if_conditional at .*$srcfile:$bp_location3.* +\[0-9\]+\[\t \]+breakpoint keep y.* in multi_line_while_conditional at .*$srcfile:$bp_location4.* +\[0-9\]+\[\t \]+breakpoint keep y.* *non_existent_function" \ + "breakpoint info" + +# FIXME: The rest of this test doesn't work with anything that can't +# handle arguments. +# Huh? There doesn't *appear* to be anything that passes arguments +# below. +if [istarget "mips-idt-*"] then { + return +} + +# +# run until the breakpoint at main is hit. For non-stubs-using targets. +# +if ![target_info exists use_gdb_stub] { + if [istarget "*-*-vxworks*"] then { + send_gdb "run vxmain \"2\"\n" + set timeout 120 + verbose "Timeout is now $timeout seconds" 2 + } else { + send_gdb "run\n" + } + gdb_expect { + -re "The program .* has been started already.*y or n. $" { + send_gdb "y\n" + exp_continue + } + -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $"\ + { pass "run until function breakpoint" } + -re ".*$gdb_prompt $" { fail "run until function breakpoint" } + timeout { fail "run until function breakpoint (timeout)" } + } +} else { + if ![target_info exists gdb_stub] { + gdb_test continue ".*Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.*\{.*" "stub continue" + } +} + +# +# run until the breakpoint at a line number +# +gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location1.*$bp_location1\[\t \]+printf.*factorial.*" \ + "run until breakpoint set at a line number" + +# +# Run until the breakpoint set in a function in a file +# +for {set i 6} {$i >= 1} {incr i -1} { + gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, factorial \\(value=$i\\) at .*$srcfile:$bp_location7.*$bp_location7\[\t \]+.*if .value > 1. \{.*" \ + "run until file:function($i) breakpoint" +} + +# +# Run until the breakpoint set at a quoted function +# +gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, (0x\[0-9a-f\]+ in )?marker2 \\(a=43\\) at .*$srcfile1:($bp_location8|$bp_location9).*" \ + "run until quoted breakpoint" +# +# run until the file:function breakpoint at a line number in a file +# +gdb_test continue "Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location2.*$bp_location2\[\t \]+argc = \\(argc == 12345\\);.*" \ + "run until file:linenum breakpoint" + +# Test break at offset +1 +set bp_location10 [gdb_get_line_number "set breakpoint 10 here"] + +gdb_test "break +1" \ + "Breakpoint.*at.* file .*$srcfile, line $bp_location10\\." \ + "breakpoint offset +1" + +# Check to see if breakpoint is hit when stepped onto + +gdb_test "step" \ + ".*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location10.*$bp_location10\[\t \]+return argc;.*breakpoint 10 here.*" \ + "step onto breakpoint" + +# +# delete all breakpoints so we can start over, course this can be a test too +# +delete_breakpoints + +# +# test temporary breakpoint at function +# + +gdb_test "tbreak main" "reakpoint.*at.* file .*$srcfile, line.*" "Temporary breakpoint function" + +# +# test break at function in file +# + +gdb_test "tbreak $srcfile:factorial" "reakpoint.*at.* file .*$srcfile, line.*" \ + "Temporary breakpoint function in file" + +# +# test break at line number +# +send_gdb "tbreak $bp_location1\n" +gdb_expect { + -re "reakpoint.*at.* file .*$srcfile, line $bp_location1.*$gdb_prompt $" { pass "Temporary breakpoint line number #1" } + -re ".*$gdb_prompt $" { pass "Temporary breakpoint line number #1" } + timeout { fail "breakpoint line number #1 (timeout)" } +} + +gdb_test "tbreak $bp_location6" "reakpoint.*at.* file .*$srcfile, line $bp_location6.*" "Temporary breakpoint line number #2" + +# +# test break at line number in file +# +send_gdb "tbreak $srcfile:$bp_location2\n" +gdb_expect { + -re "reakpoint.*at.* file .*$srcfile, line $bp_location2.*$gdb_prompt $" { pass "Temporary breakpoint line number in file #1" } + -re ".*$gdb_prompt $" { pass "Temporary breakpoint line number in file #1" } + timeout { fail "Temporary breakpoint line number in file #1 (timeout)" } +} + +set bp_location11 [gdb_get_line_number "set breakpoint 11 here"] +gdb_test "tbreak $srcfile:$bp_location11" "reakpoint.*at.* file .*$srcfile, line $bp_location11.*" "Temporary breakpoint line number in file #2" + +# +# check to see what breakpoints are set (temporary this time) +# +gdb_test "info break" "Num.*Type.*Disp Enb Address.*What.*\[\r\n\] +\[0-9\]+\[\t \]+breakpoint del.*y.*in main at .*$srcfile:$main_line.*\[\r\n\] +\[0-9\]+\[\t \]+breakpoint del.*y.*in factorial$proto at .*$srcfile:$bp_location7.*\[\r\n\] +\[0-9\]+\[\t \]+breakpoint del.*y.*in main at .*$srcfile:$bp_location1.*\[\r\n\] +\[0-9\]+\[\t \]+breakpoint del.*y.*in main at .*$srcfile:$bp_location6.*\[\r\n\] +\[0-9\]+\[\t \]+breakpoint del.*y.*in main at .*$srcfile:$bp_location2.*\[\r\n\] +\[0-9\]+\[\t \]+breakpoint del.*y.*in main at .*$srcfile:$bp_location11.*" \ + "Temporary breakpoint info" + + +#*********** + +# Verify that catchpoints for fork, vfork and exec don't trigger +# inappropriately. (There are no calls to those system functions +# in this test program.) +# +if ![runto_main] then { fail "break tests suppressed" } + +send_gdb "catch\n" +gdb_expect { + -re "Catch requires an event name.*$gdb_prompt $"\ + {pass "catch requires an event name"} + -re "$gdb_prompt $"\ + {fail "catch requires an event name"} + timeout {fail "(timeout) catch requires an event name"} +} + + +set name "set catch fork, never expected to trigger" +send_gdb "catch fork\n" +gdb_expect { + -re "Catchpoint \[0-9\]* .fork..*$gdb_prompt $" + {pass $name} + -re "Catch of fork not yet implemented.*$gdb_prompt $" + {pass $name} + -re "$gdb_prompt $" + {fail $name} + timeout {fail "(timeout) $name"} +} + + +set name "set catch vfork, never expected to trigger" +send_gdb "catch vfork\n" + +# If we are on HP-UX 10.20, we expect an error message to be +# printed if we type "catch vfork" at the gdb gdb_prompt. This is +# because on HP-UX 10.20, we cannot catch vfork events. + +if [istarget "hppa*-hp-hpux10.20"] then { + gdb_expect { + -re "Catch of vfork events not supported on HP-UX 10.20..*$gdb_prompt $" + {pass $name} + -re "$gdb_prompt $" + {fail $name} + timeout {fail "(timeout) $name"} + } +} else { + gdb_expect { + -re "Catchpoint \[0-9\]* .vfork..*$gdb_prompt $" + {pass $name} + -re "Catch of vfork not yet implemented.*$gdb_prompt $" + {pass $name} + -re "$gdb_prompt $" + {fail $name} + timeout {fail "(timeout) $name"} + } +} + +set name "set catch exec, never expected to trigger" +send_gdb "catch exec\n" +gdb_expect { + -re "Catchpoint \[0-9\]* .exec..*$gdb_prompt $" + {pass $name} + -re "Catch of exec not yet implemented.*$gdb_prompt $" + {pass $name} + -re "$gdb_prompt $" {fail $name} + timeout {fail "(timeout) $name"} +} + +# Verify that GDB responds gracefully when asked to set a breakpoint +# on a nonexistent source line. +# +gdb_test_no_output "set breakpoint pending off" +gdb_test "break 999" \ + "No line 999 in the current file." \ + "break on non-existent source line" + +# Run to the desired default location. If not positioned here, the +# tests below don't work. +# +gdb_test "until $bp_location1" "main .* at .*:$bp_location1.*" "until bp_location1" + + +# Verify that GDB allows one to just say "break", which is treated +# as the "default" breakpoint. Note that GDB gets cute when printing +# the informational message about other breakpoints at the same +# location. We'll hit that bird with this stone too. +# +send_gdb "break\n" +gdb_expect { + -re "Breakpoint \[0-9\]*.*$gdb_prompt $"\ + {pass "break on default location, 1st time"} + -re "$gdb_prompt $"\ + {fail "break on default location, 1st time"} + timeout {fail "(timeout) break on default location, 1st time"} +} + +send_gdb "break\n" +gdb_expect { + -re "Note: breakpoint \[0-9\]* also set at .*Breakpoint \[0-9\]*.*$gdb_prompt $"\ + {pass "break on default location, 2nd time"} + -re "$gdb_prompt $"\ + {fail "break on default location, 2nd time"} + timeout {fail "(timeout) break on default location, 2nd time"} +} + +send_gdb "break\n" +gdb_expect { + -re "Note: breakpoints \[0-9\]* and \[0-9\]* also set at .*Breakpoint \[0-9\]*.*$gdb_prompt $"\ + {pass "break on default location, 3rd time"} + -re "$gdb_prompt $"\ + {fail "break on default location, 3rd time"} + timeout {fail "(timeout) break on default location, 3rd time"} +} + +send_gdb "break\n" +gdb_expect { + -re "Note: breakpoints \[0-9\]*, \[0-9\]* and \[0-9\]* also set at .*Breakpoint \[0-9\]*.*$gdb_prompt $"\ + {pass "break on default location, 4th time"} + -re "$gdb_prompt $"\ + {fail "break on default location, 4th time"} + timeout {fail "(timeout) break on default location, 4th time"} +} + +# Verify that a "silent" breakpoint can be set, and that GDB is indeed +# "silent" about its triggering. +# +if ![runto_main] then { fail "break tests suppressed" } + +send_gdb "break $bp_location1\n" +gdb_expect { + -re "Breakpoint (\[0-9\]*) at .*, line $bp_location1.*$gdb_prompt $"\ + {pass "set to-be-silent break bp_location1"} + -re "$gdb_prompt $"\ + {fail "set to-be-silent break bp_location1"} + timeout {fail "(timeout) set to-be-silent break bp_location1"} +} + +send_gdb "commands $expect_out(1,string)\n" +send_gdb "silent\n" +send_gdb "end\n" +gdb_expect { + -re ".*$gdb_prompt $"\ + {pass "set silent break bp_location1"} + timeout {fail "(timeout) set silent break bp_location1"} +} + +send_gdb "info break $expect_out(1,string)\n" +gdb_expect { + -re "\[0-9\]*\[ \t\]*breakpoint.*:$bp_location1\r\n\[ \t\]*silent.*$gdb_prompt $"\ + {pass "info silent break bp_location1"} + -re "$gdb_prompt $"\ + {fail "info silent break bp_location1"} + timeout {fail "(timeout) info silent break bp_location1"} +} +send_gdb "continue\n" +gdb_expect { + -re "Continuing.\r\n$gdb_prompt $"\ + {pass "hit silent break bp_location1"} + -re "$gdb_prompt $"\ + {fail "hit silent break bp_location1"} + timeout {fail "(timeout) hit silent break bp_location1"} +} +send_gdb "bt\n" +gdb_expect { + -re "#0 main .* at .*:$bp_location1.*$gdb_prompt $"\ + {pass "stopped for silent break bp_location1"} + -re "$gdb_prompt $"\ + {fail "stopped for silent break bp_location1"} + timeout {fail "(timeout) stopped for silent break bp_location1"} +} + +# Verify that GDB can at least parse a breakpoint with the +# "thread" keyword. (We won't attempt to test here that a +# thread-specific breakpoint really triggers appropriately. +# The gdb.threads subdirectory contains tests for that.) +# +set bp_location12 [gdb_get_line_number "set breakpoint 12 here"] +send_gdb "break $bp_location12 thread 999\n" +gdb_expect { + -re "Unknown thread 999.*$gdb_prompt $"\ + {pass "thread-specific breakpoint on non-existent thread disallowed"} + -re "$gdb_prompt $"\ + {fail "thread-specific breakpoint on non-existent thread disallowed"} + timeout {fail "(timeout) thread-specific breakpoint on non-existent thread disallowed"} +} + +gdb_test "break $bp_location12 thread foo" \ + "Invalid thread ID: foo" \ + "thread-specific breakpoint on bogus thread ID disallowed" + +# Verify that GDB responds gracefully to a breakpoint command with +# trailing garbage. +# +send_gdb "break $bp_location12 foo\n" +gdb_expect { + -re "malformed linespec error: unexpected string, \"foo\"\r\n$gdb_prompt $"\ + {pass "breakpoint with trailing garbage disallowed"} + -re "$gdb_prompt $"\ + {fail "breakpoint with trailing garbage disallowed"} + timeout {fail "(timeout) breakpoint with trailing garbage disallowed"} +} + +# Verify that GDB responds gracefully to a "clear" command that has +# no matching breakpoint. (First, get us off the current source line, +# which we know has a breakpoint.) +# +send_gdb "next\n" +gdb_expect { + -re ".*$gdb_prompt $"\ + {pass "step over breakpoint"} + timeout {fail "(timeout) step over breakpoint"} +} +send_gdb "clear 81\n" +gdb_expect { + -re "No breakpoint at 81..*$gdb_prompt $"\ + {pass "clear line has no breakpoint disallowed"} + -re "$gdb_prompt $"\ + {fail "clear line has no breakpoint disallowed"} + timeout {fail "(timeout) clear line has no breakpoint disallowed"} +} +send_gdb "clear\n" +gdb_expect { + -re "No breakpoint at this line..*$gdb_prompt $"\ + {pass "clear current line has no breakpoint disallowed"} + -re "$gdb_prompt $"\ + {fail "clear current line has no breakpoint disallowed"} + timeout {fail "(timeout) clear current line has no breakpoint disallowed"} +} + +# Verify that we can set and clear multiple breakpoints. +# +# We don't test that it deletes the correct breakpoints. We do at +# least test that it deletes more than one breakpoint. +# +gdb_test "break marker3" "Breakpoint.*at.*" "break marker3 #1" +gdb_test "break marker3" "Breakpoint.*at.*" "break marker3 #2" +gdb_test "clear marker3" {Deleted breakpoints [0-9]+ [0-9]+.*} + +# Verify that a breakpoint can be set via a convenience variable. +# +send_gdb "set \$foo=$bp_location11\n" +gdb_expect { + -re "$gdb_prompt $"\ + {pass "set convenience variable \$foo to bp_location11"} + timeout {fail "(timeout) set convenience variable \$foo to bp_location11"} +} +send_gdb "break \$foo\n" +gdb_expect { + -re "Breakpoint (\[0-9\]*) at .*, line $bp_location11.*$gdb_prompt $"\ + {pass "set breakpoint via convenience variable"} + -re "$gdb_prompt $"\ + {fail "set breakpoint via convenience variable"} + timeout {fail "(timeout) set breakpoint via convenience variable"} +} + +# Verify that GDB responds gracefully to an attempt to set a +# breakpoint via a convenience variable whose type is not integer. +# +send_gdb "set \$foo=81.5\n" +gdb_expect { + -re "$gdb_prompt $"\ + {pass "set convenience variable \$foo to 81.5"} + timeout {fail "(timeout) set convenience variable \$foo to 81.5"} +} +send_gdb "break \$foo\n" +gdb_expect { + -re "Convenience variables used in line specs must have integer values..*$gdb_prompt $"\ + {pass "set breakpoint via non-integer convenience variable disallowed"} + -re "$gdb_prompt $"\ + {fail "set breakpoint via non-integer convenience variable disallowed"} + timeout {fail "(timeout) set breakpoint via non-integer convenience variable disallowed"} +} + +# Verify that we can set and trigger a breakpoint in a user-called function. +# +send_gdb "break marker2\n" +gdb_expect { + -re "Breakpoint (\[0-9\]*) at .*, line ($bp_location8|$bp_location9).*$gdb_prompt $"\ + {pass "set breakpoint on to-be-called function"} + -re "$gdb_prompt $"\ + {fail "set breakpoint on to-be-called function"} + timeout {fail "(timeout) set breakpoint on to-be-called function"} +} +send_gdb "print marker2(99)\n" +gdb_expect { + -re "The program being debugged stopped while in a function called from GDB.\r\nEvaluation of the expression containing the function\r\n.marker2$proto. will be abandoned.\r\nWhen the function is done executing, GDB will silently stop.\r\n$gdb_prompt $"\ + {pass "hit breakpoint on called function"} + -re "$gdb_prompt $"\ + {fail "hit breakpoint on called function"} + timeout {fail "(timeout) hit breakpoint on called function"} +} + +# As long as we're stopped (breakpointed) in a called function, +# verify that we can successfully backtrace & such from here. +# +# In this and the following test, the _sr4export check apparently is needed +# for hppa*-*-hpux. +# +send_gdb "bt\n" +gdb_expect { + -re "#0\[ \t\]*($hex in )?marker2.*:($bp_location8|$bp_location9)\r\n#1.*_sr4export.*$gdb_prompt $"\ + {pass "backtrace while in called function"} + -re "#0\[ \t\]*($hex in )?marker2.*:($bp_location8|$bp_location9)\r\n#1.*function called from gdb.*$gdb_prompt $"\ + {pass "backtrace while in called function"} + -re "$gdb_prompt $"\ + {fail "backtrace while in called function"} + timeout {fail "(timeout) backtrace while in called function"} +} + +# Return from the called function. For remote targets, it's important to do +# this before runto_main, which otherwise may silently stop on the dummy +# breakpoint inserted by GDB at the program's entry point. +# +send_gdb "finish\n" +gdb_expect { + -re "Run till exit from .*marker2.* at .*($bp_location8|$bp_location9)\r\n.* in _sr4export.*$gdb_prompt $"\ + {pass "finish from called function"} + -re "Run till exit from .*marker2.* at .*($bp_location8|$bp_location9)\r\n.*function called from gdb.*$gdb_prompt $"\ + {pass "finish from called function"} + -re "Run till exit from .*marker2.* at .*($bp_location8|$bp_location9)\r\n.*Value returned.*$gdb_prompt $"\ + {pass "finish from called function"} + -re "$gdb_prompt $"\ + {fail "finish from called function"} + timeout {fail "(timeout) finish from called function"} +} + +# Verify that GDB responds gracefully to a "finish" command with +# arguments. +# +if ![runto_main] then { fail "break tests suppressed" } + +send_gdb "finish 123\n" +gdb_expect { + -re "The \"finish\" command does not take any arguments.\r\n$gdb_prompt $"\ + {pass "finish with arguments disallowed"} + -re "$gdb_prompt $"\ + {fail "finish with arguments disallowed"} + timeout {fail "(timeout) finish with arguments disallowed"} +} + +# Verify that GDB responds gracefully to a request to "finish" from +# the outermost frame. On a stub that never exits, this will just +# run to the stubs routine, so we don't get this error... Thus the +# second condition. +# + +send_gdb "finish\n" +gdb_expect { + -re "\"finish\" not meaningful in the outermost frame.\r\n$gdb_prompt $"\ + {pass "finish from outermost frame disallowed"} + -re "Run till exit from.*\r\n$gdb_prompt $" { + pass "finish from outermost frame disallowed" + } + -re "$gdb_prompt $"\ + {fail "finish from outermost frame disallowed"} + timeout {fail "(timeout) finish from outermost frame disallowed"} +} + +# Verify that we can explicitly ask GDB to stop on all shared library +# events, and that it does so. +# +if [istarget "hppa*-*-hpux*"] then { + if ![runto_main] then { fail "break tests suppressed" } + + send_gdb "set stop-on-solib-events 1\n" + gdb_expect { + -re "$gdb_prompt $"\ + {pass "set stop-on-solib-events"} + timeout {fail "(timeout) set stop-on-solib-events"} + } + + send_gdb "run\n" + gdb_expect { + -re ".*Start it from the beginning.*y or n. $"\ + {send_gdb "y\n" + gdb_expect { + -re ".*Stopped due to shared library event.*$gdb_prompt $"\ + {pass "triggered stop-on-solib-events"} + -re "$gdb_prompt $"\ + {fail "triggered stop-on-solib-events"} + timeout {fail "(timeout) triggered stop-on-solib-events"} + } + } + -re "$gdb_prompt $"\ + {fail "rerun for stop-on-solib-events"} + timeout {fail "(timeout) rerun for stop-on-solib-events"} + } + + send_gdb "set stop-on-solib-events 0\n" + gdb_expect { + -re "$gdb_prompt $"\ + {pass "reset stop-on-solib-events"} + timeout {fail "(timeout) reset stop-on-solib-events"} + } +} + +# Hardware breakpoints are unsupported on HP-UX. Verify that GDB +# gracefully responds to requests to create them. +# +if [istarget "hppa*-*-hpux*"] then { + if ![runto_main] then { fail "break tests suppressed" } + + send_gdb "hbreak\n" + gdb_expect { + -re "No hardware breakpoint support in the target.*$gdb_prompt $"\ + {pass "hw breaks disallowed"} + -re "$gdb_prompt $"\ + {fail "hw breaks disallowed"} + timeout {fail "(timeout) hw breaks disallowed"} + } + + send_gdb "thbreak\n" + gdb_expect { + -re "No hardware breakpoint support in the target.*$gdb_prompt $"\ + {pass "temporary hw breaks disallowed"} + -re "$gdb_prompt $"\ + {fail "temporary hw breaks disallowed"} + timeout {fail "(timeout) temporary hw breaks disallowed"} + } +} + +#******** + + +# +# Test "next" over recursive function call. +# + +proc test_next_with_recursion {} { + global gdb_prompt + global decimal + global binfile + + if [target_info exists use_gdb_stub] { + # Reload the program. + delete_breakpoints + gdb_load ${binfile}; + } else { + # FIXME: should be using runto + gdb_test "kill" "" "kill program" "Kill the program being debugged.*y or n. $" "y" + + delete_breakpoints + } + + gdb_test "break factorial" "Breakpoint $decimal at .*" "break at factorial" + + # Run until we call factorial with 6 + + if [istarget "*-*-vxworks*"] then { + send_gdb "run vxmain \"6\"\n" + } else { + gdb_run_cmd + } + gdb_expect { + -re "Break.* factorial .value=6. .*$gdb_prompt $" {} + -re ".*$gdb_prompt $" { + fail "run to factorial(6)"; + gdb_suppress_tests; + } + timeout { fail "run to factorial(6) (timeout)" ; gdb_suppress_tests } + } + + # Continue until we call factorial recursively with 5. + + if [gdb_test "continue" \ + "Continuing.*Break.* factorial .value=5. .*" \ + "continue to factorial(5)"] then { gdb_suppress_tests } + + # Do a backtrace just to confirm how many levels deep we are. + + if [gdb_test "backtrace" \ + "#0\[ \t\]+ factorial .value=5..*" \ + "backtrace from factorial(5)"] then { gdb_suppress_tests } + + # Now a "next" should position us at the recursive call, which + # we will be performing with 4. + + if [gdb_test "next" \ + ".* factorial .value - 1.;.*" \ + "next to recursive call"] then { gdb_suppress_tests } + + # Disable the breakpoint at the entry to factorial by deleting them all. + # The "next" should run until we return to the next line from this + # recursive call to factorial with 4. + # Buggy versions of gdb will stop instead at the innermost frame on + # the line where we are trying to "next" to. + + delete_breakpoints + + if [istarget "mips*tx39-*"] { + set timeout 60 + } + # We used to set timeout here for all other targets as well. This + # is almost certainly wrong. The proper timeout depends on the + # target system in use, and how we communicate with it, so there + # is no single value appropriate for all targets. The timeout + # should be established by the Dejagnu config file(s) for the + # board, and respected by the test suite. + # + # For example, if I'm running GDB over an SSH tunnel talking to a + # portmaster in California talking to an ancient 68k board running + # a crummy ROM monitor (a situation I can only wish were + # hypothetical), then I need a large timeout. But that's not the + # kind of knowledge that belongs in this file. + + gdb_test next "\[0-9\]*\[\t \]+return \\(value\\);.*" \ + "next over recursive call" + + # OK, we should be back in the same stack frame we started from. + # Do a backtrace just to confirm. + + set result [gdb_test "backtrace" \ + "#0\[ \t\]+ factorial .value=120.*\r\n#1\[ \t\]+ \[0-9a-fx\]+ in factorial .value=6..*" \ + "backtrace from factorial(5.1)"] + if { $result != 0 } { gdb_suppress_tests } + + if [target_info exists gdb,noresults] { gdb_suppress_tests } + gdb_continue_to_end "recursive next test" + gdb_stop_suppressing_tests; +} + +test_next_with_recursion + + +#******** + +# build a new file with optimization enabled so that we can try breakpoints +# on targets with optimized prologues + +set binfileo2 [standard_output_file ${testfile}o2] + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}O0.o" object {debug "additional_flags=-w -O2 -fpie -pie"}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile}O1.o" object {debug "additional_flags=-w -O2 -fpie -pie"}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +if { [gdb_compile "${binfile}O0.o ${binfile}O1.o" "${binfileo2}" executable {debug "additional_flags=-w -fpie -pie"}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +if [get_compiler_info ${binfileo2}] { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfileo2} + +if [target_info exists gdb_stub] { + gdb_step_for_stub; +} + +# +# test break at function +# +gdb_test "break main" \ + "Breakpoint.*at.* file .*$srcfile, line.*" \ + "breakpoint function, optimized file" + +# +# test break at function +# +gdb_test "break marker4" \ + "Breakpoint.*at.* file .*$srcfile1, line.*" \ + "breakpoint small function, optimized file" + +# +# run until the breakpoint at main is hit. For non-stubs-using targets. +# +if ![target_info exists use_gdb_stub] { + if [istarget "*-*-vxworks*"] then { + send_gdb "run vxmain \"2\"\n" + set timeout 120 + verbose "Timeout is now $timeout seconds" 2 + } else { + send_gdb "run\n" + } + gdb_expect { + -re "The program .* has been started already.*y or n. $" { + send_gdb "y\n" + exp_continue + } + -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.* \{.*$gdb_prompt $"\ + { pass "run until function breakpoint, optimized file" } + -re "Starting program.*Breakpoint \[0-9\]+,.*main .*argc.*argv.* at .*$gdb_prompt $"\ + { pass "run until function breakpoint, optimized file (code motion)" } + -re ".*$gdb_prompt $" { fail "run until function breakpoint, optimized file" } + timeout { fail "run until function breakpoint, optimized file (timeout)" } + } +} else { + if ![target_info exists gdb_stub] { + gdb_test continue ".*Continuing\\..*Breakpoint \[0-9\]+, main \\(argc=.*, argv=.*, envp=.*\\) at .*$srcfile:$bp_location6.*$bp_location6\[\t \]+if .argc.*\{.*" "stub continue, optimized file" + } +} + +# +# run until the breakpoint at a small function +# + +# +# Add a second pass pattern. The behavior differs here between stabs +# and dwarf for one-line functions. Stabs preserves two line symbols +# (one before the prologue and one after) with the same line number, +# but dwarf regards these as duplicates and discards one of them. +# Therefore the address after the prologue (where the breakpoint is) +# has no exactly matching line symbol, and GDB reports the breakpoint +# as if it were in the middle of a line rather than at the beginning. + +set bp_location13 [gdb_get_line_number "set breakpoint 13 here" $srcfile1] +set bp_location14 [gdb_get_line_number "set breakpoint 14 here" $srcfile1] +send_gdb "continue\n" +gdb_expect { + -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile1:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" { + pass "run until breakpoint set at small function, optimized file" + } + -re "Breakpoint $decimal, $hex in marker4 \\(d=177601976\\) at .*$srcfile1:$bp_location13\[\r\n\]+$bp_location13\[\t \]+void marker4.*" { + pass "run until breakpoint set at small function, optimized file" + } + -re "Breakpoint $decimal, marker4 \\(d=177601976\\) at .*$srcfile1:$bp_location14\[\r\n\]+$bp_location14\[\t \]+void marker4.*" { + # marker4() is defined at line 46 when compiled with -DPROTOTYPES + pass "run until breakpoint set at small function, optimized file (line bp_location14)" + } + -re ".*$gdb_prompt " { + fail "run until breakpoint set at small function, optimized file" + } + timeout { + fail "run until breakpoint set at small function, optimized file (timeout)" + } +} + + +# Reset the default arguments for VxWorks +if [istarget "*-*-vxworks*"] { + set timeout 10 + verbose "Timeout is now $timeout seconds" 2 + send_gdb "set args main\n" + gdb_expect -re ".*$gdb_prompt $" {} +} diff --git a/gdb/testsuite/gdb.pie/break1.c b/gdb/testsuite/gdb.pie/break1.c new file mode 100644 index 00000000000..2ed8b2a4a02 --- /dev/null +++ b/gdb/testsuite/gdb.pie/break1.c @@ -0,0 +1,44 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 1992, 1993, 1994, 1995, 1999, 2002, 2003 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +/* The code for this file was extracted from the gdb testsuite + testcase "break.c". */ + +/* The following functions do nothing useful. They are included + simply as places to try setting breakpoints at. They are + explicitly "one-line functions" to verify that this case works + (some versions of gcc have or have had problems with this). + + These functions are in a separate source file to prevent an + optimizing compiler from inlining them and optimizing them away. */ + +#ifdef PROTOTYPES +int marker1 (void) { return (0); } /* set breakpoint 15 here */ +int marker2 (int a) { return (1); } /* set breakpoint 8 here */ +void marker3 (char *a, char *b) {} /* set breakpoint 17 here */ +void marker4 (long d) {} /* set breakpoint 14 here */ +#else +int marker1 () { return (0); } /* set breakpoint 16 here */ +int marker2 (a) int a; { return (1); } /* set breakpoint 9 here */ +void marker3 (a, b) char *a, *b; {} /* set breakpoint 18 here */ +void marker4 (d) long d; {} /* set breakpoint 13 here */ +#endif diff --git a/gdb/testsuite/gdb.pie/corefile.exp b/gdb/testsuite/gdb.pie/corefile.exp new file mode 100644 index 00000000000..ca4b01be3eb --- /dev/null +++ b/gdb/testsuite/gdb.pie/corefile.exp @@ -0,0 +1,233 @@ +# Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# This file was written by Fred Fish. (fnf@cygnus.com) + +# are we on a target board +if ![isnative] then { + return +} + +set testfile "coremaker" +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug "additional_flags=-fpie -pie"}] != "" } { + gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail." +} + +# Create and source the file that provides information about the compiler +# used to compile the test case. +if [get_compiler_info ${binfile}] { + return -1; +} + +# Create a core file named "corefile" rather than just "core", to +# avoid problems with sys admin types that like to regularly prune all +# files named "core" from the system. +# +# Arbitrarily try setting the core size limit to "unlimited" since +# this does not hurt on systems where the command does not work and +# allows us to generate a core on systems where it does. +# +# Some systems append "core" to the name of the program; others append +# the name of the program to "core"; still others (like Linux, as of +# May 2003) create cores named "core.PID". In the latter case, we +# could have many core files lying around, and it may be difficult to +# tell which one is ours, so let's run the program in a subdirectory. +set found 0 +set coredir [standard_output_file coredir.[getpid]] +file mkdir $coredir +catch "system \"(cd ${coredir}; ulimit -c unlimited; ${binfile}; true) >/dev/null 2>&1\"" +# remote_exec host "${binfile}" +foreach i "${coredir}/core ${coredir}/core.coremaker.c ${binfile}.core" { + if [remote_file build exists $i] { + remote_exec build "mv $i [standard_output_file corefile]" + set found 1 + } +} +# Check for "core.PID". +if { $found == 0 } { + set names [glob -nocomplain -directory $coredir core.*] + if {[llength $names] == 1} { + set corefile [file join $coredir [lindex $names 0]] + remote_exec build "mv $corefile [standard_output_file corefile]" + set found 1 + } +} +if { $found == 0 } { + # The braindamaged HPUX shell quits after the ulimit -c above + # without executing ${binfile}. So we try again without the + # ulimit here if we didn't find a core file above. + # Oh, I should mention that any "braindamaged" non-Unix system has + # the same problem. I like the cd bit too, it's really neat'n stuff. + catch "system \"(cd [file dirname [standard_output_file ${binfile}]]; ${binfile}; true) >/dev/null 2>&1\"" + foreach i "[standard_output_file core] [standard_output_file core.coremaker.c] ${binfile}.core" { + if [remote_file build exists $i] { + remote_exec build "mv $i [standard_output_file corefile]" + set found 1 + } + } +} + +# Try to clean up after ourselves. +remote_file build delete [file join $coredir coremmap.data] +remote_exec build "rmdir $coredir" + +if { $found == 0 } { + warning "can't generate a core file - core tests suppressed - check ulimit -c" + return 0 +} + +# +# Test that we can simply startup with a "-core=corefile" command line arg +# and recognize that the core file is a valid, usable core file. +# To do this, we must shutdown the currently running gdb and restart +# with the -core args. We can't use gdb_start because it looks for +# the first gdb prompt, and the message we are looking for occurs +# before the first prompt. Also, we can't include GDBFLAGS because +# if it is empty, this confuses gdb with an empty argument that it +# grumbles about (said grumbling currently being ignored in gdb_start). +# **FIXME** +# +# Another problem is that on some systems (solaris for example), there +# is apparently a limit on the length of a fully specified path to +# the coremaker executable, at about 80 chars. For this case, consider +# it a pass, but note that the program name is bad. + +gdb_exit +if $verbose>1 then { + send_user "Spawning $GDB -nw $GDBFLAGS -core=[standard_output_file corefile]\n" +} + +set oldtimeout $timeout +set timeout [expr "$timeout + 60"] +verbose "Timeout is now $timeout seconds" 2 +eval "spawn $GDB -nw $GDBFLAGS -core=[standard_output_file corefile]" +expect { + -re "Couldn't find .* registers in core file.*$gdb_prompt $" { + fail "args: -core=corefile (couldn't find regs)" + } + -re "Core was generated by .*coremaker.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { + pass "args: -core=corefile" + } + -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { + pass "args: -core=corefile (with bad program name)" + } + -re ".*registers from core file: File in wrong format.* $" { + fail "args: -core=corefile (could not read registers from core file)" + } + -re ".*$gdb_prompt $" { fail "args: -core=corefile" } + timeout { fail "(timeout) starting with -core" } +} + + +# +# Test that startup with both an executable file and -core argument. +# See previous comments above, they are still applicable. +# + +close; + +if $verbose>1 then { + send_user "Spawning $GDB -nw $GDBFLAGS $binfile -core=[standard_output_file corefile]\n" +} + + +eval "spawn $GDB -nw $GDBFLAGS $binfile -core=[standard_output_file corefile]"; +expect { + -re "Core was generated by .*coremaker.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { + pass "args: execfile -core=corefile" + } + -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { + pass "args: execfile -core=corefile (with bad program name)" + } + -re ".*registers from core file: File in wrong format.* $" { + fail "args: execfile -core=corefile (could not read registers from core file)" + } + -re ".*$gdb_prompt $" { fail "args: execfile -core=corefile" } + timeout { fail "(timeout) starting with -core" } +} +set timeout $oldtimeout +verbose "Timeout is now $timeout seconds" 2 + +close; + +# Now restart normally. + +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# Test basic corefile recognition via core-file command. + +send_gdb "core-file [standard_output_file corefile]\n" +gdb_expect { + -re ".* program is being debugged already.*y or n. $" { + # gdb_load may connect us to a gdbserver. + send_gdb "y\n" + exp_continue; + } + -re "Core was generated by .*coremaker.*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { + pass "core-file command" + } + -re "Core was generated by .*\r\n\#0 .*\(\).*\r\n$gdb_prompt $" { + pass "core-file command (with bad program name)" + } + -re ".*registers from core file: File in wrong format.* $" { + fail "core-file command (could not read registers from core file)" + } + -re ".*$gdb_prompt $" { fail "core-file command" } + timeout { fail "(timeout) core-file command" } +} + +# Test correct mapping of corefile sections by printing some variables. + +gdb_test "print coremaker_data" "\\\$$decimal = 202" +gdb_test "print coremaker_bss" "\\\$$decimal = 10" +gdb_test "print coremaker_ro" "\\\$$decimal = 201" + +gdb_test "print func2::coremaker_local" "\\\$$decimal = \\{0, 1, 2, 3, 4\\}" + +# Somehow we better test the ability to read the registers out of the core +# file correctly. I don't think the other tests do this. + +gdb_test "bt" "abort.*func2.*func1.*main.*" "backtrace in corefile.exp" +gdb_test "up" "#\[0-9\]* *\[0-9xa-fH'\]* in .* \\(.*\\).*" "up in corefile.exp" + +# Test ability to read mmap'd data + +gdb_test "x/8bd buf1" ".*:.*0.*1.*2.*3.*4.*5.*6.*7" "accessing original mmap data in core file" +setup_xfail "*-*-sunos*" "*-*-ultrix*" "*-*-aix*" +set test "accessing mmapped data in core file" +gdb_test_multiple "x/8bd buf2" "$test" { + -re ".*:.*0.*1.*2.*3.*4.*5.*6.*7.*$gdb_prompt $" { + pass "$test" + } + -re "0x\[f\]*:.*Cannot access memory at address 0x\[f\]*.*$gdb_prompt $" { + fail "$test (mapping failed at runtime)" + } + -re "0x.*:.*Cannot access memory at address 0x.*$gdb_prompt $" { + fail "$test (mapping address not found in core file)" + } +} + +# test reinit_frame_cache + +gdb_load ${binfile} +gdb_test "up" "#\[0-9\]* *\[0-9xa-fH'\]* in .* \\(.*\\).*" "up in corefile.exp (reinit)" + +gdb_test "core" "No core file now." diff --git a/gdb/testsuite/gdb.pie/coremaker.c b/gdb/testsuite/gdb.pie/coremaker.c new file mode 100644 index 00000000000..a7fbd94141a --- /dev/null +++ b/gdb/testsuite/gdb.pie/coremaker.c @@ -0,0 +1,142 @@ +/* Copyright 1992, 1993, 1994, 1995, 1996, 1999 + 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Simple little program that just generates a core dump from inside some + nested function calls. */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef __STDC__ +#define const /**/ +#endif + +#define MAPSIZE (8 * 1024) + +/* Don't make these automatic vars or we will have to walk back up the + stack to access them. */ + +char *buf1; +char *buf2; + +int coremaker_data = 1; /* In Data section */ +int coremaker_bss; /* In BSS section */ + +const int coremaker_ro = 201; /* In Read-Only Data section */ + +/* Note that if the mapping fails for any reason, we set buf2 + to -1 and the testsuite notices this and reports it as + a failure due to a mapping error. This way we don't have + to test for specific errors when running the core maker. */ + +void +mmapdata () +{ + int j, fd; + + /* Allocate and initialize a buffer that will be used to write + the file that is later mapped in. */ + + buf1 = (char *) malloc (MAPSIZE); + for (j = 0; j < MAPSIZE; ++j) + { + buf1[j] = j; + } + + /* Write the file to map in */ + + fd = open ("coremmap.data", O_CREAT | O_RDWR, 0666); + if (fd == -1) + { + perror ("coremmap.data open failed"); + buf2 = (char *) -1; + return; + } + write (fd, buf1, MAPSIZE); + + /* Now map the file into our address space as buf2 */ + + buf2 = (char *) mmap (0, MAPSIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (buf2 == (char *) -1) + { + perror ("mmap failed"); + return; + } + + /* Verify that the original data and the mapped data are identical. + If not, we'd rather fail now than when trying to access the mapped + data from the core file. */ + + for (j = 0; j < MAPSIZE; ++j) + { + if (buf1[j] != buf2[j]) + { + fprintf (stderr, "mapped data is incorrect"); + buf2 = (char *) -1; + return; + } + } +} + +void +func2 () +{ + int coremaker_local[5]; + int i; + +#ifdef SA_FULLDUMP + /* Force a corefile that includes the data section for AIX. */ + { + struct sigaction sa; + + sigaction (SIGABRT, (struct sigaction *)0, &sa); + sa.sa_flags |= SA_FULLDUMP; + sigaction (SIGABRT, &sa, (struct sigaction *)0); + } +#endif + + /* Make sure that coremaker_local doesn't get optimized away. */ + for (i = 0; i < 5; i++) + coremaker_local[i] = i; + coremaker_bss = 0; + for (i = 0; i < 5; i++) + coremaker_bss += coremaker_local[i]; + coremaker_data = coremaker_ro + 1; + abort (); +} + +void +func1 () +{ + func2 (); +} + +int main () +{ + mmapdata (); + func1 (); + return 0; +} + diff --git a/gdb/testsuite/gdb.python/Makefile.in b/gdb/testsuite/gdb.python/Makefile.in new file mode 100644 index 00000000000..46280d7989e --- /dev/null +++ b/gdb/testsuite/gdb.python/Makefile.in @@ -0,0 +1,22 @@ +VPATH = @srcdir@ +srcdir = @srcdir@ + +EXECUTABLES = py-type py-value py-prettyprint py-template py-block \ + py-symbol py-mi py-breakpoint py-inferior py-infthread \ + py-shared python lib-types py-events py-evthreads py-frame \ + py-mi py-pp-maint py-progspace py-section-script py-objfile \ + py-finish-breakpoint py-finish-breakpoint2 py-value-cc py-explore \ + py-explore-cc py-arch py-minsymbol + +MISCELLANEOUS = py-shared-sl.sl py-events-shlib.so py-events-shlib-nodebug.so + +all info install-info dvi install uninstall installcheck check: + @echo "Nothing to be done for $@..." + +clean mostlyclean: + -rm -f *~ *.o *.ci + -rm -f *.dwo *.dwp + -rm -f core $(EXECUTABLES) $(MISCELLANEOUS) + +distclean maintainer-clean realclean: clean + -rm -f Makefile config.status config.log gdb.log gdb.sum diff --git a/gdb/testsuite/gdb.python/py-frame.exp b/gdb/testsuite/gdb.python/py-frame.exp index 5b675ec3e5a..c0d5c305e8d 100644 --- a/gdb/testsuite/gdb.python/py-frame.exp +++ b/gdb/testsuite/gdb.python/py-frame.exp @@ -95,6 +95,8 @@ gdb_test "python print ('result = %s' % f0.read_var ('a'))" " = 1" "test Frame.r gdb_test "python print ('result = %s' % (gdb.selected_frame () == f1))" " = True" "test gdb.selected_frame" +gdb_test "python print ('result = %s' % (f0.block ()))" "" "test Frame.block" + # Can read SP register. gdb_test "python print ('result = %s' % (gdb.selected_frame ().read_register ('sp') == gdb.parse_and_eval ('\$sp')))" \ " = True" \ diff --git a/gdb/testsuite/gdb.python/py-framefilter-thread.c b/gdb/testsuite/gdb.python/py-framefilter-thread.c new file mode 100644 index 00000000000..6cebabb67a4 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-framefilter-thread.c @@ -0,0 +1,39 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2016 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 . */ + +#include +#include + +static void * +start (void *arg) +{ + return arg; /* Backtrace end breakpoint */ +} + +int +main (void) +{ + pthread_t thread1; + int i; + + i = pthread_create (&thread1, NULL, start, NULL); + assert (i == 0); + i = pthread_join (thread1, NULL); + assert (i == 0); + + return 0; +} diff --git a/gdb/testsuite/gdb.python/py-framefilter-thread.exp b/gdb/testsuite/gdb.python/py-framefilter-thread.exp new file mode 100644 index 00000000000..71f97463372 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-framefilter-thread.exp @@ -0,0 +1,54 @@ +# Copyright (C) 2016 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 . + +load_lib gdb-python.exp + +standard_testfile + +if {[prepare_for_testing $testfile.exp $testfile $srcfile {debug pthreads}]} { + return -1 +} + +# Skip all tests if Python scripting is not enabled. +if { [skip_python_tests] } { continue } + +if ![runto_main] then { + return +} +gdb_test_no_output "set python print-stack full" \ + "Set python print-stack to full" + +# Load global frame-filters +set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py] +gdb_test_no_output "python exec (open ('${remote_python_file}').read ())" \ + "Load python file" + +gdb_breakpoint [gdb_get_line_number "Backtrace end breakpoint"] +gdb_continue_to_breakpoint "Backtrace end breakpoint" + +# #2 0x00007ffff75f228d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113^M +gdb_test "bt no-filters" " in (\\.?_*clone|thread_start) \[^\r\n\]*" "bt no-filters" + +# #2 0x00007ffff75f228d in 941595343737041 () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:113^M +# vs. +# #2 0x00007ffff75f228d in 941595343737041Traceback (most recent call last): +# File "/home/jkratoch/redhat/rhel/gdb/rhel-7.3/gdb-7.6.1/gdb/testsuite/../data-directory/python/gdb/FrameDecorator.py", line 145, in frame_args +# return self._base.frame_args() +# File "/home/jkratoch/redhat/rhel/gdb/rhel-7.3/gdb-7.6.1/gdb/testsuite/../data-directory/python/gdb/FrameDecorator.py", line 152, in frame_args +# return args.fetch_frame_args() +# File "/home/jkratoch/redhat/rhel/gdb/rhel-7.3/gdb-7.6.1/gdb/testsuite/../data-directory/python/gdb/FrameDecorator.py", line 276, in fetch_frame_args +# block = self.frame.block() +# RuntimeError: Cannot locate object file for block. +gdb_test "bt" " in \[0-9\]+ \[^\r\n\]*" "bt with filters" diff --git a/gdb/testsuite/gdb.python/py-framefilter-thread.py b/gdb/testsuite/gdb.python/py-framefilter-thread.py new file mode 100644 index 00000000000..8964799408a --- /dev/null +++ b/gdb/testsuite/gdb.python/py-framefilter-thread.py @@ -0,0 +1,60 @@ +# Copyright (C) 2016 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 . + +# This file is part of the GDB testsuite. It tests Python-based +# frame-filters. + +# This test is specifically crafted for RH BZ 1197665. + +import gdb +import itertools +from gdb.FrameDecorator import FrameDecorator +import copy + +class Reverse_Function (FrameDecorator): + + def __init__(self, fobj): + super(Reverse_Function, self).__init__(fobj) + self.fobj = fobj + + def function (self): + # This function call should not fail. + gdb.target_charset () + + fname = str (self.fobj.function()) + if (fname == None or fname == ""): + return None + else: + fname = fname[::-1] + return fname + +class FrameFilter (): + + def __init__ (self): + self.name = "Reverse" + self.priority = 100 + self.enabled = True + gdb.frame_filters [self.name] = self + + def filter (self, frame_iter): + # Python 3.x moved the itertools.imap functionality to map(), + # so check if it is available. + if hasattr(itertools, "imap"): + frame_iter = itertools.imap (Reverse_Function, frame_iter) + else: + frame_iter = map (Reverse_Function, frame_iter) + return frame_iter + +FrameFilter() diff --git a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.c b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.c new file mode 100644 index 00000000000..f2697efa9aa --- /dev/null +++ b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.c @@ -0,0 +1,27 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2014 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 . */ + +static struct x + { + char unsigned u[4096]; + } x, *px = &x; + +int +main (int argc, char *argv[]) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp new file mode 100644 index 00000000000..2e6786d499a --- /dev/null +++ b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.exp @@ -0,0 +1,68 @@ +# Copyright 2014 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 . + +set testfile py-gdb-rhbz1007614-memleak-infpy_read_memory +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] + +if { [prepare_for_testing ${testfile}.exp ${testfile} ${srcfile}] } { + return -1 +} + +if { [skip_python_tests] } { continue } + +set pid_of_gdb [exp_pid -i [board_info host fileid]] + +proc memory_v_pages_get {} { + global pid_of_gdb + set fd [open "/proc/$pid_of_gdb/statm"] + gets $fd line + close $fd + # number of pages of virtual memory + scan $line "%d" drs + return $drs +} + +if { ![runto_main] } { + untested $testfile.exp + return -1 +} + +set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py] + +gdb_test "source ${remote_python_file}" "" + +gdb_test "hello-world" "" + +set kbytes_before [memory_v_pages_get] +verbose -log "kbytes_before = $kbytes_before" + +gdb_test "hello-world" "" + +set kbytes_after [memory_v_pages_get] +verbose -log "kbytes_after = $kbytes_after" + +set kbytes_diff [expr $kbytes_after - $kbytes_before] +verbose -log "kbytes_diff = $kbytes_diff" + +# The value "1000" was calculated by running a few GDB sessions with this +# testcase, and seeing how much (in average) the memory consumption +# increased after the "hello-world" command issued above. The average +# was around 500 bytes, so I chose 1000 as a high estimate. +if { $kbytes_diff > 1000 } { + fail "there is a memory leak on GDB (RHBZ 1007614)" +} else { + pass "there is not a memory leak on GDB (RHBZ 1007614)" +} diff --git a/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.py b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.py new file mode 100644 index 00000000000..e8077280479 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-gdb-rhbz1007614-memleak-infpy_read_memory.py @@ -0,0 +1,30 @@ +# Copyright (C) 2014 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 . + +class HelloWorld (gdb.Command): + """Greet the whole world.""" + + def __init__ (self): + super (HelloWorld, self).__init__ ("hello-world", + gdb.COMMAND_OBSCURE) + + def invoke (self, arg, from_tty): + px = gdb.parse_and_eval("px") + core = gdb.inferiors()[0] + for i in range(256 * 1024): + chunk = core.read_memory(px, 4096) + print "Hello, World!" + +HelloWorld () diff --git a/gdb/testsuite/gdb.python/py-gil-mthread.c b/gdb/testsuite/gdb.python/py-gil-mthread.c new file mode 100644 index 00000000000..1a12fc9c6dc --- /dev/null +++ b/gdb/testsuite/gdb.python/py-gil-mthread.c @@ -0,0 +1,13 @@ +#include +#include + +int +main (void) +{ + int i; + for (i = 0; i < 10; i++) + { + sleep (1); /* break-here */ + printf ("Sleeping %d\n", i); + } +} diff --git a/gdb/testsuite/gdb.python/py-gil-mthread.exp b/gdb/testsuite/gdb.python/py-gil-mthread.exp new file mode 100644 index 00000000000..a89c16a45b4 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-gil-mthread.exp @@ -0,0 +1,69 @@ +# Copyright (C) 2014 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 . + +standard_testfile .c .py +set executable $testfile + +if { [prepare_for_testing $testfile.exp $executable $srcfile] } { + return -1 +} + +# Skip all tests if Python scripting is not enabled. +if { [skip_python_tests] } { continue } + +if ![runto_main] { + return -1 +} + +gdb_breakpoint $srcfile:[gdb_get_line_number "break-here"] temporary +gdb_continue_to_breakpoint "break-here" ".* break-here .*" + +set test "response" +set timeout 60 +set sleeping_last -1 +set hello_last 0 +set minimal 5 +gdb_test_multiple "python exec (open ('$srcdir/$subdir/$srcfile2').read ())" $test { + -re "Error: unable to start thread\r\n" { + fail $test + # Not $gdb_prompt-synced! + } + -re "Sleeping (\[0-9\]+)\r\n" { + set n $expect_out(1,string) + if { $sleeping_last + 1 != $n } { + fail $test + } else { + set sleeping_last $n + if { $sleeping_last >= $minimal && $hello_last >= $minimal } { + pass $test + } else { + exp_continue + } + } + } + -re "Hello \\( (\[0-9\]+) \\)\r\n" { + set n $expect_out(1,string) + if { $hello_last + 1 != $n } { + fail $test + } else { + set hello_last $n + if { $sleeping_last >= $minimal && $hello_last >= $minimal } { + pass $test + } else { + exp_continue + } + } + } +} diff --git a/gdb/testsuite/gdb.python/py-gil-mthread.py b/gdb/testsuite/gdb.python/py-gil-mthread.py new file mode 100644 index 00000000000..6a89964139d --- /dev/null +++ b/gdb/testsuite/gdb.python/py-gil-mthread.py @@ -0,0 +1,28 @@ +try: + import thread +except: + import _thread +import time +import gdb + +# Define a function for the thread +def print_thread_hello(): + count = 0 + while count < 10: + time.sleep(1) + count += 1 + print ("Hello ( %d )" % count) + +# Create a threads a continue +try: + thread.start_new_thread (print_thread_hello, ()) + gdb.execute ("continue", release_gil=True) +except: + try: + _thread.start_new_thread (print_thread_hello, ()) + gdb.execute ("continue", release_gil=True) + except: + print ("Error: unable to start thread") + +while 1: + pass diff --git a/gdb/testsuite/gdb.python/py-minsymbol.exp b/gdb/testsuite/gdb.python/py-minsymbol.exp new file mode 100644 index 00000000000..877e17fc130 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-minsymbol.exp @@ -0,0 +1,59 @@ +# Copyright (C) 2010-2015 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# This file is part of the GDB testsuite. It tests the mechanism +# exposing values to Python. + +load_lib gdb-python.exp + +standard_testfile + +if {[prepare_for_testing $testfile.exp $testfile $srcfile debug]} { + return -1 +} + +# Skip all tests if Python scripting is not enabled. +if { [skip_python_tests] } { continue } + +# Test looking up missing value +gdb_test "python print gdb.lookup_minimal_symbol('xyz')" "None" "lookup missing symbol" + +# Test looking up a minimal symbol of text type +gdb_test "print text_msym" " = \{\} 0x\[0-9a-f\]* " "locate text_msym with print" +gdb_py_test_silent_cmd "python x = gdb.lookup_minimal_symbol('text_msym')" "Lookup text_msym" 1 +gdb_test "python print x" "text_msym" "lookup text min sym" +gdb_test "python print x.name" "text_msym" "get text minsym name" +gdb_test "python print x.linkage_name" "text_msym" "get text minsym linkage_name" +# Using asm() ends up inventing a compiler-dependent filename +gdb_test "python print x.filename" ".*" "get text minsym filename" +gdb_test "python print x.print_name" "text_msym" "get text minsym print_name" +gdb_test "python print x.section" ".text" "get text minsym section" +gdb_test "python print x.value()" "0x\[0-9a-f\]*.*" "get text minsym value" +gdb_test "python print x.value().type" "void \\(\\*\\)\\(\\)" "get text minsym value type" + +# Test looking up a minimal symbol of data type +gdb_test "print data_msym" " = \[0-9\]*" "locate data_msym with print" +gdb_py_test_silent_cmd "python x = gdb.lookup_minimal_symbol('data_msym')" "Lookup data_msym" 1 +gdb_test "python print x.name" "data_msym" "get data minsym name" +gdb_test "python print x.linkage_name" "data_msym" "get data minsym linkage_name" +# Using asm() ends up inventing a compiler-dependent filename +gdb_test "python print x.filename" ".*" "get data minsym filename" +gdb_test "python print x.print_name" "data_msym" "get data minsym print_name" +gdb_test "python print x.section" ".data" "get data minsym section" +gdb_test "python print x.value()" "0x\[0-9a-f\]*.*" "get data minsym value" + +gdb_unload +gdb_test "python print (x.is_valid())" "False" "Test symbol non-validity" +gdb_test_no_output "python a = None" "Test symbol destructor" diff --git a/gdb/testsuite/gdb.python/py-register.c b/gdb/testsuite/gdb.python/py-register.c new file mode 100644 index 00000000000..413b1827c48 --- /dev/null +++ b/gdb/testsuite/gdb.python/py-register.c @@ -0,0 +1,19 @@ +/* So we have a data section */ +const char foo[] = "somestring"; + +asm("\ +.section .text\n\ +.global text_msym\n\ +text_msym:\n\ + .byte 0\n\ +.section .data\n\ +.globl data_msym\n\ +data_msym:\n\ + .asciz \"minsym text\"\n\ +"); + +int +main(void) +{ + return 0; +} diff --git a/gdb/testsuite/gdb.python/py-register.exp b/gdb/testsuite/gdb.python/py-register.exp new file mode 100644 index 00000000000..b18de66ee5c --- /dev/null +++ b/gdb/testsuite/gdb.python/py-register.exp @@ -0,0 +1,59 @@ +# Copyright (C) 2010-2015 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# This file is part of the GDB testsuite. It tests the mechanism +# exposing values to Python. + +load_lib gdb-python.exp + +#set verbose 10 + +standard_testfile + +if {[prepare_for_testing $testfile.exp $testfile $srcfile debug]} { + return -1 +} + +# Skip all tests if Python scripting is not enabled. +if { [skip_python_tests] } { continue } + +if ![runto_main] then { + fail "Can't run to main" + return 0 +} + +#gdb_py_test_silent_cmd +gdb_py_test_silent_cmd "python regs = gdb.selected_thread().registers" "Keep a set of registers" 1 + +# Hopefully an architecture-independent way of finding a GPR to test; Reg #0 +gdb_py_test_silent_cmd "python gpr0 = sorted(regs.values(), key=lambda x: x.regnum)\[0\]" "saving the name of GPR#0" 1 +gdb_test "python print gpr0" " s; basic_string bs; +class Other +{ +}; + +Other ovar; + int main() { return 0; diff --git a/gdb/testsuite/gdb.python/py-typeprint.exp b/gdb/testsuite/gdb.python/py-typeprint.exp index 8fc788d37d2..0f2225263c9 100644 --- a/gdb/testsuite/gdb.python/py-typeprint.exp +++ b/gdb/testsuite/gdb.python/py-typeprint.exp @@ -50,3 +50,7 @@ gdb_test_no_output "enable type-printer string" gdb_test "whatis bs" "string" "whatis with enabled printer" gdb_test "whatis s" "templ" + +gdb_test "info type-printers" "Type printers for \[^\r\n\]*/py-typeprint:\r\n *other\r\n.*" \ + "info type-printers for other" +gdb_test "whatis ovar" "type = Another" diff --git a/gdb/testsuite/gdb.python/py-typeprint.py b/gdb/testsuite/gdb.python/py-typeprint.py index 516410d5855..dde452c4f5b 100644 --- a/gdb/testsuite/gdb.python/py-typeprint.py +++ b/gdb/testsuite/gdb.python/py-typeprint.py @@ -15,7 +15,7 @@ import gdb -class Recognizer(object): +class StringRecognizer(object): def __init__(self): self.enabled = True @@ -30,6 +30,26 @@ def __init__(self): self.enabled = True def instantiate(self): - return Recognizer() + return StringRecognizer() gdb.type_printers.append(StringTypePrinter()) + +class OtherRecognizer(object): + def __init__(self): + self.enabled = True + + def recognize(self, type_obj): + if type_obj.tag == 'Other': + return 'Another' + return None + +class OtherTypePrinter(object): + def __init__(self): + self.name = 'other' + self.enabled = True + + def instantiate(self): + return OtherRecognizer() + +import gdb.types +gdb.types.register_type_printer(gdb.objfiles()[0], OtherTypePrinter()) diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp index b3d90b52272..0988b8be511 100644 --- a/gdb/testsuite/gdb.python/py-value.exp +++ b/gdb/testsuite/gdb.python/py-value.exp @@ -122,6 +122,29 @@ proc test_value_numeric_ops {} { gdb_test_no_output "python evalue = gdb.history (0)" gdb_test "python print (int (evalue))" "2" + # Implicit and explicit conversions to long + gdb_test "print (unsigned long long) -1" ".*" "" + gdb_test_no_output "python x = gdb.history (0)" "" + gdb_test "python print x" "18446744073709551615" "print unsigned long long value" + gdb_test "python print long(x)" "18446744073709551615" "print unsigned long long value as Python long" + + gdb_test "print (long long) -1" ".*" "" + gdb_test_no_output "python x = gdb.history (0)" "" + gdb_test "python print x" "-1" "print long long value" + gdb_test "python print long(x)" "-1" "print long long value as Python long" + + set pointer_size [get_sizeof "char *" 99] + + gdb_test "print (void *) -1" ".*" "" + gdb_test_no_output "python c = gdb.history (0)" "" + if {$pointer_size == 8} { + gdb_test "python print c" "0xffffffffffffffff" "print pointer" + gdb_test "python print long(c)" "18446744073709551615" "print pointer as Python long" + } elseif {$pointer_size == 4} { + gdb_test "python print c" "0xffffffff" "print pointer" + gdb_test "python print long(c)" "4294967295" "print pointer as Python long" + } + # Test pointer arithmethic # First, obtain the pointers @@ -399,6 +422,15 @@ proc test_value_after_death {} { "print value's type" } +# Regression test for a cast failure. The bug was that if we cast a +# value to its own type, gdb could crash. This happened because we +# could end up double-freeing a struct value. +proc test_cast_regression {} { + gdb_test "python v = gdb.Value(5)" "" "create value for cast test" + gdb_test "python v = v.cast(v.type)" "" "cast value for cast test" + gdb_test "python print(v)" "5" "print value for cast test" +} + # Regression test for invalid subscript operations. The bug was that # the type of the value was not being checked before allowing a # subscript operation to proceed. @@ -585,6 +617,7 @@ test_value_in_inferior test_value_from_buffer test_inferior_function_call test_value_after_death +test_cast_regression # Test either C or C++ values. diff --git a/gdb/testsuite/gdb.python/rh634108-solib_address.exp b/gdb/testsuite/gdb.python/rh634108-solib_address.exp new file mode 100644 index 00000000000..c0451cf09ed --- /dev/null +++ b/gdb/testsuite/gdb.python/rh634108-solib_address.exp @@ -0,0 +1,24 @@ +# Copyright (C) 2008, 2009, 2010 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 . + +# https://bugzilla.redhat.com/show_bug.cgi?id=634108 + +gdb_exit +gdb_start + +# Skip all tests if Python scripting is not enabled. +if { [skip_python_tests] } { continue } + +gdb_test "python print gdb.solib_name(-1)" "None" "gdb.solib_name exists" diff --git a/gdb/testsuite/gdb.threads/atomic-seq-threaded.c b/gdb/testsuite/gdb.threads/atomic-seq-threaded.c new file mode 100644 index 00000000000..04f998bfa6d --- /dev/null +++ b/gdb/testsuite/gdb.threads/atomic-seq-threaded.c @@ -0,0 +1,171 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + +/* Test stepping over RISC atomic sequences. + This variant testcases the code for stepping another thread while skipping + over the atomic sequence in the former thread + (STEPPING_PAST_SINGLESTEP_BREAKPOINT). + Code comes from gcc/testsuite/gcc.dg/sync-2.c */ + +/* { dg-options "-march=i486" { target { { i?86-*-* x86_64-*-* } && ilp32 } } } */ +/* { dg-options "-mcpu=v9" { target sparc*-*-* } } */ + +/* Test functionality of the intrinsics for 'short' and 'char'. */ + +#include +#include +#include +#include +#include + +#define LOOPS 2 + +static int unused; + +static char AI[18]; +static char init_qi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 }; +static char test_qi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 }; + +static void +do_qi (void) +{ + if (__sync_fetch_and_add(AI+4, 1) != 0) + abort (); + if (__sync_fetch_and_add(AI+5, 4) != 0) + abort (); + if (__sync_fetch_and_add(AI+6, 22) != 0) + abort (); + if (__sync_fetch_and_sub(AI+7, 12) != 0) + abort (); + if (__sync_fetch_and_and(AI+8, 7) != (char)-1) + abort (); + if (__sync_fetch_and_or(AI+9, 8) != 0) + abort (); + if (__sync_fetch_and_xor(AI+10, 9) != 0) + abort (); + if (__sync_fetch_and_nand(AI+11, 7) != 0) + abort (); + + if (__sync_add_and_fetch(AI+12, 1) != 1) + abort (); + if (__sync_sub_and_fetch(AI+13, 12) != (char)-12) + abort (); + if (__sync_and_and_fetch(AI+14, 7) != 7) + abort (); + if (__sync_or_and_fetch(AI+15, 8) != 8) + abort (); + if (__sync_xor_and_fetch(AI+16, 9) != 9) + abort (); + if (__sync_nand_and_fetch(AI+17, 7) != 7) + abort (); +} + +static short AL[18]; +static short init_hi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 }; +static short test_hi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 }; + +static void +do_hi (void) +{ + if (__sync_fetch_and_add(AL+4, 1) != 0) + abort (); + if (__sync_fetch_and_add(AL+5, 4) != 0) + abort (); + if (__sync_fetch_and_add(AL+6, 22) != 0) + abort (); + if (__sync_fetch_and_sub(AL+7, 12) != 0) + abort (); + if (__sync_fetch_and_and(AL+8, 7) != -1) + abort (); + if (__sync_fetch_and_or(AL+9, 8) != 0) + abort (); + if (__sync_fetch_and_xor(AL+10, 9) != 0) + abort (); + if (__sync_fetch_and_nand(AL+11, 7) != 0) + abort (); + + if (__sync_add_and_fetch(AL+12, 1) != 1) + abort (); + if (__sync_sub_and_fetch(AL+13, 12) != -12) + abort (); + if (__sync_and_and_fetch(AL+14, 7) != 7) + abort (); + if (__sync_or_and_fetch(AL+15, 8) != 8) + abort (); + if (__sync_xor_and_fetch(AL+16, 9) != 9) + abort (); + if (__sync_nand_and_fetch(AL+17, 7) != 7) + abort (); +} + +static void * +start1 (void *arg) +{ + unsigned loop; + sleep(1); + + for (loop = 0; loop < LOOPS; loop++) + { + memcpy(AI, init_qi, sizeof(init_qi)); + + do_qi (); + + if (memcmp (AI, test_qi, sizeof(test_qi))) + abort (); + } + + return arg; /* _delete1_ */ +} + +static void * +start2 (void *arg) +{ + unsigned loop; + + for (loop = 0; loop < LOOPS; loop++) + { + memcpy(AL, init_hi, sizeof(init_hi)); + + do_hi (); + + if (memcmp (AL, test_hi, sizeof(test_hi))) + abort (); + } + + return arg; /* _delete2_ */ +} + +int +main (int argc, char **argv) +{ + pthread_t thread; + int i; + + i = pthread_create (&thread, NULL, start1, NULL); /* _create_ */ + assert (i == 0); /* _create_after_ */ + + sleep (1); + + start2 (NULL); + + i = pthread_join (thread, NULL); /* _delete_ */ + assert (i == 0); + + return 0; /* _exit_ */ +} diff --git a/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp b/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp new file mode 100644 index 00000000000..eb49db506e9 --- /dev/null +++ b/gdb/testsuite/gdb.threads/atomic-seq-threaded.exp @@ -0,0 +1,84 @@ +# atomic-seq-threaded.exp -- Test case for stepping over RISC atomic code seqs. +# This variant testcases the code for stepping another thread while skipping +# over the atomic sequence in the former thread +# (STEPPING_PAST_SINGLESTEP_BREAKPOINT). +# Copyright (C) 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +set testfile atomic-seq-threaded +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] + +foreach opts {{} {compiler=gcc4} {FAIL}} { + if {$opts eq "FAIL"} { + return -1 + } + if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug $opts]] eq "" } { + break + } +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir + +gdb_load ${binfile} +if ![runto_main] then { + fail "Can't run to main" + return 0 +} + +# pthread_create () will not pass even on x86_64 with software watchpoint. +# Pass after pthread_create () without any watchpoint active. +set line [gdb_get_line_number "_create_after_"] +gdb_test "tbreak $line" \ + "reakpoint (\[0-9\]+) at .*$srcfile, line $line\..*" \ + "set breakpoint after pthread_create ()" +gdb_test "c" \ + ".*/\\* _create_after_ \\*/.*" \ + "run till after pthread_create ()" + +# Without a watchpoint being software no single-stepping would be used. +set test "Start (software) watchpoint" +gdb_test_multiple "watch unused" $test { + -re "Watchpoint \[0-9\]+: unused.*$gdb_prompt $" { + pass $test + } + -re "Hardware watchpoint \[0-9\]+: unused.*$gdb_prompt $" { + # We do not test the goal but still the whole testcase should pass. + unsupported $test + } +} + +# More thorough testing of the scheduling logic. +gdb_test "set scheduler-locking step" "" + +# Critical code path is stepped through at this point. +set line [gdb_get_line_number "_exit_"] +gdb_test "tbreak $line" \ + "reakpoint \[0-9\]+ at .*$srcfile, line $line\..*" \ + "set breakpoint at _exit_" +gdb_test "c" \ + ".*/\\* _exit_ \\*/.*" \ + "run till _exit_" + +# Just a nonproblematic program exit. +gdb_test "c" \ + ".*Program exited normally\\..*" \ + "run till program exit" diff --git a/gdb/testsuite/gdb.threads/attach-stopped.exp b/gdb/testsuite/gdb.threads/attach-stopped.exp index e3d0c51af72..6ee3b0d4976 100644 --- a/gdb/testsuite/gdb.threads/attach-stopped.exp +++ b/gdb/testsuite/gdb.threads/attach-stopped.exp @@ -56,7 +56,65 @@ proc corefunc { threadtype } { gdb_reinitialize_dir $srcdir/$subdir gdb_load ${binfile} - # Verify that we can attach to the stopped process. + # Verify that we can attach to the process by first giving its + # executable name via the file command, and using attach with the + # process ID. + + set test "$threadtype: set file, before attach1 to stopped process" + gdb_test_multiple "file $binfile" "$test" { + -re "Load new symbol table from.*y or n. $" { + gdb_test "y" "Reading symbols from $escapedbinfile\.\.\.*done." \ + "$test (re-read)" + } + -re "Reading symbols from $escapedbinfile\.\.\.*done.*$gdb_prompt $" { + pass "$test" + } + } + + set test "$threadtype: attach1 to stopped, after setting file" + gdb_test_multiple "attach $testpid" "$test" { + -re "Attaching to program.*`?$escapedbinfile'?, process $testpid.*$gdb_prompt $" { + pass "$test" + } + } + + # ".*sleep.*clone.*" would fail on s390x as bt stops at START_THREAD there. + if {[string equal $threadtype threaded]} { + gdb_test "thread apply all bt" ".*sleep.*start_thread.*" "$threadtype: attach1 to stopped bt" + } else { + gdb_test "bt" ".*sleep.*main.*" "$threadtype: attach1 to stopped bt" + } + + # Exit and detach the process. + + gdb_exit + + # Avoid some race: + sleep 2 + + if [catch {open /proc/${testpid}/status r} fileid] { + set line2 "NOTFOUND" + } else { + gets $fileid line1; + gets $fileid line2; + close $fileid; + } + + set test "$threadtype: attach1, exit leaves process stopped" + if {[string match "*(stopped)*" $line2]} { + pass $test + } else { + fail $test + } + + # At this point, the process should still be stopped + + gdb_start + gdb_reinitialize_dir $srcdir/$subdir + gdb_load ${binfile} + + # Verify that we can attach to the process just by giving the + # process ID. set test "$threadtype: attach2 to stopped, after setting file" gdb_test_multiple "attach $testpid" "$test" { diff --git a/gdb/testsuite/gdb.threads/bt-clone-stop.c b/gdb/testsuite/gdb.threads/bt-clone-stop.c new file mode 100644 index 00000000000..2ac93f86641 --- /dev/null +++ b/gdb/testsuite/gdb.threads/bt-clone-stop.c @@ -0,0 +1,39 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2006 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 2 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, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA. */ + + +#include +#include +#include + + +void *threader (void *arg) +{ + assert (0); + return NULL; +} + +int main (void) +{ + pthread_t t1; + + pthread_create (&t1, NULL, threader, (void *) NULL); + for (;;) + pause(); +} diff --git a/gdb/testsuite/gdb.threads/bt-clone-stop.exp b/gdb/testsuite/gdb.threads/bt-clone-stop.exp new file mode 100644 index 00000000000..02728e05b99 --- /dev/null +++ b/gdb/testsuite/gdb.threads/bt-clone-stop.exp @@ -0,0 +1,61 @@ +# Copyright 2006 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Backtraced `clone' must not have `PC == 0' as its previous frame. + +if $tracelevel then { + strace $tracelevel +} + +set testfile bt-clone-stop +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +# Get things started. + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +# threader: threader.c:8: threader: Assertion `0' failed. +# Program received signal SIGABRT, Aborted. + +gdb_test "run" \ + {Thread 2 "bt-clone-stop" received signal SIGABRT.*} \ + "run" + +# Former gdb unwind (the first function is `clone'): +# #5 0x0000003421ecd62d in ?? () from /lib64/libc.so.6 +# #6 0x0000000000000000 in ?? () +# (gdb) +# Tested `amd64_linux_outermost_frame' functionality should omit the line `#6'. +# +# Two `-re' cases below must be in this order (1st is a subset of the 2nd one). +# Unhandled case below should not happen and it is fortunately handled by +# `amd64_linux_outermost_frame' as FAIL (and result `0x0 entry output invalid'). +gdb_test_multiple "bt" "0x0 entry output invalid" { + -re "in threader \\(.*\n#\[0-9\]* *0x0* in .*$gdb_prompt $" { + fail "0x0 entry found" + } + -re "in threader \\(.*$gdb_prompt $" { + pass "0x0 entry not found" + } +} diff --git a/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.c b/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.c new file mode 100644 index 00000000000..1f32bbf889e --- /dev/null +++ b/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.c @@ -0,0 +1,79 @@ +/* Copyright 2009 Free Software Foundation, Inc. + + Written by Fred Fish of Cygnus Support + Contributed by Cygnus Support + + 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 . */ + +/* Test multiple threads stepping into a .debug_line-less function with + a breakpoint placed on its return-to-caller point. */ + +#include +#include +#include +#include +#include + +#define THREADS 3 + +static void * +func (void *unused) +{ + int i; + + errno = 0; + i = 0xdeadf00d; + i = sleep (THREADS); /* sleep-call */ + if (errno != 0) /* sleep-after */ + perror ("sleep"); + + /* The GDB bug with forgotten step-resume breakpoint could leave stale + breakpoint on the I assignment making it a nop. */ + if (i == 0xdeadf00d) + assert (0); + + assert (i == 0); + + pthread_exit (NULL); +} + +int +main (void) +{ + pthread_t threads[THREADS]; + int threadi; + + for (threadi = 0; threadi < THREADS; threadi++) + { + int i; + + i = pthread_create (&threads[threadi], NULL, func, NULL); + assert (i == 0); + + i = sleep (1); + assert (i == 0); + } + + for (threadi = 0; threadi < THREADS; threadi++) + { + int i; + + i = pthread_join (threads[threadi], NULL); + assert (i == 0); + } + + return 0; /* final-exit */ +} diff --git a/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.exp b/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.exp new file mode 100644 index 00000000000..ac5111c5ce5 --- /dev/null +++ b/gdb/testsuite/gdb.threads/simultaneous-step-resume-breakpoint.exp @@ -0,0 +1,65 @@ +# Copyright (C) 2009 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 . */ + +# Test multiple threads stepping into a .debug_line-less function with +# a breakpoint placed on its return-to-caller point. + +set testfile simultaneous-step-resume-breakpoint +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir + +# Ensure we have no debuginfo for the `sleep' call itself (=for libc). +gdb_test "set debug-file-directory /DoesNotExist" + +gdb_load ${binfile} +if ![runto_main] { + return -1 +} + +# Red Hat vendor patch does set it to "step" by default. +gdb_test "set scheduler-locking off" + +gdb_breakpoint [gdb_get_line_number "final-exit"] + +gdb_breakpoint [gdb_get_line_number "sleep-call"] +gdb_continue_to_breakpoint "sleep-call" + +gdb_test "step" "sleep-call.*" "step thread 1" +gdb_test "step" "sleep-call.*" "step thread 2" +gdb_test "step" "sleep-after.*" "step thread 3" + +set test "first continue" +gdb_test_multiple "continue" $test { + -re "final-exit.*$gdb_prompt $" { + # gdb-7.0. + pass $test + return + } + -re "sleep-after.*$gdb_prompt $" { + # Fedora/RHEL branch. + pass $test + } +} + +gdb_test "continue" "sleep-after.*" "second continue" +gdb_test "continue" "final-exit.*" "third continue" diff --git a/gdb/testsuite/gdb.threads/threadcrash.c b/gdb/testsuite/gdb.threads/threadcrash.c new file mode 100644 index 00000000000..80c599d0fba --- /dev/null +++ b/gdb/testsuite/gdb.threads/threadcrash.c @@ -0,0 +1,301 @@ +/* + * The point of this program is to crash in a multi-threaded app. + * There are seven threads, doing the following things: + * * Spinning + * * Spinning inside a signal handler + * * Spinning inside a signal handler executing on the altstack + * * In a syscall + * * In a syscall inside a signal handler + * * In a syscall inside a signal handler executing on the altstack + * * Finally, the main thread crashes in main, with no frills. + * + * These are the things threads in JRockit tend to be doing. If gdb + * can handle those things, both in core files and during live + * debugging, that will help (at least) JRockit development. + * + * Let the program create a core file, then load the core file into + * gdb. Inside gdb, you should be able to do something like this: + * + * (gdb) t a a bt + * + * Thread 7 (process 4352): + * #0 0x001ba7dc in __nanosleep_nocancel () from /lib/tls/libc.so.6 + * #1 0x001ba5ff in sleep () from /lib/tls/libc.so.6 + * #2 0x080488a2 in makeSyscall (ignored=0x0) at threadcrash.c:118 + * #3 0x006aadec in start_thread () from /lib/tls/libpthread.so.0 + * #4 0x001ed19a in clone () from /lib/tls/libc.so.6 + * + * Thread 6 (process 4353): + * #0 0x001ba7dc in __nanosleep_nocancel () from /lib/tls/libc.so.6 + * #1 0x001ba5ff in sleep () from /lib/tls/libc.so.6 + * #2 0x0804898f in syscallingSighandler (signo=10, info=0xb6be76f0, context=0xb6be7770) + * at threadcrash.c:168 + * #3 + * #4 0x006adf5e in pthread_kill () from /lib/tls/libpthread.so.0 + * #5 0x08048a51 in makeSyscallFromSighandler (ignored=0x0) at threadcrash.c:204 + * #6 0x006aadec in start_thread () from /lib/tls/libpthread.so.0 + * #7 0x001ed19a in clone () from /lib/tls/libc.so.6 + * + * Thread 5 (process 4354): + * #0 0x001ba7dc in __nanosleep_nocancel () from /lib/tls/libc.so.6 + * #1 0x001ba5ff in sleep () from /lib/tls/libc.so.6 + * #2 0x08048936 in syscallingAltSighandler (signo=3, info=0x959cd70, context=0x959cdf0) + * at threadcrash.c:144 + * #3 + * #4 0x006adf5e in pthread_kill () from /lib/tls/libpthread.so.0 + * #5 0x080489e2 in makeSyscallFromAltSighandler (ignored=0x0) at threadcrash.c:190 + * #6 0x006aadec in start_thread () from /lib/tls/libpthread.so.0 + * #7 0x001ed19a in clone () from /lib/tls/libc.so.6 + * + * Thread 4 (process 4355): + * #0 spin (ignored=0x0) at threadcrash.c:242 + * #1 0x006aadec in start_thread () from /lib/tls/libpthread.so.0 + * #2 0x001ed19a in clone () from /lib/tls/libc.so.6 + * + * Thread 3 (process 4356): + * #0 spinningSighandler (signo=12, info=0xb4de46f0, context=0xb4de4770) at threadcrash.c:180 + * #1 + * #2 0x006adf5e in pthread_kill () from /lib/tls/libpthread.so.0 + * #3 0x08048b2f in spinFromSighandler (ignored=0x0) at threadcrash.c:232 + * #4 0x006aadec in start_thread () from /lib/tls/libpthread.so.0 + * #5 0x001ed19a in clone () from /lib/tls/libc.so.6 + * + * Thread 2 (process 4357): + * #0 spinningAltSighandler (signo=14, info=0x959ee50, context=0x959eed0) at threadcrash.c:156 + * #1 + * #2 0x006adf5e in pthread_kill () from /lib/tls/libpthread.so.0 + * #3 0x08048ac0 in spinFromAltSighandler (ignored=0x0) at threadcrash.c:218 + * #4 0x006aadec in start_thread () from /lib/tls/libpthread.so.0 + * #5 0x001ed19a in clone () from /lib/tls/libc.so.6 + * + * Thread 1 (process 4351): + * #0 0x08048cf3 in main (argc=1, argv=0xbfff9d74) at threadcrash.c:273 + * (gdb) + */ + +#include +#include +#include +#include +#include +#include +#include + +#define SIGSYSCALL_ALT SIGQUIT +#define SIGSYSCALL SIGUSR1 +#define SIGSPIN_ALT SIGALRM +#define SIGSPIN SIGUSR2 + +typedef void (*sigaction_t)(int, siginfo_t *, void *); + +static void installHandler(int signo, sigaction_t handler, int onAltstack) { + struct sigaction action; + sigset_t sigset; + int result; + stack_t altstack; + stack_t oldaltstack; + + memset(&action, 0, sizeof(action)); + memset(&altstack, 0, sizeof(altstack)); + memset(&oldaltstack, 0, sizeof(oldaltstack)); + + if (onAltstack) { + altstack.ss_sp = malloc(SIGSTKSZ); + assert(altstack.ss_sp != NULL); + altstack.ss_size = SIGSTKSZ; + altstack.ss_flags = 0; + result = sigaltstack(&altstack, &oldaltstack); + assert(result == 0); + assert(oldaltstack.ss_flags == SS_DISABLE); + } + + sigemptyset(&sigset); + + action.sa_handler = NULL; + action.sa_sigaction = handler; + action.sa_mask = sigset; + action.sa_flags = SA_SIGINFO; + if (onAltstack) { + action.sa_flags |= SA_ONSTACK; + } + + result = sigaction(signo, &action, NULL); + assert(result == 0); +} + +static void installNormalHandler(int signo, sigaction_t handler) { + installHandler(signo, handler, 0); +} + +static void installAlthandler(int signo, sigaction_t handler) { + installHandler(signo, handler, 1); +} + +static void *makeSyscall(void *ignored) { + (void)ignored; + + sleep(42); + + fprintf(stderr, "%s: returning\n", __FUNCTION__); + return NULL; +} + +/* Return true if we're currently executing on the altstack */ +static int onAltstack(void) { + stack_t stack; + int result; + + result = sigaltstack(NULL, &stack); + assert(result == 0); + + return stack.ss_flags & SS_ONSTACK; +} + +static void syscallingAltSighandler(int signo, siginfo_t *info, void *context) { + (void)signo; + (void)info; + (void)context; + + if (!onAltstack()) { + printf("%s() not running on altstack!\n", __FUNCTION__); + } + + sleep(42); +} + +static void spinningAltSighandler(int signo, siginfo_t *info, void *context) { + (void)signo; + (void)info; + (void)context; + + if (!onAltstack()) { + printf("%s() not running on altstack!\n", __FUNCTION__); + } + + while (1); +} + +static void syscallingSighandler(int signo, siginfo_t *info, void *context) { + (void)signo; + (void)info; + (void)context; + + if (onAltstack()) { + printf("%s() running on altstack!\n", __FUNCTION__); + } + + sleep(42); +} + +static void spinningSighandler(int signo, siginfo_t *info, void *context) { + (void)signo; + (void)info; + (void)context; + + if (onAltstack()) { + printf("%s() running on altstack!\n", __FUNCTION__); + } + + while (1); +} + +static void *makeSyscallFromAltSighandler(void *ignored) { + (void)ignored; + + int result; + + installAlthandler(SIGSYSCALL_ALT, syscallingAltSighandler); + + result = pthread_kill(pthread_self(), SIGSYSCALL_ALT); + assert(result == 0); + + fprintf(stderr, "%s: returning\n", __FUNCTION__); + return NULL; +} + +static void *makeSyscallFromSighandler(void *ignored) { + (void)ignored; + + int result; + + installNormalHandler(SIGSYSCALL, syscallingSighandler); + + result = pthread_kill(pthread_self(), SIGSYSCALL); + assert(result == 0); + + fprintf(stderr, "%s: returning\n", __FUNCTION__); + return NULL; +} + +static void *spinFromAltSighandler(void *ignored) { + (void)ignored; + + int result; + + installAlthandler(SIGSPIN_ALT, spinningAltSighandler); + + result = pthread_kill(pthread_self(), SIGSPIN_ALT); + assert(result == 0); + + fprintf(stderr, "%s: returning\n", __FUNCTION__); + return NULL; +} + +static void *spinFromSighandler(void *ignored) { + (void)ignored; + + int result; + + installNormalHandler(SIGSPIN, spinningSighandler); + + result = pthread_kill(pthread_self(), SIGSPIN); + assert(result == 0); + + fprintf(stderr, "%s: returning\n", __FUNCTION__); + return NULL; +} + +static void *spin(void *ignored) { + (void)ignored; + + while (1); + + fprintf(stderr, "%s: returning\n", __FUNCTION__); + return NULL; +} + +int main(int argc, char *argv[]) { + int result; + pthread_t thread; + volatile int bad; + + result = pthread_create(&thread, NULL, makeSyscall, NULL); + assert(result == 0); + result = pthread_create(&thread, NULL, makeSyscallFromSighandler, NULL); + assert(result == 0); + result = pthread_create(&thread, NULL, makeSyscallFromAltSighandler, NULL); + assert(result == 0); + result = pthread_create(&thread, NULL, spin, NULL); + assert(result == 0); + result = pthread_create(&thread, NULL, spinFromSighandler, NULL); + assert(result == 0); + result = pthread_create(&thread, NULL, spinFromAltSighandler, NULL); + assert(result == 0); + + // Give threads some time to get going + sleep(3); + + // Crash + bad = *(int*)7; + + /* Workaround: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29628 + Simulate use to ensure `DW_AT_location' for them: + readelf -a --debug threadcrash|grep -A5 -w argc + --> DW_AT_location : 2 byte block: 71 0 (DW_OP_breg1: 0) + This case verified on: gcc-4.1.1-30.i386 + Keep it late to ensure persistency in the registers. */ + bad = (int) argc; + bad = (unsigned long) argv; + + return 0; +} diff --git a/gdb/testsuite/gdb.threads/threadcrash.exp b/gdb/testsuite/gdb.threads/threadcrash.exp new file mode 100644 index 00000000000..af6b919f586 --- /dev/null +++ b/gdb/testsuite/gdb.threads/threadcrash.exp @@ -0,0 +1,37 @@ +# threadcrash.exp - The point of this program is to crash in a multi-threaded app. + + +set testfile threadcrash +set srcfile ${testfile}.c +set shellfile ${srcdir}/${subdir}/${testfile}.sh +set binfile [standard_output_file ${testfile}] + +set GDB_abs ${GDB} +if [regexp "^\[^/\]" ${GDB_abs}] { + set GDB_abs $env(PWD)/${GDB_abs} +} + +if [istarget "*-*-linux"] then { + set target_cflags "-D_MIT_POSIX_THREADS" +} else { + set target_cflags "" +} + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } { + return -1 +} + +# ${shellfile} argument must not contain any directories. +set fd [open "|bash ${shellfile} ${binfile} $GDB $INTERNAL_GDBFLAGS $GDBFLAGS [host_info gdb_opts]" r] +while { [gets $fd line] >= 0 } { + if [regexp " PASS: (.*)$" $line trash message] { + pass $message + } elseif [regexp " FAIL: (.*)$" $line trash message] { + fail $message + } +} +catch { + close $fd +} + +return 0 diff --git a/gdb/testsuite/gdb.threads/threadcrash.sh b/gdb/testsuite/gdb.threads/threadcrash.sh new file mode 100644 index 00000000000..7f7e6520d6b --- /dev/null +++ b/gdb/testsuite/gdb.threads/threadcrash.sh @@ -0,0 +1,324 @@ +#! /bin/bash + +# NOTE: threadcrash.c *must* be built with debugging symbols +# +# The point of this shell script is to crash treadcrash.c, load the +# resulting core file into gdb and verify that gdb can extract enough +# information from the core file. +# +# The return code from this script is the number of failed tests. + +LOG=gdbresult.log + +if [ $# = 0 ] ; then + echo >&2 Syntax: $0 \ [\ \] + exit 1 +fi +RUNME="$1" +shift +GDB="${*:-gdb}" + + +pf_prefix="" +function pf_prefix() { + pf_prefix="$*" +} + +set_test="" +function set_test() { + if [ -n "$set_test" ] ; then + echo >&2 "DEJAGNU-BASH ERROR: set_test already set" + exit 1 + fi + set_test="$*" + if [ -n "$pf_prefix" ] ; then + set_test="$pf_prefix: $set_test" + fi +} + +# INTERNAL +function record_test { + if [ -z "$set_test" ] ; then + echo >&2 "DEJAGNU-BASH ERROR: set_test not set" + exit 1 + fi + # Provide the leading whitespace delimiter: + echo " $1: $set_test" + set_test="" +} + +function pass() { + record_test PASS +} +function fail() { + record_test FAIL +} + + +# Verify that the gdb output doesn't contain $1. +function mustNotHave() { + local BADWORD=$1 + set_test gdb output contains "$BADWORD" + if grep -q "$BADWORD" $LOG ; then + fail + return 1 + fi + pass + return 0 +} + +# Verify that the gdb output contains exactly $1 $2s. +function mustHaveCorrectAmount() { + local WANTEDNUMBER=$1 + local GOODWORD=$2 + local ACTUALNUMBER=$(grep "$GOODWORD" $LOG | wc -l) + set_test gdb output contained $ACTUALNUMBER \""$GOODWORD"\", not $WANTEDNUMBER as expected + if [ $ACTUALNUMBER != $WANTEDNUMBER ] ; then + fail + return 1 + fi + pass + return 0 +} + +# Verify that the gdb output contains seven threads +function mustHaveSevenThreads() { + NTHREADS=$(egrep "^Thread [1-7] \(" $LOG | wc -l) + set_test gdb output contains $NTHREADS threads, not 7 as expected + if [ $NTHREADS != 7 ] ; then + fail + return 1 + fi + pass + return 0 +} + +# Verify that the gdb output has all parameters on consecutive lines +function mustHaveSequence() { + SEQUENCE="$*" + NPARTS=$# + grep "$1" -A$((NPARTS - 1)) $LOG > matches.log + + while [ $# -gt 1 ] ; do + shift + ((NPARTS--)) + grep "$1" -A$((NPARTS - 1)) matches.log > temp.log + mv temp.log matches.log + done + LASTPART=$1 + + set_test gdb output does not contain the sequence: $SEQUENCE + if ! grep -q "$LASTPART" matches.log ; then + fail + return 1 + fi + pass + return 0 +} + +# Verify that $LOG contains all information we want +function verifyLog() { + local FAILURES=0 + + mustNotHave '??' || ((FAILURES++)) + mustHaveCorrectAmount 11 threadcrash.c: || ((FAILURES++)) + + mustHaveSevenThreads || ((FAILURES++)) + mustHaveSequence sleep "makeSyscall (ignored=" || ((FAILURES++)) + + mustHaveSequence sleep "syscallingSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) + mustHaveSequence pthread_kill "makeSyscallFromSighandler (ignored=" || ((FAILURES++)) + + mustHaveSequence sleep "syscallingAltSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) + mustHaveSequence pthread_kill "makeSyscallFromAltSighandler (ignored=" || ((FAILURES++)) + + mustHaveSequence Thread "spin (ignored=" || ((FAILURES++)) + + mustHaveSequence "spinningSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) + mustHaveSequence pthread_kill "spinFromSighandler (ignored=" || ((FAILURES++)) + + mustHaveSequence "spinningAltSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) + mustHaveSequence pthread_kill "spinFromAltSighandler (ignored=" || ((FAILURES++)) + + mustHaveSequence Thread "main (argc=1, argv=" || ((FAILURES++)) + + return $FAILURES +} + +# Put result of debugging a core file in $LOG +function getLogFromCore() { + # Make sure we get a core file + set_test Make sure we get a core file + if ! ulimit -c unlimited ; then + fail + exit 1 + fi + pass + + # Run the crasher + ./$(basename "$RUNME") + EXITCODE=$? + + # Verify that we actually crashed + set_test $RUNME should have been killed by a signal, got non-signal exit code $EXITCODE + if [ $EXITCODE -lt 128 ] ; then + fail + exit 1 + fi + pass + + # Verify that we got a core file + set_test $RUNME did not create a core file + if [ ! -r core* ] ; then + fail + exit 1 + fi + pass + + # Run gdb + cat > gdbscript.gdb < $LOG + EXITCODE=$? + + set_test gdb exited with error code + if [ $EXITCODE != 0 ] ; then + ((FAILURES++)) + echo >&2 gdb exited with error code $EXITCODE + fail + fi + pass +} + +# Put result of debugging a gcore file in $LOG +function getLogFromGcore() { + # Create the core file + rm -f core* + cat > gdbscript.gdb < /dev/null + EXITCODE=$? + + set_test gdb exited with error code when creating gcore file + if [ $EXITCODE != 0 ] ; then + ((FAILURES++)) + echo >&2 gdb exited with error code $EXITCODE when creating gcore file + fail + fi + pass + + # Verify that we got a core file from gcore + set_test gdb gcore did not create a core file + if [ ! -r core* ] ; then + fail + exit 1 + fi + pass + + # Run gdb on the gcore file + cat > gdbscript.gdb < $LOG + EXITCODE=$? + + set_test gdb exited with error code when examining gcore file + if [ $EXITCODE != 0 ] ; then + ((FAILURES++)) + echo >&2 gdb exited with error code $EXITCODE when examining gcore file + fail + fi + pass +} + +# Put result of debugging a core file in $LOG +function getLogFromLiveProcess() { + # Run gdb + cat > gdbscript.gdb < $LOG + EXITCODE=$? + + set_test gdb exited with error code + if [ $EXITCODE != 0 ] ; then + ((FAILURES++)) + echo >&2 gdb exited with error code $EXITCODE + fail + fi + pass +} + +####### Main program follows ##################### + +# Make sure we don't clobber anybody else's (core) file(s) +WORKDIR=/tmp/$PPID +mkdir -p $WORKDIR +cp "$RUNME" $WORKDIR +cd $WORKDIR + +# Count problems +FAILURES=0 + +echo === Testing gdb vs core file... +pf_prefix core file +getLogFromCore +verifyLog +((FAILURES+=$?)) +pf_prefix +echo === Core file tests done. + +echo + +echo === Testing gdb vs gcore file... +pf_prefix gcore file +getLogFromGcore +verifyLog +((FAILURES+=$?)) +pf_prefix +echo === Gcore file tests done. + +echo + +echo === Testing gdb vs live process... +pf_prefix live process +getLogFromLiveProcess +verifyLog +((FAILURES+=$?)) +pf_prefix +echo === Live process tests done. + +# Executive summary +echo +if [ $FAILURES == 0 ] ; then + echo All tests passed! +else + echo $FAILURES tests failed! + echo + echo Make sure the threadcrash binary contains debugging information \(build with \"gcc -g\"\). +fi + +# Clean up +cd / +rm -rf $WORKDIR + +exit $FAILURES diff --git a/gdb/testsuite/gdb.threads/threadcrash.sh-orig b/gdb/testsuite/gdb.threads/threadcrash.sh-orig new file mode 100644 index 00000000000..eb602036c25 --- /dev/null +++ b/gdb/testsuite/gdb.threads/threadcrash.sh-orig @@ -0,0 +1,248 @@ +#! /bin/bash + +# NOTE: threadcrash.c *must* be built with debugging symbols +# +# The point of this shell script is to crash treadcrash.c, load the +# resulting core file into gdb and verify that gdb can extract enough +# information from the core file. +# +# The return code from this script is the number of failed tests. + +LOG=gdbresult.log + +if [ $# != 1 ] ; then + echo > /dev/stderr Syntax: $0 \ + exit 1 +fi +RUNME="$1" + +# Verify that the gdb output doesn't contain $1. +function mustNotHave() { + local BADWORD=$1 + if grep -q "$BADWORD" $LOG ; then + echo >> /dev/stderr WARNING: gdb output contains "$BADWORD" + return 1 + fi + return 0 +} + +# Verify that the gdb output contains exactly $1 $2s. +function mustHaveCorrectAmount() { + local WANTEDNUMBER=$1 + local GOODWORD=$2 + local ACTUALNUMBER=$(grep "$GOODWORD" $LOG | wc -l) + if [ $ACTUALNUMBER != $WANTEDNUMBER ] ; then + echo >> /dev/stderr WARNING: gdb output contained $ACTUALNUMBER \""$GOODWORD"\", not $WANTEDNUMBER as expected + return 1 + fi + return 0 +} + +# Verify that the gdb output contains seven threads +function mustHaveSevenThreads() { + NTHREADS=$(egrep "^Thread [1-7] \(" $LOG | wc -l) + if [ $NTHREADS != 7 ] ; then + echo >> /dev/stderr WARNING: gdb output contains $NTHREADS threads, not 7 as expected + return 1 + fi + return 0 +} + +# Verify that the gdb output has all parameters on consecutive lines +function mustHaveSequence() { + SEQUENCE="$*" + NPARTS=$# + grep "$1" -A$((NPARTS - 1)) $LOG > matches.log + + while [ $# -gt 1 ] ; do + shift + ((NPARTS--)) + grep "$1" -A$((NPARTS - 1)) matches.log > temp.log + mv temp.log matches.log + done + LASTPART=$1 + + if ! grep -q "$LASTPART" matches.log ; then + echo >> /dev/stderr WARNING: gdb output does not contain the sequence: $SEQUENCE + return 1 + fi + return 0 +} + +# Verify that $LOG contains all information we want +function verifyLog() { + local FAILURES=0 + + mustNotHave '??' || ((FAILURES++)) + mustHaveCorrectAmount 12 threadcrash.c: || ((FAILURES++)) + + mustHaveSevenThreads || ((FAILURES++)) + mustHaveSequence sleep "makeSyscall (ignored=" || ((FAILURES++)) + + mustHaveSequence sleep "syscallingSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) + mustHaveSequence pthread_kill "makeSyscallFromSighandler (ignored=" || ((FAILURES++)) + + mustHaveSequence sleep "syscallingAltSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) + mustHaveSequence pthread_kill "makeSyscallFromAltSighandler (ignored=" || ((FAILURES++)) + + mustHaveSequence Thread "spin (ignored=" || ((FAILURES++)) + + mustHaveSequence "spinningSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) + mustHaveSequence pthread_kill "spinFromSighandler (ignored=" || ((FAILURES++)) + + mustHaveSequence "spinningAltSighandler (signo=" "signal handler called" 0x || ((FAILURES++)) + mustHaveSequence pthread_kill "spinFromAltSighandler (ignored=" || ((FAILURES++)) + + mustHaveSequence Thread "main (argc=1, argv=" || ((FAILURES++)) + + return $FAILURES +} + +# Put result of debugging a core file in $LOG +function getLogFromCore() { + # Make sure we get a core file + ulimit -c unlimited || exit 1 + + # Run the crasher + ./$(basename "$RUNME") + EXITCODE=$? + + # Verify that we actually crashed + if [ $EXITCODE -lt 128 ] ; then + echo >> /dev/stderr ERROR: $RUNME should have been killed by a signal, got non-signal exit code $EXITCODE + exit 1 + fi + + # Verify that we got a core file + if [ ! -r core* ] ; then + echo >> /dev/stderr ERROR: $RUNME did not create a core file + exit 1 + fi + + # Run gdb + cat > gdbscript.gdb < $LOG + EXITCODE=$? + + if [ $EXITCODE != 0 ] ; then + ((FAILURES++)) + echo >> /dev/stderr WARNING: gdb exited with error code $EXITCODE + fi +} + +# Put result of debugging a gcore file in $LOG +function getLogFromGcore() { + # Create the core file + rm -f core* + cat > gdbscript.gdb < /dev/null + EXITCODE=$? + + if [ $EXITCODE != 0 ] ; then + ((FAILURES++)) + echo >> /dev/stderr WARNING: gdb exited with error code $EXITCODE when creating gcore file + fi + + # Verify that we got a core file from gcore + if [ ! -r core* ] ; then + echo >> /dev/stderr ERROR: gdb gcore did not create a core file + exit 1 + fi + + # Run gdb on the gcore file + cat > gdbscript.gdb < $LOG + EXITCODE=$? + + if [ $EXITCODE != 0 ] ; then + ((FAILURES++)) + echo >> /dev/stderr WARNING: gdb exited with error code $EXITCODE when examining gcore file + fi +} + +# Put result of debugging a core file in $LOG +function getLogFromLiveProcess() { + # Run gdb + cat > gdbscript.gdb < $LOG + EXITCODE=$? + + if [ $EXITCODE != 0 ] ; then + ((FAILURES++)) + echo >> /dev/stderr WARNING: gdb exited with error code $EXITCODE + fi +} + +####### Main program follows ##################### + +# Make sure we don't clobber anybody else's (core) file(s) +WORKDIR=/tmp/$PPID +mkdir -p $WORKDIR +cp "$RUNME" $WORKDIR +cd $WORKDIR + +# Count problems +FAILURES=0 + +echo === Testing gdb vs core file... +getLogFromCore +verifyLog +((FAILURES+=$?)) +echo === Core file tests done. + +echo + +echo === Testing gdb vs gcore file... +getLogFromGcore +verifyLog +((FAILURES+=$?)) +echo === Gcore file tests done. + +echo + +echo === Testing gdb vs live process... +getLogFromLiveProcess +verifyLog +((FAILURES+=$?)) +echo === Live process tests done. + +# Executive summary +echo +if [ $FAILURES == 0 ] ; then + echo All tests passed! +else + echo $FAILURES tests failed! + echo + echo Make sure the threadcrash binary contains debugging information \(build with \"gcc -g\"\). +fi + +# Clean up +cd / +rm -rf $WORKDIR + +exit $FAILURES diff --git a/gdb/testsuite/gdb.threads/threaded-exec.c b/gdb/testsuite/gdb.threads/threaded-exec.c new file mode 100644 index 00000000000..7079317d3aa --- /dev/null +++ b/gdb/testsuite/gdb.threads/threaded-exec.c @@ -0,0 +1,147 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2007 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include +#include +#include + +#ifdef THREADS + +# include + +static void * +threader (void *arg) +{ + return NULL; +} + +#endif + +int +main (int argc, char **argv) +{ + char *exec_nothreads, *exec_threads, *cmd; + int phase; + char phase_s[8]; + + setbuf (stdout, NULL); + + if (argc != 4) + { + fprintf (stderr, "%s \n", argv[0]); + return 1; + } + +#ifdef THREADS + puts ("THREADS: Y"); +#else + puts ("THREADS: N"); +#endif + exec_nothreads = argv[1]; + printf ("exec_nothreads: %s\n", exec_nothreads); + exec_threads = argv[2]; + printf ("exec_threads: %s\n", exec_threads); + phase = atoi (argv[3]); + printf ("phase: %d\n", phase); + + /* Phases: threading + 0: N -> N + 1: N -> Y + 2: Y -> Y + 3: Y -> N + 4: N -> exit */ + + cmd = NULL; + +#ifndef THREADS + switch (phase) + { + case 0: + cmd = exec_nothreads; + break; + case 1: + cmd = exec_threads; + break; + case 2: + fprintf (stderr, "%s: We should have threads for phase %d!\n", argv[0], + phase); + return 1; + case 3: + fprintf (stderr, "%s: We should have threads for phase %d!\n", argv[0], + phase); + return 1; + case 4: + return 0; + default: + assert (0); + } +#else /* THREADS */ + switch (phase) + { + case 0: + fprintf (stderr, "%s: We should not have threads for phase %d!\n", + argv[0], phase); + return 1; + case 1: + fprintf (stderr, "%s: We should not have threads for phase %d!\n", + argv[0], phase); + return 1; + case 2: + cmd = exec_threads; + { + pthread_t t1; + int i; + + i = pthread_create (&t1, NULL, threader, (void *) NULL); + assert (i == 0); + i = pthread_join (t1, NULL); + assert (i == 0); + } + break; + case 3: + cmd = exec_nothreads; + { + pthread_t t1; + int i; + + i = pthread_create (&t1, NULL, threader, (void *) NULL); + assert (i == 0); + i = pthread_join (t1, NULL); + assert (i == 0); + } + break; + case 4: + fprintf (stderr, "%s: We should not have threads for phase %d!\n", + argv[0], phase); + return 1; + default: + assert (0); + } +#endif /* THREADS */ + + assert (cmd != NULL); + + phase++; + snprintf (phase_s, sizeof phase_s, "%d", phase); + + execl (cmd, cmd, exec_nothreads, exec_threads, phase_s, NULL); + assert (0); +} diff --git a/gdb/testsuite/gdb.threads/threaded-exec.exp b/gdb/testsuite/gdb.threads/threaded-exec.exp new file mode 100644 index 00000000000..8c43162b36e --- /dev/null +++ b/gdb/testsuite/gdb.threads/threaded-exec.exp @@ -0,0 +1,46 @@ +# threaded-exec.exp -- Check reset of the tracked threads on exec*(2) +# Copyright (C) 2007 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +# Please email any bugs, comments, and/or additions to this file to: +# bug-gdb@prep.ai.mit.edu + +set testfile threaded-exec +set srcfile ${testfile}.c +set binfile_nothreads [standard_output_file ${testfile}N] +set binfile_threads [standard_output_file ${testfile}Y] + +if {[gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile_nothreads}" executable {additional_flags=-UTHREADS}] != "" } { + return -1 +} + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile_threads}" executable {additional_flags=-DTHREADS}] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir + +gdb_load ${binfile_nothreads} + +gdb_run_cmd ${binfile_nothreads} ${binfile_threads} 0 + +gdb_test_multiple {} "Program exited" { + -re "\r\n\\\[Inferior .* exited normally\\\]\r\n$gdb_prompt $" { + pass "Program exited" + } +} diff --git a/gdb/testsuite/gdb.threads/tls-rhbz947564.cc b/gdb/testsuite/gdb.threads/tls-rhbz947564.cc new file mode 100644 index 00000000000..efb25ab926f --- /dev/null +++ b/gdb/testsuite/gdb.threads/tls-rhbz947564.cc @@ -0,0 +1,53 @@ +#include +#include + +class x + { + public: + int n; + + x() : n(0) {} + }; + +class y + { + public: + int v; + + y() : v(0) {} + static __thread x *xp; + }; + +__thread x *y::xp; + +static void +foo (y *yp) +{ + yp->v = 1; /* foo_marker */ +} + +static void * +bar (void *unused) +{ + x xinst; + y::xp= &xinst; + + y yy; + foo(&yy); + + return NULL; +} + +int +main(int argc, char *argv[]) +{ + pthread_t t[2]; + + pthread_create (&t[0], NULL, bar, NULL); + pthread_create (&t[1], NULL, bar, NULL); + + pthread_join (t[0], NULL); + pthread_join (t[1], NULL); + + return 0; +} diff --git a/gdb/testsuite/gdb.threads/tls-rhbz947564.exp b/gdb/testsuite/gdb.threads/tls-rhbz947564.exp new file mode 100644 index 00000000000..e8112e965d2 --- /dev/null +++ b/gdb/testsuite/gdb.threads/tls-rhbz947564.exp @@ -0,0 +1,75 @@ +# Copyright (C) 2013 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 . */ + +set testfile tls-rhbz947564 +set srcfile ${testfile}.cc +set binfile [standard_output_file ${testfile}] + +if [istarget "*-*-linux"] then { + set target_cflags "-D_MIT_POSIX_THREADS" +} else { + set target_cflags "" +} + +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list c++ debug]] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir + +gdb_load ${binfile} + +if { ![runto_main] } { + fail "Can't run to function main" + return 0 +} + +gdb_breakpoint "foo" +gdb_continue_to_breakpoint "foo" ".* foo_marker .*" + +proc get_xp_val {try} { + global expect_out + global gdb_prompt + global hex + + set xp_val "" + gdb_test_multiple "print *yp" "print yp value" { + -re { = \{v = 0, static xp = (0x[0-9a-f]+)\}.* } { + pass "print $try value of *yp" + set xp_val $expect_out(1,string) + } + -re "$gdb_prompt $" { + fail "print $try value of *yp" + } + timeout { + fail "print $try value of *yp (timeout)" + } + } + return $xp_val +} + +set first_run [get_xp_val "first"] + +gdb_test "continue" "Breakpoint \[0-9\]+, foo \\\(yp=$hex\\\) at.*" + +set second_run [get_xp_val "second"] + +if { $first_run != $second_run } { + pass "different values for TLS variable" +} else { + fail "different values for TLS variable" +} diff --git a/gdb/testsuite/gdb.threads/tls-sepdebug-main.c b/gdb/testsuite/gdb.threads/tls-sepdebug-main.c new file mode 100644 index 00000000000..ea5d0174d6a --- /dev/null +++ b/gdb/testsuite/gdb.threads/tls-sepdebug-main.c @@ -0,0 +1,25 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2006 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +int main() +{ + return 0; +} diff --git a/gdb/testsuite/gdb.threads/tls-sepdebug-shared.c b/gdb/testsuite/gdb.threads/tls-sepdebug-shared.c new file mode 100644 index 00000000000..61b49251bab --- /dev/null +++ b/gdb/testsuite/gdb.threads/tls-sepdebug-shared.c @@ -0,0 +1,22 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2006 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + Please email any bugs, comments, and/or additions to this file to: + bug-gdb@prep.ai.mit.edu */ + +__thread int var = 42; diff --git a/gdb/testsuite/gdb.threads/tls-sepdebug.exp b/gdb/testsuite/gdb.threads/tls-sepdebug.exp new file mode 100644 index 00000000000..00773f78f2e --- /dev/null +++ b/gdb/testsuite/gdb.threads/tls-sepdebug.exp @@ -0,0 +1,87 @@ +# Copyright 2006 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +if $tracelevel then { + strace $tracelevel +} + +set testfile tls-sepdebug +set srcmainfile ${testfile}-main.c +set srcsharedfile ${testfile}-shared.c + +set binmainfile [standard_output_file ${testfile}-main] +set binsharedbase ${testfile}-shared.so +set binsharedfile [standard_output_file ${binsharedbase}] +set binshareddebugfile [standard_output_file ${binsharedbase}.debug] + +# Use explicit -soname as otherwise the full path to the library would get +# encoded into ${binmainfile} making LD_LIBRARY_PATH tests useless. + +# FIXME: gcc dependency (-Wl,-soname). + +if { [gdb_compile_shlib "${srcdir}/${subdir}/${srcsharedfile}" "${binsharedfile}" [list debug additional_flags=-Wl,-soname=${binsharedbase}]] != "" } { + untested "Couldn't compile test library" + return -1 +} + +# eu-strip(1) works fine but it is a part of `elfutils', not `binutils'. +if 0 then { + remote_exec build "eu-strip -f ${binshareddebugfile} ${binsharedfile}" +} else { + remote_exec build "objcopy --only-keep-debug ${binsharedfile} ${binshareddebugfile}" + remote_exec build "objcopy --strip-debug ${binsharedfile}" + remote_exec build "objcopy --add-gnu-debuglink=${binshareddebugfile} ${binsharedfile}" +} + +# Do not use `shlib=' as it will automatically add also -rpath for gcc. + +if { [gdb_compile_pthreads "${srcdir}/${subdir}/${srcmainfile} ${binsharedfile}" "${binmainfile}" executable {debug}] != "" } { + untested "Couldn't compile test program" + return -1 +} + +# Get things started. + +# Test also the proper resolving of relative library names to absolute ones. +# \$PWD is easy - it is the absolute way +# ${subdir} would fail on "print var" + +set absdir [file dirname [standard_output_file ${binsharedbase}]] +foreach ld_library_path [list $absdir [relative_filename [pwd] $absdir]] name { absolute relative } { + + gdb_exit + gdb_start + ###gdb_reinitialize_dir $srcdir/$subdir + + gdb_test "set env LD_LIBRARY_PATH=$ld_library_path" \ + "" \ + "set env LD_LIBRARY_PATH is $name" + + gdb_load ${binmainfile} + + # For C programs, "start" should stop in main(). + + gdb_test "start" \ + "main \\(\\) at .*${srcmainfile}.*" \ + "start" + + # Check for: Cannot find shared library `/usr/lib/debug/lib/libc-2.4.90.so.debug' in dynamic linker's load module list + # as happens with TLS variables and `separate_debug_objfile_backlink'. + + gdb_test "print var" \ + "\\\$1 = \[0-9\].*" \ + "print TLS variable from a shared library with $name-directory separate debug info file" +} diff --git a/gdb/testsuite/gdb.threads/watchthreads-threaded.c b/gdb/testsuite/gdb.threads/watchthreads-threaded.c new file mode 100644 index 00000000000..1402640ccfd --- /dev/null +++ b/gdb/testsuite/gdb.threads/watchthreads-threaded.c @@ -0,0 +1,66 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2002, 2003, 2004, 2005 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + This file is copied from schedlock.c. */ + +#include +#include +#include +#include + +void *thread_function(void *arg); /* Pointer to function executed by each thread */ + +#define NUM 5 + +unsigned int args[NUM+1]; + +int main() { + int res; + pthread_t threads[NUM]; + void *thread_result; + long i; + + for (i = 0; i < NUM; i++) + { + args[i] = 1; /* Init value. */ + res = pthread_create(&threads[i], + NULL, + thread_function, + (void *) i); + } + + args[i] = 1; + thread_function ((void *) i); + + exit(EXIT_SUCCESS); +} + +void *thread_function(void *arg) { + int my_number = (long) arg; + int *myp = (int *) &args[my_number]; + + /* Don't run forever. Run just short of it :) */ + while (*myp > 0) + { + (*myp) ++; usleep (1); /* Loop increment. */ + } + + pthread_exit(NULL); +} + diff --git a/gdb/testsuite/gdb.threads/watchthreads-threaded.exp b/gdb/testsuite/gdb.threads/watchthreads-threaded.exp new file mode 100644 index 00000000000..e9cdd59771c --- /dev/null +++ b/gdb/testsuite/gdb.threads/watchthreads-threaded.exp @@ -0,0 +1,126 @@ +# This testcase is part of GDB, the GNU debugger. + +# Copyright 2005 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# Check that GDB can support multiple watchpoints across threads. + +# This test verifies that a watchpoint is detected in the proper thread +# so the test is only meaningful on a system with hardware watchpoints. +if [target_info exists gdb,no_hardware_watchpoints] { + return 0; +} + +set testfile "watchthreads-threaded" +set srcfile ${testfile}.c +set binfile [standard_output_file ${testfile}] +if {[gdb_compile_pthreads "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable [list debug "incdir=${objdir}"]] != "" } { + return -1 +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +gdb_load ${binfile} + +gdb_test "set can-use-hw-watchpoints 1" "" "" + +# +# Run to `main' where we begin our tests. +# + +if ![runto_main] then { + gdb_suppress_tests +} + +set args_2 0 +set args_3 0 + +gdb_breakpoint "thread_function" +gdb_continue_to_breakpoint "thread_function" +gdb_test "disable 2" "" + +gdb_test_multiple "p args\[2\]" "get initial args2" { + -re "\\\$\[0-9\]* = (.*)$gdb_prompt $" { + set init_args_2 $expect_out(1,string) + pass "get initial args2" + } +} + +gdb_test_multiple "p args\[3\]" "get initial args3" { + -re "\\\$\[0-9\]* = (.*)$gdb_prompt $" { + set init_args_3 $expect_out(1,string) + pass "get initial args3" + } +} + +set args_2 $init_args_2 +set args_3 $init_args_3 + +# Watch values that will be modified by distinct threads. +gdb_test "watch args\[2\]" "Hardware watchpoint 3: args\\\[2\\\]" +gdb_test "watch args\[3\]" "Hardware watchpoint 4: args\\\[3\\\]" + +set init_line [expr [gdb_get_line_number "Init value"]+1] +set inc_line [gdb_get_line_number "Loop increment"] + +# Loop and continue to allow both watchpoints to be triggered. +for {set i 0} {$i < 30} {incr i} { + set test_flag 0 + gdb_test_multiple "continue" "threaded watch loop" { + -re "Hardware watchpoint 3: args\\\[2\\\].*Old value = 0.*New value = 1.*main \\\(\\\) at .*watchthreads-threaded.c:$init_line.*$gdb_prompt $" + { set args_2 1; set test_flag 1 } + -re "Hardware watchpoint 4: args\\\[3\\\].*Old value = 0.*New value = 1.*main \\\(\\\) at .*watchthreads-threaded.c:$init_line.*$gdb_prompt $" + { set args_3 1; set test_flag 1 } + -re "Hardware watchpoint 3: args\\\[2\\\].*Old value = $args_2.*New value = [expr $args_2+1].*in thread_function \\\(arg=0x2\\\) at .*watchthreads-threaded.c:$inc_line.*$gdb_prompt $" + { set args_2 [expr $args_2+1]; set test_flag 1 } + -re "Hardware watchpoint 4: args\\\[3\\\].*Old value = $args_3.*New value = [expr $args_3+1].*in thread_function \\\(arg=0x3\\\) at .*watchthreads-threaded.c:$inc_line.*$gdb_prompt $" + { set args_3 [expr $args_3+1]; set test_flag 1 } + } + # If we fail above, don't bother continuing loop + if { $test_flag == 0 } { + set i 30; + } +} + +# Print success message if loop succeeded. +if { $test_flag == 1 } { + pass "threaded watch loop" +} + +# Verify that we hit first watchpoint in child thread. +set message "watchpoint on args\[2\] hit in thread" +if { $args_2 > 1 } { + pass $message +} else { + fail $message +} + +# Verify that we hit second watchpoint in child thread. +set message "watchpoint on args\[3\] hit in thread" +if { $args_3 > 1 } { + pass $message +} else { + fail $message +} + +# Verify that all watchpoint hits are accounted for. +set message "combination of threaded watchpoints = 30 + initial values" +if { [expr $args_2+$args_3] == [expr [expr 30+$init_args_2]+$init_args_3] } { + pass $message +} else { + fail $message +} diff --git a/gdb/testsuite/lib/future.exp b/gdb/testsuite/lib/future.exp index a56cd019b4d..e04a3903bf3 100644 --- a/gdb/testsuite/lib/future.exp +++ b/gdb/testsuite/lib/future.exp @@ -185,6 +185,10 @@ proc gdb_default_target_compile {source destfile type options} { set ldflags "" set dest [target_info name] + if {[board_info $dest exists multilib_flags]} { + append add_flags " [board_info $dest multilib_flags]" + } + if {[info exists CFLAGS_FOR_TARGET]} { append add_flags " $CFLAGS_FOR_TARGET" } @@ -519,10 +523,6 @@ proc gdb_default_target_compile {source destfile type options} { } } - if {[board_info $dest exists multilib_flags]} { - append add_flags " [board_info $dest multilib_flags]" - } - verbose "doing compile" set sources "" diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 1176fdded14..219df0a25b2 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -170,6 +170,11 @@ proc gdb_unload {} { send_gdb "y\n" exp_continue } + -re "A program is being debugged already..*Are you sure you want to change the file.*y or n. $"\ + { send_gdb "y\n" + verbose "\t\tUnloading symbols for program being debugged" + exp_continue + } -re "Discard symbol table from .*y or n.*$" { send_gdb "y\n" exp_continue @@ -1716,6 +1721,16 @@ proc default_gdb_start { } { warning "Couldn't set the width to 0." } } + # Turn off the missing warnings as the testsuite does not expect it. + send_gdb "set build-id-verbose 0\n" + gdb_expect 10 { + -re "$gdb_prompt $" { + verbose "Disabled the missing debug infos warnings." 2 + } + timeout { + warning "Could not disable the missing debug infos warnings.." + } + } return 0 } diff --git a/gdb/testsuite/lib/mi-support.exp b/gdb/testsuite/lib/mi-support.exp index a58c4f6e119..ef19b26a752 100644 --- a/gdb/testsuite/lib/mi-support.exp +++ b/gdb/testsuite/lib/mi-support.exp @@ -309,6 +309,16 @@ proc default_mi_gdb_start { args } { warning "Couldn't set the width to 0." } } + # Turn off the missing warnings as the testsuite does not expect it. + send_gdb "190-gdb-set build-id-verbose 0\n" + gdb_expect 10 { + -re ".*190-gdb-set build-id-verbose 0\r\n190\\\^done\r\n$mi_gdb_prompt$" { + verbose "Disabled the missing debug infos warnings." 2 + } + timeout { + warning "Could not disable the missing debug infos warnings.." + } + } if { $separate_inferior_pty } { mi_create_inferior_pty diff --git a/gdb/testsuite/lib/pascal.exp b/gdb/testsuite/lib/pascal.exp index 796c2a781e8..2c000525f18 100644 --- a/gdb/testsuite/lib/pascal.exp +++ b/gdb/testsuite/lib/pascal.exp @@ -37,6 +37,9 @@ proc pascal_init {} { global pascal_compiler_is_fpc global gpc_compiler global fpc_compiler + global fpcversion_major + global fpcversion_minor + global fpcversion_release global env if { $pascal_init_done == 1 } { @@ -64,6 +67,20 @@ proc pascal_init {} { set pascal_compiler_is_fpc 1 verbose -log "Free Pascal compiler found" } + + # Detect the fpc-version + if { $pascal_compiler_is_fpc == 1 } { + set fpcversion_major 1 + set fpcversion_minor 0 + set fpcversion_release 0 + set fpcversion [ remote_exec host $fpc_compiler "-iV" ] + if [regexp {.*([0-9]+)\.([0-9]+)\.([0-9]+).?} $fpcversion] { + regsub {.*([0-9]+)\.([0-9]+)\.([0-9]+).?\n?.?} $fpcversion {\1} fpcversion_major + regsub {.*([0-9]+)\.([0-9]+)\.([0-9]+).?\n?.?} $fpcversion {\2} fpcversion_minor + regsub {.*([0-9]+)\.([0-9]+)\.([0-9]+).?\n?.?} $fpcversion {\3} fpcversion_release + } + verbose -log "Freepascal version: $fpcversion_major.$fpcversion_minor.$fpcversion_release" + } } set pascal_init_done 1 } diff --git a/gdb/testsuite/lib/selftest-support.exp b/gdb/testsuite/lib/selftest-support.exp index dae5ae99b76..1cac0ec319d 100644 --- a/gdb/testsuite/lib/selftest-support.exp +++ b/gdb/testsuite/lib/selftest-support.exp @@ -151,18 +151,18 @@ proc do_self_tests {function body} { } # Remove any old copy lying around. - remote_file host delete $xgdb + #remote_file host delete $xgdb gdb_start - set file [remote_download host $GDB_FULLPATH $xgdb] + #set file [remote_download host $GDB_FULLPATH $xgdb] - set result [selftest_setup $file $function] + set result [selftest_setup $GDB_FULLPATH $function] if {$result == 0} then { set result [uplevel $body] } gdb_exit - catch "remote_file host delete $file" + #catch "remote_file host delete $file" if {$result < 0} then { warning "Couldn't test self" diff --git a/gdb/tic6x-tdep.c b/gdb/tic6x-tdep.c index 61dc676de3b..f45c7707d3f 100644 --- a/gdb/tic6x-tdep.c +++ b/gdb/tic6x-tdep.c @@ -881,7 +881,7 @@ tic6x_push_dummy_call (struct gdbarch *gdbarch, struct value *function, int argreg = 0; int argnum; int stack_offset = 4; - int references_offset = 4; + LONGEST references_offset = 4; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct type *func_type = value_type (function); /* The first arg passed on stack. Mostly the first 10 args are passed by @@ -914,7 +914,7 @@ tic6x_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Now make space on the stack for the args. */ for (argnum = 0; argnum < nargs; argnum++) { - int len = align_up (TYPE_LENGTH (value_type (args[argnum])), 4); + LONGEST len = align_up (TYPE_LENGTH (value_type (args[argnum])), 4); if (argnum >= 10 - argreg) references_offset += len; stack_offset += len; @@ -933,7 +933,7 @@ tic6x_push_dummy_call (struct gdbarch *gdbarch, struct value *function, const gdb_byte *val; struct value *arg = args[argnum]; struct type *arg_type = check_typedef (value_type (arg)); - int len = TYPE_LENGTH (arg_type); + ssize_t len = TYPE_LENGTH (arg_type); enum type_code typecode = TYPE_CODE (arg_type); val = value_contents (arg); @@ -1088,7 +1088,8 @@ tic6x_push_dummy_call (struct gdbarch *gdbarch, struct value *function, } else internal_error (__FILE__, __LINE__, - _("unexpected length %d of arg %d"), len, argnum); + _("unexpected length %s of arg %d"), + plongest (len), argnum); addr = sp + stack_offset; write_memory (addr, val, len); diff --git a/gdb/tilegx-tdep.c b/gdb/tilegx-tdep.c index 3b1954fe419..eb7aae32958 100644 --- a/gdb/tilegx-tdep.c +++ b/gdb/tilegx-tdep.c @@ -288,7 +288,7 @@ tilegx_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR stack_dest = sp; int argreg = TILEGX_R0_REGNUM; int i, j; - int typelen, slacklen; + LONGEST typelen, slacklen; static const gdb_byte four_zero_words[16] = { 0 }; /* If struct_return is 1, then the struct return address will diff --git a/gdb/top.c b/gdb/top.c index 60ca74da253..7d0d4ebd686 100644 --- a/gdb/top.c +++ b/gdb/top.c @@ -1618,7 +1618,13 @@ quit_force (int *exit_arg, int from_tty) qt.from_tty = from_tty; +#ifndef NEED_DETACH_SIGSTOP /* We want to handle any quit errors and exit regardless. */ +#else + /* We want to handle any quit errors and exit regardless but we should never + get user-interrupted to properly detach the inferior. */ + quit_flag_cleanup = 1; +#endif /* Get out of tfind mode, and kill or detach all inferiors. */ try diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c index c7585c67839..6f56ee159ac 100644 --- a/gdb/tracepoint.c +++ b/gdb/tracepoint.c @@ -893,10 +893,10 @@ collection_list::add_local_register (struct gdbarch *gdbarch, void collection_list::add_memrange (struct gdbarch *gdbarch, int type, bfd_signed_vma base, - unsigned long len, CORE_ADDR scope) + ULONGEST len, CORE_ADDR scope) { if (info_verbose) - printf_filtered ("(%d,%s,%ld)\n", type, paddress (gdbarch, base), len); + printf_filtered ("(%d,%s,%s)\n", type, paddress (gdbarch, base), pulongest (len)); /* type: memrange_absolute == memory, other n == basereg */ /* base: addr if memory, offset if reg relative. */ @@ -916,7 +916,7 @@ collection_list::collect_symbol (struct symbol *sym, CORE_ADDR scope, int trace_string) { - unsigned long len; + ULONGEST len; unsigned int reg; bfd_signed_vma offset; int treat_as_expr = 0; @@ -937,8 +937,8 @@ collection_list::collect_symbol (struct symbol *sym, offset = SYMBOL_VALUE_ADDRESS (sym); if (info_verbose) { - printf_filtered ("LOC_STATIC %s: collect %ld bytes at %s.\n", - SYMBOL_PRINT_NAME (sym), len, + printf_filtered ("LOC_STATIC %s: collect %s bytes at %s.\n", + SYMBOL_PRINT_NAME (sym), pulongest (len), paddress (gdbarch, offset)); } /* A struct may be a C++ class with static fields, go to general @@ -970,9 +970,9 @@ collection_list::collect_symbol (struct symbol *sym, offset = frame_offset + SYMBOL_VALUE (sym); if (info_verbose) { - printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset %s" + printf_filtered ("LOC_LOCAL %s: Collect %s bytes at offset %s" " from frame ptr reg %d\n", - SYMBOL_PRINT_NAME (sym), len, + SYMBOL_PRINT_NAME (sym), pulongest (len), paddress (gdbarch, offset), reg); } add_memrange (gdbarch, reg, offset, len, scope); @@ -982,9 +982,9 @@ collection_list::collect_symbol (struct symbol *sym, offset = 0; if (info_verbose) { - printf_filtered ("LOC_REGPARM_ADDR %s: Collect %ld bytes at offset %s" + printf_filtered ("LOC_REGPARM_ADDR %s: Collect %s bytes at offset %s" " from reg %d\n", - SYMBOL_PRINT_NAME (sym), len, + SYMBOL_PRINT_NAME (sym), pulongest (len), paddress (gdbarch, offset), reg); } add_memrange (gdbarch, reg, offset, len, scope); @@ -994,9 +994,9 @@ collection_list::collect_symbol (struct symbol *sym, offset = frame_offset + SYMBOL_VALUE (sym); if (info_verbose) { - printf_filtered ("LOC_LOCAL %s: Collect %ld bytes at offset %s" + printf_filtered ("LOC_LOCAL %s: Collect %s bytes at offset %s" " from frame ptr reg %d\n", - SYMBOL_PRINT_NAME (sym), len, + SYMBOL_PRINT_NAME (sym), pulongest (len), paddress (gdbarch, offset), reg); } add_memrange (gdbarch, reg, offset, len, scope); @@ -2492,7 +2492,8 @@ info_scope_command (const char *args_in, int from_tty) const char *symname; const char *save_args = args_in; struct block_iterator iter; - int j, count = 0; + int count = 0; + LONGEST j; struct gdbarch *gdbarch; int regno; const char *args = args_in; diff --git a/gdb/tracepoint.h b/gdb/tracepoint.h index ca9d2a77943..9e6250cddf8 100644 --- a/gdb/tracepoint.h +++ b/gdb/tracepoint.h @@ -269,7 +269,7 @@ class collection_list CORE_ADDR scope); void add_memrange (struct gdbarch *gdbarch, int type, bfd_signed_vma base, - unsigned long len, CORE_ADDR scope); + ULONGEST len, CORE_ADDR scope); void collect_symbol (struct symbol *sym, struct gdbarch *gdbarch, long frame_regno, long frame_offset, diff --git a/gdb/typeprint.c b/gdb/typeprint.c index 02c04514303..adb06da31af 100644 --- a/gdb/typeprint.c +++ b/gdb/typeprint.c @@ -589,6 +589,25 @@ whatis_exp (const char *exp, int show) printf_filtered (" */\n"); } + /* Resolve any dynamic target type, as we might print + additional information about the target. + For example, in Fortran and C we are printing the dimension of the + dynamic array the pointer is pointing to. */ + if (TYPE_CODE (type) == TYPE_CODE_PTR + && is_dynamic_type (type) == 1) + { + CORE_ADDR addr; + if (NULL != TYPE_DATA_LOCATION (TYPE_TARGET_TYPE(type))) + addr = value_address (val); + else + addr = value_as_address (val); + + if (addr != 0 + && type_not_associated (type) == 0) + TYPE_TARGET_TYPE (type) = resolve_dynamic_type (TYPE_TARGET_TYPE (type), + NULL, addr); + } + LA_PRINT_TYPE (type, "", gdb_stdout, show, 0, &flags); printf_filtered ("\n"); } diff --git a/gdb/utils.c b/gdb/utils.c index fa7a2674ef7..bf5f7fe6e77 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -100,6 +100,13 @@ static std::chrono::steady_clock::duration prompt_for_continue_wait_time; static int debug_timestamp = 0; +#ifdef NEED_DETACH_SIGSTOP +/* Nonzero means we are already processing the quitting cleanups and we should + no longer get aborted. */ + +int quit_flag_cleanup; +#endif + /* Nonzero means that strings with character values >0x7F should be printed as octal escapes. Zero means just print the value (e.g. it's an international character, and the terminal or window can cope.) */ @@ -692,13 +699,11 @@ malloc_failure (long size) { if (size > 0) { - internal_error (__FILE__, __LINE__, - _("virtual memory exhausted: can't allocate %ld bytes."), - size); + error (_("virtual memory exhausted: can't allocate %ld bytes."), size); } else { - internal_error (__FILE__, __LINE__, _("virtual memory exhausted.")); + error (_("virtual memory exhausted.")); } } @@ -2930,6 +2935,17 @@ string_to_core_addr (const char *my_string) return addr; } +/* Ensure that the input NUM is not larger than the maximum capacity of the + host system. We choose SIZE_MAX / 8 as a conservative estimate of the size + of a resource that a system may allocate. */ +void +ulongest_fits_host_or_error (ULONGEST num) +{ + if (num > SIZE_MAX / 8) + error (_("Insufficient memory in host GDB for object of size %s bytes, " + "maximum allowed %s bytes."), pulongest (num), + pulongest (SIZE_MAX / 8)); +} #if GDB_SELF_TEST static void diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c index 4f3cc5e9e2b..2dc7b570cdf 100644 --- a/gdb/v850-tdep.c +++ b/gdb/v850-tdep.c @@ -1019,7 +1019,7 @@ v850_push_dummy_call (struct gdbarch *gdbarch, enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int argreg; int argnum; - int arg_space = 0; + LONGEST arg_space = 0; int stack_offset; if (gdbarch_tdep (gdbarch)->abi == V850_ABI_RH850) @@ -1047,7 +1047,7 @@ v850_push_dummy_call (struct gdbarch *gdbarch, in four registers available. Loop thru args from first to last. */ for (argnum = 0; argnum < nargs; argnum++) { - int len; + LONGEST len; gdb_byte *val; gdb_byte valbuf[v850_reg_size]; diff --git a/gdb/valarith.c b/gdb/valarith.c index d59f692a4a0..2b14cff1b8f 100644 --- a/gdb/valarith.c +++ b/gdb/valarith.c @@ -182,16 +182,22 @@ value_subscript (struct value *array, LONGEST index) to doubles, but no longer does. */ struct value * -value_subscripted_rvalue (struct value *array, LONGEST index, int lowerbound) +value_subscripted_rvalue (struct value *array, LONGEST index, LONGEST lowerbound) { struct type *array_type = check_typedef (value_type (array)); struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type)); ULONGEST elt_size = type_length_units (elt_type); - ULONGEST elt_offs = elt_size * (index - lowerbound); + LONGEST elt_offs = index - lowerbound; + LONGEST elt_stride = TYPE_BYTE_STRIDE (TYPE_INDEX_TYPE (array_type)); + + if (elt_stride != 0) + elt_offs *= elt_stride; + else + elt_offs *= elt_size; if (index < lowerbound || (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type) - && elt_offs >= type_length_units (array_type)) + && abs (elt_offs) >= type_length_units (array_type)) || (VALUE_LVAL (array) != lval_memory && TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type))) { @@ -650,7 +656,7 @@ value_concat (struct value *arg1, struct value *arg2) struct value *inval1; struct value *inval2; struct value *outval = NULL; - int inval1len, inval2len; + ssize_t inval1len, inval2len; int count, idx; char inchar; struct type *type1 = check_typedef (value_type (arg1)); @@ -1410,7 +1416,7 @@ value_binop (struct value *arg1, struct value *arg2, enum exp_opcode op) int value_logical_not (struct value *arg1) { - int len; + LONGEST len; const gdb_byte *p; struct type *type1; @@ -1438,11 +1444,11 @@ value_logical_not (struct value *arg1) static int value_strcmp (struct value *arg1, struct value *arg2) { - int len1 = TYPE_LENGTH (value_type (arg1)); - int len2 = TYPE_LENGTH (value_type (arg2)); + LONGEST len1 = TYPE_LENGTH (value_type (arg1)); + LONGEST len2 = TYPE_LENGTH (value_type (arg2)); const gdb_byte *s1 = value_contents (arg1); const gdb_byte *s2 = value_contents (arg2); - int i, len = len1 < len2 ? len1 : len2; + LONGEST i, len = len1 < len2 ? len1 : len2; for (i = 0; i < len; i++) { diff --git a/gdb/valops.c b/gdb/valops.c index fd92a4d1655..eaa4c523531 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -81,7 +81,7 @@ static enum oload_classification classify_oload_match (const badness_vector &, int, int); static struct value *value_struct_elt_for_reference (struct type *, - int, struct type *, + LONGEST, struct type *, const char *, struct type *, int, enum noside); @@ -171,7 +171,7 @@ find_function_in_inferior (const char *name, struct objfile **objf_p) space. */ struct value * -value_allocate_space_in_inferior (int len) +value_allocate_space_in_inferior (LONGEST len) { struct objfile *objf; struct value *val = find_function_in_inferior ("malloc", &objf); @@ -386,12 +386,12 @@ value_cast (struct type *type, struct value *arg2) if (code1 == TYPE_CODE_ARRAY) { struct type *element_type = TYPE_TARGET_TYPE (type); - unsigned element_length = TYPE_LENGTH (check_typedef (element_type)); + ULONGEST element_length = TYPE_LENGTH (check_typedef (element_type)); if (element_length > 0 && TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (type)) { struct type *range_type = TYPE_INDEX_TYPE (type); - int val_length = TYPE_LENGTH (type2); + LONGEST val_length = TYPE_LENGTH (type2); LONGEST low_bound, high_bound, new_length; if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0) @@ -1043,7 +1043,7 @@ value_assign (struct value *toval, struct value *fromval) { const gdb_byte *dest_buffer; CORE_ADDR changed_addr; - int changed_len; + LONGEST changed_len; gdb_byte buffer[sizeof (LONGEST)]; if (value_bitsize (toval)) @@ -1092,6 +1092,8 @@ value_assign (struct value *toval, struct value *fromval) struct gdbarch *gdbarch; int value_reg; + value_reg = VALUE_REGNUM (toval); + /* Figure out which frame this is in currently. We use VALUE_FRAME_ID for obtaining the value's frame id instead of @@ -1101,8 +1103,14 @@ value_assign (struct value *toval, struct value *fromval) frame. */ frame = frame_find_by_id (VALUE_FRAME_ID (toval)); - value_reg = VALUE_REGNUM (toval); - + /* "set $reg+=1" should work on programs with no debug info, + but frame_find_by_id returns NULL here (RH bug 436037). + Use current frame, it represents CPU state in this case. + If frame_find_by_id is changed to do it internally + (it is contemplated there), remove this. */ + if (!frame) + frame = get_current_frame (); + /* Probably never happens. */ if (!frame) error (_("Value being assigned to is no longer active.")); @@ -1553,6 +1561,19 @@ value_ind (struct value *arg1) if (TYPE_CODE (base_type) == TYPE_CODE_PTR) { struct type *enc_type; + CORE_ADDR addr; + + if (type_not_associated (base_type)) + error (_("Attempt to take contents of a not associated pointer.")); + + if (NULL != TYPE_DATA_LOCATION (TYPE_TARGET_TYPE (base_type))) + addr = value_address (arg1); + else + addr = value_as_address (arg1); + + if (addr != 0) + TYPE_TARGET_TYPE (base_type) = + resolve_dynamic_type (TYPE_TARGET_TYPE (base_type), NULL, addr); /* We may be pointing to something embedded in a larger object. Get the real type of the enclosing object. */ @@ -1568,8 +1589,7 @@ value_ind (struct value *arg1) else /* Retrieve the enclosing object pointed to. */ arg2 = value_at_lazy (enc_type, - (value_as_address (arg1) - - value_pointed_to_offset (arg1))); + (addr - value_pointed_to_offset (arg1))); enc_type = value_type (arg2); return readjust_indirect_value_type (arg2, enc_type, base_type, arg1); @@ -2044,6 +2064,7 @@ search_struct_method (const char *name, struct value **arg1p, { CORE_ADDR address; + ulongest_fits_host_or_error (TYPE_LENGTH (baseclass)); gdb::byte_vector tmp (TYPE_LENGTH (baseclass)); address = value_address (*arg1p); @@ -3315,7 +3336,7 @@ get_baseclass_offset (struct type *vt, struct type *cls, the form "DOMAIN::NAME". */ static struct value * -value_struct_elt_for_reference (struct type *domain, int offset, +value_struct_elt_for_reference (struct type *domain, LONGEST offset, struct type *curtype, const char *name, struct type *intype, int want_address, @@ -3349,7 +3370,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, if (want_address) return value_from_longest (lookup_memberptr_type (TYPE_FIELD_TYPE (t, i), domain), - offset + (LONGEST) (TYPE_FIELD_BITPOS (t, i) >> 3)); + offset + (TYPE_FIELD_BITPOS (t, i) >> 3)); else if (noside != EVAL_NORMAL) return allocate_value (TYPE_FIELD_TYPE (t, i)); else @@ -3528,7 +3549,7 @@ value_struct_elt_for_reference (struct type *domain, int offset, for (i = TYPE_N_BASECLASSES (t) - 1; i >= 0; i--) { struct value *v; - int base_offset; + LONGEST base_offset; if (BASETYPE_VIA_VIRTUAL (t, i)) base_offset = 0; @@ -3676,7 +3697,7 @@ value_rtti_indirect_type (struct value *v, int *full, struct value * value_full_object (struct value *argp, struct type *rtype, - int xfull, int xtop, + int xfull, LONGEST xtop, int xusing_enc) { struct type *real_type; @@ -3790,56 +3811,195 @@ value_of_this_silent (const struct language_defn *lang) struct value * value_slice (struct value *array, int lowbound, int length) +{ + /* Pass unaltered arguments to VALUE_SLICE_1, plus a default stride + value of '1', which returns every element between LOWBOUND and + (LOWBOUND + LENGTH). We also provide a default CALL_COUNT of '1' + as we are only considering the highest dimension, or we are + working on a one dimensional array. So we call VALUE_SLICE_1 + exactly once. */ + return value_slice_1 (array, lowbound, length, 1, 1); +} + +/* VALUE_SLICE_1 is called for each array dimension to calculate the number + of elements as defined by the subscript expression. + CALL_COUNT is used to determine if we are calling the function once, e.g. + we are working on the current dimension of ARRAY, or if we are calling + the function repeatedly. In the later case we need to take elements + from the TARGET_TYPE of ARRAY. + With a CALL_COUNT greater than 1 we calculate the offsets for every element + that should be in the result array. Then we fetch the contents and then + copy them into the result array. The result array will have one dimension + less than the input array, so later on we need to recreate the indices and + ranges in the calling function. */ + +struct value * +value_slice_1 (struct value *array, int lowbound, int length, + int stride_length, int call_count) { struct type *slice_range_type, *slice_type, *range_type; - LONGEST lowerbound, upperbound; - struct value *slice; - struct type *array_type; + struct type *array_type = check_typedef (value_type (array)); + struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type)); + unsigned int elt_size, elt_offs; + LONGEST ary_high_bound, ary_low_bound; + struct value *v; + int slice_range_size, i = 0, row_count = 1, elem_count = 1; - array_type = check_typedef (value_type (array)); + /* Check for legacy code if we are actually dealing with an array or + string. */ if (TYPE_CODE (array_type) != TYPE_CODE_ARRAY && TYPE_CODE (array_type) != TYPE_CODE_STRING) error (_("cannot take slice of non-array")); - range_type = TYPE_INDEX_TYPE (array_type); - if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0) - error (_("slice from bad array or bitstring")); + ary_low_bound = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (array_type)); + ary_high_bound = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (array_type)); + + /* When we are working on a multi-dimensional array, we need to get the + attributes of the underlying type. */ + if (call_count > 1) + { + ary_low_bound = TYPE_LOW_BOUND (TYPE_INDEX_TYPE (elt_type)); + ary_high_bound = TYPE_HIGH_BOUND (TYPE_INDEX_TYPE (elt_type)); + elt_type = check_typedef (TYPE_TARGET_TYPE (elt_type)); + row_count = TYPE_LENGTH (array_type) + / TYPE_LENGTH (TYPE_TARGET_TYPE (array_type)); + } + + /* With a stride of '1', the number of elements per result row is equal to + the LENGTH of the subarray. With non-default stride values, we skip + elements, but have to add the start element to the total number of + elements per row. */ + if (stride_length == 1) + elem_count = length; + else + elem_count = ((length - 1) / stride_length) + 1; + + elt_size = TYPE_LENGTH (elt_type); + elt_offs = lowbound - ary_low_bound; - if (lowbound < lowerbound || length < 0 - || lowbound + length - 1 > upperbound) - error (_("slice out of range")); + elt_offs *= elt_size; + + /* Check for valid user input. In case of Fortran this was already done + in the calling function. */ + if (call_count == 1 + && (!TYPE_ARRAY_UPPER_BOUND_IS_UNDEFINED (array_type) + && elt_offs >= TYPE_LENGTH (array_type))) + error (_("no such vector element")); + + /* CALL_COUNT is 1 when we are dealing either with the highest dimension + of the array, or a one dimensional array. Set RANGE_TYPE accordingly. + In both cases we calculate how many rows/elements will be in the output + array by setting slice_range_size. */ + if (call_count == 1) + { + range_type = TYPE_INDEX_TYPE (array_type); + slice_range_size = ary_low_bound + elem_count - 1; + + /* Check if the array bounds are valid. */ + if (get_discrete_bounds (range_type, &ary_low_bound, &ary_high_bound) < 0) + error (_("slice from bad array or bitstring")); + } + /* When CALL_COUNT is greater than 1, we are dealing with an array of arrays. + So we need to get the type below the current one and set the RANGE_TYPE + accordingly. */ + else + { + range_type = TYPE_INDEX_TYPE (TYPE_TARGET_TYPE (array_type)); + slice_range_size = ary_low_bound + (row_count * elem_count) - 1; + ary_low_bound = TYPE_LOW_BOUND (range_type); + } /* FIXME-type-allocation: need a way to free this type when we are - done with it. */ - slice_range_type = create_static_range_type ((struct type *) NULL, - TYPE_TARGET_TYPE (range_type), - lowbound, - lowbound + length - 1); + done with it. */ + slice_range_type = create_static_range_type (NULL, TYPE_TARGET_TYPE (range_type), + ary_low_bound, slice_range_size); { - struct type *element_type = TYPE_TARGET_TYPE (array_type); - LONGEST offset - = (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type)); + struct type *element_type; + + /* When both CALL_COUNT and STRIDE_LENGTH equal 1, we can use the legacy + code for subarrays. */ + if (call_count == 1 && stride_length == 1) + { + element_type = TYPE_TARGET_TYPE (array_type); + + slice_type = create_array_type (NULL, element_type, slice_range_type); - slice_type = create_array_type ((struct type *) NULL, - element_type, - slice_range_type); - TYPE_CODE (slice_type) = TYPE_CODE (array_type); + TYPE_CODE (slice_type) = TYPE_CODE (array_type); + + if (VALUE_LVAL (array) == lval_memory && value_lazy (array)) + v = allocate_value_lazy (slice_type); + else + { + v = allocate_value (slice_type); + value_contents_copy (v, + value_embedded_offset (v), + array, + value_embedded_offset (array) + elt_offs, + elt_size * longest_to_int (length)); + } - if (VALUE_LVAL (array) == lval_memory && value_lazy (array)) - slice = allocate_value_lazy (slice_type); + } + /* With a CALL_COUNT or STRIDE_LENGTH are greater than 1 we are working + on a range of ranges. So we copy the relevant elements into the + new array we return. */ else { - slice = allocate_value (slice_type); - value_contents_copy (slice, 0, array, offset, - type_length_units (slice_type)); + int j, offs_store = elt_offs; + LONGEST dst_offset = 0; + LONGEST src_row_length = TYPE_LENGTH (TYPE_TARGET_TYPE (array_type)); + + if (call_count == 1) + { + /* When CALL_COUNT is equal to 1 we are working on the current range + and use these elements directly. */ + element_type = TYPE_TARGET_TYPE (array_type); + } + else + { + /* Working on an array of arrays, the type of the elements is the type + of the subarrays' type. */ + element_type = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (array_type)); + } + + slice_type = create_array_type (NULL, element_type, slice_range_type); + + /* If we have a one dimensional array, we copy its TYPE_CODE. For a + multi dimensional array we copy the embedded type's TYPE_CODE. */ + if (call_count == 1) + TYPE_CODE (slice_type) = TYPE_CODE (array_type); + else + TYPE_CODE (slice_type) = TYPE_CODE (TYPE_TARGET_TYPE (array_type)); + + v = allocate_value (slice_type); + + /* Iterate through the rows of the outer array and set the new offset + for each row. */ + for (i = 0; i < row_count; i++) + { + elt_offs = offs_store + i * src_row_length; + + /* Iterate through the elements in each row to copy only those. */ + for (j = 1; j <= elem_count; j++) + { + /* Fetches the contents of ARRAY and copies them into V. */ + value_contents_copy (v, dst_offset, array, elt_offs, elt_size); + elt_offs += elt_size * stride_length; + dst_offset += elt_size; + } + } } - set_value_component_location (slice, array); - set_value_offset (slice, value_offset (array) + offset); + set_value_component_location (v, array); + if (VALUE_LVAL (v) == lval_register) + { + VALUE_REGNUM (v) = VALUE_REGNUM (array); + VALUE_NEXT_FRAME_ID (v) = VALUE_NEXT_FRAME_ID (array); + } + set_value_offset (v, value_offset (array) + elt_offs); } - return slice; + return v; } /* Create a value for a FORTRAN complex number. Currently most of the diff --git a/gdb/valprint.c b/gdb/valprint.c index b02ebf6c272..c1c6d97203d 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -879,7 +879,7 @@ generic_val_print_complex (struct type *type, void generic_val_print (struct type *type, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *original_value, const struct value_print_options *options, @@ -1105,12 +1105,6 @@ value_check_printable (struct value *val, struct ui_file *stream, return 0; } - if (type_not_associated (value_type (val))) - { - val_print_not_associated (stream); - return 0; - } - if (type_not_allocated (value_type (val))) { val_print_not_allocated (stream); @@ -1777,7 +1771,7 @@ print_decimal_chars (struct ui_file *stream, const gdb_byte *valaddr, void print_hex_chars (struct ui_file *stream, const gdb_byte *valaddr, - unsigned len, enum bfd_endian byte_order, + ULONGEST len, enum bfd_endian byte_order, bool zero_pad) { const gdb_byte *p; @@ -1930,17 +1924,17 @@ val_print_array_elements (struct type *type, int recurse, struct value *val, const struct value_print_options *options, - unsigned int i) + ULONGEST i) { unsigned int things_printed = 0; - unsigned len; + ULONGEST len; struct type *elttype, *index_type, *base_index_type; - unsigned eltlen; + ULONGEST eltlen; /* Position of the array element we are examining to see whether it is repeated. */ - unsigned int rep1; + ULONGEST rep1; /* Number of repetitions we have detected so far. */ - unsigned int reps; + ULONGEST reps; LONGEST low_bound, high_bound; LONGEST low_pos, high_pos; @@ -2030,7 +2024,7 @@ val_print_array_elements (struct type *type, address, stream, recurse + 1, val, options, current_language); annotate_elt_rep (reps); - fprintf_filtered (stream, " ", reps); + fprintf_filtered (stream, " ", pulongest (reps)); annotate_elt_rep_end (); i = rep1 - 1; @@ -2672,7 +2666,7 @@ print_converted_chars_to_obstack (struct obstack *obstack, void generic_printstr (struct ui_file *stream, struct type *type, - const gdb_byte *string, unsigned int length, + const gdb_byte *string, ULONGEST length, const char *encoding, int force_ellipses, int quote_char, int c_style_terminator, const struct value_print_options *options) diff --git a/gdb/valprint.h b/gdb/valprint.h index db99b52b2ad..3364c8f51e1 100644 --- a/gdb/valprint.h +++ b/gdb/valprint.h @@ -119,7 +119,7 @@ extern void val_print_array_elements (struct type *, LONGEST, CORE_ADDR, struct ui_file *, int, struct value *, const struct value_print_options *, - unsigned int); + ULONGEST); extern void val_print_scalar_formatted (struct type *, LONGEST, @@ -138,7 +138,7 @@ extern void print_decimal_chars (struct ui_file *, const gdb_byte *, unsigned int, bool, enum bfd_endian); extern void print_hex_chars (struct ui_file *, const gdb_byte *, - unsigned int, enum bfd_endian, bool); + ULONGEST, enum bfd_endian, bool); extern void print_char_chars (struct ui_file *, struct type *, const gdb_byte *, unsigned int, enum bfd_endian); @@ -192,7 +192,7 @@ struct generic_val_print_decorations extern void generic_val_print (struct type *type, - int embedded_offset, CORE_ADDR address, + LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *original_value, const struct value_print_options *options, @@ -202,7 +202,7 @@ extern void generic_emit_char (int c, struct type *type, struct ui_file *stream, int quoter, const char *encoding); extern void generic_printstr (struct ui_file *stream, struct type *type, - const gdb_byte *string, unsigned int length, + const gdb_byte *string, ULONGEST length, const char *encoding, int force_ellipses, int quote_char, int c_style_terminator, const struct value_print_options *options); diff --git a/gdb/value.c b/gdb/value.c index dad9f07b68e..b3edada5814 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -383,7 +383,8 @@ value_bytes_available (const struct value *value, } int -value_bits_any_optimized_out (const struct value *value, int bit_offset, int bit_length) +value_bits_any_optimized_out (const struct value *value, LONGEST bit_offset, + LONGEST bit_length) { gdb_assert (!value->lazy); @@ -831,8 +832,8 @@ find_first_range_overlap_and_match (struct ranges_and_idx *rp1, Return true if the available bits match. */ static bool -value_contents_bits_eq (const struct value *val1, int offset1, - const struct value *val2, int offset2, +value_contents_bits_eq (const struct value *val1, LONGEST offset1, + const struct value *val2, LONGEST offset2, int length) { /* Each array element corresponds to a ranges source (unavailable, @@ -932,6 +933,7 @@ allocate_value_lazy (struct type *type) description correctly. */ check_typedef (type); + ulongest_fits_host_or_error (TYPE_LENGTH (type)); val = new struct value (type); /* Values start out on the all_values chain. */ @@ -1014,6 +1016,8 @@ check_type_length_before_alloc (const struct type *type) static void allocate_value_contents (struct value *val) { + ulongest_fits_host_or_error (TYPE_LENGTH (val->enclosing_type)); + if (!val->contents) { check_type_length_before_alloc (val->enclosing_type); @@ -1422,7 +1426,8 @@ value_optimized_out (struct value *value) the following LENGTH bytes. */ void -mark_value_bytes_optimized_out (struct value *value, int offset, int length) +mark_value_bytes_optimized_out (struct value *value, LONGEST offset, + LONGEST length) { mark_value_bits_optimized_out (value, offset * TARGET_CHAR_BIT, @@ -2825,7 +2830,8 @@ value_static_field (struct type *type, int fieldno) { case FIELD_LOC_KIND_PHYSADDR: retval = value_at_lazy (TYPE_FIELD_TYPE (type, fieldno), - TYPE_FIELD_STATIC_PHYSADDR (type, fieldno)); + TYPE_FIELD_STATIC_PHYSADDR (type, fieldno) + + (TYPE_OBJFILE (type) == NULL ? 0 : ANOFFSET (TYPE_OBJFILE (type)->section_offsets, SECT_OFF_TEXT (TYPE_OBJFILE (type))))); break; case FIELD_LOC_KIND_PHYSNAME: { @@ -2869,6 +2875,7 @@ set_value_enclosing_type (struct value *val, struct type *new_encl_type) if (TYPE_LENGTH (new_encl_type) > TYPE_LENGTH (value_enclosing_type (val))) { check_type_length_before_alloc (new_encl_type); + ulongest_fits_host_or_error (TYPE_LENGTH (new_encl_type)); val->contents .reset ((gdb_byte *) xrealloc (val->contents.release (), TYPE_LENGTH (new_encl_type))); diff --git a/gdb/value.h b/gdb/value.h index 0756d13b6d7..1fc66cb2f7c 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -274,7 +274,7 @@ struct lval_funcs /* If non-NULL, this is used to determine whether the indicated bits of VALUE are a synthetic pointer. */ int (*check_synthetic_pointer) (const struct value *value, - LONGEST offset, int length); + LONGEST offset, LONGEST length); /* Return a duplicate of VALUE's closure, for use in a new value. This may simply return the same closure, if VALUE's is @@ -405,7 +405,8 @@ extern int value_optimized_out (struct value *value); otherwise. */ extern int value_bits_any_optimized_out (const struct value *value, - int bit_offset, int bit_length); + LONGEST bit_offset, + LONGEST bit_length); /* Like value_optimized_out, but return true iff the whole value is optimized out. */ @@ -415,7 +416,7 @@ extern int value_entirely_optimized_out (struct value *value); LENGTH bytes as optimized out. */ extern void mark_value_bytes_optimized_out (struct value *value, - int offset, int length); + LONGEST offset, LONGEST length); /* Mark VALUE's content bits starting at OFFSET and extending for LENGTH bits as optimized out. */ @@ -850,12 +851,11 @@ extern struct value *value_primitive_field (struct value *arg1, LONGEST offset, int fieldno, struct type *arg_type); - extern struct type *value_rtti_indirect_type (struct value *, int *, LONGEST *, int *); extern struct value *value_full_object (struct value *, struct type *, int, - int, int); + LONGEST, int); extern struct value *value_cast_pointers (struct type *, struct value *, int); @@ -1140,16 +1140,19 @@ extern struct value *varying_to_slice (struct value *); extern struct value *value_slice (struct value *, int, int); +extern struct value *value_slice_1 (struct value *, int, int, int, int); + extern struct value *value_literal_complex (struct value *, struct value *, struct type *); extern struct value *find_function_in_inferior (const char *, struct objfile **); -extern struct value *value_allocate_space_in_inferior (int); +extern struct value *value_allocate_space_in_inferior (LONGEST); extern struct value *value_subscripted_rvalue (struct value *array, - LONGEST index, int lowerbound); + LONGEST index, + LONGEST lowerbound); /* User function handler. */ diff --git a/gdb/vax-tdep.c b/gdb/vax-tdep.c index 6046c0e98b4..6971866ea2a 100644 --- a/gdb/vax-tdep.c +++ b/gdb/vax-tdep.c @@ -110,7 +110,7 @@ vax_store_arguments (struct regcache *regcache, int nargs, struct gdbarch *gdbarch = regcache->arch (); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_byte buf[4]; - int count = 0; + LONGEST count = 0; int i; /* We create an argument list on the stack, and make the argument @@ -119,7 +119,7 @@ vax_store_arguments (struct regcache *regcache, int nargs, /* Push arguments in reverse order. */ for (i = nargs - 1; i >= 0; i--) { - int len = TYPE_LENGTH (value_enclosing_type (args[i])); + LONGEST len = TYPE_LENGTH (value_enclosing_type (args[i])); sp -= (len + 3) & ~3; count += (len + 3) / 4; @@ -219,6 +219,7 @@ vax_return_value (struct gdbarch *gdbarch, struct value *function, ULONGEST addr; regcache_raw_read_unsigned (regcache, VAX_R0_REGNUM, &addr); + ulongest_fits_host_or_error (TYPE_LENGTH (type)); read_memory (addr, readbuf, len); } diff --git a/gdb/x86-nat.c b/gdb/x86-nat.c index cd9ce17e8dc..32354519454 100644 --- a/gdb/x86-nat.c +++ b/gdb/x86-nat.c @@ -173,7 +173,7 @@ x86_remove_watchpoint (CORE_ADDR addr, int len, address ADDR and whose length is LEN bytes. */ int -x86_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) +x86_region_ok_for_hw_watchpoint (CORE_ADDR addr, LONGEST len) { struct x86_debug_reg_state *state = x86_debug_reg_state (inferior_ptid.pid ()); diff --git a/gdb/x86-nat.h b/gdb/x86-nat.h index baa4218a87b..867a72d417a 100644 --- a/gdb/x86-nat.h +++ b/gdb/x86-nat.h @@ -49,7 +49,7 @@ extern void x86_forget_process (pid_t pid); definitions. */ extern int x86_can_use_hw_breakpoint (enum bptype type, int cnt, int othertype); -extern int x86_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len); +extern int x86_region_ok_for_hw_watchpoint (CORE_ADDR addr, LONGEST len); extern int x86_stopped_by_watchpoint (); extern int x86_stopped_data_address (CORE_ADDR *addr_p); extern int x86_insert_watchpoint (CORE_ADDR addr, int len, @@ -75,7 +75,7 @@ struct x86_nat_target : public BaseTarget int can_use_hw_breakpoint (enum bptype type, int cnt, int othertype) override { return x86_can_use_hw_breakpoint (type, cnt, othertype); } - int region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) override + int region_ok_for_hw_watchpoint (CORE_ADDR addr, LONGEST len) override { return x86_region_ok_for_hw_watchpoint (addr, len); } int insert_watchpoint (CORE_ADDR addr, int len, diff --git a/gdb/xstormy16-tdep.c b/gdb/xstormy16-tdep.c index 49c72e231c5..0e4408414f4 100644 --- a/gdb/xstormy16-tdep.c +++ b/gdb/xstormy16-tdep.c @@ -233,8 +233,9 @@ xstormy16_push_dummy_call (struct gdbarch *gdbarch, enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR stack_dest = sp; int argreg = E_1ST_ARG_REGNUM; - int i, j; - int typelen, slacklen; + int i, slacklen; + LONGEST j; + LONGEST typelen; gdb_byte buf[xstormy16_pc_size]; /* If returning a struct using target ABI method, then the struct return diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c index efa0bcb1dc3..424829435c3 100644 --- a/gdb/xtensa-tdep.c +++ b/gdb/xtensa-tdep.c @@ -1689,18 +1689,18 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR struct_addr) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); - int size, onstack_size; + LONGEST size, onstack_size; gdb_byte *buf = (gdb_byte *) alloca (16); CORE_ADDR ra, ps; struct argument_info { const bfd_byte *contents; - int length; + ssize_t length; int onstack; /* onstack == 0 => in reg */ int align; /* alignment */ union { - int offset; /* stack offset if on stack. */ + ssize_t offset; /* stack offset if on stack. */ int regno; /* regno if in register. */ } u; }; @@ -1794,8 +1794,8 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch, info->align = TYPE_LENGTH (builtin_type (gdbarch)->builtin_long); break; } - info->length = TYPE_LENGTH (arg_type); info->contents = value_contents (arg); + info->length = TYPE_LENGTH (arg_type); /* Align size and onstack_size. */ size = (size + info->align - 1) & ~(info->align - 1); @@ -1840,7 +1840,7 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch, if (info->onstack) { - int n = info->length; + ssize_t n = info->length; CORE_ADDR offset = sp + info->u.offset; /* Odd-sized structs are aligned to the lower side of a memory @@ -1856,7 +1856,7 @@ xtensa_push_dummy_call (struct gdbarch *gdbarch, } else { - int n = info->length; + ssize_t n = info->length; const bfd_byte *cp = info->contents; int r = info->u.regno;