Fully redone gdb-7.6.patch to gdb-10.1.patch to keep all
functionality. Changes which were dropped are saved in
dropped-gdb-7.6-to-10.1.patch
Main difference between gdb-7.6 and gdb-10.1 is the last
one was rewritten in C++.
I continue to keep crash code in C. Mark transition
functions as extern "C" to resolve linking issues.
Eliminated error_hook() and SJLJ while running in C++ code
(after gdb_command_funnel()) use try-catch mechanism instead.
request_types() was redone to do not call
GNU_GET_NEXT_DATATYPE multiple times but single usage of
GNU_ITERATE_DATATYPES with proper callback instead.
Complete iteration happens on C++ side now.
Removed "struct global_iterator" from request structure,
but added several fields (including callback pointer) to
be able to perform iteration on C++ side.
Type of "linux_banner" symbol is reported as 'D' by new
gdb as its section ".rodata" marked as writable in vmlinux.
BFD API has changed.
deprecated_command_loop_hook got deprecated. So, call crash
main_loop() directly from gdb captured_main().
Added symbol file (vmlinux) rebase in gdb by kaslr_offset.
Added crash_target for gdb to provide target operations
such as xfer_partial to read and write crash dump memory.
Removed previously used hooks for that in target.c.
Keep crash_target.c as a file in crash folder instead of
in gdb-10.1.patch for easier development and history
tracking.
crash_target can be enhanced in future to provide access
to CPU registers, so backtrace and frame related commands
from gdb can be used.
Removed gdb-7.6-proc_service.h.patch is not required as
gdb-10.1 already has this change.
TODO:
1) gdb-10.1-ppc64le-support.patch has to be updated with
following commits.
2) deprecate #if defined(GDB_X_Y) code as crash really
supports only the latest gdb (only one patch).
3) move gdb_funnel_command() and subfunctions to separate
file, similar to crash_target.c
Signed-off-by: Alexey Makhalov <amakhalov(a)vmware.com>
---
Makefile | 13 +-
configure.c | 20 +-
crash_target.c | 104 +
defs.h | 27 +-
dropped-gdb-7.6-to-10.1.patch | 303 +++
...support.patch => gdb-10.1-ppc64le-support.patch | 0
gdb-10.1.patch | 1577 ++++++++++++
gdb-7.6-proc_service.h.patch | 67 -
gdb-7.6.patch | 2503 --------------------
gdb_interface.c | 64 +-
kernel.c | 2 +-
main.c | 1 -
symbols.c | 125 +-
x86_64.c | 2 +-
14 files changed, 2115 insertions(+), 2693 deletions(-)
create mode 100644 crash_target.c
create mode 100644 dropped-gdb-7.6-to-10.1.patch
rename gdb-7.6-ppc64le-support.patch => gdb-10.1-ppc64le-support.patch (100%)
create mode 100644 gdb-10.1.patch
delete mode 100644 gdb-7.6-proc_service.h.patch
delete mode 100644 gdb-7.6.patch
diff --git a/Makefile b/Makefile
index d185719..3e8e3eb 100644
--- a/Makefile
+++ b/Makefile
@@ -180,6 +180,9 @@ GDB_7.3.1_OFILES=${GDB}/gdb/symtab.o
GDB_7.6_FILES=
GDB_7.6_OFILES=${GDB}/gdb/symtab.o
+GDB_10.1_FILES=
+GDB_10.1_OFILES=${GDB}/gdb/symtab.o
+
#
# GDB_FLAGS is passed up from the gdb Makefile.
#
@@ -192,7 +195,7 @@ GDB_FLAGS=
# usefulness is also dependent upon the processor's compiler -- your mileage
# may vary.
#
-#WARNING_OPTIONS=-Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector
-Wformat-security
+WARNING_OPTIONS=-Wall -O2 -Wstrict-prototypes -Wmissing-prototypes -fstack-protector
-Wformat-security
#WARNING_ERROR=-Werror
# TARGET_CFLAGS will be configured automatically by configure
@@ -205,7 +208,7 @@ TAR_FILES=${SOURCE_FILES} Makefile ${GPL_FILES} README .rh_rpm_package
crash.8 \
${EXTENSION_SOURCE_FILES} ${MEMORY_DRIVER_FILES}
CSCOPE_FILES=${SOURCE_FILES}
-READLINE_DIRECTORY=./${GDB}/readline
+READLINE_DIRECTORY=./${GDB}/readline/readline
BFD_DIRECTORY=./${GDB}/bfd
GDB_INCLUDE_DIRECTORY=./${GDB}/include
@@ -269,12 +272,6 @@ gdb_patch:
if [ "${ARCH}" = "x86_64" ] && [ "${TARGET}" =
"PPC64" ] && [ -f ${GDB}-ppc64le-support.patch ]; then \
patch -d ${GDB} -p1 -F0 < ${GDB}-ppc64le-support.patch ; \
fi
- if [ -f /usr/include/proc_service.h ]; then \
- grep 'extern ps_err_e ps_get_thread_area (struct' /usr/include/proc_service.h;
\
- if [ $$? -eq 0 ]; then \
- patch -p0 < ${GDB}-proc_service.h.patch; \
- fi; \
- fi
library: make_build_data ${OBJECT_FILES}
ar -rs ${PROGRAM}lib.a ${OBJECT_FILES}
diff --git a/configure.c b/configure.c
index 7f6d19e..9fe22a9 100644
--- a/configure.c
+++ b/configure.c
@@ -177,9 +177,10 @@ void add_extra_lib(char *);
#define GDB_7_0 (3)
#define GDB_7_3_1 (4)
#define GDB_7_6 (5)
-#define SUPPORTED_GDB_VERSIONS (GDB_7_6 + 1)
+#define GDB_10_1 (6)
+#define SUPPORTED_GDB_VERSIONS (GDB_10_1 + 1)
-int default_gdb = GDB_7_6;
+int default_gdb = GDB_10_1;
struct supported_gdb_version {
char *GDB;
@@ -244,6 +245,15 @@ struct supported_gdb_version {
"GDB_FLAGS=-DGDB_7_6",
"GPLv3"
},
+ {
+ "GDB=gdb-10.1",
+ "10.1",
+ "GDB_FILES=${GDB_10.1_FILES}",
+ "GDB_OFILES=${GDB_10.1_OFILES}",
+ "GDB_PATCH_FILES=gdb-10.1.patch gdb-10.1-ppc64le-support.patch",
+ "GDB_FLAGS=-DGDB_10_1",
+ "GPLv3"
+ },
};
#define DAEMON 0x1
@@ -1494,6 +1504,12 @@ setup_gdb_defaults(void)
fprintf(stderr, ".gdb configuration: %s\n", sp->GDB_VERSION_IN);
return store_gdb_defaults(sp);
}
+ if (strcmp(buf, "10.1") == 0) {
+ fclose(fp);
+ sp = &supported_gdb_versions[GDB_10_1];
+ fprintf(stderr, ".gdb configuration: %s\n", sp->GDB_VERSION_IN);
+ return store_gdb_defaults(sp);
+ }
}
diff --git a/crash_target.c b/crash_target.c
new file mode 100644
index 0000000..f26dcf2
--- /dev/null
+++ b/crash_target.c
@@ -0,0 +1,104 @@
+/*
+ * crash_target.c
+ *
+ * Copyright (c) 2020 VMware, 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.
+ *
+ * Author: Alexey Makhalov <amakhalov(a)vmware.com>
+ */
+
+#include <defs.h>
+#include "top.h"
+#include "target.h"
+#include "inferior.h"
+#include "regcache.h"
+#include "gdbarch.h"
+
+void crash_target_init (void);
+
+extern "C" int gdb_readmem_callback(unsigned long, void *, int, int);
+extern "C" int crash_get_nr_cpus(void);
+
+
+/* The crash target. */
+
+static const target_info crash_target_info = {
+ "crash",
+ N_("Local core dump file"),
+ N_("Use a built-in crash instance as a target.")
+};
+
+class crash_target final : public process_stratum_target
+{
+public:
+
+ const target_info &info () const override
+ { return crash_target_info; }
+
+ enum target_xfer_status xfer_partial (enum target_object object,
+ const char *annex,
+ gdb_byte *readbuf,
+ const gdb_byte *writebuf,
+ ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len) override;
+
+ bool has_all_memory () override { return true; }
+ bool has_memory () override { return true; }
+ bool has_stack () override { return true; }
+ bool has_registers () override { return false; }
+ bool thread_alive (ptid_t ptid) override { return true; }
+ std::string pid_to_str (ptid_t ptid) override
+ { return string_printf ("CPU %ld", ptid.tid ()); }
+
+};
+
+
+enum target_xfer_status
+crash_target::xfer_partial (enum target_object object, const char *annex,
+ gdb_byte *readbuf, const gdb_byte *writebuf,
+ ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
+{
+ if (object != TARGET_OBJECT_MEMORY && object != TARGET_OBJECT_STACK_MEMORY
+ && object != TARGET_OBJECT_CODE_MEMORY)
+ return TARGET_XFER_E_IO;
+
+ if (gdb_readmem_callback(offset, (void *)(readbuf ? readbuf : writebuf), len,
!readbuf))
+ {
+ *xfered_len = len;
+ return TARGET_XFER_OK;
+ }
+
+ return TARGET_XFER_E_IO;
+}
+
+#define CRASH_INFERIOR_PID 1
+
+void
+crash_target_init (void)
+{
+ int nr_cpus = crash_get_nr_cpus();
+ crash_target *target = new crash_target ();
+
+ /* Own the target until it is successfully pushed. */
+ target_ops_up target_holder (target);
+
+ push_target (std::move (target_holder));
+
+ inferior_appeared (current_inferior (), CRASH_INFERIOR_PID);
+ for (int i = 0; i < nr_cpus; i++)
+ {
+ thread_info *thread = add_thread_silent (target,
+ ptid_t(CRASH_INFERIOR_PID, 0, i));
+ if (!i)
+ switch_to_thread (thread);
+ }
+}
diff --git a/defs.h b/defs.h
index 9594950..a149d86 100644
--- a/defs.h
+++ b/defs.h
@@ -502,7 +502,6 @@ struct program_context {
struct sigaction gdb_sigaction; /* gdb's SIGINT sigaction. */
jmp_buf main_loop_env; /* longjmp target default */
jmp_buf foreach_loop_env; /* longjmp target within foreach */
- jmp_buf gdb_interface_env; /* longjmp target for gdb error catch */
struct termios termios_orig; /* non-raw settings */
struct termios termios_raw; /* while gathering command input */
int ncmds; /* number of commands in menu */
@@ -4648,13 +4647,10 @@ struct gnu_request {
ulong task;
ulong debug;
struct stack_hook *hookp;
- struct global_iterator {
- int finished;
- int block_index;
- struct symtab *symtab;
- struct symbol *sym;
- struct objfile *obj;
- } global_iterator;
+ ulong lowest;
+ ulong highest;
+ void (*callback) (struct gnu_request *req, void *data);
+ void *callback_data;
struct load_module *lm;
char *member_main_type_name;
char *member_main_type_tag_name;
@@ -4684,7 +4680,7 @@ struct gnu_request {
#define GNU_USER_PRINT_OPTION (16)
#define GNU_SET_CRASH_BLOCK (17)
#define GNU_GET_FUNCTION_RANGE (18)
-#define GNU_GET_NEXT_DATATYPE (19)
+#define GNU_ITERATE_DATATYPES (19)
#define GNU_LOOKUP_STRUCT_CONTENTS (20)
#define GNU_DEBUG_COMMAND (100)
/*
@@ -4709,14 +4705,15 @@ struct gnu_request {
/*
* function prototypes required by modified gdb source files.
*/
-int console(char *, ...);
-int gdb_CRASHDEBUG(ulong);
+extern "C" int console(char *, ...);
+extern "C" int gdb_CRASHDEBUG(ulong);
int gdb_readmem_callback(ulong, void *, int, int);
void patch_load_module(struct objfile *objfile, struct minimal_symbol *msymbol);
-int patch_kernel_symbol(struct gnu_request *);
+extern "C" int patch_kernel_symbol(struct gnu_request *);
struct syment *symbol_search(char *);
int gdb_line_number_callback(ulong, ulong, ulong);
int gdb_print_callback(ulong);
+extern "C" int same_file(char *, char *);
#endif
#ifndef GDB_COMMON
@@ -4730,8 +4727,8 @@ enum type_code {
TYPE_CODE_STRUCT, /* C struct or Pascal record */
TYPE_CODE_UNION, /* C union or Pascal variant part */
TYPE_CODE_ENUM, /* Enumeration type */
-#if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1) || defined(GDB_7_0) ||
defined(GDB_7_3_1) || defined(GDB_7_6)
-#if defined(GDB_7_0) || defined(GDB_7_3_1) || defined(GDB_7_6)
+#if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1) || defined(GDB_7_0) ||
defined(GDB_7_3_1) || defined(GDB_7_6) || defined(GDB_10_1)
+#if defined(GDB_7_0) || defined(GDB_7_3_1) || defined(GDB_7_6) || defined(GDB_10_1)
TYPE_CODE_FLAGS, /* Bit flags type */
#endif
TYPE_CODE_FUNC, /* Function type */
@@ -5395,8 +5392,8 @@ int file_dump(ulong, ulong, ulong, int, int);
#define DUMP_DENTRY_ONLY 0x4
#define DUMP_EMPTY_FILE 0x8
#define DUMP_FILE_NRPAGES 0x10
-#endif /* !GDB_COMMON */
int same_file(char *, char *);
+#endif /* !GDB_COMMON */
#ifndef GDB_COMMON
int cleanup_memory_driver(void);
diff --git a/dropped-gdb-7.6-to-10.1.patch b/dropped-gdb-7.6-to-10.1.patch
new file mode 100644
index 0000000..e819966
--- /dev/null
+++ b/dropped-gdb-7.6-to-10.1.patch
@@ -0,0 +1,303 @@
+--- gdb-10.1/gdb/c-typeprint.c.orig
++++ gdb-10.1/gdb/c-typeprint.c
+@@ -1097,7 +1097,8 @@ c_type_print_base (struct type *type, st
+ fprintf_filtered (stream, "static ");
+ c_print_type (TYPE_FIELD_TYPE (type, i),
+ TYPE_FIELD_NAME (type, i),
+- stream, show - 1, level + 4,
++ stream, strlen(TYPE_FIELD_NAME (type, i)) ?
++ show - 1 : show, level + 4,
+ &local_flags);
+ if (!field_is_static (&TYPE_FIELD (type, i))
+ && TYPE_FIELD_PACKED (type, i))
+--- gdb-10.1/gdb/main.c.orig
++++ gdb-10.1/gdb/main.c
+@@ -929,8 +944,12 @@ captured_main_1 (struct captured_main_args
+ catch_command_errors returns non-zero on success! */
+ if (catch_command_errors (exec_file_attach, execarg,
+ !batch_flag, RETURN_MASK_ALL))
++#ifdef CRASH_MERGE
++ catch_command_errors (symbol_file_add_main, symarg, 0, RETURN_MASK_ALL);
++#else
+ catch_command_errors (symbol_file_add_main, symarg,
+ !batch_flag, RETURN_MASK_ALL);
++#endif
+ }
+ else
+ {
+@@ -992,8 +1011,12 @@ captured_main (void *data)
+ {
+ auto_load_local_gdbinit_loaded = 1;
+
++#ifdef CRASH_MERGE
++ catch_command_errors (source_script, local_gdbinit, -1, RETURN_MASK_ALL);
++#else
+ catch_command_errors (source_script, local_gdbinit, 0,
+ RETURN_MASK_ALL);
++#endif
+ }
+ }
+
+@@ -1039,6 +1062,12 @@ captured_main (void *data)
+ while (1)
+ {
+ catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
++#ifdef CRASH_MERGE
++ {
++ int console(char *, ...);
++ console("<CAPTURED_MAIN WHILE LOOP>\n");
++ }
++#endif
+ }
+ /* No exit -- exit is through quit_command. */
+ }
+--- gdb-10.1/gdb/Makefile.in.orig
++++ gdb-10.1/gdb/Makefile.in
+@@ -1389,12 +1390,12 @@ $(srcdir)/copying.c: @MAINTAINER_MODE_TR
+ mv $(srcdir)/copying.tmp $(srcdir)/copying.c
+
+ version.c: stamp-version; @true
+- rm -f version.c-tmp version.c
+- echo '#include "version.h"' >> version.c-tmp
+- echo 'const char version[] = "'"`sed q
${srcdir}/version.in`"'";' >> version.c-tmp
+- echo 'const char host_name[] = "$(host_alias)";' >>
version.c-tmp
+- echo 'const char target_name[] = "$(target_alias)";' >>
version.c-tmp
+- mv version.c-tmp version.c
++ @rm -f version.c-tmp version.c
++ @echo '#include "version.h"' >> version.c-tmp
++ @echo 'const char version[] = "'"`sed q
${srcdir}/version.in`"'";' >> version.c-tmp
++ @echo 'const char host_name[] = "$(host_alias)";' >>
version.c-tmp
++ @echo 'const char target_name[] = "$(target_alias)";' >>
version.c-tmp
++ @mv version.c-tmp version.c
+
+ observer.h: observer.sh doc/observer.texi
+ ${srcdir}/observer.sh h ${srcdir}/doc/observer.texi observer.h
+--- gdb-10.1/gdb/s390-nat.c.orig
++++ gdb-10.1/gdb/s390-nat.c
+@@ -37,6 +37,8 @@
+ #include <sys/ucontext.h>
+ #include <elf.h>
+
++#include <sys/uio.h>
++
+ #ifndef HWCAP_S390_HIGH_GPRS
+ #define HWCAP_S390_HIGH_GPRS 512
+ #endif
+--- gdb-10.1/bfd/bfd-in.h.orig
++++ gdb-10.1/bfd/bfd-in.h
+@@ -294,9 +294,6 @@ typedef struct bfd_section *sec_ptr;
+
+ #define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
+
+-#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)),
((ptr)->user_set_vma = TRUE), TRUE)
+-#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power =
(val)),TRUE)
+-#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE)
+ /* Find the address one past the end of SEC. */
+ #define bfd_get_section_limit(bfd, sec) \
+ (((bfd)->direction != write_direction && (sec)->rawsize != 0 \
+@@ -519,7 +516,6 @@ extern void warn_deprecated (const char
+
+ #define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
+
+-#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
+
+ extern bfd_boolean bfd_cache_close
+ (bfd *abfd);
+--- gdb-10.1/bfd/bfd-in2.h.orig
++++ gdb-10.1/bfd/bfd-in2.h
+@@ -301,9 +301,6 @@ typedef struct bfd_section *sec_ptr;
+
+ #define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
+
+-#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)),
((ptr)->user_set_vma = TRUE), TRUE)
+-#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power =
(val)),TRUE)
+-#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE)
+ /* Find the address one past the end of SEC. */
+ #define bfd_get_section_limit(bfd, sec) \
+ (((bfd)->direction != write_direction && (sec)->rawsize != 0 \
+@@ -526,7 +523,6 @@ extern void warn_deprecated (const char
+
+ #define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
+
+-#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
+
+ extern bfd_boolean bfd_cache_close
+ (bfd *abfd);
+@@ -1572,6 +1568,32 @@ struct relax_table {
+ int size;
+ };
+
++/* Note: the following are provided as inline functions rather than macros
++ because not all callers use the return value. A macro implementation
++ would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some
++ compilers will complain about comma expressions that have no effect. */
++static inline bfd_boolean
++bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val)
++{
++ ptr->userdata = val;
++ return TRUE;
++}
++
++static inline bfd_boolean
++bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val)
++{
++ ptr->vma = ptr->lma = val;
++ ptr->user_set_vma = TRUE;
++ return TRUE;
++}
++
++static inline bfd_boolean
++bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int
val)
++{
++ ptr->alignment_power = val;
++ return TRUE;
++}
++
+ /* These sections are global, and are managed by BFD. The application
+ and target back end are not permitted to change the values in
+ these sections. */
+@@ -6095,6 +6117,14 @@ struct bfd
+ unsigned int selective_search : 1;
+ };
+
++/* See note beside bfd_set_section_userdata. */
++static inline bfd_boolean
++bfd_set_cacheable (bfd * abfd, bfd_boolean val)
++{
++ abfd->cacheable = val;
++ return TRUE;
++}
++
+ typedef enum bfd_error
+ {
+ bfd_error_no_error = 0,
+--- gdb-10.1/opcodes/i386-dis.c.orig
++++ gdb-10.1/opcodes/i386-dis.c
+@@ -11300,6 +11300,29 @@ get_sib (disassemble_info *info, int sizeflag)
+ }
+ }
+
++static char *
++check_for_extensions(struct dis_private *priv)
++{
++ unsigned char ModRM;
++
++ if ((priv->the_buffer[0] == 0x66) &&
++ (priv->the_buffer[1] == 0x0f) &&
++ (priv->the_buffer[2] == 0xae)) {
++ ModRM = priv->the_buffer[3];
++ if (ModRM == 0xf8)
++ return "pcommit";
++
++ switch ((ModRM >> 3))
++ {
++ case 0x6:
++ return "clwb";
++ case 0x7:
++ return "clflushopt";
++ }
++ }
++ return NULL;
++}
++
+ static int
+ print_insn (bfd_vma pc, disassemble_info *info)
+ {
+@@ -11312,6 +11335,7 @@ print_insn (bfd_vma pc, disassemble_info
+ const char *p;
+ struct dis_private priv;
+ int prefix_length;
++ char *extension;
+
+ priv.orig_sizeflag = AFLAG | DFLAG;
+ if ((info->mach & bfd_mach_i386_i386) != 0)
+@@ -11575,6 +11599,7 @@ print_insn (bfd_vma pc, disassemble_info
+
+ need_vex = 0;
+ memset (&vex, 0, sizeof (vex));
++ extension = NULL;
+
+ if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
+ {
+@@ -11610,9 +11635,14 @@ print_insn (bfd_vma pc, disassemble_info
+ name = prefix_name (all_prefixes[i], priv.orig_sizeflag);
+ if (name == NULL)
+ name = INTERNAL_DISASSEMBLER_ERROR;
+- (*info->fprintf_func) (info->stream, "%s", name);
+- return 1;
+- }
++ if ((extension = check_for_extensions(&priv))) {
++ strcpy(obuf, extension);
++ obufp = &obuf[strlen(obuf)];
++ } else {
++ (*info->fprintf_func) (info->stream, "%s", name);
++ return 1;
++ }
++ }
+ }
+
+ /* Check if the REX prefix is used. */
+@@ -11637,7 +11667,7 @@ print_insn (bfd_vma pc, disassemble_info
+ all_prefixes[last_data_prefix] = 0;
+
+ prefix_length = 0;
+- for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
++ for (i = 0; !extension && i < (int) ARRAY_SIZE (all_prefixes); i++)
+ if (all_prefixes[i])
+ {
+ const char *name;
+@@ -11655,7 +11685,8 @@ print_insn (bfd_vma pc, disassemble_info
+ return MAX_CODE_LENGTH;
+ }
+
+- obufp = mnemonicendp;
++ if (!extension)
++ obufp = mnemonicendp;
+ for (i = strlen (obuf) + prefix_length; i < 6; i++)
+ oappend (" ");
+ oappend (" ");
+diff -up gdb-10.1/bfd/elf64-ppc.c.orig gdb-10.1/bfd/elf64-ppc.c
+--- gdb-10.1/bfd/elf64-ppc.c.orig 2016-02-02 11:04:25.436527347 -0500
++++ gdb-10.1/bfd/elf64-ppc.c 2016-02-02 11:11:51.926468454 -0500
+@@ -11743,7 +11743,7 @@ ppc64_elf_size_stubs (struct bfd_link_in
+ stub_sec = stub_sec->next)
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
+ stub_sec->size = ((stub_sec->size + (1 << htab->plt_stub_align) -
1)
+- & (-1 << htab->plt_stub_align));
++ & -(1 << htab->plt_stub_align));
+
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+@@ -12093,7 +12093,7 @@ ppc64_elf_build_stubs (bfd_boolean emit_
+ stub_sec = stub_sec->next)
+ if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
+ stub_sec->size = ((stub_sec->size + (1 << htab->plt_stub_align) - 1)
+- & (-1 << htab->plt_stub_align));
++ & -(1 << htab->plt_stub_align));
+
+ for (stub_sec = htab->stub_bfd->sections;
+ stub_sec != NULL;
+diff -up gdb-10.1/bfd/configure.orig gdb-10.1/bfd/configure
+--- gdb-10.1/bfd/configure.orig 2017-02-17 17:19:51.654898822 -0500
++++ gdb-10.1/bfd/configure 2017-02-17 17:19:57.922038757 -0500
+@@ -12193,7 +12193,7 @@ fi
+
+ NO_WERROR=
+ if test "${ERROR_ON_WARNING}" = yes ; then
+- GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
++ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS"
+ NO_WERROR="-Wno-error"
+ fi
+
+diff -up gdb-10.1/opcodes/configure.orig gdb-10.1/opcodes/configure
+--- gdb-10.1/opcodes/configure.orig 2017-02-17 17:19:08.849943016 -0500
++++ gdb-10.1/opcodes/configure 2017-02-17 17:19:23.256264699 -0500
+@@ -11539,7 +11539,7 @@ fi
+
+ NO_WERROR=
+ if test "${ERROR_ON_WARNING}" = yes ; then
+- GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
++ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS"
+ NO_WERROR="-Wno-error"
+ fi
+
diff --git a/gdb-7.6-ppc64le-support.patch b/gdb-10.1-ppc64le-support.patch
similarity index 100%
rename from gdb-7.6-ppc64le-support.patch
rename to gdb-10.1-ppc64le-support.patch
diff --git a/gdb-10.1.patch b/gdb-10.1.patch
new file mode 100644
index 0000000..533157d
--- /dev/null
+++ b/gdb-10.1.patch
@@ -0,0 +1,1577 @@
+diff -aurp -X diff_exclude gdb-10.1.orig/gdb/cli/cli-cmds.c gdb-10.1/gdb/cli/cli-cmds.c
+--- gdb-10.1.orig/gdb/cli/cli-cmds.c 2020-10-23 21:23:02.000000000 -0700
++++ gdb-10.1/gdb/cli/cli-cmds.c 2020-11-10 13:06:56.423569114 -0800
+@@ -435,6 +435,11 @@ complete_command (const char *arg, int f
+ }
+ }
+
++#ifdef CRASH_MERGE
++static int crash_from_tty = 0;
++extern "C" void untrusted_file(FILE *, char *);
++#endif
++
+ int
+ is_complete_command (struct cmd_list_element *c)
+ {
+@@ -654,8 +659,32 @@ find_and_open_script (const char *script
+ close (fd);
+ errno = save_errno;
+ }
+- else
+- opened.emplace (gdb_file_up (result), std::move (full_path));
++#ifdef CRASH_MERGE
++ /*
++ * Only allow trusted versions of .gdbinit files to be
++ * sourced during session initialization.
++ */
++ if (crash_from_tty == -1)
++ {
++ struct stat statbuf;
++ FILE *stream = result;
++ int _fd = fileno (stream);
++ if (fstat (_fd, &statbuf) < 0)
++ {
++ perror_with_name (full_path.get());
++ fclose (stream);
++ return opened;
++ }
++ if (statbuf.st_uid != getuid () || (statbuf.st_mode & S_IWOTH))
++ {
++ untrusted_file(NULL, full_path.get());
++ fclose (stream);
++ return opened;
++ }
++ }
++#endif
++ opened.emplace (gdb_file_up (result), std::move (full_path));
++
+
+ return opened;
+ }
+@@ -719,7 +748,11 @@ source_script_with_search (const char *f
+ If the source command was invoked interactively, throw an
+ error. Otherwise (e.g. if it was invoked by a script),
+ just emit a warning, rather than cause an error. */
++#ifdef CRASH_MERGE
++ if (from_tty > 0)
++#else
+ if (from_tty)
++#endif
+ perror_with_name (file);
+ else
+ {
+@@ -743,7 +776,14 @@ source_script_with_search (const char *f
+ void
+ source_script (const char *file, int from_tty)
+ {
++#ifdef CRASH_MERGE
++ crash_from_tty = from_tty;
++#endif
+ source_script_with_search (file, from_tty, 0);
++#ifdef CRASH_MERGE
++ crash_from_tty = 0;
++#endif
++
+ }
+
+ static void
+diff -aurp -X diff_exclude gdb-10.1.orig/gdb/defs.h gdb-10.1/gdb/defs.h
+--- gdb-10.1.orig/gdb/defs.h 2020-09-12 19:33:41.000000000 -0700
++++ gdb-10.1/gdb/defs.h 2020-11-10 13:06:56.423569114 -0800
+@@ -629,4 +629,8 @@ DEF_ENUM_FLAGS_TYPE (enum user_selected_
+
+ #include "utils.h"
+
++#ifdef CRASH_MERGE
++extern "C" int gdb_main_entry(int, char **);
++extern void replace_ui_file_FILE(struct ui_file *, FILE *);
++#endif
+ #endif /* #ifndef DEFS_H */
+diff -aurp -X diff_exclude gdb-10.1.orig/gdb/dwarf2/read.c gdb-10.1/gdb/dwarf2/read.c
+--- gdb-10.1.orig/gdb/dwarf2/read.c 2020-10-23 21:23:02.000000000 -0700
++++ gdb-10.1/gdb/dwarf2/read.c 2020-11-10 13:06:56.427569136 -0800
+@@ -3003,7 +3003,11 @@ read_gdb_index_from_buffer (const char *
+ indices. */
+ if (version < 4)
+ {
++#ifdef CRASH_MERGE
++ static int warning_printed = 1;
++#else
+ static int warning_printed = 0;
++#endif
+ if (!warning_printed)
+ {
+ warning (_("Skipping obsolete .gdb_index section in %s."),
+@@ -3022,7 +3026,11 @@ read_gdb_index_from_buffer (const char *
+ "set use-deprecated-index-sections on". */
+ if (version < 6 && !deprecated_ok)
+ {
++#ifdef CRASH_MERGE
++ static int warning_printed = 1;
++#else
+ static int warning_printed = 0;
++#endif
+ if (!warning_printed)
+ {
+ warning (_("\
+diff -aurp -X diff_exclude gdb-10.1.orig/gdb/main.c gdb-10.1/gdb/main.c
+--- gdb-10.1.orig/gdb/main.c 2020-09-12 19:33:41.000000000 -0700
++++ gdb-10.1/gdb/main.c 2020-11-12 21:59:25.181230400 -0800
+@@ -392,6 +392,13 @@ start_event_loop ()
+ return;
+ }
+
++#ifdef CRASH_MERGE
++extern "C" void update_gdb_hooks(void);
++extern "C" void main_loop(void);
++extern "C" unsigned long crash_get_kaslr_offset(void);
++void crash_target_init (void);
++#endif
++
+ /* Call command_loop. */
+
+ /* Prevent inlining this function for the benefit of GDB's selftests
+@@ -925,7 +932,11 @@ captured_main_1 (struct captured_main_ar
+ }
+ }
+
++#ifdef CRASH_MERGE
++ save_original_signals_state (1);
++#else
+ save_original_signals_state (quiet);
++#endif
+
+ /* Try to set up an alternate signal stack for SIGSEGV handlers. */
+ gdb::alternate_signal_stack signal_stack;
+@@ -999,7 +1010,7 @@ captured_main_1 (struct captured_main_ar
+ {
+ print_gdb_version (gdb_stdout, false);
+ wrap_here ("");
+- printf_filtered ("\n");
++ printf_filtered ("\n\n");
+ exit (0);
+ }
+
+@@ -1038,6 +1049,10 @@ captured_main_1 (struct captured_main_ar
+ look at things by now. Initialize the default interpreter. */
+ set_top_level_interpreter (interpreter_p);
+
++#ifdef CRASH_MERGE
++ update_gdb_hooks();
++#endif
++
+ /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets
+ GDB retain the old MI1 interpreter startup behavior. Output the
+ copyright message after the interpreter is installed when it is
+@@ -1066,7 +1081,11 @@ captured_main_1 (struct captured_main_ar
+ if (!system_gdbinit.empty () && !inhibit_gdbinit)
+ {
+ for (const std::string &file : system_gdbinit)
++#ifdef CRASH_MERGE
++ ret = catch_command_errors (source_script, file.c_str (), -1);
++#else
+ ret = catch_command_errors (source_script, file.c_str (), 0);
++#endif
+ }
+
+ /* Read and execute $HOME/.gdbinit file, if it exists. This is done
+@@ -1075,7 +1094,11 @@ captured_main_1 (struct captured_main_ar
+ debugging or what directory you are in. */
+
+ if (!home_gdbinit.empty () && !inhibit_gdbinit &&
!inhibit_home_gdbinit)
++#ifdef CRASH_MERGE
++ ret = catch_command_errors (source_script, home_gdbinit.c_str (), -1);
++#else
+ ret = catch_command_errors (source_script, home_gdbinit.c_str (), 0);
++#endif
+
+ /* Process '-ix' and '-iex' options early. */
+ for (i = 0; i < cmdarg_vec.size (); i++)
+@@ -1242,6 +1265,16 @@ captured_main (void *data)
+
+ captured_main_1 (context);
+
++#ifdef CRASH_MERGE
++ /* Relocate the vmlinux. */
++ objfile_rebase (symfile_objfile, crash_get_kaslr_offset());
++
++ crash_target_init();
++
++ /* Back to crash. */
++ main_loop();
++#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
+@@ -1277,6 +1310,22 @@ gdb_main (struct captured_main_args *arg
+ return 1;
+ }
+
++#ifdef CRASH_MERGE
++/*
++ * NOTE: adapted from gdb.c, which is no longer built in; changed name of
++ * original main() to gdb_main_entry() for use as crash entry point
++ */
++int
++gdb_main_entry (int argc, char **argv)
++{
++ struct captured_main_args args;
++ memset (&args, 0, sizeof args);
++ args.argc = argc;
++ args.argv = argv;
++ args.interpreter_p = INTERP_CONSOLE;
++ return gdb_main (&args);
++}
++#endif
+
+ /* Don't use *_filtered for printing help. We don't want to prompt
+ for continue no matter how small the screen or how much we're going
+diff -aurp -X diff_exclude gdb-10.1.orig/gdb/Makefile.in gdb-10.1/gdb/Makefile.in
+--- gdb-10.1.orig/gdb/Makefile.in 2020-10-23 21:23:02.000000000 -0700
++++ gdb-10.1/gdb/Makefile.in 2020-11-12 18:51:04.273363098 -0800
+@@ -571,7 +571,7 @@ CONFIG_DEP_SUBDIR = $(addsuffix /$(DEPDI
+ # It is also possible that you will need to add -I/usr/include/sys if
+ # your system doesn't have fcntl.h in /usr/include (which is where it
+ # should be according to Posix).
+-DEFS = @DEFS@
++DEFS = -DCRASH_MERGE @DEFS@
+ GDB_CFLAGS = -I. -I$(srcdir) -I$(srcdir)/config \
+ -DLOCALEDIR="\"$(localedir)\"" $(DEFS)
+
+@@ -1135,6 +1135,7 @@ COMMON_SFILES = \
+ symmisc.c \
+ symtab.c \
+ target.c \
++ ../../crash_target.c \
+ target-connection.c \
+ target-dcache.c \
+ target-descriptions.c \
+@@ -1564,7 +1565,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
+ $(SUBDIR_TARGET_OBS) \
+ $(SUBDIR_GCC_COMPILE_OBS)
+
+-SUBDIRS = doc @subdirs@ data-directory
++SUBDIRS = build_no_subdirs
+ CLEANDIRS = $(SUBDIRS)
+
+ # List of subdirectories in the build tree that must exist.
+@@ -1606,8 +1607,8 @@ generated_files = \
+ # Flags needed to compile Python code
+ PYTHON_CFLAGS = @PYTHON_CFLAGS@
+
+-all: gdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb
+- @$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed
's/testsuite//'`" subdir_do
++all: gdb$(EXEEXT) gdb-gdb.py gdb-gdb.gdb
++ @$(MAKE) -s $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed
's/testsuite//'`" subdir_do
+
+ # Rule for compiling .c files in the top-level gdb directory.
+ # The order-only dependencies ensure that we create the build subdirectories.
+@@ -1864,9 +1865,10 @@ libgdb.a: $(LIBGDB_OBS)
+ # Removing the old gdb first works better if it is running, at least on SunOS.
+ gdb$(EXEEXT): gdb.o $(LIBGDB_OBS) $(CDEPS) $(TDEPLIBS)
+ $(SILENCE) rm -f gdb$(EXEEXT)
++ @(cd ../..; make --no-print-directory GDB_FLAGS=-DGDB_10_1 library)
+ $(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \
+- -o gdb$(EXEEXT) gdb.o $(LIBGDB_OBS) \
+- $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES)
++ -o $(shell /bin/cat mergeobj) $(LIBGDB_OBS) \
++ $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) $(shell /bin/cat mergelibs)
+ ifneq ($(CODESIGN_CERT),)
+ $(ECHO_SIGN) $(CODESIGN) -s $(CODESIGN_CERT) gdb$(EXEEXT)
+ endif
+@@ -2530,9 +2532,9 @@ ifeq ($(DEPMODE),depmode=gcc3)
+ # into place if the compile succeeds. We need this because gcc does
+ # not atomically write the dependency output file.
+ override COMPILE.post = -c -o $@ -MT $@ -MMD -MP \
+- -MF $(@D)/$(DEPDIR)/$(basename $((a)F)).Tpo
+-override POSTCOMPILE = @mv $(@D)/$(DEPDIR)/$(basename $((a)F)).Tpo \
+- $(@D)/$(DEPDIR)/$(basename $((a)F)).Po
++ -MF $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $((a)F)).Tpo
++override POSTCOMPILE = @mv $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $((a)F)).Tpo \
++ $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $((a)F)).Po
+ else
+ override COMPILE.pre = source='$<' object='$@' libtool=no \
+ DEPDIR=$(DEPDIR) $(DEPMODE) $(depcomp) \
+diff -aurp -X diff_exclude gdb-10.1.orig/gdb/objfiles.h gdb-10.1/gdb/objfiles.h
+--- gdb-10.1.orig/gdb/objfiles.h 2020-09-12 19:33:41.000000000 -0700
++++ gdb-10.1/gdb/objfiles.h 2020-11-10 13:06:56.431569157 -0800
+@@ -747,9 +747,9 @@ extern int objfile_has_full_symbols (str
+
+ extern int objfile_has_symbols (struct objfile *objfile);
+
+-extern int have_partial_symbols (void);
++extern "C" int have_partial_symbols (void);
+
+-extern int have_full_symbols (void);
++extern "C" int have_full_symbols (void);
+
+ extern void objfile_set_sym_fns (struct objfile *objfile,
+ const struct sym_fns *sf);
+diff -aurp -X diff_exclude gdb-10.1.orig/gdb/printcmd.c gdb-10.1/gdb/printcmd.c
+--- gdb-10.1.orig/gdb/printcmd.c 2020-10-23 21:23:02.000000000 -0700
++++ gdb-10.1/gdb/printcmd.c 2020-11-10 13:06:56.431569157 -0800
+@@ -524,6 +524,9 @@ set_next_address (struct gdbarch *gdbarc
+ form. However note that DO_DEMANGLE can be overridden by the specific
+ settings of the demangle and asm_demangle variables. Returns
+ non-zero if anything was printed; zero otherwise. */
++#ifdef CRASH_MERGE
++extern "C" int gdb_print_callback(unsigned long);
++#endif
+
+ int
+ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
+@@ -535,6 +538,12 @@ print_address_symbolic (struct gdbarch *
+ int offset = 0;
+ int line = 0;
+
++#ifdef CRASH_MERGE
++ if (!gdb_print_callback(addr)) {
++ return 0;
++ }
++#endif
++
+ if (build_address_symbolic (gdbarch, addr, do_demangle, false, &name,
+ &offset, &filename, &line, &unmapped))
+ return 0;
+@@ -1221,6 +1230,43 @@ print_command_1 (const char *args, int v
+ print_value (val, print_opts);
+ }
+
++static void
++print_command_2 (const char *args, int voidprint)
++{
++ struct value *val;
++ value_print_options print_opts;
++
++ get_user_print_options (&print_opts);
++ /* Override global settings with explicit options, if any. */
++ auto group = make_value_print_options_def_group (&print_opts);
++ gdb::option::process_options
++ (&args, gdb::option::PROCESS_OPTIONS_REQUIRE_DELIMITER, group);
++
++ print_command_parse_format (&args, "print", &print_opts);
++
++ const char *exp = args;
++
++ if (exp != nullptr && *exp)
++ {
++ expression_up expr = parse_expression (exp);
++ val = evaluate_expression (expr.get ());
++ }
++ else
++ val = access_value_history (0);
++
++ printf_filtered ("%d %d %ld %ld %ld %ld\n",
++ check_typedef(value_type (val))->code(),
++ TYPE_UNSIGNED (check_typedef(value_type (val))),
++ TYPE_LENGTH (check_typedef(value_type(val))),
++ value_offset (val), value_bitpos (val), value_bitsize(val));
++}
++
++static void
++printm_command (const char *exp, int from_tty)
++{
++ print_command_2 (exp, 1);
++}
++
+ /* See valprint.h. */
+
+ void
+@@ -2855,6 +2901,12 @@ but no count or size letter (see \"x\" c
+ c = add_com ("print", class_vars, print_command, print_help.c_str ());
+ set_cmd_completer_handle_brkchars (c, print_command_completer);
+ add_com_alias ("p", "print", class_vars, 1);
++
++ c = add_com ("printm", class_vars, printm_command, _("\
++Similar to \"print\" command, but it used to print the type, size, offset,\n\
++bitpos and bitsize of the expression EXP."));
++ set_cmd_completer (c, expression_completer);
++
+ add_com_alias ("inspect", "print", class_vars, 1);
+
+ add_setshow_uinteger_cmd ("max-symbolic-offset", no_class,
+diff -aurp -X diff_exclude gdb-10.1.orig/gdb/psymtab.c gdb-10.1/gdb/psymtab.c
+--- gdb-10.1.orig/gdb/psymtab.c 2020-10-23 21:23:02.000000000 -0700
++++ gdb-10.1/gdb/psymtab.c 2020-11-10 13:06:56.431569157 -0800
+@@ -283,6 +283,9 @@ find_pc_sect_psymtab_closer (struct objf
+ return best_pst;
+ }
+
++#ifdef CRASH_MERGE
++ extern "C" int gdb_line_number_callback(unsigned long, unsigned long,
unsigned long);
++#endif
+ /* Find which partial symtab contains PC and SECTION. Return NULL if
+ none. We return the psymtab that contains a symbol whose address
+ exactly matches PC, or, if we cannot find an exact match, the
+@@ -305,6 +308,7 @@ find_pc_sect_psymtab (struct objfile *ob
+ partial symtabs then we will end up returning a pointer to an object
+ that is not a partial_symtab, which doesn't end well. */
+
++#ifndef __i386__
+ if (objfile->partial_symtabs->psymtabs != NULL
+ && objfile->partial_symtabs->psymtabs_addrmap != NULL)
+ {
+@@ -345,6 +349,7 @@ find_pc_sect_psymtab (struct objfile *ob
+ }
+
+ next:
++#endif
+
+ /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs
+ which still have no corresponding full SYMTABs read. But it is not
+@@ -363,7 +368,12 @@ find_pc_sect_psymtab (struct objfile *ob
+
+ best_pst = find_pc_sect_psymtab_closer (objfile, pc, section, pst,
+ msymbol);
++#ifdef CRASH_MERGE
++ if ((best_pst != NULL) &&
++ gdb_line_number_callback(pc, pst->text_low (objfile), pst->text_high
(objfile)))
++#else
+ if (best_pst != NULL)
++#endif
+ return best_pst;
+ }
+
+diff -aurp -X diff_exclude gdb-10.1.orig/gdb/symfile.c gdb-10.1/gdb/symfile.c
+--- gdb-10.1.orig/gdb/symfile.c 2020-10-23 21:23:02.000000000 -0700
++++ gdb-10.1/gdb/symfile.c 2020-11-10 13:06:56.431569157 -0800
+@@ -652,7 +652,26 @@ default_symfile_offsets (struct objfile
+ for (cur_sec = abfd->sections; cur_sec != NULL; cur_sec = cur_sec->next)
+ /* We do not expect this to happen; just skip this step if the
+ relocatable file has a section with an assigned VMA. */
+- if (bfd_section_vma (cur_sec) != 0)
++ if (bfd_section_vma (cur_sec) != 0
++ /*
++ * Kernel modules may have some non-zero VMAs, i.e., like the
++ * __ksymtab and __ksymtab_gpl sections in this example:
++ *
++ * Section Headers:
++ * [Nr] Name Type Address Offset
++ * Size EntSize Flags Link Info Align
++ * ...
++ * [ 8] __ksymtab PROGBITS 0000000000000060 0000ad90
++ * 0000000000000010 0000000000000000 A 0 0 16
++ * [ 9] .rela__ksymtab RELA 0000000000000000 0000ada0
++ * 0000000000000030 0000000000000018 43 8 8
++ * [10] __ksymtab_gpl PROGBITS 0000000000000070 0000add0
++ * 00000000000001a0 0000000000000000 A 0 0 16
++ * ...
++ *
++ * but they should be treated as if they are NULL.
++ */
++ && strncmp (bfd_section_name (cur_sec), "__k", 3) != 0)
+ break;
+
+ if (cur_sec == NULL)
+@@ -1083,6 +1102,12 @@ symbol_file_add_with_addrs (bfd *abfd, c
+ if (mainline)
+ flags |= OBJF_MAINLINE;
+ objfile = objfile::make (abfd, name, flags, parent);
++#ifdef CRASH_MERGE
++ if (add_flags & SYMFILE_MAINLINE) {
++ extern struct objfile *gdb_kernel_objfile;
++ gdb_kernel_objfile = objfile;
++ }
++#endif
+
+ /* We either created a new mapped symbol table, mapped an existing
+ symbol table file which has not had initial symbol reading
+@@ -1375,6 +1400,10 @@ show_debug_file_directory (struct ui_fil
+ #if ! defined (DEBUG_SUBDIRECTORY)
+ #define DEBUG_SUBDIRECTORY ".debug"
+ #endif
++#ifdef CRASH_MERGE
++extern "C" int check_specified_module_tree(const char *, const char *);
++extern "C" char *check_specified_kernel_debug_file();
++#endif
+
+ /* Find a separate debuginfo file for OBJFILE, using DIR as the directory
+ where the original file resides (may not be the same as
+@@ -1410,6 +1439,15 @@ find_separate_debug_file (const char *di
+ if (separate_debug_file_exists (debugfile, crc32, objfile))
+ return debugfile;
+
++#ifdef CRASH_MERGE
++{
++ if (check_specified_module_tree(objfile_name (objfile), debugfile.c_str()) &&
++ separate_debug_file_exists(debugfile, crc32, objfile)) {
++ return debugfile;
++ }
++}
++#endif
++
+ /* Then try in the global debugfile directories.
+
+ Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
+@@ -1568,6 +1606,13 @@ find_separate_debug_file_by_debuglink (s
+ }
+ }
+
++#ifdef CRASH_MERGE
++ if (debugfile.empty ()) {
++ char *name_copy;
++ name_copy = check_specified_kernel_debug_file();
++ return std::string (name_copy);
++ }
++#endif
+ return debugfile;
+ }
+
+@@ -2334,8 +2379,10 @@ add_symbol_file_command (const char *arg
+ else if (section_addrs.empty ())
+ printf_unfiltered ("\n");
+
++#ifndef CRASH_MERGE
+ if (from_tty && (!query ("%s", "")))
+ error (_("Not confirmed."));
++#endif
+
+ objf = symbol_file_add (filename.get (), add_flags, §ion_addrs,
+ flags);
+@@ -3622,6 +3669,15 @@ bfd_byte *
+ symfile_relocate_debug_section (struct objfile *objfile,
+ asection *sectp, bfd_byte *buf)
+ {
++#ifdef CRASH_MERGE
++ /* Executable files have all the relocations already resolved.
++ * Handle files linked with --emit-relocs.
++ *
http://sources.redhat.com/ml/gdb/2006-08/msg00137.html
++ */
++ bfd *abfd = objfile->obfd;
++ if ((abfd->flags & EXEC_P) != 0)
++ return NULL;
++#endif
+ gdb_assert (objfile->sf->sym_relocate);
+
+ return (*objfile->sf->sym_relocate) (objfile, sectp, buf);
+diff -aurp -X diff_exclude gdb-10.1.orig/gdb/symtab.c gdb-10.1/gdb/symtab.c
+--- gdb-10.1.orig/gdb/symtab.c 2020-10-23 21:23:02.000000000 -0700
++++ gdb-10.1/gdb/symtab.c 2020-11-12 22:32:49.237561633 -0800
+@@ -1870,27 +1870,44 @@ search_name_hash (enum language language
+ variable and thus can probably assume it will never hit the C++
+ code). */
+
++#ifdef CRASH_MERGE
++static void gdb_bait_and_switch(char *, struct symbol *);
++#endif
+ struct block_symbol
+ lookup_symbol_in_language (const char *name, const struct block *block,
+ const domain_enum domain, enum language lang,
+ struct field_of_this_result *is_a_field_of_this)
+ {
++ struct block_symbol result;
+ demangle_result_storage storage;
+ const char *modified_name = demangle_for_lookup (name, lang, storage);
+
+- return lookup_symbol_aux (modified_name,
++ result = lookup_symbol_aux (modified_name,
+ symbol_name_match_type::FULL,
+ block, domain, lang,
+ is_a_field_of_this);
++#ifdef CRASH_MERGE
++ if (result.symbol && (domain == VAR_DOMAIN))
++ gdb_bait_and_switch((char *)modified_name, result.symbol);
++#endif
++ return result;
+ }
+
+ /* See symtab.h. */
+
++#ifdef CRASH_MERGE
++static const struct block *gdb_get_crash_block(void);
++#endif
++
+ struct block_symbol
+ lookup_symbol (const char *name, const struct block *block,
+ domain_enum domain,
+ struct field_of_this_result *is_a_field_of_this)
+ {
++#ifdef CRASH_MERGE
++ if (!block)
++ block = gdb_get_crash_block();
++#endif
+ return lookup_symbol_in_language (name, block, domain,
+ current_language->la_language,
+ is_a_field_of_this);
+@@ -6886,3 +6903,813 @@ If zero then the symbol cache is disable
+ gdb::observers::new_objfile.attach (symtab_new_objfile_observer);
+ gdb::observers::free_objfile.attach (symtab_free_objfile_observer);
+ }
++
++#ifdef CRASH_MERGE
++#include "gdb-stabs.h"
++#include "gdbsupport/version.h"
++#define GDB_COMMON
++#include "../../defs.h"
++
++static void get_member_data(struct gnu_request *, struct type *, long, int);
++static void dump_enum(struct type *, struct gnu_request *);
++static void eval_enum(struct type *, struct gnu_request *);
++static void gdb_get_line_number(struct gnu_request *);
++static void gdb_get_datatype(struct gnu_request *);
++static void gdb_get_symbol_type(struct gnu_request *);
++static void gdb_command_exists(struct gnu_request *);
++static void gdb_debug_command(struct gnu_request *);
++static void gdb_function_numargs(struct gnu_request *);
++static void gdb_add_symbol_file(struct gnu_request *);
++static void gdb_delete_symbol_file(struct gnu_request *);
++static void gdb_patch_symbol_values(struct gnu_request *);
++extern void replace_ui_file_FILE(struct ui_file *, FILE *);
++static void get_user_print_option_address(struct gnu_request *);
++extern int get_frame_offset(CORE_ADDR);
++static void gdb_set_crash_block(struct gnu_request *);
++extern "C" void gdb_command_funnel(struct gnu_request *);
++void gdb_command_funnel_1(struct gnu_request *);
++static long lookup_struct_contents(struct gnu_request *);
++static void iterate_datatypes(struct gnu_request *);
++
++struct objfile *gdb_kernel_objfile = { 0 };
++
++static ulong gdb_merge_flags = 0;
++#define KERNEL_SYMBOLS_PATCHED (0x1)
++
++#undef STREQ
++#define STREQ(A, B) (A && B && (strcmp(A, B) == 0))
++#define TYPE_CODE(t) (t->code ())
++#define TYPE_TAG_NAME(t) (TYPE_MAIN_TYPE(t)->name)
++#define TYPE_NFIELDS(t) (t->num_fields ())
++#define TYPE_NAME(t) (t->name ())
++
++/*
++ * All commands from above come through here.
++ */
++void
++gdb_command_funnel(struct gnu_request *req)
++{
++ try {
++ gdb_command_funnel_1(req);
++ } catch (const gdb_exception &ex) {
++ if (req->flags & GNU_RETURN_ON_ERROR)
++ req->flags |= GNU_COMMAND_FAILED;
++ else
++ throw ex;
++ }
++}
++
++void
++gdb_command_funnel_1(struct gnu_request *req)
++{
++ struct symbol *sym;
++
++ if (req->command != GNU_VERSION) {
++ (dynamic_cast<stdio_file *>gdb_stdout)->set_stream(req->fp);
++ (dynamic_cast<stdio_file *>gdb_stderr)->set_stream(req->fp);
++ }
++
++ switch (req->command)
++ {
++ case GNU_VERSION:
++ req->buf = (char *)version;
++ break;
++
++ case GNU_PASS_THROUGH:
++ execute_command(req->buf,
++ req->flags & GNU_FROM_TTY_OFF ? FALSE : TRUE);
++ break;
++
++ case GNU_USER_PRINT_OPTION:
++ get_user_print_option_address(req);
++ break;
++
++ case GNU_RESOLVE_TEXT_ADDR:
++ sym = find_pc_function(req->addr);
++ if (!sym || TYPE_CODE(sym->type) != TYPE_CODE_FUNC)
++ req->flags |= GNU_COMMAND_FAILED;
++ break;
++
++ case GNU_DISASSEMBLE:
++ if (req->addr2)
++ sprintf(req->buf, "disassemble 0x%lx 0x%lx",
++ req->addr, req->addr2);
++ else
++ sprintf(req->buf, "disassemble 0x%lx", req->addr);
++ execute_command(req->buf, TRUE);
++ break;
++
++ case GNU_ADD_SYMBOL_FILE:
++ gdb_add_symbol_file(req);
++ break;
++
++ case GNU_DELETE_SYMBOL_FILE:
++ gdb_delete_symbol_file(req);
++ break;
++
++ case GNU_GET_LINE_NUMBER:
++ gdb_get_line_number(req);
++ break;
++
++ case GNU_GET_DATATYPE:
++ gdb_get_datatype(req);
++ break;
++
++ case GNU_GET_SYMBOL_TYPE:
++ gdb_get_symbol_type(req);
++ break;
++
++ case GNU_COMMAND_EXISTS:
++ gdb_command_exists(req);
++ break;
++
++ case GNU_ALPHA_FRAME_OFFSET:
++ req->value = 0;
++ break;
++
++ case GNU_FUNCTION_NUMARGS:
++ gdb_function_numargs(req);
++ break;
++
++ case GNU_DEBUG_COMMAND:
++ gdb_debug_command(req);
++ break;
++
++ case GNU_PATCH_SYMBOL_VALUES:
++ gdb_patch_symbol_values(req);
++ break;
++
++ case GNU_SET_CRASH_BLOCK:
++ gdb_set_crash_block(req);
++ break;
++
++ case GNU_GET_FUNCTION_RANGE:
++ sym = lookup_symbol(req->name, 0, VAR_DOMAIN, 0).symbol;
++ if (!find_pc_partial_function(req->pc, NULL, &req->addr,
&req->addr2))
++ req->flags |= GNU_COMMAND_FAILED;
++ break;
++
++ case GNU_LOOKUP_STRUCT_CONTENTS:
++ req->value = lookup_struct_contents(req);
++ break;
++
++ case GNU_ITERATE_DATATYPES:
++ iterate_datatypes(req);
++ break;
++
++ default:
++ req->flags |= GNU_COMMAND_FAILED;
++ break;
++ }
++}
++
++/*
++ * Given a PC value, return the file and line number.
++ */
++static void
++gdb_get_line_number(struct gnu_request *req)
++{
++ struct symtab_and_line sal;
++ struct symbol *sym;
++ struct objfile *objfile;
++ CORE_ADDR pc;
++
++#define LASTCHAR(s) (s[strlen(s)-1])
++
++ /*
++ * Prime the addrmap pump.
++ */
++ if (req->name)
++ sym = lookup_symbol(req->name, 0, VAR_DOMAIN, 0).symbol;
++
++ pc = req->addr;
++
++ sal = find_pc_line(pc, 0);
++
++ if (!sal.symtab) {
++ /*
++ * If a module address line number can't be found, it's typically
++ * due to its addrmap still containing offset values because its
++ * objfile doesn't have full symbols loaded.
++ */
++ if (req->lm) {
++ objfile = req->lm->loaded_objfile;
++ if (!objfile_has_full_symbols(objfile) && objfile->sf) {
++ objfile->sf->qf->expand_all_symtabs(objfile);
++ sal = find_pc_line(pc, 0);
++ }
++ }
++ if (!sal.symtab) {
++ req->buf[0] = '\0';
++ return;
++ }
++ }
++
++ if (sal.symtab->filename && SYMTAB_DIRNAME(sal.symtab)) {
++ if (sal.symtab->filename[0] == '/')
++ sprintf(req->buf, "%s: %d",
++ sal.symtab->filename, sal.line);
++ else
++ sprintf(req->buf, "%s%s%s: %d",
++ SYMTAB_DIRNAME(sal.symtab),
++ LASTCHAR(SYMTAB_DIRNAME(sal.symtab)) == '/' ?
"" : "/",
++ sal.symtab->filename, sal.line);
++ }
++}
++
++
++/*
++ * General purpose routine for determining datatypes.
++ */
++
++static void
++gdb_get_datatype(struct gnu_request *req)
++{
++ register struct type *type;
++ register struct type *typedef_type;
++ expression_up expr;
++ struct symbol *sym;
++ register int i;
++ struct field *nextfield;
++ struct value *val;
++
++ if (gdb_CRASHDEBUG(2))
++ console("gdb_get_datatype [%s] (a)\n", req->name);
++
++ req->typecode = TYPE_CODE_UNDEF;
++
++ /*
++ * lookup_symbol() will pick up struct and union names.
++ */
++ sym = lookup_symbol(req->name, 0, STRUCT_DOMAIN, 0).symbol;
++ if (sym) {
++ req->typecode = TYPE_CODE(sym->type);
++ req->length = TYPE_LENGTH(sym->type);
++ if (req->member)
++ get_member_data(req, sym->type, 0, 1);
++
++ if (TYPE_CODE(sym->type) == TYPE_CODE_ENUM) {
++ if (req->flags & GNU_PRINT_ENUMERATORS)
++ dump_enum(sym->type, req);
++ }
++
++ return;
++ }
++
++ /*
++ * Otherwise parse the expression.
++ */
++ if (gdb_CRASHDEBUG(2))
++ console("gdb_get_datatype [%s] (b)\n", req->name);
++
++ expr = parse_expression(req->name);
++
++
++ switch (expr.get()->elts[0].opcode)
++ {
++ case OP_VAR_VALUE:
++ if (gdb_CRASHDEBUG(2))
++ console("expr->elts[0].opcode: OP_VAR_VALUE\n");
++ type = expr.get()->elts[2].symbol->type;
++ if (req->flags & GNU_VAR_LENGTH_TYPECODE) {
++ req->typecode = TYPE_CODE(type);
++ req->length = TYPE_LENGTH(type);
++ }
++ if (TYPE_CODE(type) == TYPE_CODE_ENUM) {
++ req->typecode = TYPE_CODE(type);
++ req->value = SYMBOL_VALUE(expr.get()->elts[2].symbol);
++ req->tagname = (char *)TYPE_TAG_NAME(type);
++ if (!req->tagname) {
++ val = evaluate_type(expr.get());
++ eval_enum(value_type(val), req);
++ }
++ }
++ break;
++
++ case OP_TYPE:
++ if (gdb_CRASHDEBUG(2))
++ console("expr->elts[0].opcode: OP_TYPE\n");
++ type = expr.get()->elts[1].type;
++
++ req->typecode = TYPE_CODE(type);
++ req->length = TYPE_LENGTH(type);
++
++ if (TYPE_CODE(type) == TYPE_CODE_TYPEDEF) {
++ req->is_typedef = TYPE_CODE_TYPEDEF;
++ if ((typedef_type = check_typedef(type))) {
++ req->typecode = TYPE_CODE(typedef_type);
++ req->length = TYPE_LENGTH(typedef_type);
++ type = typedef_type;
++ }
++ }
++
++ if (TYPE_CODE(type) == TYPE_CODE_ENUM) {
++ if (req->is_typedef)
++ if (req->flags & GNU_PRINT_ENUMERATORS) {
++ if (req->is_typedef)
++ fprintf_filtered(gdb_stdout,
++ "typedef ");
++ dump_enum(type, req);
++ }
++ }
++
++ if (req->member)
++ get_member_data(req, type, 0, 1);
++
++ break;
++
++ default:
++ if (gdb_CRASHDEBUG(2))
++ console("expr.get()->elts[0].opcode: %d (?)\n",
++ expr.get()->elts[0].opcode);
++ break;
++
++ }
++}
++
++/*
++ * More robust enum list dump that gdb's, showing the value of each
++ * identifier, each on its own line.
++ */
++static void
++dump_enum(struct type *type, struct gnu_request *req)
++{
++ register int i;
++ int len;
++ int lastval;
++
++ len = TYPE_NFIELDS (type);
++ lastval = 0;
++ if (TYPE_TAG_NAME(type))
++ fprintf_filtered(gdb_stdout,
++ "enum %s {\n", TYPE_TAG_NAME (type));
++ else
++ fprintf_filtered(gdb_stdout, "enum {\n");
++
++ for (i = 0; i < len; i++) {
++ fprintf_filtered(gdb_stdout, " %s",
++ TYPE_FIELD_NAME (type, i));
++ if (lastval != TYPE_FIELD_ENUMVAL (type, i)) {
++ fprintf_filtered (gdb_stdout, " = %s",
++ plongest(TYPE_FIELD_ENUMVAL (type, i)));
++ lastval = TYPE_FIELD_ENUMVAL (type, i);
++ } else
++ fprintf_filtered(gdb_stdout, " = %s",
plongest(lastval));
++ fprintf_filtered(gdb_stdout, "\n");
++ lastval++;
++ }
++ if (TYPE_TAG_NAME(type))
++ fprintf_filtered(gdb_stdout, "};\n");
++ else
++ fprintf_filtered(gdb_stdout, "} %s;\n", req->name);
++}
++
++/*
++ * Given an enum type with no tagname, determine its value.
++ */
++static void
++eval_enum(struct type *type, struct gnu_request *req)
++{
++ register int i;
++ int len;
++ long long lastval;
++
++ len = TYPE_NFIELDS (type);
++ lastval = 0;
++
++ for (i = 0; i < len; i++) {
++ if (lastval != TYPE_FIELD_ENUMVAL (type, i))
++ lastval = TYPE_FIELD_ENUMVAL (type, i);
++
++ if (STREQ(TYPE_FIELD_NAME(type, i), req->name)) {
++ req->tagname = "(unknown)";
++ req->value = lastval;
++ return;
++ }
++ lastval++;
++ }
++}
++
++/*
++ * Walk through a struct type's list of fields looking for the desired
++ * member field, and when found, return its relevant data.
++ */
++static void
++get_member_data(struct gnu_request *req, struct type *type, long offset, int is_first)
++{
++ register short i;
++ struct field *nextfield;
++ short nfields;
++ struct type *typedef_type, *target_type;
++
++ req->member_offset = -1;
++
++ nfields = TYPE_MAIN_TYPE(type)->nfields;
++ nextfield = TYPE_MAIN_TYPE(type)->flds_bnds.fields;
++
++ if (nfields == 0 && is_first /* The first call */) {
++ struct type *newtype;
++ newtype = lookup_transparent_type(req->name);
++ if (newtype) {
++ console("get_member_data(%s.%s): switching type from %lx to
%lx\n",
++ req->name, req->member, type, newtype);
++ nfields = TYPE_MAIN_TYPE(newtype)->nfields;
++ nextfield = TYPE_MAIN_TYPE(newtype)->flds_bnds.fields;
++ }
++ }
++
++ for (i = 0; i < nfields; i++) {
++ if (STREQ(req->member, nextfield->name)) {
++ req->member_offset = offset + nextfield->loc.bitpos;
++ req->member_length = TYPE_LENGTH(nextfield->type());
++ req->member_typecode = TYPE_CODE(nextfield->type());
++ req->member_main_type_name = (char *)TYPE_NAME(nextfield->type());
++ req->member_main_type_tag_name = (char *)TYPE_TAG_NAME(nextfield->type());
++ target_type = TYPE_TARGET_TYPE(nextfield->type());
++ if (target_type) {
++ req->member_target_type_name = (char *)TYPE_NAME(target_type);
++ req->member_target_type_tag_name = (char *)TYPE_TAG_NAME(target_type);
++ }
++ if ((req->member_typecode == TYPE_CODE_TYPEDEF) &&
++ (typedef_type = check_typedef(nextfield->type())))
++ req->member_length = TYPE_LENGTH(typedef_type);
++ return;
++ } else if (*nextfield->name == 0) { /* Anonymous struct/union */
++ get_member_data(req, nextfield->type(),
++ offset + nextfield->loc.bitpos, 0);
++ if (req->member_offset != -1)
++ return;
++ }
++ nextfield++;
++ }
++}
++
++/*
++ * Check whether a command exists. If it doesn't, the command will be
++ * returned indirectly via the error_hook.
++ */
++static void
++gdb_command_exists(struct gnu_request *req)
++{
++ extern struct cmd_list_element *cmdlist;
++ register struct cmd_list_element *c;
++
++ req->value = FALSE;
++ c = lookup_cmd((const char **)&req->name, cmdlist, "", NULL, 0,
1);
++ req->value = TRUE;
++}
++
++static void
++gdb_function_numargs(struct gnu_request *req)
++{
++ struct symbol *sym;
++
++ sym = find_pc_function(req->pc);
++
++ if (!sym || TYPE_CODE(sym->type) != TYPE_CODE_FUNC) {
++ req->flags |= GNU_COMMAND_FAILED;
++ return;
++ }
++
++ req->value = (ulong)TYPE_NFIELDS(sym->type);
++}
++
++struct load_module *gdb_current_load_module = NULL;
++
++static void
++gdb_add_symbol_file(struct gnu_request *req)
++{
++ register struct minimal_symbol *m;
++ struct load_module *lm;
++ int external, subsequent, found;
++ off_t offset;
++ ulong value, adjusted;
++ struct symbol *sym;
++ int i;
++ int allsect = 0;
++ char *secname;
++ char buf[80];
++
++ gdb_current_load_module = lm = (struct load_module *)req->addr;
++
++ req->name = lm->mod_namelist;
++ gdb_delete_symbol_file(req);
++ lm->loaded_objfile = NULL;
++
++ if ((lm->mod_flags & MOD_NOPATCH) == 0) {
++ for (i = 0 ; i < lm->mod_sections; i++) {
++ if (STREQ(lm->mod_section_data[i].name, ".text") &&
++ (lm->mod_section_data[i].flags & SEC_FOUND))
++ allsect = 1;
++ }
++
++ if (!allsect) {
++ sprintf(req->buf, "add-symbol-file %s 0x%lx %s",
lm->mod_namelist,
++ lm->mod_text_start ? lm->mod_text_start : lm->mod_base,
++ lm->mod_flags & MOD_DO_READNOW ? "-readnow" : "");
++ if (lm->mod_data_start) {
++ sprintf(buf, " -s .data 0x%lx", lm->mod_data_start);
++ strcat(req->buf, buf);
++ }
++ if (lm->mod_bss_start) {
++ sprintf(buf, " -s .bss 0x%lx", lm->mod_bss_start);
++ strcat(req->buf, buf);
++ }
++ if (lm->mod_rodata_start) {
++ sprintf(buf, " -s .rodata 0x%lx",
lm->mod_rodata_start);
++ strcat(req->buf, buf);
++ }
++ } else {
++ sprintf(req->buf, "add-symbol-file %s 0x%lx %s",
lm->mod_namelist,
++ lm->mod_text_start, lm->mod_flags & MOD_DO_READNOW ?
++ "-readnow" : "");
++ for (i = 0; i < lm->mod_sections; i++) {
++ secname = lm->mod_section_data[i].name;
++ if ((lm->mod_section_data[i].flags & SEC_FOUND) &&
++ !STREQ(secname, ".text")) {
++ sprintf(buf, " -s %s 0x%lx", secname,
++ lm->mod_section_data[i].offset + lm->mod_base);
++ strcat(req->buf, buf);
++ }
++ }
++ }
++ }
++
++ if (gdb_CRASHDEBUG(1))
++ fprintf_filtered(gdb_stdout, "%s\n", req->buf);
++
++ execute_command(req->buf, FALSE);
++
++ for (objfile *objfile : current_program_space->objfiles ()) {
++ if (same_file((char *)objfile_name(objfile), lm->mod_namelist)) {
++ if (objfile->separate_debug_objfile)
++ lm->loaded_objfile = objfile->separate_debug_objfile;
++ else
++ lm->loaded_objfile = objfile;
++ break;
++ }
++ }
++
++ if (!lm->loaded_objfile)
++ req->flags |= GNU_COMMAND_FAILED;
++}
++
++static void
++gdb_delete_symbol_file(struct gnu_request *req)
++{
++ for (objfile *objfile : current_program_space->objfiles ()) {
++ if (STREQ(objfile_name(objfile), req->name) ||
++ same_file((char *)objfile_name(objfile), req->name)) {
++ break;
++ }
++ }
++
++ if (gdb_CRASHDEBUG(2)) {
++ fprintf_filtered(gdb_stdout, "current object files:\n");
++ for (objfile *objfile : current_program_space->objfiles ())
++ fprintf_filtered(gdb_stdout, " %s\n", objfile_name(objfile));
++ }
++}
++
++/*
++ * Walk through all minimal_symbols, patching their values with the
++ * correct addresses.
++ */
++static void
++gdb_patch_symbol_values(struct gnu_request *req)
++{
++ req->name = PATCH_KERNEL_SYMBOLS_START;
++ patch_kernel_symbol(req);
++
++ for (objfile *objfile : current_program_space->objfiles ())
++ for (minimal_symbol *msymbol : objfile->msymbols ())
++ {
++ req->name = (char *)msymbol->m_name;
++ req->addr = (ulong)(&MSYMBOL_VALUE(msymbol));
++ if (!patch_kernel_symbol(req)) {
++ req->flags |= GNU_COMMAND_FAILED;
++ break;
++ }
++ }
++
++ req->name = PATCH_KERNEL_SYMBOLS_STOP;
++ patch_kernel_symbol(req);
++
++ clear_symtab_users(0);
++ gdb_merge_flags |= KERNEL_SYMBOLS_PATCHED;
++}
++
++static void
++gdb_get_symbol_type(struct gnu_request *req)
++{
++ expression_up expr;
++ struct value *val;
++ struct type *type;
++ struct type *target_type;
++
++ req->typecode = TYPE_CODE_UNDEF;
++
++ expr = parse_expression (req->name);
++ val = evaluate_type (expr.get());
++
++ type = value_type(val);
++
++ req->type_name = (char *)TYPE_MAIN_TYPE(type)->name;
++ req->typecode = TYPE_MAIN_TYPE(type)->code;
++ req->length = type->length;
++ req->type_tag_name = (char *)TYPE_TAG_NAME(type);
++ target_type = TYPE_MAIN_TYPE(type)->target_type;
++
++ if (target_type) {
++ req->target_typename = (char *)TYPE_MAIN_TYPE(target_type)->name;
++ req->target_typecode = TYPE_MAIN_TYPE(target_type)->code;
++ req->target_length = target_type->length;
++ }
++
++ if (req->member)
++ get_member_data(req, type, 0, 1);
++}
++
++static void
++gdb_debug_command(struct gnu_request *req)
++{
++
++}
++
++/*
++ * Only necessary on "patched" kernel symbol sessions, and called only by
++ * lookup_symbol(), pull a symbol value bait-and-switch operation by altering
++ * either a data symbol's address value or a text symbol's block start
address.
++ */
++static void
++gdb_bait_and_switch(char *name, struct symbol *sym)
++{
++ struct bound_minimal_symbol msym;
++ struct block *block;
++
++ if ((gdb_merge_flags & KERNEL_SYMBOLS_PATCHED) &&
++ (msym = lookup_minimal_symbol(name, NULL, gdb_kernel_objfile)).minsym) {
++ if (SYMBOL_CLASS(sym) == LOC_BLOCK) {
++ block = (struct block *)SYMBOL_BLOCK_VALUE(sym);
++ BLOCK_START(block) = BMSYMBOL_VALUE_ADDRESS(msym);
++ } else
++ SET_SYMBOL_VALUE_ADDRESS(sym, BMSYMBOL_VALUE_ADDRESS(msym));
++ }
++}
++
++#include "valprint.h"
++
++void
++get_user_print_option_address(struct gnu_request *req)
++{
++ extern struct value_print_options user_print_options;
++
++ req->addr = 0;
++
++ if (strcmp(req->name, "output_format") == 0)
++ req->addr = (ulong)&user_print_options.output_format;
++ if (strcmp(req->name, "print_max") == 0)
++ req->addr = (ulong)&user_print_options.print_max;
++ if (strcmp(req->name, "prettyprint_structs") == 0)
++ req->addr = (ulong)&user_print_options.prettyformat_structs;
++ if (strcmp(req->name, "prettyprint_arrays") == 0)
++ req->addr = (ulong)&user_print_options.prettyformat_arrays;
++ if (strcmp(req->name, "repeat_count_threshold") == 0)
++ req->addr = (ulong)&user_print_options.repeat_count_threshold;
++ if (strcmp(req->name, "stop_print_at_null") == 0)
++ req->addr = (ulong)&user_print_options.stop_print_at_null;
++ if (strcmp(req->name, "output_radix") == 0)
++ req->addr = (ulong)&output_radix;
++}
++
++CORE_ADDR crash_text_scope;
++
++static void
++gdb_set_crash_block(struct gnu_request *req)
++{
++ if (!req->addr) { /* debug */
++ crash_text_scope = 0;
++ return;
++ }
++
++ if ((req->addr2 = (ulong)block_for_pc(req->addr)))
++ crash_text_scope = req->addr;
++ else {
++ crash_text_scope = 0;
++ req->flags |= GNU_COMMAND_FAILED;
++ }
++}
++
++static const struct block *
++gdb_get_crash_block(void)
++{
++ if (crash_text_scope)
++ return block_for_pc(crash_text_scope);
++ else
++ return NULL;
++}
++
++static long
++lookup_struct_contents(struct gnu_request *req)
++{
++ int i;
++ long r;
++ struct field *f;
++ struct main_type *m;
++ const char *n;
++ struct main_type *top_m = (struct main_type *)req->addr;
++ char *type_name = req->type_name;
++
++ if (!top_m || !type_name)
++ return 0;
++
++ for (i = 0; i < top_m->nfields; i++)
++ {
++ f = top_m->flds_bnds.fields + i;
++ if (!f->type())
++ continue;
++ m = f->type()->main_type;
++
++ // If the field is an array, check the target type -
++ // it might be structure, or might not be.
++ // - struct request_sock *syn_table[0];
++ // here m->target_type->main_type->code is expected
++ // to be TYPE_CODE_PTR
++ // - struct list_head vec[TVN_SIZE];
++ // here m->target_type->main_type->code should be
++ // TYPE_CODE_STRUCT
++ if (m->code == TYPE_CODE_ARRAY && m->target_type)
++ m = m->target_type->main_type;
++
++ /* Here is a recursion.
++ * If we have struct variable (not pointer),
++ * scan this inner structure
++ */
++ if (m->code == TYPE_CODE_STRUCT) {
++ req->addr = (ulong)m;
++ r = lookup_struct_contents(req);
++ req->addr = (ulong)top_m;
++ if (r)
++ return 1;
++ }
++
++ if (m->code == TYPE_CODE_PTR && m->target_type)
++ m = m->target_type->main_type;
++ if (m->name)
++ n = m->name;
++ else
++ continue;
++
++ if (strstr(n, type_name))
++ return 1;
++ }
++
++ return 0;
++}
++
++static void
++iterate_datatypes (struct gnu_request *req)
++{
++ for (objfile *objfile : current_program_space->objfiles ())
++ {
++ if (!objfile_has_full_symbols(objfile) && objfile->sf) {
++ objfile->sf->qf->expand_all_symtabs(objfile);
++ }
++ struct compunit_symtab *cust = objfile->compunit_symtabs;
++ for (; cust != NULL; cust = cust->next)
++ {
++ const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (cust);
++
++ for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i)
++ {
++ const struct block *b = BLOCKVECTOR_BLOCK (bv, i);
++ struct block_iterator iter;
++ struct symbol *sym;
++
++ ALL_BLOCK_SYMBOLS (b, iter, sym)
++ {
++ QUIT;
++
++ if (SYMBOL_CLASS (sym) != LOC_TYPEDEF)
++ continue;
++
++ if (req->highest &&
++ !(req->lowest <= sym->type->length && sym->type->length
<= req->highest))
++ continue;
++
++ req->addr = (ulong)(sym->type->main_type);
++ req->name = (char *)(sym->m_name);
++ req->length = sym->type->length;
++
++ if (req->member) {
++ req->value = lookup_struct_contents(req);
++ if (!req->value)
++ continue;
++ }
++ req->callback(req, req->callback_data);
++ }
++ }
++ }
++ }
++}
++#endif
+diff -aurp -X diff_exclude gdb-10.1.orig/gdb/ui-file.h gdb-10.1/gdb/ui-file.h
+--- gdb-10.1.orig/gdb/ui-file.h 2020-09-12 19:33:41.000000000 -0700
++++ gdb-10.1/gdb/ui-file.h 2020-11-10 13:06:56.435569179 -0800
+@@ -195,10 +195,10 @@ public:
+
+ bool can_emit_style_escape () override;
+
+-private:
+ /* Sets the internal stream to FILE, and saves the FILE's file
+ descriptor in M_FD. */
+ void set_stream (FILE *file);
++private:
+
+ /* The file. */
+ FILE *m_file;
+diff -aurp -X diff_exclude gdb-10.1.orig/gdb/xml-syscall.c gdb-10.1/gdb/xml-syscall.c
+--- gdb-10.1.orig/gdb/xml-syscall.c 2020-10-23 21:23:02.000000000 -0700
++++ gdb-10.1/gdb/xml-syscall.c 2020-11-10 13:06:56.435569179 -0800
+@@ -37,7 +37,11 @@
+ static void
+ syscall_warn_user (void)
+ {
++#ifdef CRASH_MERGE
++ static int have_warned = 1;
++#else
+ static int have_warned = 0;
++#endif
+ if (!have_warned)
+ {
+ have_warned = 1;
+diff -aurp -X diff_exclude gdb-10.1.orig/libiberty/Makefile.in
gdb-10.1/libiberty/Makefile.in
+--- gdb-10.1.orig/libiberty/Makefile.in 2020-09-12 19:33:41.000000000 -0700
++++ gdb-10.1/libiberty/Makefile.in 2020-11-10 13:06:56.439569200 -0800
+@@ -180,6 +180,7 @@ REQUIRED_OFILES = \
+ ./getruntime.$(objext) ./hashtab.$(objext) ./hex.$(objext) \
+ ./lbasename.$(objext) ./lrealpath.$(objext) \
+ ./make-relative-prefix.$(objext) ./make-temp-file.$(objext) \
++ ./mkstemps.$(objext) \
+ ./objalloc.$(objext) \
+ ./obstack.$(objext) \
+ ./partition.$(objext) ./pexecute.$(objext) ./physmem.$(objext) \
+@@ -213,7 +214,7 @@ CONFIGURED_OFILES = ./asprintf.$(objext)
+ ./index.$(objext) ./insque.$(objext) \
+ ./memchr.$(objext) ./memcmp.$(objext) ./memcpy.$(objext) \
+ ./memmem.$(objext) ./memmove.$(objext) \
+- ./mempcpy.$(objext) ./memset.$(objext) ./mkstemps.$(objext) \
++ ./mempcpy.$(objext) ./memset.$(objext) \
+ ./pex-djgpp.$(objext) ./pex-msdos.$(objext) \
+ ./pex-unix.$(objext) ./pex-win32.$(objext) \
+ ./putenv.$(objext) \
+diff -aurp -X diff_exclude gdb-10.1.orig/Makefile.in gdb-10.1/Makefile.in
+--- gdb-10.1.orig/Makefile.in 2020-10-23 21:25:19.000000000 -0700
++++ gdb-10.1/Makefile.in 2020-11-10 13:06:56.447569243 -0800
+@@ -340,6 +340,9 @@ AR_FOR_BUILD = @AR_FOR_BUILD@
+ AS_FOR_BUILD = @AS_FOR_BUILD@
+ CC_FOR_BUILD = @CC_FOR_BUILD@
+ CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
++ifeq (${CRASH_TARGET}, PPC64)
++CFLAGS_FOR_BUILD += -m64 -fPIC
++endif
+ CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
+ CXX_FOR_BUILD = @CXX_FOR_BUILD@
+ DLLTOOL_FOR_BUILD = @DLLTOOL_FOR_BUILD@
+@@ -406,6 +409,9 @@ GNATBIND = @GNATBIND@
+ GNATMAKE = @GNATMAKE@
+
+ CFLAGS = @CFLAGS@
++ifeq (${CRASH_TARGET}, PPC64)
++CFLAGS += -m64 -fPIC
++endif
+ LDFLAGS = @LDFLAGS@
+ LIBCFLAGS = $(CFLAGS)
+ CXXFLAGS = @CXXFLAGS@
+diff -aurp -X diff_exclude gdb-10.1.orig/opcodes/i386-dis.c gdb-10.1/opcodes/i386-dis.c
+--- gdb-10.1.orig/opcodes/i386-dis.c 2020-10-23 21:23:02.000000000 -0700
++++ gdb-10.1/opcodes/i386-dis.c 2020-11-10 13:06:56.451569264 -0800
+@@ -9778,6 +9778,10 @@ print_insn (bfd_vma pc, disassemble_info
+ threebyte = *codep;
+ dp = &dis386_twobyte[threebyte];
+ need_modrm = twobyte_has_modrm[*codep];
++ if (dp->name && ((strcmp(dp->name, "ud2a") == 0) ||
(strcmp(dp->name, "ud2") == 0))) {
++ extern int kernel_BUG_encoding_bytes(void);
++ codep += kernel_BUG_encoding_bytes();
++ }
+ codep++;
+ }
+ else
+diff -aurp -X diff_exclude gdb-10.1.orig/readline/readline/misc.c
gdb-10.1/readline/readline/misc.c
+--- gdb-10.1.orig/readline/readline/misc.c 2020-09-12 19:33:41.000000000 -0700
++++ gdb-10.1/readline/readline/misc.c 2020-11-10 13:06:56.451569264 -0800
+@@ -403,7 +403,7 @@ _rl_history_set_point (void)
+
+ #if defined (VI_MODE)
+ if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
+- rl_point = 0;
++ rl_point = rl_end;
+ #endif /* VI_MODE */
+
+ if (rl_editing_mode == emacs_mode)
+diff -aurp -X diff_exclude gdb-10.1.orig/readline/readline/readline.h
gdb-10.1/readline/readline/readline.h
+--- gdb-10.1.orig/readline/readline/readline.h 2020-09-12 19:33:41.000000000 -0700
++++ gdb-10.1/readline/readline/readline.h 2020-11-10 13:06:56.451569264 -0800
+@@ -395,7 +395,7 @@ extern int rl_crlf PARAMS((void));
+ #if defined (USE_VARARGS) && defined (PREFER_STDARG)
+ extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
+ #else
+-extern int rl_message ();
++extern int rl_message (void);
+ #endif
+
+ extern int rl_show_char PARAMS((int));
+diff -aurp -X diff_exclude gdb-10.1.orig/readline/readline/rltypedefs.h
gdb-10.1/readline/readline/rltypedefs.h
+--- gdb-10.1.orig/readline/readline/rltypedefs.h 2020-09-12 19:33:41.000000000 -0700
++++ gdb-10.1/readline/readline/rltypedefs.h 2020-11-10 13:06:56.451569264 -0800
+@@ -32,10 +32,10 @@ extern "C" {
+ # define _FUNCTION_DEF
+
+ #if defined(__GNUC__) || defined(__clang__)
+-typedef int Function () __attribute__ ((deprecated));
+-typedef void VFunction () __attribute__ ((deprecated));
+-typedef char *CPFunction () __attribute__ ((deprecated));
+-typedef char **CPPFunction () __attribute__ ((deprecated));
++typedef int Function (void) __attribute__ ((deprecated));
++typedef void VFunction (void) __attribute__ ((deprecated));
++typedef char *CPFunction (void) __attribute__ ((deprecated));
++typedef char **CPPFunction (void) __attribute__ ((deprecated));
+ #else
+ typedef int Function ();
+ typedef void VFunction ();
+diff -aurp -X diff_exclude gdb-10.1.orig/readline/readline/util.c
gdb-10.1/readline/readline/util.c
+--- gdb-10.1.orig/readline/readline/util.c 2020-09-12 19:33:41.000000000 -0700
++++ gdb-10.1/readline/readline/util.c 2020-11-10 13:06:56.451569264 -0800
+@@ -487,10 +487,13 @@ _rl_trace (va_alist)
+
+ if (_rl_tracefp == 0)
+ _rl_tropen ();
++ if (!_rl_tracefp)
++ goto out;
+ vfprintf (_rl_tracefp, format, args);
+ fprintf (_rl_tracefp, "\n");
+ fflush (_rl_tracefp);
+
++out:
+ va_end (args);
+ }
+
+@@ -513,16 +516,17 @@ _rl_tropen (void)
+ sprintf (fnbuf, "/var/tmp/rltrace.%ld", (long) getpid ());
+ #endif
+ unlink (fnbuf);
+- _rl_tracefp = fopen (fnbuf, "w+");
++ _rl_tracefp = fopen (fnbuf, "w+xe");
+ return _rl_tracefp != 0;
+ }
+
+ int
+ _rl_trclose (void)
+ {
+- int r;
++ int r = 0;
+
+- r = fclose (_rl_tracefp);
++ if (_rl_tracefp)
++ r = fclose (_rl_tracefp);
+ _rl_tracefp = 0;
+ return r;
+ }
diff --git a/gdb-7.6-proc_service.h.patch b/gdb-7.6-proc_service.h.patch
deleted file mode 100644
index e4a788e..0000000
--- a/gdb-7.6-proc_service.h.patch
+++ /dev/null
@@ -1,67 +0,0 @@
---- gdb-7.6/gdb/gdb_proc_service.h.orig
-+++ gdb-7.6/gdb/gdb_proc_service.h
-@@ -115,7 +115,7 @@ extern pid_t ps_getpid (struct ps_procha
- /* Fetch the special per-thread address associated with the given LWP.
- This call is only used on a few platforms (most use a normal register).
- The meaning of the `int' parameter is machine-dependent. */
--extern ps_err_e ps_get_thread_area (const struct ps_prochandle *,
-+extern ps_err_e ps_get_thread_area (struct ps_prochandle *,
- lwpid_t, int, psaddr_t *);
-
-
---- gdb-7.6/gdb/amd64-linux-nat.c.orig
-+++ gdb-7.6/gdb/amd64-linux-nat.c
-@@ -493,7 +493,7 @@ amd64_linux_new_fork (struct lwp_info *p
- a request for a thread's local storage address. */
-
- ps_err_e
--ps_get_thread_area (const struct ps_prochandle *ph,
-+ps_get_thread_area (struct ps_prochandle *ph,
- lwpid_t lwpid, int idx, void **base)
- {
- if (gdbarch_bfd_arch_info (target_gdbarch ())->bits_per_word == 32)
---- gdb-7.6/gdb/aarch64-linux-nat.c.orig
-+++ gdb-7.6/gdb/aarch64-linux-nat.c
-@@ -750,7 +750,7 @@ aarch64_linux_new_fork (struct lwp_info
- storage (or its descriptor). */
-
- ps_err_e
--ps_get_thread_area (const struct ps_prochandle *ph,
-+ps_get_thread_area (struct ps_prochandle *ph,
- lwpid_t lwpid, int idx, void **base)
- {
- struct iovec iovec;
---- gdb-7.6/gdb/arm-linux-nat.c.orig
-+++ gdb-7.6/gdb/arm-linux-nat.c
-@@ -613,7 +613,7 @@ supply_fpregset (struct regcache *regcac
- /* Fetch the thread-local storage pointer for libthread_db. */
-
- ps_err_e
--ps_get_thread_area (const struct ps_prochandle *ph,
-+ps_get_thread_area (struct ps_prochandle *ph,
- lwpid_t lwpid, int idx, void **base)
- {
- if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
---- gdb-7.6/gdb/i386-linux-nat.c.orig
-+++ gdb-7.6/gdb/i386-linux-nat.c
-@@ -849,7 +849,7 @@ i386_linux_new_fork (struct lwp_info *pa
- storage (or its descriptor). */
-
- ps_err_e
--ps_get_thread_area (const struct ps_prochandle *ph,
-+ps_get_thread_area (struct ps_prochandle *ph,
- lwpid_t lwpid, int idx, void **base)
- {
- /* NOTE: cagney/2003-08-26: The definition of this buffer is found
---- gdb-7.6/gdb/mips-linux-nat.c.orig
-+++ gdb-7.6/gdb/mips-linux-nat.c
-@@ -154,7 +154,7 @@ mips64_linux_register_addr (struct gdbarch *gdbarch, int regno, int
store)
- /* Fetch the thread-local storage pointer for libthread_db. */
-
- ps_err_e
--ps_get_thread_area (const struct ps_prochandle *ph,
-+ps_get_thread_area (struct ps_prochandle *ph,
- lwpid_t lwpid, int idx, void **base)
- {
- if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
-
diff --git a/gdb-7.6.patch b/gdb-7.6.patch
deleted file mode 100644
index f64b55f..0000000
--- a/gdb-7.6.patch
+++ /dev/null
@@ -1,2503 +0,0 @@
-
-# When this file is updated in an existing source tree, it gets re-applied
-# during the next build using "patch -N --fuzz=0", which ignores patches
-# that have already been applied. However, if a gdb file has been modified
-# multiple times, the subsequent patching may fail to recognize that a
-# given patch has been previously applied, and will attempt to re-apply it.
-# To prevent any uninintended consequences, this file also acts as a
-# shell script that can restore any gdb file to its original state prior
-# to all subsequent patch applications.
-
-# The gdb-7.6-ppc64le-support.patch will have modified both files below
-# during the initial build, so continue previous behavior.
-
-if [ "$1" = "PPC64" ]
-then
- exit 0
-fi
-
-tar xvzmf gdb-7.6.tar.gz \
- gdb-7.6/gdb/symtab.c \
- gdb-7.6/gdb/printcmd.c
-
-exit 0
-
---- gdb-7.6/libiberty/Makefile.in.orig
-+++ gdb-7.6/libiberty/Makefile.in
-@@ -175,6 +175,7 @@ REQUIRED_OFILES = \
- ./getruntime.$(objext) ./hashtab.$(objext) ./hex.$(objext) \
- ./lbasename.$(objext) ./lrealpath.$(objext) \
- ./make-relative-prefix.$(objext) ./make-temp-file.$(objext) \
-+ ./mkstemps.$(objext) \
- ./objalloc.$(objext) \
- ./obstack.$(objext) \
- ./partition.$(objext) ./pexecute.$(objext) ./physmem.$(objext) \
-@@ -206,7 +207,7 @@ CONFIGURED_OFILES = ./asprintf.$(objext)
- ./index.$(objext) ./insque.$(objext) \
- ./memchr.$(objext) ./memcmp.$(objext) ./memcpy.$(objext) \
- ./memmem.$(objext) ./memmove.$(objext) \
-- ./mempcpy.$(objext) ./memset.$(objext) ./mkstemps.$(objext) \
-+ ./mempcpy.$(objext) ./memset.$(objext) \
- ./pex-djgpp.$(objext) ./pex-msdos.$(objext) \
- ./pex-unix.$(objext) ./pex-win32.$(objext) \
- ./putenv.$(objext) \
---- gdb-7.6/opcodes/i386-dis.c.orig
-+++ gdb-7.6/opcodes/i386-dis.c
-@@ -11510,6 +11510,10 @@ print_insn (bfd_vma pc, disassemble_info
- threebyte = *++codep;
- dp = &dis386_twobyte[threebyte];
- need_modrm = twobyte_has_modrm[*codep];
-+ if (dp->name && ((strcmp(dp->name, "ud2a") == 0) ||
(strcmp(dp->name, "ud2") == 0))) {
-+ extern int kernel_BUG_encoding_bytes(void);
-+ codep += kernel_BUG_encoding_bytes();
-+ }
- codep++;
- }
- else
---- gdb-7.6/gdb/dwarf2read.c.orig
-+++ gdb-7.6/gdb/dwarf2read.c
-@@ -2670,7 +2670,11 @@ read_index_from_section (struct objfile
- indices. */
- if (version < 4)
- {
-+#ifdef CRASH_MERGE
-+ static int warning_printed = 1;
-+#else
- static int warning_printed = 0;
-+#endif
- if (!warning_printed)
- {
- warning (_("Skipping obsolete .gdb_index section in %s."),
-@@ -2689,7 +2693,11 @@ read_index_from_section (struct objfile
- "set use-deprecated-index-sections on". */
- if (version < 6 && !deprecated_ok)
- {
-+#ifdef CRASH_MERGE
-+ static int warning_printed = 1;
-+#else
- static int warning_printed = 0;
-+#endif
- if (!warning_printed)
- {
- warning (_("\
---- gdb-7.6/gdb/amd64-linux-nat.c.orig
-+++ gdb-7.6/gdb/amd64-linux-nat.c
-@@ -45,6 +45,17 @@
- /* ezannoni-2003-07-09: I think this is fixed. The extraneous defs have
- been removed from ptrace.h in the kernel. However, better safe than
- sorry. */
-+#ifdef CRASH_MERGE
-+/*
-+ * When compiling within a 2.6.25-based Fedora build environment with
-+ * gcc 4.3, four new "typedef unsigned int u32;" declarations were
-+ * required due to a new ptrace_bts_config structure declaration in
-+ * "asm-x86/ptrace-abi.h" that used u32 members, but u32 is defined in
-+ * "asm-x86/types.h" within a __KERNEL__ section. They've been changed
-+ * to __u32, but this patch remains for building in that environment.
-+ */
-+typedef unsigned int u32;
-+#endif
- #include <asm/ptrace.h>
- #include <sys/reg.h>
- #include "gdb_proc_service.h"
---- gdb-7.6/gdb/symfile.c.orig
-+++ gdb-7.6/gdb/symfile.c
-@@ -693,7 +693,26 @@ default_symfile_offsets (struct objfile
- for (cur_sec = abfd->sections; cur_sec != NULL; cur_sec = cur_sec->next)
- /* We do not expect this to happen; just skip this step if the
- relocatable file has a section with an assigned VMA. */
-- if (bfd_section_vma (abfd, cur_sec) != 0)
-+ if (bfd_section_vma (abfd, cur_sec) != 0
-+ /*
-+ * Kernel modules may have some non-zero VMAs, i.e., like the
-+ * __ksymtab and __ksymtab_gpl sections in this example:
-+ *
-+ * Section Headers:
-+ * [Nr] Name Type Address Offset
-+ * Size EntSize Flags Link Info Align
-+ * ...
-+ * [ 8] __ksymtab PROGBITS 0000000000000060 0000ad90
-+ * 0000000000000010 0000000000000000 A 0 0 16
-+ * [ 9] .rela__ksymtab RELA 0000000000000000 0000ada0
-+ * 0000000000000030 0000000000000018 43 8 8
-+ * [10] __ksymtab_gpl PROGBITS 0000000000000070 0000add0
-+ * 00000000000001a0 0000000000000000 A 0 0 16
-+ * ...
-+ *
-+ * but they should be treated as if they are NULL.
-+ */
-+ && strncmp (bfd_get_section_name (abfd, cur_sec), "__k", 3) !=
0)
- break;
-
- if (cur_sec == NULL)
-@@ -1122,6 +1141,12 @@ symbol_file_add_with_addrs_or_offsets (b
- error (_("Not confirmed."));
-
- objfile = allocate_objfile (abfd, flags | (mainline ? OBJF_MAINLINE : 0));
-+#ifdef CRASH_MERGE
-+ if (add_flags & SYMFILE_MAINLINE) {
-+ extern struct objfile *gdb_kernel_objfile;
-+ gdb_kernel_objfile = objfile;
-+ }
-+#endif
-
- if (parent)
- add_separate_debug_objfile (objfile, parent);
-@@ -1484,6 +1509,9 @@ find_separate_debug_file (const char *di
- VEC (char_ptr) *debugdir_vec;
- struct cleanup *back_to;
- int ix;
-+#ifdef CRASH_MERGE
-+ extern int check_specified_module_tree(char *, char *);
-+#endif
-
- /* Set I to max (strlen (canon_dir), strlen (dir)). */
- i = strlen (dir);
-@@ -1513,6 +1541,15 @@ find_separate_debug_file (const char *di
- if (separate_debug_file_exists (debugfile, crc32, objfile))
- return debugfile;
-
-+#ifdef CRASH_MERGE
-+{
-+ if (check_specified_module_tree(objfile->name, debugfile) &&
-+ separate_debug_file_exists(debugfile, crc32, objfile)) {
-+ return debugfile;
-+ }
-+}
-+#endif
-+
- /* Then try in the global debugfile directories.
-
- Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
-@@ -1583,6 +1620,10 @@ find_separate_debug_file_by_debuglink (s
- char *debugfile;
- unsigned long crc32;
- struct cleanup *cleanups;
-+#ifdef CRASH_MERGE
-+ char *name_copy;
-+ extern char *check_specified_kernel_debug_file();
-+#endif
-
- debuglink = get_debug_link_info (objfile, &crc32);
-
-@@ -1635,6 +1676,12 @@ find_separate_debug_file_by_debuglink (s
- }
-
- do_cleanups (cleanups);
-+#ifdef CRASH_MERGE
-+ if (debugfile == NULL) {
-+ name_copy = check_specified_kernel_debug_file();
-+ return (name_copy ? xstrdup(name_copy) : NULL);
-+ }
-+#endif
- return debugfile;
- }
-
-@@ -2409,8 +2456,10 @@ add_symbol_file_command (char *args, int
- so we can't determine what section names are valid. */
- }
-
-+#ifndef CRASH_MERGE
- if (from_tty && (!query ("%s", "")))
- error (_("Not confirmed."));
-+#endif
-
- symbol_file_add (filename, from_tty ? SYMFILE_VERBOSE : 0,
- section_addrs, flags);
-@@ -3690,6 +3739,15 @@ bfd_byte *
- symfile_relocate_debug_section (struct objfile *objfile,
- asection *sectp, bfd_byte *buf)
- {
-+#ifdef CRASH_MERGE
-+ /* Executable files have all the relocations already resolved.
-+ * Handle files linked with --emit-relocs.
-+ *
http://sources.redhat.com/ml/gdb/2006-08/msg00137.html
-+ */
-+ bfd *abfd = objfile->obfd;
-+ if ((abfd->flags & EXEC_P) != 0)
-+ return NULL;
-+#endif
- gdb_assert (objfile->sf->sym_relocate);
-
- return (*objfile->sf->sym_relocate) (objfile, sectp, buf);
---- gdb-7.6/gdb/cli/cli-cmds.c.orig
-+++ gdb-7.6/gdb/cli/cli-cmds.c
-@@ -466,6 +466,10 @@ show_script_ext_mode (struct ui_file *fi
- If SEARCH_PATH is non-zero, and the file isn't found in cwd,
- search for it in the source search path. */
-
-+#ifdef CRASH_MERGE
-+static int crash_from_tty = 0;
-+#endif
-+
- int
- find_and_open_script (const char *script_file, int search_path,
- FILE **streamp, char **full_pathp)
-@@ -508,6 +512,32 @@ find_and_open_script (const char *script
- return 0;
- }
-
-+#ifdef CRASH_MERGE
-+ /*
-+ * Only allow trusted versions of .gdbinit files to be
-+ * sourced during session initialization.
-+ */
-+ if (crash_from_tty == -1)
-+ {
-+ struct stat statbuf;
-+ FILE *stream = *streamp;
-+ int fd = fileno (stream);
-+ if (fstat (fd, &statbuf) < 0)
-+ {
-+ perror_with_name (*full_pathp);
-+ fclose (stream);
-+ return 0;
-+ }
-+ if (statbuf.st_uid != getuid () || (statbuf.st_mode & S_IWOTH))
-+ {
-+ extern void untrusted_file(FILE *, char *);
-+ untrusted_file(NULL, *full_pathp);
-+ fclose (stream);
-+ return 0;
-+ }
-+ }
-+#endif
-+
- return 1;
- }
-
-@@ -566,7 +596,11 @@ source_script_with_search (const char *f
- If the source command was invoked interactively, throw an
- error. Otherwise (e.g. if it was invoked by a script),
- silently ignore the error. */
-+#ifdef CRASH_MERGE
-+ if (from_tty > 0)
-+#else
- if (from_tty)
-+#endif
- perror_with_name (file);
- else
- return;
-@@ -589,7 +623,14 @@ source_script_with_search (const char *f
- void
- source_script (char *file, int from_tty)
- {
-+#ifdef CRASH_MERGE
-+ crash_from_tty = from_tty;
-+#endif
- source_script_with_search (file, from_tty, 0);
-+#ifdef CRASH_MERGE
-+ crash_from_tty = 0;
-+#endif
-+
- }
-
- /* Return the source_verbose global variable to its previous state
---- gdb-7.6/gdb/psymtab.c.orig
-+++ gdb-7.6/gdb/psymtab.c
-@@ -305,10 +305,14 @@ find_pc_sect_psymtab (struct objfile *ob
- struct minimal_symbol *msymbol)
- {
- struct partial_symtab *pst;
-+#ifdef CRASH_MERGE
-+ extern int gdb_line_number_callback(unsigned long, unsigned long, unsigned long);
-+#endif
-
- /* Try just the PSYMTABS_ADDRMAP mapping first as it has better granularity
- than the later used TEXTLOW/TEXTHIGH one. */
-
-+#ifndef __i386__
- if (objfile->psymtabs_addrmap != NULL)
- {
- pst = addrmap_find (objfile->psymtabs_addrmap, pc);
-@@ -343,6 +347,7 @@ find_pc_sect_psymtab (struct objfile *ob
- }
-
- next:
-+#endif
-
- /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs
- which still have no corresponding full SYMTABs read. But it is not
-@@ -361,7 +366,12 @@ find_pc_sect_psymtab (struct objfile *ob
-
- best_pst = find_pc_sect_psymtab_closer (objfile, pc, section, pst,
- msymbol);
-+#ifdef CRASH_MERGE
-+ if ((best_pst != NULL) &&
-+ gdb_line_number_callback(pc, pst->textlow, pst->texthigh))
-+#else
- if (best_pst != NULL)
-+#endif
- return best_pst;
- }
-
---- gdb-7.6/gdb/symtab.c.orig
-+++ gdb-7.6/gdb/symtab.c
-@@ -1198,7 +1198,9 @@ demangle_for_lookup (const char *name, e
- doesn't affect these calls since they are looking for a known
- variable and thus can probably assume it will never hit the C++
- code). */
--
-+#ifdef CRASH_MERGE
-+static void gdb_bait_and_switch(char *, struct symbol *);
-+#endif
- struct symbol *
- lookup_symbol_in_language (const char *name, const struct block *block,
- const domain_enum domain, enum language lang,
-@@ -1212,17 +1214,30 @@ lookup_symbol_in_language (const char *n
- is_a_field_of_this);
- do_cleanups (cleanup);
-
-+#ifdef CRASH_MERGE
-+ if (returnval && (domain == VAR_DOMAIN))
-+ gdb_bait_and_switch((char *)modified_name, returnval);
-+#endif
-+
- return returnval;
- }
-
- /* Behave like lookup_symbol_in_language, but performed with the
- current language. */
-
-+#ifdef CRASH_MERGE
-+static struct block *gdb_get_crash_block(void);
-+#endif
-+
- struct symbol *
- lookup_symbol (const char *name, const struct block *block,
- domain_enum domain,
- struct field_of_this_result *is_a_field_of_this)
- {
-+#ifdef CRASH_MERGE
-+ if (!block)
-+ block = gdb_get_crash_block();
-+#endif
- return lookup_symbol_in_language (name, block, domain,
- current_language->la_language,
- is_a_field_of_this);
-@@ -5100,3 +5115,662 @@ When enabled, debugging messages are pri
-
- observer_attach_executable_changed (symtab_observer_executable_changed);
- }
-+
-+#ifdef CRASH_MERGE
-+#include "gdb-stabs.h"
-+#include "version.h"
-+#define GDB_COMMON
-+#include "../../defs.h"
-+
-+static void get_member_data(struct gnu_request *, struct type *);
-+static void dump_enum(struct type *, struct gnu_request *);
-+static void eval_enum(struct type *, struct gnu_request *);
-+static void gdb_get_line_number(struct gnu_request *);
-+static void gdb_get_datatype(struct gnu_request *);
-+static void gdb_get_symbol_type(struct gnu_request *);
-+static void gdb_command_exists(struct gnu_request *);
-+static void gdb_debug_command(struct gnu_request *);
-+static void gdb_function_numargs(struct gnu_request *);
-+static void gdb_add_symbol_file(struct gnu_request *);
-+static void gdb_delete_symbol_file(struct gnu_request *);
-+static void gdb_patch_symbol_values(struct gnu_request *);
-+extern void replace_ui_file_FILE(struct ui_file *, FILE *);
-+static void get_user_print_option_address(struct gnu_request *);
-+extern int get_frame_offset(CORE_ADDR);
-+static void gdb_set_crash_block(struct gnu_request *);
-+void gdb_command_funnel(struct gnu_request *);
-+
-+struct objfile *gdb_kernel_objfile = { 0 };
-+
-+static ulong gdb_merge_flags = 0;
-+#define KERNEL_SYMBOLS_PATCHED (0x1)
-+
-+#undef STREQ
-+#define STREQ(A, B) (A && B && (strcmp(A, B) == 0))
-+
-+/*
-+ * All commands from above come through here.
-+ */
-+void
-+gdb_command_funnel(struct gnu_request *req)
-+{
-+ struct symbol *sym;
-+
-+ if (req->command != GNU_VERSION) {
-+ replace_ui_file_FILE(gdb_stdout, req->fp);
-+ replace_ui_file_FILE(gdb_stderr, req->fp);
-+ do_cleanups(all_cleanups());
-+ }
-+
-+ switch (req->command)
-+ {
-+ case GNU_VERSION:
-+ req->buf = (char *)version;
-+ break;
-+
-+ case GNU_PASS_THROUGH:
-+ execute_command(req->buf,
-+ req->flags & GNU_FROM_TTY_OFF ? FALSE : TRUE);
-+ break;
-+
-+ case GNU_USER_PRINT_OPTION:
-+ get_user_print_option_address(req);
-+ break;
-+
-+ case GNU_RESOLVE_TEXT_ADDR:
-+ sym = find_pc_function(req->addr);
-+ if (!sym || TYPE_CODE(sym->type) != TYPE_CODE_FUNC)
-+ req->flags |= GNU_COMMAND_FAILED;
-+ break;
-+
-+ case GNU_DISASSEMBLE:
-+ if (req->addr2)
-+ sprintf(req->buf, "disassemble 0x%lx 0x%lx",
-+ req->addr, req->addr2);
-+ else
-+ sprintf(req->buf, "disassemble 0x%lx", req->addr);
-+ execute_command(req->buf, TRUE);
-+ break;
-+
-+ case GNU_ADD_SYMBOL_FILE:
-+ gdb_add_symbol_file(req);
-+ break;
-+
-+ case GNU_DELETE_SYMBOL_FILE:
-+ gdb_delete_symbol_file(req);
-+ break;
-+
-+ case GNU_GET_LINE_NUMBER:
-+ gdb_get_line_number(req);
-+ break;
-+
-+ case GNU_GET_DATATYPE:
-+ gdb_get_datatype(req);
-+ break;
-+
-+ case GNU_GET_SYMBOL_TYPE:
-+ gdb_get_symbol_type(req);
-+ break;
-+
-+ case GNU_COMMAND_EXISTS:
-+ gdb_command_exists(req);
-+ break;
-+
-+ case GNU_ALPHA_FRAME_OFFSET:
-+ req->value = 0;
-+ break;
-+
-+ case GNU_FUNCTION_NUMARGS:
-+ gdb_function_numargs(req);
-+ break;
-+
-+ case GNU_DEBUG_COMMAND:
-+ gdb_debug_command(req);
-+ break;
-+
-+ case GNU_PATCH_SYMBOL_VALUES:
-+ gdb_patch_symbol_values(req);
-+ break;
-+
-+ case GNU_SET_CRASH_BLOCK:
-+ gdb_set_crash_block(req);
-+ break;
-+
-+ default:
-+ req->flags |= GNU_COMMAND_FAILED;
-+ break;
-+ }
-+}
-+
-+/*
-+ * Given a PC value, return the file and line number.
-+ */
-+static void
-+gdb_get_line_number(struct gnu_request *req)
-+{
-+ struct symtab_and_line sal;
-+ struct symbol *sym;
-+ CORE_ADDR pc;
-+
-+#define LASTCHAR(s) (s[strlen(s)-1])
-+
-+ /*
-+ * Prime the addrmap pump.
-+ */
-+ if (req->name)
-+ sym = lookup_symbol(req->name, 0, VAR_DOMAIN, 0);
-+
-+ pc = req->addr;
-+
-+ sal = find_pc_line(pc, 0);
-+
-+ if (!sal.symtab) {
-+ req->buf[0] = '\0';
-+ return;
-+ }
-+
-+ if (sal.symtab->filename && sal.symtab->dirname) {
-+ if (sal.symtab->filename[0] == '/')
-+ sprintf(req->buf, "%s: %d",
-+ sal.symtab->filename, sal.line);
-+ else
-+ sprintf(req->buf, "%s%s%s: %d",
-+ sal.symtab->dirname,
-+ LASTCHAR(sal.symtab->dirname) == '/' ?
"" : "/",
-+ sal.symtab->filename, sal.line);
-+ }
-+}
-+
-+
-+/*
-+ * General purpose routine for determining datatypes.
-+ */
-+
-+static void
-+gdb_get_datatype(struct gnu_request *req)
-+{
-+ register struct cleanup *old_chain = NULL;
-+ register struct type *type;
-+ register struct type *typedef_type;
-+ struct expression *expr;
-+ struct symbol *sym;
-+ register int i;
-+ struct field *nextfield;
-+ struct value *val;
-+
-+ if (gdb_CRASHDEBUG(2))
-+ console("gdb_get_datatype [%s] (a)\n", req->name);
-+
-+ req->typecode = TYPE_CODE_UNDEF;
-+
-+ /*
-+ * lookup_symbol() will pick up struct and union names.
-+ */
-+ sym = lookup_symbol(req->name, 0, STRUCT_DOMAIN, 0);
-+ if (sym) {
-+ req->typecode = TYPE_CODE(sym->type);
-+ req->length = TYPE_LENGTH(sym->type);
-+ if (req->member)
-+ get_member_data(req, sym->type);
-+
-+ if (TYPE_CODE(sym->type) == TYPE_CODE_ENUM) {
-+ if (req->flags & GNU_PRINT_ENUMERATORS)
-+ dump_enum(sym->type, req);
-+ }
-+
-+ return;
-+ }
-+
-+ /*
-+ * Otherwise parse the expression.
-+ */
-+ if (gdb_CRASHDEBUG(2))
-+ console("gdb_get_datatype [%s] (b)\n", req->name);
-+
-+ expr = parse_expression(req->name);
-+
-+ old_chain = make_cleanup(free_current_contents, &expr);
-+
-+
-+ switch (expr->elts[0].opcode)
-+ {
-+ case OP_VAR_VALUE:
-+ if (gdb_CRASHDEBUG(2))
-+ console("expr->elts[0].opcode: OP_VAR_VALUE\n");
-+ type = expr->elts[2].symbol->type;
-+ if (req->flags & GNU_VAR_LENGTH_TYPECODE) {
-+ req->typecode = TYPE_CODE(type);
-+ req->length = TYPE_LENGTH(type);
-+ }
-+ if (TYPE_CODE(type) == TYPE_CODE_ENUM) {
-+ req->typecode = TYPE_CODE(type);
-+ req->value = SYMBOL_VALUE(expr->elts[2].symbol);
-+ req->tagname = (char *)TYPE_TAG_NAME(type);
-+ if (!req->tagname) {
-+ val = evaluate_type(expr);
-+ eval_enum(value_type(val), req);
-+ }
-+ }
-+ break;
-+
-+ case OP_TYPE:
-+ if (gdb_CRASHDEBUG(2))
-+ console("expr->elts[0].opcode: OP_TYPE\n");
-+ type = expr->elts[1].type;
-+
-+ req->typecode = TYPE_CODE(type);
-+ req->length = TYPE_LENGTH(type);
-+
-+ if (TYPE_CODE(type) == TYPE_CODE_TYPEDEF) {
-+ req->is_typedef = TYPE_CODE_TYPEDEF;
-+ if ((typedef_type = check_typedef(type))) {
-+ req->typecode = TYPE_CODE(typedef_type);
-+ req->length = TYPE_LENGTH(typedef_type);
-+ type = typedef_type;
-+ }
-+ }
-+
-+ if (TYPE_CODE(type) == TYPE_CODE_ENUM) {
-+ if (req->is_typedef)
-+ if (req->flags & GNU_PRINT_ENUMERATORS) {
-+ if (req->is_typedef)
-+ fprintf_filtered(gdb_stdout,
-+ "typedef ");
-+ dump_enum(type, req);
-+ }
-+ }
-+
-+ if (req->member)
-+ get_member_data(req, type);
-+
-+ break;
-+
-+ default:
-+ if (gdb_CRASHDEBUG(2))
-+ console("expr->elts[0].opcode: %d (?)\n",
-+ expr->elts[0].opcode);
-+ break;
-+
-+ }
-+
-+ do_cleanups(old_chain);
-+}
-+
-+/*
-+ * More robust enum list dump that gdb's, showing the value of each
-+ * identifier, each on its own line.
-+ */
-+static void
-+dump_enum(struct type *type, struct gnu_request *req)
-+{
-+ register int i;
-+ int len;
-+ int lastval;
-+
-+ len = TYPE_NFIELDS (type);
-+ lastval = 0;
-+ if (TYPE_TAG_NAME(type))
-+ fprintf_filtered(gdb_stdout,
-+ "enum %s {\n", TYPE_TAG_NAME (type));
-+ else
-+ fprintf_filtered(gdb_stdout, "enum {\n");
-+
-+ for (i = 0; i < len; i++) {
-+ fprintf_filtered(gdb_stdout, " %s",
-+ TYPE_FIELD_NAME (type, i));
-+ if (lastval != TYPE_FIELD_BITPOS (type, i)) {
-+ fprintf_filtered (gdb_stdout, " = %d",
-+ TYPE_FIELD_BITPOS (type, i));
-+ lastval = TYPE_FIELD_BITPOS (type, i);
-+ } else
-+ fprintf_filtered(gdb_stdout, " = %d", lastval);
-+ fprintf_filtered(gdb_stdout, "\n");
-+ lastval++;
-+ }
-+ if (TYPE_TAG_NAME(type))
-+ fprintf_filtered(gdb_stdout, "};\n");
-+ else
-+ fprintf_filtered(gdb_stdout, "} %s;\n", req->name);
-+}
-+
-+/*
-+ * Given an enum type with no tagname, determine its value.
-+ */
-+static void
-+eval_enum(struct type *type, struct gnu_request *req)
-+{
-+ register int i;
-+ int len;
-+ int lastval;
-+
-+ len = TYPE_NFIELDS (type);
-+ lastval = 0;
-+
-+ for (i = 0; i < len; i++) {
-+ if (lastval != TYPE_FIELD_BITPOS (type, i)) {
-+ lastval = TYPE_FIELD_BITPOS (type, i);
-+ }
-+ if (STREQ(TYPE_FIELD_NAME(type, i), req->name)) {
-+ req->tagname = "(unknown)";
-+ req->value = lastval;
-+ return;
-+ }
-+ lastval++;
-+ }
-+}
-+
-+/*
-+ * Walk through a struct type's list of fields looking for the desired
-+ * member field, and when found, return its relevant data.
-+ */
-+static void
-+get_member_data(struct gnu_request *req, struct type *type)
-+{
-+ register short i;
-+ struct field *nextfield;
-+ short nfields;
-+ struct type *typedef_type;
-+
-+ req->member_offset = -1;
-+
-+ nfields = TYPE_MAIN_TYPE(type)->nfields;
-+ nextfield = TYPE_MAIN_TYPE(type)->flds_bnds.fields;
-+
-+ if (nfields == 0) {
-+ struct type *newtype;
-+ newtype = lookup_transparent_type(req->name);
-+ if (newtype) {
-+ console("get_member_data(%s.%s): switching type from %lx to
%lx\n",
-+ req->name, req->member, type, newtype);
-+ nfields = TYPE_MAIN_TYPE(newtype)->nfields;
-+ nextfield = TYPE_MAIN_TYPE(newtype)->flds_bnds.fields;
-+ }
-+ }
-+
-+ for (i = 0; i < nfields; i++) {
-+ if (STREQ(req->member, nextfield->name)) {
-+ req->member_offset = nextfield->loc.bitpos;
-+ req->member_length = TYPE_LENGTH(nextfield->type);
-+ req->member_typecode = TYPE_CODE(nextfield->type);
-+ if ((req->member_typecode == TYPE_CODE_TYPEDEF) &&
-+ (typedef_type = check_typedef(nextfield->type)))
-+ req->member_length = TYPE_LENGTH(typedef_type);
-+ return;
-+ }
-+ nextfield++;
-+ }
-+}
-+
-+/*
-+ * Check whether a command exists. If it doesn't, the command will be
-+ * returned indirectly via the error_hook.
-+ */
-+static void
-+gdb_command_exists(struct gnu_request *req)
-+{
-+ extern struct cmd_list_element *cmdlist;
-+ register struct cmd_list_element *c;
-+
-+ req->value = FALSE;
-+ c = lookup_cmd(&req->name, cmdlist, "", 0, 1);
-+ req->value = TRUE;
-+}
-+
-+static void
-+gdb_function_numargs(struct gnu_request *req)
-+{
-+ struct symbol *sym;
-+
-+ sym = find_pc_function(req->pc);
-+
-+ if (!sym || TYPE_CODE(sym->type) != TYPE_CODE_FUNC) {
-+ req->flags |= GNU_COMMAND_FAILED;
-+ return;
-+ }
-+
-+ req->value = (ulong)TYPE_NFIELDS(sym->type);
-+}
-+
-+struct load_module *gdb_current_load_module = NULL;
-+
-+static void
-+gdb_add_symbol_file(struct gnu_request *req)
-+{
-+ register struct objfile *loaded_objfile = NULL;
-+ register struct objfile *objfile;
-+ register struct minimal_symbol *m;
-+ struct load_module *lm;
-+ int external, subsequent, found;
-+ off_t offset;
-+ ulong value, adjusted;
-+ struct symbol *sym;
-+ struct expression *expr;
-+ struct cleanup *old_chain;
-+ int i;
-+ int allsect = 0;
-+ char *secname;
-+ char buf[80];
-+
-+ gdb_current_load_module = lm = (struct load_module *)req->addr;
-+
-+ req->name = lm->mod_namelist;
-+ gdb_delete_symbol_file(req);
-+
-+ if ((lm->mod_flags & MOD_NOPATCH) == 0) {
-+ for (i = 0 ; i < lm->mod_sections; i++) {
-+ if (STREQ(lm->mod_section_data[i].name, ".text") &&
-+ (lm->mod_section_data[i].flags & SEC_FOUND))
-+ allsect = 1;
-+ }
-+
-+ if (!allsect) {
-+ sprintf(req->buf, "add-symbol-file %s 0x%lx %s",
lm->mod_namelist,
-+ lm->mod_text_start ? lm->mod_text_start : lm->mod_base,
-+ lm->mod_flags & MOD_DO_READNOW ? "-readnow" : "");
-+ if (lm->mod_data_start) {
-+ sprintf(buf, " -s .data 0x%lx", lm->mod_data_start);
-+ strcat(req->buf, buf);
-+ }
-+ if (lm->mod_bss_start) {
-+ sprintf(buf, " -s .bss 0x%lx", lm->mod_bss_start);
-+ strcat(req->buf, buf);
-+ }
-+ if (lm->mod_rodata_start) {
-+ sprintf(buf, " -s .rodata 0x%lx",
lm->mod_rodata_start);
-+ strcat(req->buf, buf);
-+ }
-+ } else {
-+ sprintf(req->buf, "add-symbol-file %s 0x%lx %s",
lm->mod_namelist,
-+ lm->mod_text_start, lm->mod_flags & MOD_DO_READNOW ?
-+ "-readnow" : "");
-+ for (i = 0; i < lm->mod_sections; i++) {
-+ secname = lm->mod_section_data[i].name;
-+ if ((lm->mod_section_data[i].flags & SEC_FOUND) &&
-+ !STREQ(secname, ".text")) {
-+ sprintf(buf, " -s %s 0x%lx", secname,
-+ lm->mod_section_data[i].offset + lm->mod_base);
-+ strcat(req->buf, buf);
-+ }
-+ }
-+ }
-+ }
-+
-+ if (gdb_CRASHDEBUG(1))
-+ fprintf_filtered(gdb_stdout, "%s\n", req->buf);
-+
-+ execute_command(req->buf, FALSE);
-+
-+ ALL_OBJFILES(objfile) {
-+ if (same_file(objfile->name, lm->mod_namelist)) {
-+ loaded_objfile = objfile;
-+ break;
-+ }
-+ }
-+
-+ if (!loaded_objfile)
-+ req->flags |= GNU_COMMAND_FAILED;
-+}
-+
-+static void
-+gdb_delete_symbol_file(struct gnu_request *req)
-+{
-+ register struct objfile *objfile;
-+
-+ ALL_OBJFILES(objfile) {
-+ if (STREQ(objfile->name, req->name) ||
-+ same_file(objfile->name, req->name)) {
-+ free_objfile(objfile);
-+ break;
-+ }
-+ }
-+
-+ if (gdb_CRASHDEBUG(2)) {
-+ fprintf_filtered(gdb_stdout, "current object files:\n");
-+ ALL_OBJFILES(objfile)
-+ fprintf_filtered(gdb_stdout, " %s\n", objfile->name);
-+ }
-+}
-+
-+/*
-+ * Walk through all minimal_symbols, patching their values with the
-+ * correct addresses.
-+ */
-+static void
-+gdb_patch_symbol_values(struct gnu_request *req)
-+{
-+ struct minimal_symbol *msymbol;
-+ struct objfile *objfile;
-+
-+ req->name = PATCH_KERNEL_SYMBOLS_START;
-+ patch_kernel_symbol(req);
-+
-+ ALL_MSYMBOLS (objfile, msymbol)
-+ {
-+ req->name = (char *)msymbol->ginfo.name;
-+ req->addr = (ulong)(&SYMBOL_VALUE_ADDRESS(msymbol));
-+ if (!patch_kernel_symbol(req)) {
-+ req->flags |= GNU_COMMAND_FAILED;
-+ break;
-+ }
-+ }
-+
-+ req->name = PATCH_KERNEL_SYMBOLS_STOP;
-+ patch_kernel_symbol(req);
-+
-+ clear_symtab_users(0);
-+ gdb_merge_flags |= KERNEL_SYMBOLS_PATCHED;
-+}
-+
-+static void
-+gdb_get_symbol_type(struct gnu_request *req)
-+{
-+ struct expression *expr;
-+ struct value *val;
-+ struct cleanup *old_chain = NULL;
-+ struct type *type;
-+ struct type *target_type;
-+
-+ req->typecode = TYPE_CODE_UNDEF;
-+
-+ expr = parse_expression (req->name);
-+ old_chain = make_cleanup (free_current_contents, &expr);
-+ val = evaluate_type (expr);
-+
-+ type = value_type(val);
-+
-+ req->type_name = (char *)TYPE_MAIN_TYPE(type)->name;
-+ req->typecode = TYPE_MAIN_TYPE(type)->code;
-+ req->length = type->length;
-+ target_type = TYPE_MAIN_TYPE(type)->target_type;
-+
-+ if (target_type) {
-+ req->target_typename = (char *)TYPE_MAIN_TYPE(target_type)->name;
-+ req->target_typecode = TYPE_MAIN_TYPE(target_type)->code;
-+ req->target_length = target_type->length;
-+ }
-+
-+ if (req->member)
-+ get_member_data(req, type);
-+
-+ do_cleanups (old_chain);
-+}
-+
-+static void
-+gdb_debug_command(struct gnu_request *req)
-+{
-+
-+}
-+
-+/*
-+ * Only necessary on "patched" kernel symbol sessions, and called only by
-+ * lookup_symbol(), pull a symbol value bait-and-switch operation by altering
-+ * either a data symbol's address value or a text symbol's block start
address.
-+ */
-+static void
-+gdb_bait_and_switch(char *name, struct symbol *sym)
-+{
-+ struct minimal_symbol *msym;
-+ struct block *block;
-+
-+ if ((gdb_merge_flags & KERNEL_SYMBOLS_PATCHED) &&
-+ (msym = lookup_minimal_symbol(name, NULL, gdb_kernel_objfile))) {
-+ if (sym->aclass == LOC_BLOCK) {
-+ block = (struct block *)SYMBOL_BLOCK_VALUE(sym);
-+ BLOCK_START(block) = SYMBOL_VALUE_ADDRESS(msym);
-+ } else
-+ SYMBOL_VALUE_ADDRESS(sym) = SYMBOL_VALUE_ADDRESS(msym);
-+ }
-+}
-+
-+#include "valprint.h"
-+
-+void
-+get_user_print_option_address(struct gnu_request *req)
-+{
-+ extern struct value_print_options user_print_options;
-+
-+ req->addr = 0;
-+
-+ if (strcmp(req->name, "output_format") == 0)
-+ req->addr = (ulong)&user_print_options.output_format;
-+ if (strcmp(req->name, "print_max") == 0)
-+ req->addr = (ulong)&user_print_options.print_max;
-+ if (strcmp(req->name, "prettyprint_structs") == 0)
-+ req->addr = (ulong)&user_print_options.prettyprint_structs;
-+ if (strcmp(req->name, "prettyprint_arrays") == 0)
-+ req->addr = (ulong)&user_print_options.prettyprint_arrays;
-+ if (strcmp(req->name, "repeat_count_threshold") == 0)
-+ req->addr = (ulong)&user_print_options.repeat_count_threshold;
-+ if (strcmp(req->name, "stop_print_at_null") == 0)
-+ req->addr = (ulong)&user_print_options.stop_print_at_null;
-+ if (strcmp(req->name, "output_radix") == 0)
-+ req->addr = (ulong)&output_radix;
-+}
-+
-+CORE_ADDR crash_text_scope;
-+
-+static void
-+gdb_set_crash_block(struct gnu_request *req)
-+{
-+ if (!req->addr) { /* debug */
-+ crash_text_scope = 0;
-+ return;
-+ }
-+
-+ if ((req->addr2 = (ulong)block_for_pc(req->addr)))
-+ crash_text_scope = req->addr;
-+ else {
-+ crash_text_scope = 0;
-+ req->flags |= GNU_COMMAND_FAILED;
-+ }
-+}
-+
-+static struct block *
-+gdb_get_crash_block(void)
-+{
-+ if (crash_text_scope)
-+ return block_for_pc(crash_text_scope);
-+ else
-+ return NULL;
-+}
-+#endif
---- gdb-7.6/gdb/c-typeprint.c.orig
-+++ gdb-7.6/gdb/c-typeprint.c
-@@ -1097,7 +1097,8 @@ c_type_print_base (struct type *type, st
- fprintf_filtered (stream, "static ");
- c_print_type (TYPE_FIELD_TYPE (type, i),
- TYPE_FIELD_NAME (type, i),
-- stream, show - 1, level + 4,
-+ stream, strlen(TYPE_FIELD_NAME (type, i)) ?
-+ show - 1 : show, level + 4,
- &local_flags);
- if (!field_is_static (&TYPE_FIELD (type, i))
- && TYPE_FIELD_PACKED (type, i))
---- gdb-7.6/gdb/xml-syscall.c.orig
-+++ gdb-7.6/gdb/xml-syscall.c
-@@ -38,7 +38,11 @@
- static void
- syscall_warn_user (void)
- {
-+#ifdef CRASH_MERGE
-+ static int have_warned = 1;
-+#else
- static int have_warned = 0;
-+#endif
- if (!have_warned)
- {
- have_warned = 1;
---- gdb-7.6/gdb/exceptions.c.orig
-+++ gdb-7.6/gdb/exceptions.c
-@@ -218,6 +218,10 @@ exceptions_state_mc_action_iter_1 (void)
-
- /* Return EXCEPTION to the nearest containing catch_errors(). */
-
-+#ifdef CRASH_MERGE
-+void (*error_hook) (void) ATTRIBUTE_NORETURN;
-+#endif
-+
- void
- throw_exception (struct gdb_exception exception)
- {
-@@ -225,6 +229,13 @@ throw_exception (struct gdb_exception ex
- immediate_quit = 0;
-
- do_cleanups (all_cleanups ());
-+#ifdef CRASH_MERGE
-+ if (error_hook) {
-+ fprintf_filtered(gdb_stderr, "%s\n", exception.message);
-+ (*error_hook)();
-+ } else
-+ fprintf_filtered(gdb_stderr, "gdb called without error_hook: %s\n",
exception.message);
-+#endif
-
- /* Jump to the containing catch_errors() call, communicating REASON
- to that call via setjmp's return value. Note that REASON can't
---- gdb-7.6/gdb/valprint.h.orig
-+++ gdb-7.6/gdb/valprint.h
-@@ -152,11 +152,17 @@ extern void print_function_pointer_addre
- struct gdbarch *gdbarch,
- CORE_ADDR address,
- struct ui_file *stream);
--
-+#ifdef CRASH_MERGE
-+extern int valprint_read_string (CORE_ADDR addr, int len, int width,
-+ unsigned int fetchlimit,
-+ enum bfd_endian byte_order, gdb_byte **buffer,
-+ int *bytes_read);
-+#else
- extern int read_string (CORE_ADDR addr, int len, int width,
- unsigned int fetchlimit,
- enum bfd_endian byte_order, gdb_byte **buffer,
- int *bytes_read);
-+#endif
-
- extern void val_print_optimized_out (struct ui_file *stream);
-
---- gdb-7.6/gdb/target.c.orig
-+++ gdb-7.6/gdb/target.c
-@@ -1779,6 +1779,13 @@ target_xfer_partial (struct target_ops *
- int
- target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
- {
-+#ifdef CRASH_MERGE
-+ extern int gdb_readmem_callback(unsigned long, void *, int, int);
-+ if (gdb_readmem_callback(memaddr, (void *)myaddr, len, 0))
-+ return 0;
-+ else
-+ return EIO;
-+#endif
- /* Dispatch to the topmost target, not the flattened current_target.
- Memory accesses check target->to_has_(all_)memory, and the
- flattened target doesn't inherit those. */
-@@ -1814,6 +1821,13 @@ target_read_stack (CORE_ADDR memaddr, gd
- int
- target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
- {
-+#ifdef CRASH_MERGE
-+ extern int gdb_readmem_callback(unsigned long, void *, int, int);
-+ if (gdb_readmem_callback(memaddr, (void *)myaddr, len, 1))
-+ return 0;
-+ else
-+ return EIO;
-+#endif
- /* Dispatch to the topmost target, not the flattened current_target.
- Memory accesses check target->to_has_(all_)memory, and the
- flattened target doesn't inherit those. */
---- gdb-7.6/gdb/printcmd.c.orig
-+++ gdb-7.6/gdb/printcmd.c
-@@ -1001,11 +1001,62 @@ print_command_1 (char *exp, int voidprin
- }
-
- static void
-+print_command_2 (char *exp, int inspect, int voidprint)
-+{
-+ struct expression *expr;
-+ struct cleanup *old_chain = 0;
-+ char format = 0;
-+ struct value *val;
-+ struct format_data fmt;
-+ int cleanup = 0;
-+
-+ if (exp && *exp == '/')
-+ {
-+ exp++;
-+ fmt = decode_format (&exp, last_format, 0);
-+ validate_format (fmt, "print");
-+ last_format = format = fmt.format;
-+ }
-+ else
-+ {
-+ fmt.count = 1;
-+ fmt.format = 0;
-+ fmt.size = 0;
-+ fmt.raw = 0;
-+ }
-+
-+ if (exp && *exp)
-+ {
-+ expr = parse_expression (exp);
-+ old_chain = make_cleanup (free_current_contents, &expr);
-+ cleanup = 1;
-+ val = evaluate_expression (expr);
-+ }
-+ else
-+ val = access_value_history (0);
-+
-+ printf_filtered ("%d %d %d %d %d %d\n",
-+ TYPE_CODE (check_typedef(value_type (val))),
-+ TYPE_UNSIGNED (check_typedef(value_type (val))),
-+ TYPE_LENGTH (check_typedef(value_type(val))),
-+ value_offset (val), value_bitpos (val), value_bitsize(val));
-+
-+ if (cleanup)
-+ do_cleanups (old_chain);
-+}
-+
-+static void
- print_command (char *exp, int from_tty)
- {
- print_command_1 (exp, 1);
- }
-
-+static void
-+printm_command (char *exp, int from_tty)
-+{
-+ print_command_2 (exp, 0, 1);
-+}
-+
- /* Same as print, except it doesn't print void results. */
- static void
- call_command (char *exp, int from_tty)
-@@ -2593,6 +2644,12 @@ EXP may be preceded with /FMT, where FMT
- but no count or size letter (see \"x\" command)."));
- set_cmd_completer (c, expression_completer);
- add_com_alias ("p", "print", class_vars, 1);
-+
-+ c = add_com ("printm", class_vars, printm_command, _("\
-+Similar to \"print\" command, but it used to print the type, size, offset,\n\
-+bitpos and bitsize of the expression EXP."));
-+ set_cmd_completer (c, expression_completer);
-+
- add_com_alias ("inspect", "print", class_vars, 1);
-
- add_setshow_uinteger_cmd ("max-symbolic-offset", no_class,
---- gdb-7.6/gdb/ui-file.c.orig
-+++ gdb-7.6/gdb/ui-file.c
-@@ -671,6 +671,17 @@ gdb_fopen (char *name, char *mode)
- return stdio_file_new (f, 1);
- }
-
-+#ifdef CRASH_MERGE
-+void
-+replace_ui_file_FILE(struct ui_file *file, FILE *fp)
-+{
-+ struct stdio_file *stdio_file;
-+
-+ stdio_file = (struct stdio_file *)ui_file_data(file);
-+ stdio_file->file = fp;
-+}
-+#endif
-+
- /* ``struct ui_file'' implementation that maps onto two ui-file objects. */
-
- static ui_file_write_ftype tee_file_write;
---- gdb-7.6/gdb/main.c.orig
-+++ gdb-7.6/gdb/main.c
-@@ -806,7 +806,7 @@ captured_main (void *data)
- {
- print_gdb_version (gdb_stdout);
- wrap_here ("");
-- printf_filtered ("\n");
-+ printf_filtered ("\n\n");
- exit (0);
- }
-
-@@ -853,6 +853,13 @@ captured_main (void *data)
- }
- }
-
-+#ifdef CRASH_MERGE
-+{
-+ extern void update_gdb_hooks(void);
-+ update_gdb_hooks();
-+}
-+#endif
-+
- /* FIXME: cagney/2003-02-03: The big hack (part 2 of 2) that lets
- GDB retain the old MI1 interpreter startup behavior. Output the
- copyright message after the interpreter is installed when it is
-@@ -880,7 +887,11 @@ captured_main (void *data)
- processed; it sets global parameters, which are independent of
- what file you are debugging or what directory you are in. */
- if (system_gdbinit && !inhibit_gdbinit)
-+#ifdef CRASH_MERGE
-+ catch_command_errors (source_script, system_gdbinit, -1, RETURN_MASK_ALL);
-+#else
- catch_command_errors (source_script, system_gdbinit, 0, RETURN_MASK_ALL);
-+#endif
-
- /* Read and execute $HOME/.gdbinit file, if it exists. This is done
- *before* all the command line arguments are processed; it sets
-@@ -888,7 +899,11 @@ captured_main (void *data)
- debugging or what directory you are in. */
-
- if (home_gdbinit && !inhibit_gdbinit && !inhibit_home_gdbinit)
-+#ifdef CRASH_MERGE
-+ catch_command_errors (source_script, home_gdbinit, -1, RETURN_MASK_ALL);
-+#else
- catch_command_errors (source_script, home_gdbinit, 0, RETURN_MASK_ALL);
-+#endif
-
- /* Process '-ix' and '-iex' options early. */
- for (i = 0; VEC_iterate (cmdarg_s, cmdarg_vec, i, cmdarg_p); i++)
-@@ -929,8 +944,12 @@ captured_main (void *data)
- catch_command_errors returns non-zero on success! */
- if (catch_command_errors (exec_file_attach, execarg,
- !batch_flag, RETURN_MASK_ALL))
-+#ifdef CRASH_MERGE
-+ catch_command_errors (symbol_file_add_main, symarg, 0, RETURN_MASK_ALL);
-+#else
- catch_command_errors (symbol_file_add_main, symarg,
- !batch_flag, RETURN_MASK_ALL);
-+#endif
- }
- else
- {
-@@ -992,8 +1011,12 @@ captured_main (void *data)
- {
- auto_load_local_gdbinit_loaded = 1;
-
-+#ifdef CRASH_MERGE
-+ catch_command_errors (source_script, local_gdbinit, -1, RETURN_MASK_ALL);
-+#else
- catch_command_errors (source_script, local_gdbinit, 0,
- RETURN_MASK_ALL);
-+#endif
- }
- }
-
-@@ -1039,6 +1062,12 @@ captured_main (void *data)
- while (1)
- {
- catch_errors (captured_command_loop, 0, "", RETURN_MASK_ALL);
-+#ifdef CRASH_MERGE
-+ {
-+ int console(char *, ...);
-+ console("<CAPTURED_MAIN WHILE LOOP>\n");
-+ }
-+#endif
- }
- /* No exit -- exit is through quit_command. */
- }
-@@ -1053,6 +1082,23 @@ gdb_main (struct captured_main_args *arg
- return 1;
- }
-
-+#ifdef CRASH_MERGE
-+/*
-+ * NOTE: adapted from gdb.c, which is no longer built in; changed name of
-+ * original main() to gdb_main_entry() for use as crash entry point
-+ */
-+int
-+gdb_main_entry (int argc, char **argv)
-+{
-+ struct captured_main_args args;
-+ memset (&args, 0, sizeof args);
-+ args.argc = argc;
-+ args.argv = argv;
-+ args.use_windows = 0;
-+ args.interpreter_p = INTERP_CONSOLE;
-+ return gdb_main (&args);
-+}
-+#endif
-
- /* Don't use *_filtered for printing help. We don't want to prompt
- for continue no matter how small the screen or how much we're going
---- gdb-7.6/gdb/valprint.c.orig
-+++ gdb-7.6/gdb/valprint.c
-@@ -1768,8 +1768,13 @@ partial_memory_read (CORE_ADDR memaddr,
- this function instead? */
-
- int
-+#ifdef CRASH_MERGE
-+valprint_read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
-+ enum bfd_endian byte_order, gdb_byte **buffer, int *bytes_read)
-+#else
- read_string (CORE_ADDR addr, int len, int width, unsigned int fetchlimit,
- enum bfd_endian byte_order, gdb_byte **buffer, int *bytes_read)
-+#endif
- {
- int found_nul; /* Non-zero if we found the nul char. */
- int errcode; /* Errno returned from bad reads. */
-@@ -2472,8 +2477,13 @@ val_print_string (struct type *elttype,
- fetchlimit = (len == -1 ? options->print_max : min (len,
- options->print_max));
-
-+#ifdef CRASH_MERGE
-+ errcode = valprint_read_string (addr, len, width, fetchlimit, byte_order,
-+ &buffer, &bytes_read);
-+#else
- errcode = read_string (addr, len, width, fetchlimit, byte_order,
- &buffer, &bytes_read);
-+#endif
- old_chain = make_cleanup (xfree, buffer);
-
- addr += bytes_read;
---- gdb-7.6/gdb/Makefile.in.orig
-+++ gdb-7.6/gdb/Makefile.in
-@@ -422,7 +422,7 @@ CONFIG_UNINSTALL = @CONFIG_UNINSTALL@
- # It is also possible that you will need to add -I/usr/include/sys if
- # your system doesn't have fcntl.h in /usr/include (which is where it
- # should be according to Posix).
--DEFS = @DEFS@
-+DEFS = -DCRASH_MERGE @DEFS@
- GDB_CFLAGS = -I. -I$(srcdir) -I$(srcdir)/common -I$(srcdir)/config \
- -DLOCALEDIR="\"$(localedir)\"" $(DEFS)
-
-@@ -934,7 +934,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
-
- TSOBS = inflow.o
-
--SUBDIRS = doc @subdirs@ data-directory $(GNULIB_BUILDDIR)
-+SUBDIRS = build_no_subdirs
- CLEANDIRS = $(SUBDIRS)
-
- # List of subdirectories in the build tree that must exist.
-@@ -969,8 +969,8 @@ generated_files = config.h observer.h ob
- $(COMPILE) $<
- $(POSTCOMPILE)
-
--all: gdb$(EXEEXT) $(CONFIG_ALL)
-- @$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed
's/testsuite//'`" subdir_do
-+all: gdb$(EXEEXT)
-+ @$(MAKE) -s $(FLAGS_TO_PASS) DO=all "DODIRS=`echo $(SUBDIRS) | sed
's/testsuite//'`" subdir_do
-
- installcheck:
-
-@@ -1172,15 +1172,16 @@ libgdb.a: $(LIBGDB_OBS)
-
- # Removing the old gdb first works better if it is running, at least on SunOS.
- gdb$(EXEEXT): gdb.o $(LIBGDB_OBS) $(ADD_DEPS) $(CDEPS) $(TDEPLIBS)
-- rm -f gdb$(EXEEXT)
-+ @rm -f gdb$(EXEEXT)
-+ @(cd ../..; make --no-print-directory GDB_FLAGS=-DGDB_7_6 library)
- $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \
-- -o gdb$(EXEEXT) gdb.o $(LIBGDB_OBS) \
-- $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES)
-+ -o $(shell /bin/cat mergeobj) $(LIBGDB_OBS) \
-+ $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) $(shell /bin/cat mergelibs)
-
- # Convenience rule to handle recursion.
- $(LIBGNU) $(GNULIB_H): all-lib
- all-lib: $(GNULIB_BUILDDIR)/Makefile
-- @$(MAKE) $(FLAGS_TO_PASS) DO=all DODIRS=$(GNULIB_BUILDDIR) subdir_do
-+ @$(MAKE) $(FLAGS_TO_PASS) DO=all DODIRS=$(GNULIB_BUILDDIR) subdir_do -s
- .PHONY: all-lib
-
- # Convenience rule to handle recursion.
-@@ -1389,12 +1390,12 @@ $(srcdir)/copying.c: @MAINTAINER_MODE_TR
- mv $(srcdir)/copying.tmp $(srcdir)/copying.c
-
- version.c: Makefile version.in
-- rm -f version.c-tmp version.c
-- echo '#include "version.h"' >> version.c-tmp
-- echo 'const char version[] = "'"`sed q
${srcdir}/version.in`"'";' >> version.c-tmp
-- echo 'const char host_name[] = "$(host_alias)";' >>
version.c-tmp
-- echo 'const char target_name[] = "$(target_alias)";' >>
version.c-tmp
-- mv version.c-tmp version.c
-+ @rm -f version.c-tmp version.c
-+ @echo '#include "version.h"' >> version.c-tmp
-+ @echo 'const char version[] = "'"`sed q
${srcdir}/version.in`"'";' >> version.c-tmp
-+ @echo 'const char host_name[] = "$(host_alias)";' >>
version.c-tmp
-+ @echo 'const char target_name[] = "$(target_alias)";' >>
version.c-tmp
-+ @mv version.c-tmp version.c
-
- observer.h: observer.sh doc/observer.texi
- ${srcdir}/observer.sh h ${srcdir}/doc/observer.texi observer.h
---- gdb-7.6/gdb/c-lang.c.orig
-+++ gdb-7.6/gdb/c-lang.c
-@@ -307,7 +307,11 @@ c_get_string (struct value *value, gdb_b
- {
- CORE_ADDR addr = value_as_address (value);
-
-+#ifdef CRASH_MERGE
-+ err = valprint_read_string (addr, *length, width, fetchlimit,
-+#else
- err = read_string (addr, *length, width, fetchlimit,
-+#endif
- byte_order, buffer, length);
- if (err)
- {
---- gdb-7.6/readline/rltypedefs.h.orig
-+++ gdb-7.6/readline/rltypedefs.h
-@@ -31,10 +31,10 @@ extern "C" {
- #if !defined (_FUNCTION_DEF)
- # define _FUNCTION_DEF
-
--typedef int Function ();
--typedef void VFunction ();
--typedef char *CPFunction ();
--typedef char **CPPFunction ();
-+typedef int Function (void);
-+typedef void VFunction (void);
-+typedef char *CPFunction (void);
-+typedef char **CPPFunction (void);
-
- #endif /* _FUNCTION_DEF */
-
---- gdb-7.6/readline/readline.h.orig
-+++ gdb-7.6/readline/readline.h
-@@ -378,7 +378,7 @@ extern int rl_crlf PARAMS((void));
- #if defined (USE_VARARGS) && defined (PREFER_STDARG)
- extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
- #else
--extern int rl_message ();
-+extern int rl_message (void);
- #endif
-
- extern int rl_show_char PARAMS((int));
---- gdb-7.6/readline/misc.c.orig
-+++ gdb-7.6/readline/misc.c
-@@ -405,7 +405,7 @@ _rl_history_set_point ()
-
- #if defined (VI_MODE)
- if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
-- rl_point = 0;
-+ rl_point = rl_end;
- #endif /* VI_MODE */
-
- if (rl_editing_mode == emacs_mode)
---- gdb-7.6/Makefile.in.orig
-+++ gdb-7.6/Makefile.in
-@@ -342,6 +342,9 @@ AR_FOR_BUILD = @AR_FOR_BUILD@
- AS_FOR_BUILD = @AS_FOR_BUILD@
- CC_FOR_BUILD = @CC_FOR_BUILD@
- CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
-+ifeq (${CRASH_TARGET}, PPC64)
-+CFLAGS_FOR_BUILD += -m64 -fPIC
-+endif
- CXXFLAGS_FOR_BUILD = @CXXFLAGS_FOR_BUILD@
- CXX_FOR_BUILD = @CXX_FOR_BUILD@
- DLLTOOL_FOR_BUILD = @DLLTOOL_FOR_BUILD@
-@@ -407,6 +410,9 @@ GNATBIND = @GNATBIND@
- GNATMAKE = @GNATMAKE@
-
- CFLAGS = @CFLAGS@
-+ifeq (${CRASH_TARGET}, PPC64)
-+CFLAGS += -m64 -fPIC
-+endif
- LDFLAGS = @LDFLAGS@
- LIBCFLAGS = $(CFLAGS)
- CXXFLAGS = @CXXFLAGS@
---- gdb-7.6/gdb/defs.h.orig
-+++ gdb-7.6/gdb/defs.h
-@@ -802,4 +802,8 @@ enum block_enum
-
- #include "utils.h"
-
-+#ifdef CRASH_MERGE
-+extern int gdb_main_entry(int, char **);
-+extern void replace_ui_file_FILE(struct ui_file *, FILE *);
-+#endif
- #endif /* #ifndef DEFS_H */
---- gdb-7.6/bfd/elflink.c.orig
-+++ gdb-7.6/bfd/elflink.c
-@@ -4730,7 +4730,7 @@ error_free_dyn:
- struct elf_link_hash_entry *hlook;
- asection *slook;
- bfd_vma vlook;
-- size_t i, j, idx;
-+ size_t i, j, idx = 0;
-
- hlook = weaks;
- weaks = hlook->u.weakdef;
---- gdb-7.6/gdb/s390-nat.c.orig
-+++ gdb-7.6/gdb/s390-nat.c
-@@ -37,6 +37,8 @@
- #include <sys/ucontext.h>
- #include <elf.h>
-
-+#include <sys/uio.h>
-+
- #ifndef HWCAP_S390_HIGH_GPRS
- #define HWCAP_S390_HIGH_GPRS 512
- #endif
---- gdb-7.6/gdb/printcmd.c.orig
-+++ gdb-7.6/gdb/printcmd.c
-@@ -573,11 +573,21 @@ print_address_symbolic (struct gdbarch *
- int unmapped = 0;
- int offset = 0;
- int line = 0;
-+#ifdef CRASH_MERGE
-+ extern int gdb_print_callback(unsigned long);
-+#endif
-
- /* Throw away both name and filename. */
- struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &name);
- make_cleanup (free_current_contents, &filename);
-
-+#ifdef CRASH_MERGE
-+ if (!gdb_print_callback(addr)) {
-+ do_cleanups (cleanup_chain);
-+ return 0;
-+ }
-+#endif
-+
- if (build_address_symbolic (gdbarch, addr, do_demangle, &name, &offset,
- &filename, &line, &unmapped))
- {
---- gdb-7.6/bfd/bfd-in.h.orig
-+++ gdb-7.6/bfd/bfd-in.h
-@@ -294,9 +294,6 @@ typedef struct bfd_section *sec_ptr;
-
- #define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
-
--#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)),
((ptr)->user_set_vma = TRUE), TRUE)
--#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power =
(val)),TRUE)
--#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE)
- /* Find the address one past the end of SEC. */
- #define bfd_get_section_limit(bfd, sec) \
- (((bfd)->direction != write_direction && (sec)->rawsize != 0 \
-@@ -519,7 +516,6 @@ extern void warn_deprecated (const char
-
- #define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
-
--#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
-
- extern bfd_boolean bfd_cache_close
- (bfd *abfd);
---- gdb-7.6/bfd/bfd-in2.h.orig
-+++ gdb-7.6/bfd/bfd-in2.h
-@@ -301,9 +301,6 @@ typedef struct bfd_section *sec_ptr;
-
- #define bfd_is_com_section(ptr) (((ptr)->flags & SEC_IS_COMMON) != 0)
-
--#define bfd_set_section_vma(bfd, ptr, val) (((ptr)->vma = (ptr)->lma = (val)),
((ptr)->user_set_vma = TRUE), TRUE)
--#define bfd_set_section_alignment(bfd, ptr, val) (((ptr)->alignment_power =
(val)),TRUE)
--#define bfd_set_section_userdata(bfd, ptr, val) (((ptr)->userdata = (val)),TRUE)
- /* Find the address one past the end of SEC. */
- #define bfd_get_section_limit(bfd, sec) \
- (((bfd)->direction != write_direction && (sec)->rawsize != 0 \
-@@ -526,7 +523,6 @@ extern void warn_deprecated (const char
-
- #define bfd_get_symbol_leading_char(abfd) ((abfd)->xvec->symbol_leading_char)
-
--#define bfd_set_cacheable(abfd,bool) (((abfd)->cacheable = bool), TRUE)
-
- extern bfd_boolean bfd_cache_close
- (bfd *abfd);
-@@ -1572,6 +1568,32 @@ struct relax_table {
- int size;
- };
-
-+/* Note: the following are provided as inline functions rather than macros
-+ because not all callers use the return value. A macro implementation
-+ would use a comma expression, eg: "((ptr)->foo = val, TRUE)" and some
-+ compilers will complain about comma expressions that have no effect. */
-+static inline bfd_boolean
-+bfd_set_section_userdata (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, void * val)
-+{
-+ ptr->userdata = val;
-+ return TRUE;
-+}
-+
-+static inline bfd_boolean
-+bfd_set_section_vma (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, bfd_vma val)
-+{
-+ ptr->vma = ptr->lma = val;
-+ ptr->user_set_vma = TRUE;
-+ return TRUE;
-+}
-+
-+static inline bfd_boolean
-+bfd_set_section_alignment (bfd * abfd ATTRIBUTE_UNUSED, asection * ptr, unsigned int
val)
-+{
-+ ptr->alignment_power = val;
-+ return TRUE;
-+}
-+
- /* These sections are global, and are managed by BFD. The application
- and target back end are not permitted to change the values in
- these sections. */
-@@ -6095,6 +6117,14 @@ struct bfd
- unsigned int selective_search : 1;
- };
-
-+/* See note beside bfd_set_section_userdata. */
-+static inline bfd_boolean
-+bfd_set_cacheable (bfd * abfd, bfd_boolean val)
-+{
-+ abfd->cacheable = val;
-+ return TRUE;
-+}
-+
- typedef enum bfd_error
- {
- bfd_error_no_error = 0,
---- gdb-7.6/gdb/symtab.c.orig
-+++ gdb-7.6/gdb/symtab.c
-@@ -5405,7 +5405,7 @@ dump_enum(struct type *type, struct gnu_
- {
- register int i;
- int len;
-- int lastval;
-+ long long lastval;
-
- len = TYPE_NFIELDS (type);
- lastval = 0;
-@@ -5418,12 +5418,12 @@ dump_enum(struct type *type, struct gnu_
- for (i = 0; i < len; i++) {
- fprintf_filtered(gdb_stdout, " %s",
- TYPE_FIELD_NAME (type, i));
-- if (lastval != TYPE_FIELD_BITPOS (type, i)) {
-- fprintf_filtered (gdb_stdout, " = %d",
-- TYPE_FIELD_BITPOS (type, i));
-- lastval = TYPE_FIELD_BITPOS (type, i);
-+ if (lastval != TYPE_FIELD_ENUMVAL (type, i)) {
-+ fprintf_filtered (gdb_stdout, " = %s",
-+ plongest(TYPE_FIELD_ENUMVAL (type, i)));
-+ lastval = TYPE_FIELD_ENUMVAL (type, i);
- } else
-- fprintf_filtered(gdb_stdout, " = %d", lastval);
-+ fprintf_filtered(gdb_stdout, " = %s",
plongest(lastval));
- fprintf_filtered(gdb_stdout, "\n");
- lastval++;
- }
---- gdb-7.6/gdb/aarch64-linux-nat.c.orig
-+++ gdb-7.6/gdb/aarch64-linux-nat.c
-@@ -32,6 +32,7 @@
- #include "elf/common.h"
-
- #include <sys/ptrace.h>
-+#include <asm/ptrace.h>
- #include <sys/utsname.h>
-
- #include "gregset.h"
---- gdb-7.6/sim/igen/Makefile.in.orig
-+++ gdb-7.6/sim/igen/Makefile.in
-@@ -117,7 +117,7 @@ IGEN_OBJS=\
- gen.o
-
- igen: igen.o $(IGEN_OBJS)
-- $(CC_FOR_BUILD) $(BUILD_LDFLAGS) -o igen igen.o $(IGEN_OBJS) $(LIBIBERTY_LIB)
-+ $(CC_FOR_BUILD) $(BUILD_CFLAGS) $(BUILD_LDFLAGS) -o igen igen.o $(IGEN_OBJS)
$(LIBIBERTY_LIB)
-
- igen.o: igen.c misc.h filter_host.h lf.h table.h ld-decode.h ld-cache.h ld-insn.h
filter.h gen-model.h gen-itable.h gen-icache.h gen-idecode.h gen-engine.h gen-semantics.h
gen-support.h gen.h igen.h
- $(CC_FOR_BUILD) $(BUILD_CFLAGS) -c $(srcdir)/igen.c
---- gdb-7.6/sim/mips/cp1.c.orig
-+++ gdb-7.6/sim/mips/cp1.c
-@@ -1359,7 +1359,7 @@ fp_rsqrt2(sim_cpu *cpu,
- /* Conversion operations. */
-
- uword64
--convert (sim_cpu *cpu,
-+sim_mips_convert (sim_cpu *cpu,
- address_word cia,
- int rm,
- uword64 op,
---- gdb-7.6/sim/mips/sim-main.h.orig
-+++ gdb-7.6/sim/mips/sim-main.h
-@@ -770,8 +770,8 @@ unsigned64 fp_nmadd (SIM_STATE, unsigned64 op1, unsigned64 op2,
- unsigned64 fp_nmsub (SIM_STATE, unsigned64 op1, unsigned64 op2,
- unsigned64 op3, FP_formats fmt);
- #define NegMultiplySub(op1,op2,op3,fmt) fp_nmsub(SIM_ARGS, op1, op2, op3, fmt)
--unsigned64 convert (SIM_STATE, int rm, unsigned64 op, FP_formats from, FP_formats to);
--#define Convert(rm,op,from,to) convert (SIM_ARGS, rm, op, from, to)
-+unsigned64 sim_mips_convert (SIM_STATE, int rm, unsigned64 op, FP_formats from,
FP_formats to);
-+#define Convert(rm,op,from,to) sim_mips_convert (SIM_ARGS, rm, op, from, to)
- unsigned64 convert_ps (SIM_STATE, int rm, unsigned64 op, FP_formats from,
- FP_formats to);
- #define ConvertPS(rm,op,from,to) convert_ps (SIM_ARGS, rm, op, from, to)
-
---- gdb-7.6/readline/util.c
-+++ gdb-7.6/readline/util.c
-@@ -493,10 +493,13 @@ _rl_trace (va_alist)
-
- if (_rl_tracefp == 0)
- _rl_tropen ();
-+ if (!_rl_tracefp)
-+ goto out;
- vfprintf (_rl_tracefp, format, args);
- fprintf (_rl_tracefp, "\n");
- fflush (_rl_tracefp);
-
-+out:
- va_end (args);
- }
-
-@@ -509,16 +512,17 @@ _rl_tropen ()
- fclose (_rl_tracefp);
- sprintf (fnbuf, "/var/tmp/rltrace.%ld", getpid());
- unlink(fnbuf);
-- _rl_tracefp = fopen (fnbuf, "w+");
-+ _rl_tracefp = fopen (fnbuf, "w+xe");
- return _rl_tracefp != 0;
- }
-
- int
- _rl_trclose ()
- {
-- int r;
-+ int r = 0;
-
-- r = fclose (_rl_tracefp);
-+ if (_rl_tracefp)
-+ r = fclose (_rl_tracefp);
- _rl_tracefp = 0;
- return r;
- }
---- gdb-7.6/gdb/symtab.c.orig
-+++ gdb-7.6/gdb/symtab.c
-@@ -5447,9 +5447,9 @@ eval_enum(struct type *type, struct gnu_
- lastval = 0;
-
- for (i = 0; i < len; i++) {
-- if (lastval != TYPE_FIELD_BITPOS (type, i)) {
-- lastval = TYPE_FIELD_BITPOS (type, i);
-- }
-+ if (lastval != TYPE_FIELD_ENUMVAL (type, i))
-+ lastval = TYPE_FIELD_ENUMVAL (type, i);
-+
- if (STREQ(TYPE_FIELD_NAME(type, i), req->name)) {
- req->tagname = "(unknown)";
- req->value = lastval;
---- gdb-7.6/gdb/symtab.c.orig
-+++ gdb-7.6/gdb/symtab.c
-@@ -5236,6 +5236,12 @@ gdb_command_funnel(struct gnu_request *r
- gdb_set_crash_block(req);
- break;
-
-+ case GNU_GET_FUNCTION_RANGE:
-+ sym = lookup_symbol(req->name, 0, VAR_DOMAIN, 0);
-+ if (!find_pc_partial_function(req->pc, NULL, &req->addr,
&req->addr2))
-+ req->flags |= GNU_COMMAND_FAILED;
-+ break;
-+
- default:
- req->flags |= GNU_COMMAND_FAILED;
- break;
---- gdb-7.6/opcodes/i386-dis.c.orig
-+++ gdb-7.6/opcodes/i386-dis.c
-@@ -11300,6 +11300,29 @@ get_sib (disassemble_info *info)
- }
- }
-
-+static char *
-+check_for_extensions(struct dis_private *priv)
-+{
-+ unsigned char ModRM;
-+
-+ if ((priv->the_buffer[0] == 0x66) &&
-+ (priv->the_buffer[1] == 0x0f) &&
-+ (priv->the_buffer[2] == 0xae)) {
-+ ModRM = priv->the_buffer[3];
-+ if (ModRM == 0xf8)
-+ return "pcommit";
-+
-+ switch ((ModRM >> 3))
-+ {
-+ case 0x6:
-+ return "clwb";
-+ case 0x7:
-+ return "clflushopt";
-+ }
-+ }
-+ return NULL;
-+}
-+
- static int
- print_insn (bfd_vma pc, disassemble_info *info)
- {
-@@ -11312,6 +11335,7 @@ print_insn (bfd_vma pc, disassemble_info
- struct dis_private priv;
- int prefix_length;
- int default_prefixes;
-+ char *extension;
-
- priv.orig_sizeflag = AFLAG | DFLAG;
- if ((info->mach & bfd_mach_i386_i386) != 0)
-@@ -11575,6 +11599,7 @@ print_insn (bfd_vma pc, disassemble_info
- need_vex = 0;
- need_vex_reg = 0;
- vex_w_done = 0;
-+ extension = NULL;
-
- if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE)
- {
-@@ -11610,9 +11635,14 @@ print_insn (bfd_vma pc, disassemble_info
- name = prefix_name (all_prefixes[i], priv.orig_sizeflag);
- if (name == NULL)
- name = INTERNAL_DISASSEMBLER_ERROR;
-- (*info->fprintf_func) (info->stream, "%s", name);
-- return 1;
-- }
-+ if ((extension = check_for_extensions(&priv))) {
-+ strcpy(obuf, extension);
-+ obufp = &obuf[strlen(obuf)];
-+ } else {
-+ (*info->fprintf_func) (info->stream, "%s", name);
-+ return 1;
-+ }
-+ }
- }
-
- /* Check if the REX prefix is used. */
-@@ -11637,7 +11667,7 @@ print_insn (bfd_vma pc, disassemble_info
- all_prefixes[last_data_prefix] = 0;
-
- prefix_length = 0;
-- for (i = 0; i < (int) ARRAY_SIZE (all_prefixes); i++)
-+ for (i = 0; !extension && i < (int) ARRAY_SIZE (all_prefixes); i++)
- if (all_prefixes[i])
- {
- const char *name;
-@@ -11655,7 +11685,8 @@ print_insn (bfd_vma pc, disassemble_info
- return MAX_CODE_LENGTH;
- }
-
-- obufp = mnemonicendp;
-+ if (!extension)
-+ obufp = mnemonicendp;
- for (i = strlen (obuf) + prefix_length; i < 6; i++)
- oappend (" ");
- oappend (" ");
---- gdb-7.6/bfd/coff-i386.c.orig
-+++ gdb-7.6/bfd/coff-i386.c
-@@ -141,7 +141,7 @@ coff_i386_reloc (bfd *abfd,
- #define DOIT(x) \
- x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) &
howto->dst_mask))
-
-- if (diff != 0)
-+ if (diff != 0)
- {
- reloc_howto_type *howto = reloc_entry->howto;
- unsigned char *addr = (unsigned char *) data + reloc_entry->address;
---- gdb-7.6/bfd/coff-x86_64.c.orig
-+++ gdb-7.6/bfd/coff-x86_64.c
-@@ -139,7 +139,7 @@ coff_amd64_reloc (bfd *abfd,
- #define DOIT(x) \
- x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + diff) &
howto->dst_mask))
-
-- if (diff != 0)
-+ if (diff != 0)
- {
- reloc_howto_type *howto = reloc_entry->howto;
- unsigned char *addr = (unsigned char *) data + reloc_entry->address;
---- gdb-7.6/opcodes/arm-dis.c.orig
-+++ gdb-7.6/opcodes/arm-dis.c
-@@ -2103,7 +2103,7 @@ print_insn_coprocessor (bfd_vma pc,
-
- /* Is ``imm'' a negative number? */
- if (imm & 0x40)
-- imm |= (-1 << 7);
-+ imm -= 0x80;
-
- func (stream, "%d", imm);
- }
-diff -up gdb-7.6/bfd/elf64-ppc.c.orig gdb-7.6/bfd/elf64-ppc.c
---- gdb-7.6/bfd/elf64-ppc.c.orig 2016-02-02 11:04:25.436527347 -0500
-+++ gdb-7.6/bfd/elf64-ppc.c 2016-02-02 11:11:51.926468454 -0500
-@@ -11743,7 +11743,7 @@ ppc64_elf_size_stubs (struct bfd_link_in
- stub_sec = stub_sec->next)
- if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
- stub_sec->size = ((stub_sec->size + (1 << htab->plt_stub_align) -
1)
-- & (-1 << htab->plt_stub_align));
-+ & -(1 << htab->plt_stub_align));
-
- for (stub_sec = htab->stub_bfd->sections;
- stub_sec != NULL;
-@@ -12093,7 +12093,7 @@ ppc64_elf_build_stubs (bfd_boolean emit_
- stub_sec = stub_sec->next)
- if ((stub_sec->flags & SEC_LINKER_CREATED) == 0)
- stub_sec->size = ((stub_sec->size + (1 << htab->plt_stub_align) - 1)
-- & (-1 << htab->plt_stub_align));
-+ & -(1 << htab->plt_stub_align));
-
- for (stub_sec = htab->stub_bfd->sections;
- stub_sec != NULL;
---- gdb-7.6/include/opcode/ppc.h.orig
-+++ gdb-7.6/include/opcode/ppc.h
-@@ -278,7 +278,7 @@ extern const unsigned int num_powerpc_op
- /* Use with the shift field of a struct powerpc_operand to indicate
- that BITM and SHIFT cannot be used to determine where the operand
- goes in the insn. */
--#define PPC_OPSHIFT_INV (-1 << 31)
-+#define PPC_OPSHIFT_INV (-1U << 31)
-
- /* Values defined for the flags field of a struct powerpc_operand. */
-
---- gdb-7.6/opcodes/mips-dis.c.orig
-+++ gdb-7.6/opcodes/mips-dis.c
-@@ -245,18 +245,6 @@ static const char * const mips_cp0_names
- "c0_taglo", "c0_taghi", "c0_errorepc",
"$31"
- };
-
--static const struct mips_cp0sel_name mips_cp0sel_names_mipsr5900[] =
--{
-- { 24, 2, "c0_iab" },
-- { 24, 3, "c0_iabm" },
-- { 24, 4, "c0_dab" },
-- { 24, 5, "c0_dabm" },
-- { 24, 6, "c0_dvb" },
-- { 24, 7, "c0_dvbm" },
-- { 25, 1, "c0_perfcnt,1" },
-- { 25, 2, "c0_perfcnt,2" }
--};
--
- static const char * const mips_cp0_names_mips3264[32] =
- {
- "c0_index", "c0_random", "c0_entrylo0",
"c0_entrylo1",
---- gdb-7.6/gdb/ada-lang.c.orig
-+++ gdb-7.6/gdb/ada-lang.c
-@@ -10503,7 +10503,7 @@ ada_evaluate_subexp (struct type *expect
- }
- else
- arg1 = ada_value_struct_elt (arg1, &exp->elts[pc + 2].string, 0);
-- arg1 = unwrap_value (arg1);
-+ arg1 = unwrap_value (arg1);
- return ada_to_fixed_value (arg1);
-
- case OP_TYPE:
---- gdb-7.6/gdb/linux-record.c.orig
-+++ gdb-7.6/gdb/linux-record.c
-@@ -112,7 +112,7 @@ record_linux_sockaddr (struct regcache *
- "memory at addr = 0x%s len = %d.\n",
- phex_nz (len, tdep->size_pointer),
- tdep->size_int);
-- return -1;
-+ return -1;
- }
- addrlen = (int) extract_unsigned_integer (a, tdep->size_int, byte_order);
- if (addrlen <= 0 || addrlen > tdep->size_sockaddr)
-@@ -150,7 +150,7 @@ record_linux_msghdr (struct regcache *re
- "len = %d.\n",
- phex_nz (addr, tdep->size_pointer),
- tdep->size_msghdr);
-- return -1;
-+ return -1;
- }
-
- /* msg_name msg_namelen */
-@@ -186,7 +186,7 @@ record_linux_msghdr (struct regcache *re
- "len = %d.\n",
- phex_nz (addr,tdep->size_pointer),
- tdep->size_iovec);
-- return -1;
-+ return -1;
- }
- tmpaddr = (CORE_ADDR) extract_unsigned_integer (iov,
- tdep->size_pointer,
-@@ -948,7 +948,7 @@ Do you want to stop the program?"),
- "memory at addr = 0x%s len = %d.\n",
- OUTPUT_REG (tmpulongest, tdep->arg2),
- tdep->size_ulong);
-- return -1;
-+ return -1;
- }
- tmpulongest = extract_unsigned_integer (a, tdep->size_ulong,
- byte_order);
---- gdb-7.6/gdb/inflow.c.orig
-+++ gdb-7.6/gdb/inflow.c
-@@ -391,7 +391,7 @@ terminal_ours_1 (int output_only)
- if (tinfo->run_terminal != NULL || gdb_has_a_terminal () == 0)
- return;
-
-- {
-+ {
- #ifdef SIGTTOU
- /* Ignore this signal since it will happen when we try to set the
- pgrp. */
---- gdb-7.6/gdb/printcmd.c.orig
-+++ gdb-7.6/gdb/printcmd.c
-@@ -1045,7 +1045,7 @@ print_command_2 (char *exp, int inspect,
- else
- val = access_value_history (0);
-
-- printf_filtered ("%d %d %d %d %d %d\n",
-+ printf_filtered ("%d %d %d %d %d %d\n",
- TYPE_CODE (check_typedef(value_type (val))),
- TYPE_UNSIGNED (check_typedef(value_type (val))),
- TYPE_LENGTH (check_typedef(value_type(val))),
---- gdb-7.6/gdb/c-typeprint.c.orig
-+++ gdb-7.6/gdb/c-typeprint.c
-@@ -1293,7 +1293,7 @@ c_type_print_base (struct type *type, st
- if (TYPE_NFIELDS (type) != 0 || TYPE_NFN_FIELDS (type) != 0)
- fprintf_filtered (stream, "\n");
-
-- for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); i++)
-+ for (i = 0; i < TYPE_TYPEDEF_FIELD_COUNT (type); i++)
- {
- struct type *target = TYPE_TYPEDEF_FIELD_TYPE (type, i);
-
---- gdb-7.6/gdb/symtab.c.orig
-+++ gdb-7.6/gdb/symtab.c
-@@ -5139,6 +5139,8 @@ static void get_user_print_option_addres
- extern int get_frame_offset(CORE_ADDR);
- static void gdb_set_crash_block(struct gnu_request *);
- void gdb_command_funnel(struct gnu_request *);
-+static long lookup_struct_contents(struct gnu_request *);
-+static void iterate_datatypes(struct gnu_request *);
-
- struct objfile *gdb_kernel_objfile = { 0 };
-
-@@ -5242,6 +5244,14 @@ gdb_command_funnel(struct gnu_request *r
- req->flags |= GNU_COMMAND_FAILED;
- break;
-
-+ case GNU_LOOKUP_STRUCT_CONTENTS:
-+ req->value = lookup_struct_contents(req);
-+ break;
-+
-+ case GNU_GET_NEXT_DATATYPE:
-+ iterate_datatypes(req);
-+ break;
-+
- default:
- req->flags |= GNU_COMMAND_FAILED;
- break;
-@@ -5779,4 +5789,135 @@ gdb_get_crash_block(void)
- else
- return NULL;
- }
-+
-+static long
-+lookup_struct_contents(struct gnu_request *req)
-+{
-+ int i;
-+ long r;
-+ struct field *f;
-+ struct main_type *m;
-+ const char *n;
-+ struct main_type *top_m = (struct main_type *)req->addr;
-+ char *type_name = req->type_name;
-+
-+ if (!top_m || !type_name)
-+ return 0;
-+
-+ for (i = 0; i < top_m->nfields; i++)
-+ {
-+ f = top_m->flds_bnds.fields + i;
-+ if (!f->type)
-+ continue;
-+ m = f->type->main_type;
-+
-+ // If the field is an array, check the target type -
-+ // it might be structure, or might not be.
-+ // - struct request_sock *syn_table[0];
-+ // here m->target_type->main_type->code is expected
-+ // to be TYPE_CODE_PTR
-+ // - struct list_head vec[TVN_SIZE];
-+ // here m->target_type->main_type->code should be
-+ // TYPE_CODE_STRUCT
-+ if (m->code == TYPE_CODE_ARRAY && m->target_type)
-+ m = m->target_type->main_type;
-+
-+ /* Here is a recursion.
-+ * If we have struct variable (not pointer),
-+ * scan this inner structure
-+ */
-+ if (m->code == TYPE_CODE_STRUCT) {
-+ req->addr = (ulong)m;
-+ r = lookup_struct_contents(req);
-+ req->addr = (ulong)top_m;
-+ if (r)
-+ return 1;
-+ }
-+
-+ if (m->code == TYPE_CODE_PTR && m->target_type)
-+ m = m->target_type->main_type;
-+ if (m->name)
-+ n = m->name;
-+ else if (m->tag_name)
-+ n = m->tag_name;
-+ else
-+ continue;
-+
-+ if (strstr(n, type_name))
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+static void
-+iterate_datatypes (struct gnu_request *req)
-+{
-+ static struct block_iterator bi; // Keeping this static will simplify code
-+ struct block *b;
-+ int do_return = 0;
-+ struct global_iterator *gi = &req->global_iterator;
-+
-+ if (gi->finished)
-+ return;
-+
-+ if (gi->obj == NULL)
-+ {
-+ gi->obj = current_program_space->objfiles;
-+ gi->symtab = NULL;
-+ do_return = 1; // The initial case - we don't need to make next step.
-+ }
-+
-+ for (; gi->obj; gi->obj = gi->obj->next, gi->symtab = NULL)
-+ {
-+ if (gi->symtab == NULL)
-+ {
-+ // Symtab `symtab` is nullified for every objfile
-+ if (gi->obj->sf)
-+ gi->obj->sf->qf->expand_all_symtabs(gi->obj);
-+ gi->symtab = gi->obj->symtabs;
-+ gi->sym = NULL;
-+ }
-+
-+ for (; gi->symtab; gi->symtab = gi->symtab->next, gi->block_index =
-1)
-+ {
-+ if (!gi->symtab->primary)
-+ continue;
-+
-+ if (gi->block_index == -1)
-+ {
-+ gi->block_index = GLOBAL_BLOCK;
-+ gi->sym = NULL;
-+ }
-+ for (; gi->block_index <= STATIC_BLOCK; gi->block_index++, gi->sym
= NULL)
-+ {
-+ if (!gi->sym)
-+ {
-+ b = BLOCKVECTOR_BLOCK(BLOCKVECTOR(gi->symtab),
gi->block_index);
-+ gi->sym = block_iterator_first(b, &bi);
-+ }
-+ for (; gi->sym; gi->sym = block_iterator_next(&bi))
-+ {
-+ QUIT;
-+
-+ if (SYMBOL_CLASS (gi->sym) != LOC_TYPEDEF)
-+ continue;
-+
-+ // Iteration 1 (do_return == 0): initialization
-+ // Iteration 2 (do_return == 1): iterate symbol
-+ if (do_return++ == 0)
-+ continue;
-+
-+ // Yield the current symbol and its size
-+ req->addr = (ulong)(gi->sym->type->main_type);
-+ req->name = (char *)(gi->sym->ginfo.name);
-+ req->length = gi->sym->type->length;
-+
-+ return;
-+ }
-+ }
-+ }
-+ }
-+ gi->finished = 1;
-+}
- #endif
---- gdb-7.6/bfd/elf64-s390.c.orig
-+++ gdb-7.6/bfd/elf64-s390.c
-@@ -323,10 +323,10 @@ elf_s390_reloc_name_lookup (bfd *abfd AT
- && strcasecmp (elf_howto_table[i].name, r_name) == 0)
- return &elf_howto_table[i];
-
-- if (strcasecmp (elf64_s390_vtinherit_howto.name, r_name) == 0)
-- return &elf64_s390_vtinherit_howto;
-- if (strcasecmp (elf64_s390_vtentry_howto.name, r_name) == 0)
-- return &elf64_s390_vtentry_howto;
-+ if (strcasecmp (elf64_s390_vtinherit_howto.name, r_name) == 0)
-+ return &elf64_s390_vtinherit_howto;
-+ if (strcasecmp (elf64_s390_vtentry_howto.name, r_name) == 0)
-+ return &elf64_s390_vtentry_howto;
-
- return NULL;
- }
---- gdb-7.6/gdb/symtab.c.orig
-+++ gdb-7.6/gdb/symtab.c
-@@ -5122,7 +5122,7 @@ When enabled, debugging messages are pri
- #define GDB_COMMON
- #include "../../defs.h"
-
--static void get_member_data(struct gnu_request *, struct type *);
-+static void get_member_data(struct gnu_request *, struct type *, long, int);
- static void dump_enum(struct type *, struct gnu_request *);
- static void eval_enum(struct type *, struct gnu_request *);
- static void gdb_get_line_number(struct gnu_request *);
-@@ -5327,7 +5327,7 @@ gdb_get_datatype(struct gnu_request *req
- req->typecode = TYPE_CODE(sym->type);
- req->length = TYPE_LENGTH(sym->type);
- if (req->member)
-- get_member_data(req, sym->type);
-+ get_member_data(req, sym->type, 0, 1);
-
- if (TYPE_CODE(sym->type) == TYPE_CODE_ENUM) {
- if (req->flags & GNU_PRINT_ENUMERATORS)
-@@ -5397,7 +5397,7 @@ gdb_get_datatype(struct gnu_request *req
- }
-
- if (req->member)
-- get_member_data(req, type);
-+ get_member_data(req, type, 0, 1);
-
- break;
-
-@@ -5480,7 +5480,7 @@ eval_enum(struct type *type, struct gnu_
- * member field, and when found, return its relevant data.
- */
- static void
--get_member_data(struct gnu_request *req, struct type *type)
-+get_member_data(struct gnu_request *req, struct type *type, long offset, int is_first)
- {
- register short i;
- struct field *nextfield;
-@@ -5492,7 +5492,7 @@ get_member_data(struct gnu_request *req,
- nfields = TYPE_MAIN_TYPE(type)->nfields;
- nextfield = TYPE_MAIN_TYPE(type)->flds_bnds.fields;
-
-- if (nfields == 0) {
-+ if (nfields == 0 && is_first /* The first call */) {
- struct type *newtype;
- newtype = lookup_transparent_type(req->name);
- if (newtype) {
-@@ -5505,13 +5505,18 @@ get_member_data(struct gnu_request *req,
-
- for (i = 0; i < nfields; i++) {
- if (STREQ(req->member, nextfield->name)) {
-- req->member_offset = nextfield->loc.bitpos;
-+ req->member_offset = offset + nextfield->loc.bitpos;
- req->member_length = TYPE_LENGTH(nextfield->type);
- req->member_typecode = TYPE_CODE(nextfield->type);
- if ((req->member_typecode == TYPE_CODE_TYPEDEF) &&
- (typedef_type = check_typedef(nextfield->type)))
- req->member_length = TYPE_LENGTH(typedef_type);
- return;
-+ } else if (*nextfield->name == 0) { /* Anonymous struct/union */
-+ get_member_data(req, nextfield->type,
-+ offset + nextfield->loc.bitpos, 0);
-+ if (req->member_offset != -1)
-+ return;
- }
- nextfield++;
- }
-@@ -5706,7 +5711,7 @@ gdb_get_symbol_type(struct gnu_request *
- }
-
- if (req->member)
-- get_member_data(req, type);
-+ get_member_data(req, type, 0, 1);
-
- do_cleanups (old_chain);
- }
-diff -up gdb-7.6/bfd/configure.orig gdb-7.6/bfd/configure
---- gdb-7.6/bfd/configure.orig 2017-02-17 17:19:51.654898822 -0500
-+++ gdb-7.6/bfd/configure 2017-02-17 17:19:57.922038757 -0500
-@@ -12193,7 +12193,7 @@ fi
-
- NO_WERROR=
- if test "${ERROR_ON_WARNING}" = yes ; then
-- GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
-+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS"
- NO_WERROR="-Wno-error"
- fi
-
-diff -up gdb-7.6/opcodes/configure.orig gdb-7.6/opcodes/configure
---- gdb-7.6/opcodes/configure.orig 2017-02-17 17:19:08.849943016 -0500
-+++ gdb-7.6/opcodes/configure 2017-02-17 17:19:23.256264699 -0500
-@@ -11539,7 +11539,7 @@ fi
-
- NO_WERROR=
- if test "${ERROR_ON_WARNING}" = yes ; then
-- GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS -Werror"
-+ GCC_WARN_CFLAGS="$GCC_WARN_CFLAGS"
- NO_WERROR="-Wno-error"
- fi
-
---- gdb-7.6/gdb/symtab.c.orig
-+++ gdb-7.6/gdb/symtab.c
-@@ -5266,6 +5266,7 @@ gdb_get_line_number(struct gnu_request *
- {
- struct symtab_and_line sal;
- struct symbol *sym;
-+ struct objfile *objfile;
- CORE_ADDR pc;
-
- #define LASTCHAR(s) (s[strlen(s)-1])
-@@ -5281,8 +5282,22 @@ gdb_get_line_number(struct gnu_request *
- sal = find_pc_line(pc, 0);
-
- if (!sal.symtab) {
-- req->buf[0] = '\0';
-- return;
-+ /*
-+ * If a module address line number can't be found, it's typically
-+ * due to its addrmap still containing offset values because its
-+ * objfile doesn't have full symbols loaded.
-+ */
-+ if (req->lm) {
-+ objfile = req->lm->loaded_objfile;
-+ if (!objfile_has_full_symbols(objfile) && objfile->sf) {
-+ objfile->sf->qf->expand_all_symtabs(objfile);
-+ sal = find_pc_line(pc, 0);
-+ }
-+ }
-+ if (!sal.symtab) {
-+ req->buf[0] = '\0';
-+ return;
-+ }
- }
-
- if (sal.symtab->filename && sal.symtab->dirname) {
-@@ -5557,7 +5572,6 @@ struct load_module *gdb_current_load_mod
- static void
- gdb_add_symbol_file(struct gnu_request *req)
- {
-- register struct objfile *loaded_objfile = NULL;
- register struct objfile *objfile;
- register struct minimal_symbol *m;
- struct load_module *lm;
-@@ -5576,6 +5590,7 @@ gdb_add_symbol_file(struct gnu_request *
-
- req->name = lm->mod_namelist;
- gdb_delete_symbol_file(req);
-+ lm->loaded_objfile = NULL;
-
- if ((lm->mod_flags & MOD_NOPATCH) == 0) {
- for (i = 0 ; i < lm->mod_sections; i++) {
-@@ -5623,12 +5638,15 @@ gdb_add_symbol_file(struct gnu_request *
-
- ALL_OBJFILES(objfile) {
- if (same_file(objfile->name, lm->mod_namelist)) {
-- loaded_objfile = objfile;
-+ if (objfile->separate_debug_objfile)
-+ lm->loaded_objfile = objfile->separate_debug_objfile;
-+ else
-+ lm->loaded_objfile = objfile;
- break;
- }
- }
-
-- if (!loaded_objfile)
-+ if (!lm->loaded_objfile)
- req->flags |= GNU_COMMAND_FAILED;
- }
-
---- gdb-7.6/gdb/symtab.c.orig
-+++ gdb-7.6/gdb/symtab.c
-@@ -5500,7 +5500,7 @@ get_member_data(struct gnu_request *req,
- register short i;
- struct field *nextfield;
- short nfields;
-- struct type *typedef_type;
-+ struct type *typedef_type, *target_type;
-
- req->member_offset = -1;
-
-@@ -5523,6 +5523,13 @@ get_member_data(struct gnu_request *req,
- req->member_offset = offset + nextfield->loc.bitpos;
- req->member_length = TYPE_LENGTH(nextfield->type);
- req->member_typecode = TYPE_CODE(nextfield->type);
-+ req->member_main_type_name = (char *)TYPE_NAME(nextfield->type);
-+ req->member_main_type_tag_name = (char *)TYPE_TAG_NAME(nextfield->type);
-+ target_type = TYPE_TARGET_TYPE(nextfield->type);
-+ if (target_type) {
-+ req->member_target_type_name = (char *)TYPE_NAME(target_type);
-+ req->member_target_type_tag_name = (char *)TYPE_TAG_NAME(target_type);
-+ }
- if ((req->member_typecode == TYPE_CODE_TYPEDEF) &&
- (typedef_type = check_typedef(nextfield->type)))
- req->member_length = TYPE_LENGTH(typedef_type);
-
---- gdb-7.6/gdb/symtab.c.orig
-+++ gdb-7.6/gdb/symtab.c
-@@ -5727,6 +5727,7 @@ gdb_get_symbol_type(struct gnu_request *
- req->type_name = (char *)TYPE_MAIN_TYPE(type)->name;
- req->typecode = TYPE_MAIN_TYPE(type)->code;
- req->length = type->length;
-+ req->type_tag_name = (char *)TYPE_TAG_NAME(type);
- target_type = TYPE_MAIN_TYPE(type)->target_type;
-
- if (target_type) {
---- gdb-7.6/gdb/common/linux-ptrace.c.orig
-+++ gdb-7.6/gdb/common/linux-ptrace.c
-@@ -108,14 +108,14 @@ linux_ptrace_test_ret_to_nx (void)
- ".globl linux_ptrace_test_ret_to_nx_instr;"
- "linux_ptrace_test_ret_to_nx_instr:"
- "ret"
-- : : "r" (return_address) : "%esp", "memory");
-+ : : "r" (return_address) : "memory");
- #elif defined __x86_64__
- asm volatile ("pushq %0;"
- ".globl linux_ptrace_test_ret_to_nx_instr;"
- "linux_ptrace_test_ret_to_nx_instr:"
- "ret"
- : : "r" ((uint64_t) (uintptr_t) return_address)
-- : "%rsp", "memory");
-+ : "memory");
- #else
- # error "!__i386__ && !__x86_64__"
- #endif
---- gdb-7.6/gdb/features/aarch64.c.orig
-+++ gdb-7.6/gdb/features/aarch64.c
-@@ -5,7 +5,6 @@
- #include "osabi.h"
- #include "target-descriptions.h"
-
--struct target_desc *tdesc_aarch64;
- static void
- initialize_tdesc_aarch64 (void)
- {
---- gdb-7.6/gdb/aarch64-linux-nat.c.orig
-+++ gdb-7.6/gdb/aarch64-linux-nat.c
-@@ -37,6 +37,7 @@
-
- #include "gregset.h"
-
-+extern struct target_desc *tdesc_aarch64;
- #include "features/aarch64.c"
-
- /* Defines ps_err_e, struct ps_prochandle. */
---- gdb-7.6/gdb/aarch64-tdep.c.orig
-+++ gdb-7.6/gdb/aarch64-tdep.c
-@@ -52,6 +52,7 @@
- #include "gdb_assert.h"
- #include "vec.h"
-
-+struct target_desc *tdesc_aarch64;
- #include "features/aarch64.c"
- #include "features/aarch64-without-fpu.c"
-
diff --git a/gdb_interface.c b/gdb_interface.c
index 562d2ac..a1eeaf4 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -17,7 +17,9 @@
#include "defs.h"
+#ifndef GDB_10_1
static void exit_after_gdb_info(void);
+#endif
static int is_restricted_command(char *, ulong);
static void strip_redirection(char *);
int get_frame_offset(ulong);
@@ -29,6 +31,7 @@ int *gdb_prettyprint_arrays;
int *gdb_repeat_count_threshold;
int *gdb_stop_print_at_null;
unsigned int *gdb_output_radix;
+static void gdb_error_debug(void);
static ulong gdb_user_print_option_address(char *);
@@ -68,11 +71,13 @@ gdb_main_loop(int argc, char **argv)
}
optind = 0;
+#ifndef GDB_10_1
#if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1)
command_loop_hook = main_loop;
#else
deprecated_command_loop_hook = main_loop;
#endif
+#endif
gdb_main_entry(argc, argv);
}
@@ -117,22 +122,26 @@ void
display_gdb_banner(void)
{
optind = 0;
+#ifndef GDB_10_1
#if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1)
command_loop_hook = exit_after_gdb_info;
#else
deprecated_command_loop_hook = exit_after_gdb_info;
#endif
+#endif
args[0] = "gdb";
args[1] = "-version";
gdb_main_entry(2, args);
}
+#ifndef GDB_10_1
static void
exit_after_gdb_info(void)
{
fprintf(fp, "\n");
clean_exit(0);
}
+#endif
/*
* Stash a copy of the gdb version locally. This can be called before
@@ -364,19 +373,6 @@ gdb_interface(struct gnu_request *req)
pc->cur_req = req;
pc->cur_gdb_cmd = req->command;
- if (req->flags & GNU_RETURN_ON_ERROR) {
- error_hook = gdb_error_hook;
- if (setjmp(pc->gdb_interface_env)) {
- pc->last_gdb_cmd = pc->cur_gdb_cmd;
- pc->cur_gdb_cmd = 0;
- pc->cur_req = NULL;
- req->flags |= GNU_COMMAND_FAILED;
- pc->flags &= ~IN_GDB;
- return;
- }
- } else
- error_hook = NULL;
-
if (CRASHDEBUG(2))
dump_gnu_request(req, IN_GDB);
@@ -400,10 +396,12 @@ gdb_interface(struct gnu_request *req)
SIGACTION(SIGINT, restart, &pc->sigaction, NULL);
SIGACTION(SIGSEGV, SIG_DFL, &pc->sigaction, NULL);
+ if (req->flags & GNU_COMMAND_FAILED)
+ gdb_error_debug();
+
if (CRASHDEBUG(2))
dump_gnu_request(req, !IN_GDB);
- error_hook = NULL;
pc->last_gdb_cmd = pc->cur_gdb_cmd;
pc->cur_gdb_cmd = 0;
pc->cur_req = NULL;
@@ -627,8 +625,6 @@ restore_gdb_sanity(void)
*gdb_prettyprint_structs = 1; /* these may piss somebody off... */
*gdb_repeat_count_threshold = 0x7fffffff;
- error_hook = NULL;
-
if (st->flags & ADD_SYMBOL_FILE) {
error(INFO,
"%s\n gdb add-symbol-file command failed\n",
@@ -948,8 +944,8 @@ gdb_print_callback(ulong addr)
/*
* Used by gdb_interface() to catch gdb-related errors, if desired.
*/
-void
-gdb_error_hook(void)
+static void
+gdb_error_debug(void)
{
char buf1[BUFSIZE];
char buf2[BUFSIZE];
@@ -968,14 +964,6 @@ gdb_error_hook(void)
console("%s: returned via gdb_error_hook %s",
gdb_command_string(pc->cur_gdb_cmd, buf1, TRUE), buf2);
}
-
-#ifdef GDB_7_6
- do_cleanups(all_cleanups());
-#else
- do_cleanups(NULL);
-#endif
-
- longjmp(pc->gdb_interface_env, 1);
}
@@ -1064,3 +1052,27 @@ get_frame_offset(ulong pc)
#endif /* !ALPHA */
+unsigned long crash_get_kaslr_offset(void);
+unsigned long crash_get_kaslr_offset(void)
+{
+ return kt->relocate * -1;
+}
+
+/* Callbacks for crash_target */
+int crash_get_nr_cpus(void);
+
+int crash_get_nr_cpus(void)
+{
+ if (SADUMP_DUMPFILE())
+ return sadump_get_nr_cpus();
+ else if (DISKDUMP_DUMPFILE())
+ return diskdump_get_nr_cpus();
+ else if (KDUMP_DUMPFILE())
+ return kdump_get_nr_cpus();
+ else if (VMSS_DUMPFILE())
+ return vmware_vmss_get_nr_cpus();
+
+ /* Just CPU #0 */
+ return 1;
+}
+
diff --git a/kernel.c b/kernel.c
index 9871637..f38bfe0 100644
--- a/kernel.c
+++ b/kernel.c
@@ -1048,7 +1048,7 @@ verify_version(void)
if (!(sp = symbol_search("linux_banner")))
error(FATAL, "linux_banner symbol does not exist?\n");
- else if ((sp->type == 'R') || (sp->type == 'r') ||
+ else if ((sp->type == 'R') || (sp->type == 'r') || (sp->type ==
'D') ||
(machine_type("ARM") && sp->type == 'T') ||
(machine_type("ARM64")))
linux_banner = symbol_value("linux_banner");
diff --git a/main.c b/main.c
index 388ac46..71c59d2 100644
--- a/main.c
+++ b/main.c
@@ -1704,7 +1704,6 @@ dump_program_context(void)
fprintf(fp, " gdb_sigaction: %lx\n", (ulong)&pc->gdb_sigaction);
fprintf(fp, " main_loop_env: %lx\n", (ulong)&pc->main_loop_env);
fprintf(fp, " foreach_loop_env: %lx\n", (ulong)&pc->foreach_loop_env);
- fprintf(fp, "gdb_interface_env: %lx\n",
(ulong)&pc->gdb_interface_env);
fprintf(fp, " termios_orig: %lx\n", (ulong)&pc->termios_orig);
fprintf(fp, " termios_raw: %lx\n", (ulong)&pc->termios_raw);
fprintf(fp, " ncmds: %d\n", pc->ncmds);
diff --git a/symbols.c b/symbols.c
index b2f4eb5..03bc35e 100644
--- a/symbols.c
+++ b/symbols.c
@@ -17,7 +17,7 @@
#include "defs.h"
#include <elf.h>
-#ifdef GDB_7_6
+#if defined(GDB_7_6) || defined(GDB_10_1)
#define __CONFIG_H__ 1
#include "config.h"
#endif
@@ -34,7 +34,7 @@ static int compare_mods(const void *, const void *);
static int compare_prios(const void *v1, const void *v2);
static int compare_size_name(const void *, const void *);
struct type_request;
-static void append_struct_symbol (struct type_request *, struct gnu_request *);
+static void append_struct_symbol (struct gnu_request *, void *);
static void request_types(ulong, ulong, char *);
static asection *get_kernel_section(char *);
static char * get_section(ulong vaddr, char *buf);
@@ -278,7 +278,7 @@ check_gnu_debuglink(bfd *bfd)
return FALSE;
}
- debuglink_size = bfd_section_size(bfd, sect);
+ debuglink_size = bfd_section_size(sect);
contents = GETBUF(debuglink_size);
@@ -443,7 +443,7 @@ separate_debug_file_exists(const char *name, unsigned long crc, int
*exists)
#ifdef GDB_5_3
file_crc = calc_crc32(file_crc, buffer, count);
#else
-#ifdef GDB_7_6
+#if defined(GDB_7_6) || defined(GDB_10_1)
file_crc = bfd_calc_gnu_debuglink_crc32(file_crc,
(unsigned char *)buffer, count);
#else
@@ -524,9 +524,8 @@ get_text_init_space(void)
return;
}
- kt->stext_init = (ulong)bfd_get_section_vma(st->bfd, section);
- kt->etext_init = kt->stext_init +
- (ulong)bfd_section_size(st->bfd, section);
+ kt->stext_init = (ulong)bfd_section_vma(section);
+ kt->etext_init = kt->stext_init + (ulong)bfd_section_size(section);
if (kt->relocate) {
kt->stext_init -= kt->relocate;
@@ -774,7 +773,6 @@ store_symbols(bfd *abfd, int dynamic, void *minisyms, long symcount,
bfd_get_symbol_info(abfd, sym, &syminfo);
name = strip_symbol_end(syminfo.name, buf);
-
if (machdep->verify_symbol(name, syminfo.value,
syminfo.type)) {
if (kt->flags & (RELOC_SET|RELOC_FORCE))
@@ -2864,10 +2862,8 @@ is_kernel_text(ulong value)
for (i = 0; i < st->bfd->section_count; i++, sec++) {
section = *sec;
if (section->flags & SEC_CODE) {
- start = (ulong)bfd_get_section_vma(st->bfd,
- section);
- end = start + (ulong)bfd_section_size(st->bfd,
- section);
+ start = (ulong)bfd_section_vma(section);
+ end = start + (ulong)bfd_section_size(section);
if (kt->flags2 & KASLR) {
start += (kt->relocate * -1);
@@ -3470,8 +3466,8 @@ dump_symbol_table(void)
section = *sec;
fprintf(fp, "%25s vma: %.*lx size: %ld\n",
section->name, VADDR_PRLEN,
- (ulong)bfd_get_section_vma(st->bfd, section),
- (ulong)bfd_section_size(st->bfd, section));
+ (ulong)bfd_section_vma(section),
+ (ulong)bfd_section_size(section));
}
fprintf(fp, "\n downsized: ");
if (st->downsized.name) {
@@ -4353,12 +4349,11 @@ get_section(ulong vaddr, char *buf)
sec = (asection **)st->sections;
for (i = 0; i < st->bfd->section_count; i++, sec++) {
section = *sec;
- start = (ulong)bfd_get_section_vma(st->bfd, section);
- end = start + (ulong)bfd_section_size(st->bfd, section);
+ start = (ulong)bfd_section_vma(section);
+ end = start + (ulong)bfd_section_size(section);
if ((vaddr >= start) && (vaddr < end)) {
- strcpy(buf, bfd_get_section_name(st->bfd,
- section));
+ strcpy(buf, bfd_section_name(section));
break;
}
}
@@ -6990,8 +6985,9 @@ compare_size_name(const void *va, const void *vb) {
}
static void
-append_struct_symbol (struct type_request *treq, struct gnu_request *req)
+append_struct_symbol (struct gnu_request *req, void *data)
{
+ struct type_request *treq = (struct type_request *)data;
int i;
long s;
@@ -7031,22 +7027,13 @@ request_types(ulong lowest, ulong highest, char *member_name)
request.type_name = member_name;
#endif
- while (!request.global_iterator.finished) {
- request.command = GNU_GET_NEXT_DATATYPE;
- gdb_interface(&request);
- if (highest &&
- !(lowest <= request.length && request.length <= highest))
- continue;
-
- if (member_name) {
- request.command = GNU_LOOKUP_STRUCT_CONTENTS;
- gdb_interface(&request);
- if (!request.value)
- continue;
- }
-
- append_struct_symbol(&typereq, &request);
- }
+ request.command = GNU_ITERATE_DATATYPES;
+ request.lowest = lowest;
+ request.highest = highest;
+ request.member = member_name;
+ request.callback = append_struct_symbol;
+ request.callback_data = (void *)&typereq;
+ gdb_interface(&request);
qsort(typereq.types, typereq.idx, sizeof(struct type_info), compare_size_name);
@@ -11133,39 +11120,39 @@ section_header_info(bfd *bfd, asection *section, void *reqptr)
sec++;
*sec = section;
- if (STREQ(bfd_get_section_name(bfd, section), ".text.init") ||
- STREQ(bfd_get_section_name(bfd, section), ".init.text")) {
+ if (STREQ(bfd_section_name(section), ".text.init") ||
+ STREQ(bfd_section_name(section), ".init.text")) {
kt->stext_init = (ulong)
- bfd_get_section_vma(bfd, section);
+ bfd_section_vma(section);
kt->etext_init = kt->stext_init +
- (ulong)bfd_section_size(bfd, section);
+ (ulong)bfd_section_size(section);
}
- if (STREQ(bfd_get_section_name(bfd, section), ".text")) {
+ if (STREQ(bfd_section_name(section), ".text")) {
st->first_section_start = (ulong)
- bfd_get_section_vma(bfd, section);
+ bfd_section_vma(section);
}
- if (STREQ(bfd_get_section_name(bfd, section), ".text") ||
- STREQ(bfd_get_section_name(bfd, section), ".data")) {
- if (!(bfd_get_section_flags(bfd, section) & SEC_LOAD))
+ if (STREQ(bfd_section_name(section), ".text") ||
+ STREQ(bfd_section_name(section), ".data")) {
+ if (!(bfd_section_flags(section) & SEC_LOAD))
st->flags |= NO_SEC_LOAD;
- if (!(bfd_get_section_flags(bfd, section) &
+ if (!(bfd_section_flags(section) &
SEC_HAS_CONTENTS))
st->flags |= NO_SEC_CONTENTS;
}
- if (STREQ(bfd_get_section_name(bfd, section), ".eh_frame")) {
+ if (STREQ(bfd_section_name(section), ".eh_frame")) {
st->dwarf_eh_frame_file_offset = (off_t)section->filepos;
- st->dwarf_eh_frame_size = (ulong)bfd_section_size(bfd, section);
+ st->dwarf_eh_frame_size = (ulong)bfd_section_size(section);
}
- if (STREQ(bfd_get_section_name(bfd, section), ".debug_frame"))
{
+ if (STREQ(bfd_section_name(section), ".debug_frame")) {
st->dwarf_debug_frame_file_offset = (off_t)section->filepos;
- st->dwarf_debug_frame_size = (ulong)bfd_section_size(bfd, section);
+ st->dwarf_debug_frame_size = (ulong)bfd_section_size(section);
}
if (st->first_section_start != 0) {
section_end_address =
- (ulong) bfd_get_section_vma(bfd, section) +
- (ulong) bfd_section_size(bfd, section);
+ (ulong) bfd_section_vma(section) +
+ (ulong) bfd_section_size(section);
if (section_end_address > st->last_section_end)
st->last_section_end = section_end_address;
}
@@ -11177,21 +11164,21 @@ section_header_info(bfd *bfd, asection *section, void *reqptr)
break;
case (ulong)VERIFY_SECTIONS:
- if (STREQ(bfd_get_section_name(bfd, section), ".text") ||
- STREQ(bfd_get_section_name(bfd, section), ".data")) {
- if (!(bfd_get_section_flags(bfd, section) & SEC_LOAD))
+ if (STREQ(bfd_section_name(section), ".text") ||
+ STREQ(bfd_section_name(section), ".data")) {
+ if (!(bfd_section_flags(section) & SEC_LOAD))
st->flags |= NO_SEC_LOAD;
- if (!(bfd_get_section_flags(bfd, section) &
+ if (!(bfd_section_flags(section) &
SEC_HAS_CONTENTS))
st->flags |= NO_SEC_CONTENTS;
}
- if (STREQ(bfd_get_section_name(bfd, section), ".eh_frame")) {
+ if (STREQ(bfd_section_name(section), ".eh_frame")) {
st->dwarf_eh_frame_file_offset = (off_t)section->filepos;
- st->dwarf_eh_frame_size = (ulong)bfd_section_size(bfd, section);
+ st->dwarf_eh_frame_size = (ulong)bfd_section_size(section);
}
- if (STREQ(bfd_get_section_name(bfd, section), ".debug_frame"))
{
+ if (STREQ(bfd_section_name(section), ".debug_frame")) {
st->dwarf_debug_frame_file_offset = (off_t)section->filepos;
- st->dwarf_debug_frame_size = (ulong)bfd_section_size(bfd, section);
+ st->dwarf_debug_frame_size = (ulong)bfd_section_size(section);
}
break;
@@ -11231,7 +11218,7 @@ store_section_data(struct load_module *lm, bfd *bfd, asection
*section)
char *name;
prio = 0;
- name = (char *)bfd_get_section_name(bfd, section);
+ name = (char *)bfd_section_name(section);
if (name[0] != '.' || strlen(name) != 10 || strcmp(name + 5,
".init"))
prio |= 32;
@@ -11253,10 +11240,10 @@ store_section_data(struct load_module *lm, bfd *bfd, asection
*section)
*/
if (lm->mod_percpu &&
(STREQ(name,".data.percpu") || STREQ(name, ".data..percpu"))) {
- lm->mod_percpu_size = bfd_section_size(bfd, section);
+ lm->mod_percpu_size = bfd_section_size(section);
lm->mod_section_data[i].flags |= SEC_FOUND;
}
- lm->mod_section_data[i].size = bfd_section_size(bfd, section);
+ lm->mod_section_data[i].size = bfd_section_size(section);
lm->mod_section_data[i].offset = 0;
if (strlen(name) < MAX_MOD_SEC_NAME)
strcpy(lm->mod_section_data[i].name, name);
@@ -11334,7 +11321,7 @@ calculate_load_order_v1(struct load_module *lm, bfd *bfd)
for (i = (lm->mod_sections-1); i >= 0; i--) {
section = lm->mod_section_data[i].section;
- alignment = power(2, bfd_get_section_alignment(bfd, section));
+ alignment = power(2, bfd_section_alignment(section));
if (alignment && (offset & (alignment - 1)))
offset = (offset | (alignment - 1)) + 1;
@@ -11363,9 +11350,9 @@ calculate_load_order_v1(struct load_module *lm, bfd *bfd)
if (STREQ(lm->mod_section_data[i].name, ".rodata"))
lm->mod_rodata_start = lm->mod_base + offset;
- offset += bfd_section_size(bfd, section);
+ offset += bfd_section_size(section);
- if (STREQ(bfd_get_section_name(bfd, section), ".kstrtab"))
+ if (STREQ(bfd_section_name(section), ".kstrtab"))
offset += strlen(lm->mod_name)+1;
}
}
@@ -11442,7 +11429,7 @@ calculate_load_order_v2(struct load_module *lm, bfd *bfd, int
dynamic,
(long) syminfo.value);
}
if (strcmp(syminfo.name, s1->name) == 0) {
- secname = (char *)bfd_get_section_name(bfd, sym->section);
+ secname = (char *)bfd_section_name(sym->section);
break;
}
@@ -12190,7 +12177,7 @@ store_load_module_symbols(bfd *bfd, int dynamic, void *minisyms,
bfd_get_symbol_info(bfd, sym, &syminfo);
- secname = (char *)bfd_get_section_name(bfd, sym->section);
+ secname = (char *)bfd_section_name(sym->section);
found = 0;
if (kt->flags & KMOD_V1) {
@@ -12747,8 +12734,8 @@ numeric_forward(const void *P_x, const void *P_y)
st->saved_command_line_vmlinux = valueof(y);
}
- xs = bfd_get_section(x);
- ys = bfd_get_section(y);
+ xs = bfd_asymbol_section(x);
+ ys = bfd_asymbol_section(y);
if (bfd_is_und_section(xs)) {
if (!bfd_is_und_section(ys))
diff --git a/x86_64.c b/x86_64.c
index 5002934..12a764e 100644
--- a/x86_64.c
+++ b/x86_64.c
@@ -7050,7 +7050,7 @@ x86_64_virt_phys_base(void)
ulong phys, linux_banner_phys;
if (!(sp = symbol_search("linux_banner")) ||
- !((sp->type == 'R') || (sp->type == 'r')))
+ !((sp->type == 'R') || (sp->type == 'r') || (sp->type ==
'D')))
return FALSE;
linux_banner_phys = sp->value - __START_KERNEL_map;
--
2.11.0