[Crash-utility] [PATCH v2 3/3] Update to gdb-16.2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Tao Liu <ltao@xxxxxxxxxx>
---
 Makefile        |    3 +
 configure.c     |   21 +-
 crash_target.c  |    6 +-
 defs.h          |    8 +-
 gdb-10.2.patch  | 2439 -----------------------------------------------
 gdb-16.2.patch  | 2254 +++++++++++++++++++++++++++++++++++++++++++
 gdb_interface.c |   14 +-
 kernel.c        |    6 +-
 symbols.c       |    4 +-
 9 files changed, 2295 insertions(+), 2460 deletions(-)
 delete mode 100644 gdb-10.2.patch
 create mode 100644 gdb-16.2.patch

diff --git a/Makefile b/Makefile
index 3f8f6b2..f6c4da6 100644
--- a/Makefile
+++ b/Makefile
@@ -191,6 +191,9 @@ GDB_7.6_OFILES=${GDB}/gdb/symtab.o
 GDB_10.2_FILES=
 GDB_10.2_OFILES=${GDB}/gdb/symtab.o crash_target.o
 
+GDB_16.2_FILES=
+GDB_16.2_OFILES=${GDB}/gdb/symtab.o crash_target.o
+
 # 
 # GDB_FLAGS is passed up from the gdb Makefile.
 #
diff --git a/configure.c b/configure.c
index 08b52be..1a4c4f8 100644
--- a/configure.c
+++ b/configure.c
@@ -189,9 +189,10 @@ void add_extra_lib(char *);
 #define GDB_7_3_1 (4)
 #define GDB_7_6   (5)
 #define GDB_10_2   (6)
-#define SUPPORTED_GDB_VERSIONS (GDB_10_2 + 1)
+#define GDB_16_2   (7)
+#define SUPPORTED_GDB_VERSIONS (GDB_16_2 + 1)
 
-int default_gdb = GDB_10_2;
+int default_gdb = GDB_16_2;
 
 struct supported_gdb_version {
 	char *GDB;
@@ -265,6 +266,15 @@ struct supported_gdb_version {
             "GDB_FLAGS=-DGDB_10_2",
             "GPLv3"
         },
+        {
+            "GDB=gdb-16.2",
+            "16.2",
+            "GDB_FILES=${GDB_16.2_FILES}",
+            "GDB_OFILES=${GDB_16.2_OFILES}",
+            "GDB_PATCH_FILES=gdb-16.2.patch",
+            "GDB_FLAGS=-DGDB_16_2",
+            "GPLv3"
+        },
 };
 
 #define DAEMON  0x1
@@ -1564,7 +1574,12 @@ setup_gdb_defaults(void)
                         fprintf(stderr, ".gdb configuration: %s\n", sp->GDB_VERSION_IN);
                         return store_gdb_defaults(sp);
                 }
-
+                if (strcmp(buf, "16.2") == 0) {
+                        fclose(fp);
+                        sp = &supported_gdb_versions[GDB_16_2];
+                        fprintf(stderr, ".gdb configuration: %s\n", sp->GDB_VERSION_IN);
+                        return store_gdb_defaults(sp);
+                }
         }
 	
 	fclose(fp);
diff --git a/crash_target.c b/crash_target.c
index 1080976..5966b7b 100644
--- a/crash_target.c
+++ b/crash_target.c
@@ -125,7 +125,7 @@ crash_target_init (void)
   /* Own the target until it is successfully pushed.  */
   target_ops_up target_holder (target);
 
-  push_target (std::move (target_holder));
+  current_inferior ()->push_target (std::move (target_holder));
 
   inferior_appeared (current_inferior (), CRASH_INFERIOR_PID);
 
@@ -135,7 +135,7 @@ crash_target_init (void)
   switch_to_thread (thread);
 
   /* Fetch all registers from core file.  */
-  target_fetch_registers (get_current_regcache (), -1);
+  target_fetch_registers (get_thread_regcache(thread), -1);
 
   /* Now, set up the frame cache. */
   reinit_frame_cache ();
@@ -144,7 +144,7 @@ crash_target_init (void)
 extern "C" int
 gdb_change_thread_context (void)
 {
-  target_fetch_registers(get_current_regcache(), -1);
+  target_fetch_registers(get_thread_regcache(inferior_thread()), -1);
   reinit_frame_cache();
   return TRUE;
 }
diff --git a/defs.h b/defs.h
index bc22bb6..2ffa44e 100644
--- a/defs.h
+++ b/defs.h
@@ -5262,8 +5262,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) || defined(GDB_10_2)
-#if defined(GDB_7_0) || defined(GDB_7_3_1) || defined(GDB_7_6) || defined(GDB_10_2)
+#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_2) || defined(GDB_16_2)
+#if defined(GDB_7_0) || defined(GDB_7_3_1) || defined(GDB_7_6) || defined(GDB_10_2) || defined(GDB_16_2)
   TYPE_CODE_FLAGS,              /* Bit flags type */
 #endif
   TYPE_CODE_FUNC,               /* Function type */
@@ -7939,8 +7939,8 @@ extern unsigned long calc_crc32(unsigned long, unsigned char *, size_t);
 #else
 extern unsigned long gnu_debuglink_crc32 (unsigned long, unsigned char *, size_t);
 #endif
-extern int have_partial_symbols(void); 
-extern int have_full_symbols(void);
+extern int have_partial_symbols(void *); 
+extern int have_full_symbols(void *);
 
 #if defined(X86) || defined(X86_64) || defined(IA64)
 #define XEN_HYPERVISOR_ARCH 
diff --git a/gdb-10.2.patch b/gdb-10.2.patch
deleted file mode 100644
index a7fc6c2..0000000
--- a/gdb-10.2.patch
+++ /dev/null
@@ -1,2439 +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 unintended 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.
-
-tar xvzmf gdb-10.2.tar.gz \
-	gdb-10.2/gdb/symtab.c \
-	gdb-10.2/gdb/printcmd.c \
-	gdb-10.2/gdb/symfile.c \
-	gdb-10.2/gdb/Makefile.in \
-	gdb-10.2/gdb/dwarf2/read.c \
-	gdb-10.2/gdb/ada-lang.c \
-	gdb-10.2/gdb/stack.c \
-	gdb-10.2/gdb/ui-file.h
-
-exit 0
-
---- gdb-10.2/Makefile.in.orig
-+++ gdb-10.2/Makefile.in
-@@ -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@
---- gdb-10.2/gdb/Makefile.in.orig
-+++ gdb-10.2/gdb/Makefile.in
-@@ -571,7 +571,7 @@ CONFIG_DEP_SUBDIR = $(addsuffix /$(DEPDIR),$(CONFIG_SRC_SUBDIR))
- # 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 -D${CRASH_TARGET} @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) $(YYOBJ) \
- 	$(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_2 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 $(@F)).Tpo
--override POSTCOMPILE = @mv $(@D)/$(DEPDIR)/$(basename $(@F)).Tpo \
--	$(@D)/$(DEPDIR)/$(basename $(@F)).Po
-+        -MF $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Tpo
-+override POSTCOMPILE = @mv $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Tpo \
-+        $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Po
- else
- override COMPILE.pre = source='$<' object='$@' libtool=no \
- 	DEPDIR=$(DEPDIR) $(DEPMODE) $(depcomp) \
---- gdb-10.2/gdb/cli/cli-cmds.c.orig
-+++ gdb-10.2/gdb/cli/cli-cmds.c
-@@ -435,6 +435,11 @@ complete_command (const char *arg, int from_tty)
-     }
- }
- 
-+#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_file, int search_path)
-       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 *file, int from_tty, int search_path)
-          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 *file, int from_tty, int search_path)
- 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
---- gdb-10.2/gdb/defs.h.orig
-+++ gdb-10.2/gdb/defs.h
-@@ -629,4 +629,7 @@ DEF_ENUM_FLAGS_TYPE (enum user_selected_what_flag, user_selected_what);
- 
- #include "utils.h"
- 
-+#ifdef CRASH_MERGE
-+extern "C" int gdb_main_entry(int, char **);
-+#endif
- #endif /* #ifndef DEFS_H */
---- gdb-10.2/gdb/dwarf2/read.c.orig
-+++ gdb-10.2/gdb/dwarf2/read.c
-@@ -3015,7 +3015,11 @@ read_gdb_index_from_buffer (const char *filename,
-      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."),
-@@ -3034,7 +3038,11 @@ read_gdb_index_from_buffer (const char *filename,
-      "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-10.2/gdb/main.c.orig
-+++ gdb-10.2/gdb/main.c
-@@ -392,6 +392,14 @@ 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);
-+extern "C" int console(const char *, ...);
-+void crash_target_init (void);
-+#endif
-+
- /* Call command_loop.  */
- 
- /* Prevent inlining this function for the benefit of GDB's selftests
-@@ -925,7 +933,11 @@ captured_main_1 (struct captured_main_args *context)
-       }
-   }
- 
-+#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 +1011,7 @@ captured_main_1 (struct captured_main_args *context)
-     {
-       print_gdb_version (gdb_stdout, false);
-       wrap_here ("");
--      printf_filtered ("\n");
-+      printf_filtered ("\n\n");
-       exit (0);
-     }
- 
-@@ -1038,6 +1050,10 @@ captured_main_1 (struct captured_main_args *context)
-      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 +1082,11 @@ captured_main_1 (struct captured_main_args *context)
-   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 +1095,11 @@ captured_main_1 (struct captured_main_args *context)
-      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++)
-@@ -1121,7 +1145,11 @@ captured_main_1 (struct captured_main_args *context)
- 				  !batch_flag);
-       if (ret != 0)
- 	ret = catch_command_errors (symbol_file_add_main_adapter,
-+#ifdef CRASH_MERGE
-+                                    symarg, 0);
-+#else
- 				    symarg, !batch_flag);
-+#endif
-     }
-   else
-     {
-@@ -1191,7 +1219,11 @@ captured_main_1 (struct captured_main_args *context)
- 	{
- 	  auto_load_local_gdbinit_loaded = 1;
- 
-+#ifdef CRASH_MERGE
-+          ret = catch_command_errors (source_script, local_gdbinit.c_str (), -1);
-+#else
- 	  ret = catch_command_errors (source_script, local_gdbinit.c_str (), 0);
-+#endif
- 	}
-     }
- 
-@@ -1242,6 +1274,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
-@@ -1256,6 +1298,9 @@ captured_main (void *data)
- 	{
- 	  exception_print (gdb_stderr, ex);
- 	}
-+#ifdef CRASH_MERGE
-+        console("<CAPTURED_MAIN WHILE LOOP>\n");
-+#endif
-     }
-   /* No exit -- exit is through quit_command.  */
- }
-@@ -1277,6 +1322,22 @@ gdb_main (struct captured_main_args *args)
-   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
---- gdb-10.2/gdb/objfiles.h.orig
-+++ gdb-10.2/gdb/objfiles.h
-@@ -747,9 +747,9 @@ extern int objfile_has_full_symbols (struct objfile *objfile);
- 
- 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);
---- gdb-10.2/gdb/printcmd.c.orig
-+++ gdb-10.2/gdb/printcmd.c
-@@ -524,6 +524,9 @@ set_next_address (struct gdbarch *gdbarch, CORE_ADDR addr)
-    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 *gdbarch, CORE_ADDR addr,
-   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 voidprint)
-     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\" command)."),
-   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,
---- gdb-10.2/gdb/psymtab.c.orig
-+++ gdb-10.2/gdb/psymtab.c
-@@ -283,6 +283,9 @@ find_pc_sect_psymtab_closer (struct objfile *objfile,
-   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
-@@ -363,7 +366,12 @@ find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc,
-
- 	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;
-       }
-
---- gdb-10.2/gdb/symfile.c.orig
-+++ gdb-10.2/gdb/symfile.c
-@@ -652,7 +652,26 @@ default_symfile_offsets (struct objfile *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, const char *name,
-   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_file *file, int from_tty,
- #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 *dir,
-   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,14 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile)
- 	}
-     }
- 
-+#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 +2380,10 @@ add_symbol_file_command (const char *args, int from_tty)
-   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, &section_addrs,
- 			  flags);
-@@ -3622,6 +3670,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-10.2/gdb/symtab.c.orig
-+++ gdb-10.2/gdb/symtab.c
-@@ -1870,27 +1870,46 @@ search_name_hash (enum language language, const char *search_name)
-    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 +6905,806 @@ If zero then the symbol cache is disabled."),
-   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 *);
-+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 && req->command != GNU_USER_PRINT_OPTION) {
-+                (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:
-+                {
-+                        CORE_ADDR start, end;
-+                        if (!find_pc_partial_function(req->pc, NULL, &start, &end))
-+                                req->flags |= GNU_COMMAND_FAILED;
-+                        else {
-+                                req->addr = (ulong)start;
-+                                req->addr2 = (ulong)end;
-+                        }
-+                }
-+                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 objfile *objfile;
-+        CORE_ADDR pc;
-+
-+#define LASTCHAR(s)      (s[strlen(s)-1])
-+
-+        /*
-+         * Prime the addrmap pump.
-+         */
-+        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;
-+        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;
-+        long long 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;
-+
-+        req->value = FALSE;
-+        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)
-+{
-+        struct load_module *lm;
-+        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)) {
-+                        objfile->unlink ();
-+                        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->sf)
-+        objfile->sf->qf->expand_all_symtabs(objfile);
-+
-+      for (compunit_symtab *cust : objfile->compunits ())
-+        {
-+          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
---- gdb-10.2/gdb/ui-file.h.orig
-+++ gdb-10.2/gdb/ui-file.h
-@@ -195,10 +195,10 @@ class stdio_file : public ui_file
- 
-   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;
---- gdb-10.2/gdb/xml-syscall.c.orig
-+++ gdb-10.2/gdb/xml-syscall.c
-@@ -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;
---- gdb-10.2/libiberty/Makefile.in.orig
-+++ gdb-10.2/libiberty/Makefile.in
-@@ -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) ./atexit.$(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-10.2/opcodes/i386-dis.c.orig
-+++ gdb-10.2/opcodes/i386-dis.c
-@@ -9778,6 +9778,10 @@ print_insn (bfd_vma pc, disassemble_info *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-10.2/readline/readline/misc.c.orig
-+++ gdb-10.2/readline/readline/misc.c
-@@ -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)
---- gdb-10.2/readline/readline/readline.h.orig
-+++ gdb-10.2/readline/readline/readline.h
-@@ -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));
---- gdb-10.2/readline/readline/rltypedefs.h.orig
-+++ gdb-10.2/readline/readline/rltypedefs.h
-@@ -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 ();
---- gdb-10.2/readline/readline/util.c.orig
-+++ gdb-10.2/readline/readline/util.c
-@@ -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;
- }
---- gdb-10.2/gdb/completer.c.orig
-+++ gdb-10.2/gdb/completer.c
-@@ -2949,6 +2949,8 @@
- 
-   /* How many items of MAX length can we fit in the screen window? */
-   cols = gdb_complete_get_screenwidth (displayer);
-+  rl_reset_screen_size();
-+  rl_get_screen_size(NULL, &cols);
-   max += 2;
-   limit = cols / max;
-   if (limit != 1 && (limit * max == cols))
---- gdb-10.2/gdb/ada-lang.c.orig
-+++ gdb-10.2/gdb/ada-lang.c
-@@ -997,7 +997,7 @@ ada_fold_name (gdb::string_view name)
-   int len = name.size ();
-   GROW_VECT (fold_buffer, fold_buffer_size, len + 1);
- 
--  if (name[0] == '\'')
-+  if (!name.empty () && name[0] == '\'')
-     {
-       strncpy (fold_buffer, name.data () + 1, len - 2);
-       fold_buffer[len - 2] = '\000';
-@@ -1006,8 +1006,9 @@ ada_fold_name (gdb::string_view name)
-     {
-       int i;
- 
--      for (i = 0; i <= len; i += 1)
-+      for (i = 0; i < len; i += 1)
-         fold_buffer[i] = tolower (name[i]);
-+      fold_buffer[i] = '\0';
-     }
- 
-   return fold_buffer;
-@@ -13596,7 +13597,7 @@ ada_lookup_name_info::ada_lookup_name_info (const lookup_name_info &lookup_name)
- {
-   gdb::string_view user_name = lookup_name.name ();
- 
--  if (user_name[0] == '<')
-+  if (!user_name.empty () && user_name[0] == '<')
-     {
-       if (user_name.back () == '>')
- 	m_encoded_name
---- gdb-10.2/gdb/Makefile.in.orig
-+++ gdb-10.2/gdb/Makefile.in
-@@ -1865,7 +1865,7 @@ 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_2 library)
-+	@$(MAKE) -C ../.. GDB_FLAGS=-DGDB_10_2 library
- 	$(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \
-                 -o $(shell /bin/cat mergeobj) $(LIBGDB_OBS) \
-                 $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) $(shell /bin/cat mergelibs)
---- gdb-10.2/gdb/c-typeprint.c.orig
-+++ gdb-10.2/gdb/c-typeprint.c
-@@ -1202,6 +1202,9 @@ c_type_print_base_struct_union (struct t
- 		= podata->end_bitpos
- 		  - TYPE_LENGTH (type->field (i).type ()) * TARGET_CHAR_BIT;
- 	    }
-+	  else if (strlen(TYPE_FIELD_NAME (type, i)) == 0)
-+	    /* crash: Print details for unnamed struct and union. */
-+	    newshow = show;
-
- 	  c_print_type_1 (type->field (i).type (),
- 			  TYPE_FIELD_NAME (type, i),
---- gdb-10.2/gdb/symfile.c.orig
-+++ gdb-10.2/gdb/symfile.c
-@@ -1610,7 +1610,7 @@ find_separate_debug_file_by_debuglink (struct objfile *objfile)
-   if (debugfile.empty ()) {
-        char *name_copy;
-        name_copy = check_specified_kernel_debug_file();
--       return std::string (name_copy);
-+       return name_copy ? std::string (name_copy) : std::string ();
-   }
- #endif
- 
---- gdb-10.2/gdb/printcmd.c.orig
-+++ gdb-10.2/gdb/printcmd.c
-@@ -576,6 +576,10 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
- 
- /* See valprint.h.  */
- 
-+#ifdef CRASH_MERGE
-+extern "C" char *gdb_lookup_module_symbol(unsigned long, unsigned long *);
-+#endif
-+
- int
- build_address_symbolic (struct gdbarch *gdbarch,
- 			CORE_ADDR addr,  /* IN */
-@@ -682,7 +686,19 @@ build_address_symbolic (struct gdbarch *gdbarch,
- 	}
-     }
-   if (symbol == NULL && msymbol.minsym == NULL)
-+#ifdef CRASH_MERGE
-+  {
-+    char *name_ptr = gdb_lookup_module_symbol(addr, (unsigned long *)offset);
-+    if (name_ptr) {
-+      *name = name_ptr;
-+      return 0;
-+    } else {
-+      return 1;
-+    }
-+  }
-+#else
-     return 1;
-+#endif
- 
-   /* If the nearest symbol is too far away, don't print anything symbolic.  */
- 
---- gdb-10.2/gdb/symtab.c.orig
-+++ gdb-10.2/gdb/symtab.c
-@@ -7128,8 +7128,8 @@ gdb_get_line_number(struct gnu_request *
- static void
- gdb_get_datatype(struct gnu_request *req)
- {
--        register struct type *type;
--        register struct type *typedef_type;
-+        struct type *type;
-+        struct type *typedef_type;
-         expression_up expr;
-         struct symbol *sym;
-         struct value *val;
-@@ -7235,7 +7235,7 @@ gdb_get_datatype(struct gnu_request *req
- static void
- dump_enum(struct type *type, struct gnu_request *req)
- {
--        register int i;
-+        int i;
-         int len;
-         long long lastval;
- 
-@@ -7271,7 +7271,7 @@ dump_enum(struct type *type, struct gnu_
- static void
- eval_enum(struct type *type, struct gnu_request *req)
- {
--        register int i;
-+        int i;
-         int len;
-         long long lastval;
- 
-@@ -7298,7 +7298,7 @@ eval_enum(struct type *type, struct gnu_
- static void
- get_member_data(struct gnu_request *req, struct type *type, long offset, int is_first)
- {
--        register short i;
-+        short i;
-         struct field *nextfield;
-         short nfields;
-         struct type *typedef_type, *target_type;
---- gdb-10.2/gdb/symtab.c.orig
-+++ gdb-10.2/gdb/symtab.c
-@@ -6913,7 +6913,7 @@
- #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 walk_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 *);
-@@ -7122,6 +7122,79 @@
- 
- 
- /*
-+ * Follow the type linkage for full member and value type resolution, with callback
-+ */
-+static void drillDownType(struct gnu_request *req, struct type *type)
-+{
-+        while (type)
-+        {
-+                /* check out for stub types and pull in the definition instead */
-+                if (TYPE_STUB(type) && TYPE_TAG_NAME(type)) {
-+                        struct symbol *sym;
-+                        sym = lookup_symbol(TYPE_TAG_NAME(type), 0, STRUCT_DOMAIN, 0).symbol;
-+                        if (sym)
-+                                type = sym->type;
-+                }
-+                switch (TYPE_CODE(type)) {
-+                        drill_ops_t op;
-+                        long l1, l2;
-+                        int typecode;
-+
-+                case TYPE_CODE_PTR:
-+                        req->tcb(EOP_POINTER, req, 0, 0, 0, 0);
-+                        break;
-+
-+                case TYPE_CODE_TYPEDEF:
-+                        req->is_typedef = 1;
-+                        req->typecode = TYPE_CODE(type);
-+                        if (!req->tcb(EOP_TYPEDEF, req, TYPE_NAME(type), 0, 0, 0))
-+                                return;
-+                        break;
-+
-+                case TYPE_CODE_FUNC:
-+                        req->tcb(EOP_FUNCTION, req, 0, 0, 0, 0);
-+                        break;
-+
-+                case TYPE_CODE_ARRAY:
-+                        l1 = TYPE_LENGTH (type);
-+                        l2 = TYPE_LENGTH (check_typedef(TYPE_TARGET_TYPE (type)));
-+                        req->tcb(EOP_ARRAY, req, &l1, &l2, 0, 0);
-+                        break;
-+
-+                case TYPE_CODE_VOID:
-+                case TYPE_CODE_INT:
-+                case TYPE_CODE_BOOL:
-+                        l1 = TYPE_LENGTH(type);
-+                        req->tcb(EOP_INT, req, &l1, 0, 0, 0);
-+                        break;
-+
-+                case TYPE_CODE_UNION:
-+                        op = EOP_UNION;
-+                        goto label;
-+
-+                case TYPE_CODE_ENUM:
-+                        op = EOP_ENUM;
-+                        goto label;
-+
-+                case TYPE_CODE_STRUCT:
-+                        op = EOP_STRUCT;
-+                        goto label;
-+
-+                default:
-+                        typecode = TYPE_CODE(type);
-+                        req->tcb(EOP_OOPS, req, &typecode, "Unknown typecode", 0, 0);
-+                        return; /* not reached */
-+
-+                label:
-+                        l1 = TYPE_LENGTH(type);
-+                        req->tcb(op, req, &l1, type, TYPE_TAG_NAME(type), 0);
-+                }
-+                type = TYPE_TARGET_TYPE(type);
-+        }
-+        req->tcb(EOP_DONE, req, 0, 0, 0, 0);
-+}
-+
-+/*
-  *  General purpose routine for determining datatypes.
-  */
- 
-@@ -7149,10 +7222,8 @@
-                 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);
--                }
-+                if (TYPE_CODE(sym->type) == TYPE_CODE_ENUM)
-+                        walk_enum(sym->type, req);
- 
-                 return;
-         }
-@@ -7172,17 +7243,25 @@
-                 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) {
-+                if (req->tcb) {
-+                        long value = SYMBOL_VALUE(expr->elts[2].symbol);
-+                        /* callback with symbol value */
-                         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);
-+                        req->tcb(EOP_VALUE, req, &value, 0, 0, 0);
-+                        drillDownType(req, type);
-+                } else {
-+                        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.get());
-+                                        eval_enum(value_type(val), req);
-+                                }
-                         }
-                 }
-                 break;
-@@ -7192,26 +7271,21 @@
-                         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->tcb) {
-+                        drillDownType(req, type);
-+                } else {
-+                        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)
-+                                walk_enum(type, req);
-                 }
- 
-                 if (req->member)
-@@ -7233,36 +7307,38 @@
-  *  identifier, each on its own line.
-  */
- static void
--dump_enum(struct type *type, struct gnu_request *req)
-+walk_enum(struct type *type, struct gnu_request *req)
- {
-         int i;
--        int len;
-+        int len, print = (req->flags & GNU_PRINT_ENUMERATORS);
-         long long 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");
-+        if (print) {
-+                if (req->is_typedef)
-+                        fprintf_filtered(gdb_stdout, "typedef ");
-+                if (TYPE_TAG_NAME(type))
-+                        fprintf_filtered(gdb_stdout, "enum %s {\n", TYPE_TAG_NAME (type));
-+                else
-+                        fprintf_filtered(gdb_stdout, "enum {\n");
-+        }
- 
-+        len = TYPE_NFIELDS (type);
-         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
-+                if (print)
-+                        fprintf_filtered(gdb_stdout, "  %s", TYPE_FIELD_NAME (type, i));
-+                lastval = TYPE_FIELD_ENUMVAL (type, i);
-+                if (print) {
-                         fprintf_filtered(gdb_stdout, " = %s", plongest(lastval));
--                fprintf_filtered(gdb_stdout, "\n");
--                lastval++;
-+                        fprintf_filtered(gdb_stdout, "\n");
-+                } else if (req->tcb)
-+                        req->tcb(EOP_ENUMVAL, req, TYPE_FIELD_NAME (type, i), &lastval, 0, 0);
-+        }
-+        if (print) {
-+                if (TYPE_TAG_NAME(type))
-+                        fprintf_filtered(gdb_stdout, "};\n");
-+                else
-+                        fprintf_filtered(gdb_stdout, "} %s;\n", req->name);
-         }
--        if (TYPE_TAG_NAME(type))
--                fprintf_filtered(gdb_stdout, "};\n");
--        else
--                fprintf_filtered(gdb_stdout, "} %s;\n", req->name);
- }
- 
- /*
-@@ -7320,26 +7396,43 @@
-         }
- 
-         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 */
-+                if (*nextfield->name == 0) { /* Anonymous struct/union */
-                         get_member_data(req, nextfield->type(),
-                             offset + nextfield->loc.bitpos, 0);
-                         if (req->member_offset != -1)
-                                 return;
-+                } else {
-+                        /* callback may be just looking for a specific member name */
-+                        if (req->tcb) {
-+                                if (req->tcb(EOP_MEMBER_NAME, req, nextfield->name, 0, 0, 0)) {
-+                                        long bitpos = FIELD_BITPOS(*nextfield);
-+                                        long bitsize = FIELD_BITSIZE(*nextfield);
-+                                        long len = TYPE_LENGTH(nextfield->type());
-+                                        long byteOffset;
-+                                        offset += nextfield->loc.bitpos;
-+                                        byteOffset = offset/8;
-+                                        console("EOP_MEMBER_SIZES\n");
-+                                        req->tcb(EOP_MEMBER_SIZES, req, &byteOffset, &len, &bitpos, &bitsize);
-+                                        /* callback with full type info */
-+                                        drillDownType(req, nextfield->type());
-+                                }
-+                        } else 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;
-+                        }
-                 }
-                 nextfield++;
-         }
---- gdb-10.2/gdb/gdbtypes.c.orig
-+++ gdb-10.2/gdb/gdbtypes.c
-@@ -5492,27 +5492,25 @@ copy_type_recursive (struct objfile *objfile,
- }
- 
- /* Make a copy of the given TYPE, except that the pointer & reference
--   types are not preserved.
--   
--   This function assumes that the given type has an associated objfile.
--   This objfile is used to allocate the new type.  */
-+   types are not preserved. */
- 
- struct type *
- copy_type (const struct type *type)
- {
--  struct type *new_type;
--
--  gdb_assert (TYPE_OBJFILE_OWNED (type));
-+  struct type *new_type = alloc_type_copy (type);
- 
--  new_type = alloc_type_copy (type);
-   TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type);
-   TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
-   memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type),
- 	  sizeof (struct main_type));
-   if (type->main_type->dyn_prop_list != NULL)
--    new_type->main_type->dyn_prop_list
--      = copy_dynamic_prop_list (&TYPE_OBJFILE (type) -> objfile_obstack,
--				type->main_type->dyn_prop_list);
-+    {
-+      struct obstack *storage = (TYPE_OBJFILE_OWNED (type)
-+                                ? &TYPE_OBJFILE (type)->objfile_obstack
-+                                : gdbarch_obstack (TYPE_OWNER (type).gdbarch));
-+      new_type->main_type->dyn_prop_list
-+       = copy_dynamic_prop_list (storage, type->main_type->dyn_prop_list);
-+    }
- 
-   return new_type;
- }
---- gdb-10.2/gdb/dwarf2/read.c.orig
-+++ gdb-10.2/gdb/dwarf2/read.c
-@@ -4925,7 +4925,10 @@ dw2_find_pc_sect_compunit_symtab (struct objfile *objfile,
-   result = recursively_find_pc_sect_compunit_symtab
-     (dw2_instantiate_symtab (data, per_objfile, false), pc);
- 
--  gdb_assert (result != NULL);
-+  if (warn_if_readin && result == nullptr)
-+    warning (_("(Error: pc %s in address map, but not in symtab.)"),
-+            paddress (objfile->arch (), pc));
-+
-   return result;
- }
- 
---- gdb-10.2/gdb/symtab.c.orig
-+++ gdb-10.2/gdb/symtab.c
-@@ -7476,7 +7476,7 @@ gdb_add_symbol_file(struct gnu_request *
-         int i;
-         int allsect = 0;
-         char *secname;
--        char buf[80];
-+        char buf[96];
- 
-         gdb_current_load_module = lm = (struct load_module *)req->addr;
- 
-@@ -7515,8 +7515,11 @@ gdb_add_symbol_file(struct gnu_request *
-                             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);
-+                                    if (lm->mod_section_data[i].addr)
-+                                        sprintf(buf, " -s %s 0x%lx", secname, lm->mod_section_data[i].addr);
-+                                    else
-+                                        sprintf(buf, " -s %s 0x%lx", secname,
-+                                            lm->mod_section_data[i].offset + lm->mod_base);
-                                     strcat(req->buf, buf);
-                             }
-                     }
---- gdb-10.2/gdb/ada-lang.c.orig
-+++ gdb-10.2/gdb/ada-lang.c
-@@ -1158,7 +1158,7 @@ ada_decode (const char *encoded)
-         i -= 1;
-       if (i > 1 && encoded[i] == '_' && encoded[i - 1] == '_')
-         len0 = i - 1;
--      else if (encoded[i] == '$')
-+      else if (i >= 0 && encoded[i] == '$')
-         len0 = i;
-     }
- 
---- gdb-10.2/gdb/coffread.c.orig
-+++ gdb-10.2/gdb/coffread.c
-@@ -159,6 +159,7 @@ static long linetab_offset;
- static unsigned long linetab_size;
- 
- static char *stringtab = NULL;
-+static long stringtab_length = 0;
- 
- extern void stabsread_clear_cache (void);
- 
-@@ -1297,6 +1298,7 @@ init_stringtab (bfd *abfd, long offset, gdb::unique_xmalloc_ptr<char> *storage)
-   /* This is in target format (probably not very useful, and not
-      currently used), not host format.  */
-   memcpy (stringtab, lengthbuf, sizeof lengthbuf);
-+  stringtab_length = length;
-   if (length == sizeof length)	/* Empty table -- just the count.  */
-     return 0;
- 
-@@ -1316,8 +1318,9 @@ getsymname (struct internal_syment *symbol_entry)
- 
-   if (symbol_entry->_n._n_n._n_zeroes == 0)
-     {
--      /* FIXME: Probably should be detecting corrupt symbol files by
--         seeing whether offset points to within the stringtab.  */
-+      if (symbol_entry->_n._n_n._n_offset > stringtab_length)
-+        error (_("COFF Error: string table offset (%ld) outside string table (length %ld)"),
-+               symbol_entry->_n._n_n._n_offset, stringtab_length);
-       result = stringtab + symbol_entry->_n._n_n._n_offset;
-     }
-   else
---- gdb-10.2/gdb/objfiles.h.orig
-+++ gdb-10.2/gdb/objfiles.h
-@@ -712,6 +712,8 @@ struct objfile
-      next time.  If an objfile does not have the symbols, it will
-      never have them.  */
-   bool skip_jit_symbol_lookup = false;
-+
-+  bool all_symtabs_expanded = false;
- };
- 
- /* A deleter for objfile.  */
---- gdb-10.2/gdb/symfile.c.orig
-+++ gdb-10.2/gdb/symfile.c
-@@ -1133,8 +1133,10 @@ symbol_file_add_with_addrs (bfd *abfd, const char *name,
- 	printf_filtered (_("Expanding full symbols from %ps...\n"),
- 			 styled_string (file_name_style.style (), name));
- 
--      if (objfile->sf)
-+      if (objfile->sf) {
- 	objfile->sf->qf->expand_all_symtabs (objfile);
-+	objfile->all_symtabs_expanded = true;
-+      }
-     }
- 
-   /* Note that we only print a message if we have no symbols and have
---- gdb-10.2/gdb/symtab.c.orig
-+++ gdb-10.2/gdb/symtab.c
-@@ -7097,8 +7097,9 @@ gdb_get_line_number(struct gnu_request *req)
-                  */
-                 if (req->lm) {
-                         objfile = req->lm->loaded_objfile;
--                        if (!objfile_has_full_symbols(objfile) && objfile->sf) {
-+                        if (!objfile->all_symtabs_expanded && objfile->sf) {
-                                 objfile->sf->qf->expand_all_symtabs(objfile);
-+                                objfile->all_symtabs_expanded = true;
-                                 sal = find_pc_line(pc, 0);
-                         }
-                 }
-@@ -7761,8 +7765,10 @@ iterate_datatypes (struct gnu_request *req)
- {
-   for (objfile *objfile : current_program_space->objfiles ())
-     {
--      if (objfile->sf)
-+      if (objfile->sf) {
-         objfile->sf->qf->expand_all_symtabs(objfile);
-+        objfile->all_symtabs_expanded = true;
-+      }
- 
-       for (compunit_symtab *cust : objfile->compunits ())
-         {
---- gdb-10.2/gdb/minsyms.c.orig
-+++ gdb-10.2/gdb/minsyms.c
-@@ -535,7 +535,9 @@ lookup_minimal_symbol_linkage (const char *name, struct objfile *objf)
- 	{
- 	  if (strcmp (msymbol->linkage_name (), name) == 0
- 	      && (MSYMBOL_TYPE (msymbol) == mst_data
--		  || MSYMBOL_TYPE (msymbol) == mst_bss))
-+		  || MSYMBOL_TYPE (msymbol) == mst_bss
-+		  || MSYMBOL_TYPE (msymbol) == mst_file_bss
-+		  || MSYMBOL_TYPE (msymbol) == mst_file_data))
- 	    return {msymbol, objfile};
- 	}
-     }
---- gdb-10.2/gdb/symtab.h.orig
-+++ gdb-10.2/gdb/symtab.h
-@@ -1110,7 +1110,7 @@ struct symbol : public general_symbol_info, public allocate_on_obstack
-       is_objfile_owned (1),
-       is_argument (0),
-       is_inlined (0),
--      maybe_copied (0),
-+      maybe_copied (1), /* The objfile potentially supports copy relocations. */
-       subclass (SYMBOL_NONE)
-     {
-       /* We can't use an initializer list for members of a base class, and
---- gdb-10.2/gdb/ui-file.h.orig
-+++ gdb-10.2/gdb/ui-file.h
-@@ -195,6 +195,7 @@ public:
- 
-   bool can_emit_style_escape () override;
- 
-+  FILE *get_stream(void);
-   /* Sets the internal stream to FILE, and saves the FILE's file
-      descriptor in M_FD.  */
-   void set_stream (FILE *file);
---- gdb-10.2/gdb/ui-file.c.orig
-+++ gdb-10.2/gdb/ui-file.c
-@@ -161,6 +161,12 @@ stdio_file::~stdio_file ()
-     fclose (m_file);
- }
- 
-+FILE*
-+stdio_file::get_stream(void)
-+{
-+  return m_file;
-+}
-+
- void
- stdio_file::set_stream (FILE *file)
- {
---- gdb-10.2/gdb/symtab.c.orig
-+++ gdb-10.2/gdb/symtab.c
-@@ -6964,8 +6964,12 @@ void
- gdb_command_funnel_1(struct gnu_request *req)
- {
-         struct symbol *sym;
-+        FILE *original_stdout_stream = nullptr;
-+        FILE *original_stderr_stream = nullptr;
- 
-         if (req->command != GNU_VERSION && req->command != GNU_USER_PRINT_OPTION) {
-+                original_stdout_stream = (dynamic_cast< stdio_file * >gdb_stdout)->get_stream();
-+                original_stderr_stream = (dynamic_cast< stdio_file * >gdb_stderr)->get_stream();
-                 (dynamic_cast<stdio_file *>gdb_stdout)->set_stream(req->fp);
-                 (dynamic_cast<stdio_file *>gdb_stderr)->set_stream(req->fp);
-         }
-@@ -7068,6 +7072,12 @@ gdb_command_funnel_1(struct gnu_request *req)
-                 req->flags |= GNU_COMMAND_FAILED;
-                 break;
-         }
-+
-+        /* Restore the streams gdb output was using */
-+        if (original_stdout_stream)
-+            (dynamic_cast<stdio_file *>gdb_stdout)->set_stream(original_stdout_stream);
-+        if (original_stderr_stream)
-+            (dynamic_cast<stdio_file *>gdb_stderr)->set_stream(original_stderr_stream);
- }
- 
- /*
---- gdb-10.2/gdb/stack.c.orig
-+++ gdb-10.2/gdb/stack.c
-@@ -1990,6 +1990,11 @@
- /* Print briefly all stack frames or just the innermost COUNT_EXP
-    frames.  */
- 
-+#ifdef CRASH_MERGE
-+extern "C" int is_kvaddr(ulong);
-+extern "C" int gdb_CRASHDEBUG(ulong);
-+#endif
-+
- static void
- backtrace_command_1 (const frame_print_options &fp_opts,
- 		     const backtrace_cmd_options &bt_opts,
-@@ -2082,6 +2086,17 @@
- 	     hand, perhaps the code does or could be fixed to make sure
- 	     the frame->prev field gets set to NULL in that case).  */
- 
-+#ifdef CRASH_MERGE
-+	  CORE_ADDR pc = 0;
-+	  get_frame_pc_if_available (fi, &pc);
-+	  if (!is_kvaddr(pc)) {
-+	    if (gdb_CRASHDEBUG(1)) {
-+	      printf_filtered (_("Backtrace stopped: due to non-kernel addr: 0x%lx\n"),pc);
-+	    }
-+	    fi = NULL;
-+	    break;
-+	  }
-+#endif
- 	  print_frame_info (fp_opts, fi, 1, LOCATION, 1, 0);
- 	  if ((flags & PRINT_LOCALS) != 0)
- 	    {
---- gdb-10.2/gdb/stack.c.orig
-+++ gdb-10.2/gdb/stack.c
-@@ -2127,7 +2127,7 @@
- 	  enum unwind_stop_reason reason;
- 
- 	  reason = get_frame_unwind_stop_reason (trailing);
--	  if (reason >= UNWIND_FIRST_ERROR)
-+	  if (reason >= UNWIND_FIRST_ERROR && gdb_CRASHDEBUG(1))
- 	    printf_filtered (_("Backtrace stopped: %s\n"),
- 			     frame_stop_reason_string (trailing));
- 	}
---- gdb-10.2/gdb/frame.c.orig
-+++ gdb-10.2/gdb/frame.c
-@@ -944,6 +944,10 @@ frame_find_by_id (struct frame_id id)
-   return NULL;
- }
-
-+#if defined(CRASH_MERGE) && defined(ARM64)
-+extern "C" void crash_decode_ptrauth_pc(ulong* pc);
-+#endif
-+
- static CORE_ADDR
- frame_unwind_pc (struct frame_info *this_frame)
- {
-@@ -974,6 +978,9 @@ frame_unwind_pc (struct frame_info *this_frame)
-       try
-	{
-	  pc = gdbarch_unwind_pc (prev_gdbarch, this_frame);
-+#if defined(CRASH_MERGE) && defined(ARM64)
-+	  crash_decode_ptrauth_pc(&pc);
-+#endif
-	  pc_p = true;
-	}
-       catch (const gdb_exception_error &ex)
---- gdb-10.2/readline/readline/signals.c.orig
-+++ gdb-10.2/readline/readline/signals.c
-@@ -48,23 +48,11 @@
- 
- #if defined (HANDLE_SIGNALS)
- 
--#if !defined (RETSIGTYPE)
--#  if defined (VOID_SIGHANDLER)
--#    define RETSIGTYPE void
--#  else
--#    define RETSIGTYPE int
--#  endif /* !VOID_SIGHANDLER */
--#endif /* !RETSIGTYPE */
--
--#if defined (VOID_SIGHANDLER)
--#  define SIGHANDLER_RETURN return
--#else
--#  define SIGHANDLER_RETURN return (0)
--#endif
-+#define SIGHANDLER_RETURN return
- 
- /* This typedef is equivalent to the one for Function; it allows us
-    to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
--typedef RETSIGTYPE SigHandler ();
-+typedef void SigHandler (int);
- 
- #if defined (HAVE_POSIX_SIGNALS)
- typedef struct sigaction sighandler_cxt;
-@@ -78,12 +66,12 @@ typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt
- #  define SA_RESTART 0
- #endif
- 
--static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
--static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
--static void rl_maybe_restore_sighandler PARAMS((int, sighandler_cxt *));
-+static SigHandler *rl_set_sighandler (int, SigHandler *, sighandler_cxt *);
-+static void rl_maybe_set_sighandler (int, SigHandler *, sighandler_cxt *);
-+static void rl_maybe_restore_sighandler (int, sighandler_cxt *);
- 
--static RETSIGTYPE rl_signal_handler PARAMS((int));
--static RETSIGTYPE _rl_handle_signal PARAMS((int));
-+static void rl_signal_handler (int);
-+static void _rl_handle_signal (int);
-      
- /* Exported variables for use by applications. */
- 
-@@ -137,7 +125,7 @@ void *_rl_sigcleanarg;
- /* Readline signal handler functions. */
- 
- /* Called from RL_CHECK_SIGNALS() macro */
--RETSIGTYPE
-+void
- _rl_signal_handler (int sig)
- {
-   _rl_caught_signal = 0;	/* XXX */
-@@ -160,7 +148,7 @@ _rl_signal_handler (int sig)
-   SIGHANDLER_RETURN;
- }
- 
--static RETSIGTYPE
-+static void
- rl_signal_handler (int sig)
- {
-   if (_rl_interrupt_immediately)
-@@ -174,7 +162,7 @@ rl_signal_handler (int sig)
-   SIGHANDLER_RETURN;
- }
- 
--static RETSIGTYPE
-+static void
- _rl_handle_signal (int sig)
- {
- #if defined (HAVE_POSIX_SIGNALS)
-@@ -291,7 +279,7 @@ _rl_handle_signal (int sig)
- }
- 
- #if defined (SIGWINCH)
--static RETSIGTYPE
-+static void
- rl_sigwinch_handler (int sig)
- {
-   SigHandler *oh;
diff --git a/gdb-16.2.patch b/gdb-16.2.patch
new file mode 100644
index 0000000..05aa77a
--- /dev/null
+++ b/gdb-16.2.patch
@@ -0,0 +1,2254 @@
+
+# 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 unintended 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.
+
+tar xvzmf gdb-16.2.tar.gz \
+	gdb-16.2/gdb/symtab.c \
+	gdb-16.2/gdb/printcmd.c \
+	gdb-16.2/gdb/symfile.c \
+	gdb-16.2/gdb/Makefile.in \
+	gdb-16.2/gdb/dwarf2/read.c \
+	gdb-16.2/gdb/ada-lang.c \
+	gdb-16.2/gdb/stack.c \
+	gdb-16.2/gdb/ui-file.h
+
+exit 0
+
+--- gdb-16.2/Makefile.in.orig
++++ gdb-16.2/Makefile.in
+@@ -369,6 +369,9 @@ CC_FOR_BUILD = @CC_FOR_BUILD@
+ CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@
+ CPP_FOR_BUILD = @CPP_FOR_BUILD@
+ CPPFLAGS_FOR_BUILD = @CPPFLAGS_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@
+@@ -441,6 +444,9 @@ GNATBIND = @GNATBIND@
+ GNATMAKE = @GNATMAKE@
+ 
+ CFLAGS = @CFLAGS@
++ifeq (${CRASH_TARGET}, PPC64)
++CFLAGS += -m64 -fPIC
++endif
+ LDFLAGS = @LDFLAGS@
+ LIBCFLAGS = $(CFLAGS)
+ CXXFLAGS = @CXXFLAGS@
+--- gdb-16.2/gdb/Makefile.in.orig
++++ gdb-16.2/gdb/Makefile.in
+@@ -603,7 +603,7 @@
+ # 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 -D${CRASH_TARGET} @DEFS@
+ GDB_INCLUDED_HEADER = -include $(srcdir)/defs.h
+ GDB_CFLAGS = \
+ 	-I. \
+@@ -1220,6 +1220,7 @@ COMMON_SFILES = \
+ 	symmisc.c \
+ 	symtab.c \
+ 	target.c \
++	../../crash_target.c \
+ 	target-connection.c \
+ 	target-dcache.c \
+ 	target-descriptions.c \
+@@ -1906,7 +1907,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
+ 	$(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.
+@@ -1947,8 +1948,8 @@
+ # Flags needed to compile Python code
+ PYTHON_CFLAGS = @PYTHON_CFLAGS@
+ 
+-all: gdb$(EXEEXT) $(CONFIG_ALL) gdb-gdb.py gdb-gdb.gdb gcore gstack
+-	@$(MAKE) $(FLAGS_TO_PASS) DO=all "DODIRS=$(SUBDIRS)" subdir_do
++all: gdb$(EXEEXT) gdb-gdb.py gdb-gdb.gdb gcore gstack
++	@$(MAKE) -s $(FLAGS_TO_PASS) DO=all "DODIRS=$(SUBDIRS)" subdir_do
+ 
+ # Rule for compiling .c files in the top-level gdb directory.
+ # The order-only dependencies ensure that we create the build subdirectories.
+@@ -2230,9 +2231,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_16_2 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
+@@ -2699,9 +2701,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 $(@F)).Tpo
+-override POSTCOMPILE = @mv $(@D)/$(DEPDIR)/$(basename $(@F)).Tpo \
+-	$(@D)/$(DEPDIR)/$(basename $(@F)).Po
++        -MF $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Tpo
++override POSTCOMPILE = @mv $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Tpo \
++        $(subst ../..,.,$(@D))/$(DEPDIR)/$(basename $(@F)).Po
+ else
+ override COMPILE.pre = source='$<' object='$@' libtool=no \
+ 	DEPDIR=$(DEPDIR) $(DEPMODE) $(depcomp) \
+--- gdb-16.2/gdb/cli/cli-cmds.c.orig
++++ gdb-16.2/gdb/cli/cli-cmds.c
+@@ -427,6 +427,11 @@ complete_command (const char *arg, int from_tty)
+     }
+ }
+ 
++#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)
+ {
+@@ -659,8 +664,32 @@ find_and_open_script (const char *script_file, int search_path)
+       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;
+ }
+@@ -724,7 +753,11 @@ source_script_with_search (const char *file, int from_tty, int search_path)
+ 	 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
+ 	{
+@@ -756,7 +789,14 @@ source_script_with_search (const char *file, int from_tty, int search_path)
+ 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
+--- gdb-16.2/gdb/defs.h.orig
++++ gdb-16.2/gdb/defs.h
+@@ -407,4 +407,7 @@ DEF_ENUM_FLAGS_TYPE (enum user_selected_what_flag, user_selected_what);
+ 
+ #include "utils.h"
+ 
++#ifdef CRASH_MERGE
++extern "C" int gdb_main_entry(int, char **);
++#endif
+ #endif /* GDB_DEFS_H */
+--- gdb-16.2/gdb/dwarf2/read-gdb-index.c.orig
++++ gdb-16.2/gdb/dwarf2/read-gdb-index.c
+@@ -369,7 +369,11 @@ read_gdb_index_from_buffer (const char *filename,
+      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."),
+@@ -388,7 +392,11 @@ read_gdb_index_from_buffer (const char *filename,
+      "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-16.2/gdb/main.c.orig
++++ gdb-16.2/gdb/main.c
+@@ -442,6 +442,14 @@ 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);
++extern "C" int console(const char *, ...);
++void crash_target_init (void);
++#endif
++
+ /* Call command_loop.  */
+ 
+ /* Prevent inlining this function for the benefit of GDB's selftests
+@@ -1031,7 +1039,11 @@ captured_main_1 (struct captured_main_args *context)
+       }
+   }
+ 
++#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;
+@@ -1129,7 +1141,7 @@ captured_main_1 (struct captured_main_args *context)
+   if (print_version)
+     {
+       print_gdb_version (gdb_stdout, false);
+-      gdb_printf ("\n");
++      gdb_printf ("\n\n");
+       exit (0);
+     }
+ 
+@@ -1150,6 +1162,10 @@ captured_main_1 (struct captured_main_args *context)
+      look at things by now.  Initialize the default interpreter.  */
+   set_top_level_interpreter (interpreter_p.c_str (), false);
+ 
++#ifdef CRASH_MERGE
++  update_gdb_hooks();
++#endif
++
+   /* The interpreter should have installed the real uiout by now.  */
+   gdb_assert (current_uiout != temp_uiout.get ());
+   temp_uiout = nullptr;
+@@ -1177,7 +1193,11 @@ captured_main_1 (struct captured_main_args *context)
+   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
+@@ -1186,7 +1206,11 @@ captured_main_1 (struct captured_main_args *context)
+      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.  */
+   execute_cmdargs (&cmdarg_vec, CMDARG_INIT_FILE, CMDARG_INIT_COMMAND, &ret);
+@@ -1217,7 +1241,11 @@ captured_main_1 (struct captured_main_args *context)
+ 				  !batch_flag);
+       if (ret != 0)
+ 	ret = catch_command_errors (symbol_file_add_main_adapter,
++#ifdef CRASH_MERGE
++                                    symarg, 0);
++#else
+ 				    symarg, !batch_flag);
++#endif
+     }
+   else
+     {
+@@ -1291,7 +1319,11 @@ captured_main_1 (struct captured_main_args *context)
+ 	    {
+ 	      auto_load_local_gdbinit_loaded = 1;
+ 
++#ifdef CRASH_MERGE
++              ret = catch_command_errors (source_script, local_gdbinit.c_str (), -1);
++#else
+ 	      ret = catch_command_errors (source_script, local_gdbinit.c_str (), 0);
++#endif
+ 	    }
+ 	}
+     }
+@@ -1332,6 +1364,16 @@ captured_main (void *data)
+ 
+   captured_main_1 (context);
+ 
++#ifdef CRASH_MERGE
++  /* Relocate the vmlinux. */
++  objfile_rebase (current_program_space->symfile_object_file, 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
+@@ -1350,6 +1392,9 @@ captured_main (void *data)
+ 	{
+ 	  exception_print (gdb_stderr, ex);
+ 	}
++#ifdef CRASH_MERGE
++        console("<CAPTURED_MAIN WHILE LOOP>\n");
++#endif
+     }
+   /* No exit -- exit is through quit_command.  */
+ }
+@@ -1371,6 +1416,24 @@ gdb_main (struct captured_main_args *args)
+   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
++ */
++extern bool is_main_thread ();
++int
++gdb_main_entry (int argc, char **argv)
++{
++  struct captured_main_args args;
++  gdb_assert (is_main_thread ());
++  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
+--- gdb-16.2/gdb/objfiles.h.orig
++++ gdb-16.2/gdb/objfiles.h
+@@ -951,11 +951,11 @@ extern bool objfile_has_symbols (objfile *objfile);
+ 
+ /* Return true if any objfile of PSPACE has partial symbols.  */
+ 
+-extern bool have_partial_symbols (program_space *pspace);
++extern "C" bool have_partial_symbols (program_space *pspace);
+ 
+ /* Return true if any objfile of PSPACE has full symbols.  */
+ 
+-extern bool have_full_symbols (program_space *pspace);
++extern "C" bool have_full_symbols (program_space *pspace);
+ 
+ extern void objfile_set_sym_fns (struct objfile *objfile,
+ 				 const struct sym_fns *sf);
+--- gdb-16.2/gdb/printcmd.c.orig
++++ gdb-16.2/gdb/printcmd.c
+@@ -552,6 +552,9 @@ set_next_address (struct gdbarch *gdbarch, CORE_ADDR addr)
+    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,
+@@ -563,6 +566,12 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
+   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;
+@@ -1242,6 +1251,43 @@ print_command_parse_format (const char **expp, const char *cmdname,
+   *expp = exp;
+ }
+ 
++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 = expr->evaluate ();
++    }
++  else
++    val = access_value_history (0);
++
++    gdb_printf("%d %d %ld %ld %ld %ld\n",
++      check_typedef(val->type ())->code(),
++      check_typedef(val->type ())->is_unsigned(),
++      check_typedef(val->type ())->length(),
++      val->offset(), val->bitpos(), val->bitsize());
++}
++
++static void
++printm_command (const char *exp, int from_tty)
++{
++  print_command_2 (exp, 1);
++}
++
+ /* See valprint.h.  */
+ 
+ void
+@@ -3357,6 +3403,12 @@ but no count or size letter (see \"x\" command)."),
+     = add_com ("print", class_vars, print_command, print_help.c_str ());
+   set_cmd_completer_handle_brkchars (print_cmd, print_command_completer);
+   add_com_alias ("p", print_cmd, 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_cmd, class_vars, 1);
+ 
+   add_setshow_uinteger_cmd ("max-symbolic-offset", no_class,
+--- gdb-16.2/gdb/psymtab.c.orig
++++ gdb-16.2/gdb/psymtab.c
+@@ -80,6 +80,9 @@ psymbol_functions::partial_symbols (struct objfile *objfile)
+   return m_partial_symtabs->range ();
+ }
+ 
++#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 starting at psymtab PST.
+    We may find a different psymtab than PST.  See FIND_PC_SECT_PSYMTAB.  */
+ 
+@@ -170,7 +173,12 @@ psymbol_functions::find_pc_sect_psymtab (struct objfile *objfile,
+ 
+ 	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;
+       }
+ 
+--- gdb-16.2/gdb/symfile.c.orig
++++ gdb-16.2/gdb/symfile.c
+@@ -633,7 +633,26 @@ default_symfile_offsets (struct objfile *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)
+@@ -1069,6 +1088,12 @@
+ 
+   objfile *objfile
+     = objfile::make (abfd, current_program_space, 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
+@@ -1352,6 +1377,10 @@ show_debug_file_directory (struct ui_file *file, int from_tty,
+ #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
+@@ -1390,6 +1419,15 @@ find_separate_debug_file (const char *dir,
+   if (separate_debug_file_exists (debugfile, crc32, objfile, warnings))
+     return debugfile;
+ 
++#ifdef CRASH_MERGE
++{
++  if (check_specified_module_tree(objfile_name (objfile), debugfile.c_str()) &&
++      separate_debug_file_exists(debugfile, crc32, objfile, warnings)) {
++        return debugfile;
++  }
++}
++#endif
++
+   /* Then try in the global debugfile directories.
+ 
+      Keep backward compatibility so that DEBUG_FILE_DIRECTORY being "" will
+@@ -1545,6 +1583,14 @@ find_separate_debug_file_by_debuglink
+ 	}
+     }
+ 
++#ifdef CRASH_MERGE
++  if (debugfile.empty ()) {
++       char *name_copy;
++       name_copy = check_specified_kernel_debug_file();
++       return std::string (name_copy);
++  }
++#endif
++
+   return debugfile;
+ }
+ 
+@@ -2318,8 +2364,10 @@ add_symbol_file_command (const char *args, int from_tty)
+   else if (section_addrs.empty ())
+     gdb_printf ("\n");
+ 
++#ifndef CRASH_MERGE
+   if (from_tty && (!query ("%s", "")))
+     error (_("Not confirmed."));
++#endif
+ 
+   objf = symbol_file_add (filename.get (), add_flags, &section_addrs,
+ 			  flags);
+@@ -3638,6 +3638,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.get();
++  if ((abfd->flags & EXEC_P) != 0)
++    return NULL;
++#endif
+   gdb_assert (objfile->sf->sym_relocate);
+ 
+   return (*objfile->sf->sym_relocate) (objfile, sectp, buf);
+--- gdb-16.2/gdb/symtab.c.orig
++++ gdb-16.2/gdb/symtab.c
+@@ -2012,6 +2012,10 @@ search_name_hash (enum language language, const char *search_name)
+    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_search_flags domain,
+@@ -2020,22 +2024,37 @@ lookup_symbol_in_language (const char *name, const struct block *block,
+ {
+   SYMBOL_LOOKUP_SCOPED_DEBUG_ENTER_EXIT;
+ 
++  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 & SEARCH_TYPE_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_search_flags 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);
+@@ -7320,3 +7339,805 @@ the use of prologue scanners."),
+ 					       "symtab");
+   gdb::observers::free_objfile.attach (symtab_free_objfile_observer, "symtab");
+ }
++
++#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 *);
++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 *);
++extern void execute_command (const char *, int);
++
++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 && req->command != GNU_USER_PRINT_OPTION) {
++                (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:
++                {
++                        CORE_ADDR start, end;
++                        if (!find_pc_partial_function(req->pc, NULL, &start, &end))
++                                req->flags |= GNU_COMMAND_FAILED;
++                        else {
++                                req->addr = (ulong)start;
++                                req->addr2 = (ulong)end;
++                        }
++                }
++                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 objfile *objfile;
++        CORE_ADDR pc;
++
++#define LASTCHAR(s)      (s[strlen(s)-1])
++
++        /*
++         * Prime the addrmap pump.
++         */
++        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->expand_all_symtabs();
++                                sal = find_pc_line(pc, 0);
++                        }
++                }
++                if (!sal.symtab) {
++                        req->buf[0] = '\0';
++                        return;
++                }
++        }
++
++        if (sal.symtab->filename && (sal.symtab)->compunit ()->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)->compunit ()->dirname (),
++                                LASTCHAR((sal.symtab)->compunit ()->dirname ()) == '/' ? "" : "/",
++                                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;
++        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, SEARCH_STRUCT_DOMAIN, 0).symbol;
++        if (sym) {
++                req->typecode = TYPE_CODE(sym->type());
++                req->length = sym->type()->length();
++                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->first_opcode())
++        {
++        case OP_VAR_VALUE:
++                if (gdb_CRASHDEBUG(2))
++                        console("expr->first_opcode(): OP_VAR_VALUE\n");
++                type = expr->evaluate_type()->type();
++                if (req->flags & GNU_VAR_LENGTH_TYPECODE) {
++                        req->typecode = TYPE_CODE(type);
++                        req->length = type->length();
++                }
++                if (TYPE_CODE(type) == TYPE_CODE_ENUM) {
++                        req->typecode = TYPE_CODE(type);
++                        req->value = value_as_long(expr->evaluate());
++                        req->tagname = (char *)TYPE_TAG_NAME(type);
++                        if (!req->tagname) {
++                                val = expr->evaluate_type();
++                                eval_enum(val->type(), req);
++                        }
++                }
++                break;
++
++          case OP_TYPE:
++                if (gdb_CRASHDEBUG(2))
++                        console("expr->first_opcode(): OP_TYPE\n");
++                    type = expr->evaluate_type()->type();
++
++                req->typecode = TYPE_CODE(type);
++                req->length = type->length();
++
++                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 = typedef_type->length();
++                                type = typedef_type;
++                        }
++                }
++
++                if (TYPE_CODE(type) == TYPE_CODE_ENUM) {
++                        if (req->is_typedef)
++                        if (req->flags & GNU_PRINT_ENUMERATORS) {
++                                if (req->is_typedef)
++                                        gdb_printf(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->first_opcode(): %d (?)\n",
++                                expr->first_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;
++        long long lastval;
++
++        len = TYPE_NFIELDS (type);
++        lastval = 0;
++        if (TYPE_TAG_NAME(type))
++                gdb_printf(gdb_stdout,
++                        "enum %s {\n", TYPE_TAG_NAME (type));
++        else
++                gdb_printf(gdb_stdout, "enum {\n");
++
++        for (i = 0; i < len; i++) {
++                gdb_printf(gdb_stdout, "  %s",
++                        type->field(i).name());
++                if (lastval != type->field(i).loc_enumval()) {
++                        gdb_printf (gdb_stdout, " = %s",
++                                plongest(type->field(i).loc_enumval()));
++                        lastval = type->field(i).loc_enumval();
++                } else
++                        gdb_printf(gdb_stdout, " = %s", plongest(lastval));
++                gdb_printf(gdb_stdout, "\n");
++                lastval++;
++        }
++        if (TYPE_TAG_NAME(type))
++                gdb_printf(gdb_stdout, "};\n");
++        else
++                gdb_printf(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(i).loc_enumval())
++                        lastval = type->field(i).loc_enumval();
++
++                if (STREQ(type->field(i).name(), 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)->m_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)->m_nfields;
++                        nextfield = TYPE_MAIN_TYPE(newtype)->flds_bnds.fields;
++                }
++        }
++
++        for (i = 0; i < nfields; i++) {
++                if (STREQ(req->member, nextfield->m_name)) {
++                        req->member_offset = offset + nextfield->m_loc.bitpos;
++                        req->member_length = nextfield->type()->length();
++                        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 = nextfield->type()->target_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 = typedef_type->length();
++                        return;
++                } else if (*nextfield->m_name == 0) { /* Anonymous struct/union */
++                        get_member_data(req, nextfield->type(),
++                            offset + nextfield->m_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;
++
++        req->value = FALSE;
++        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)
++{
++        struct load_module *lm;
++        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))
++            gdb_printf(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)) {
++                        objfile->unlink ();
++                        break;
++                }
++        }
++
++        if (gdb_CRASHDEBUG(2)) {
++                gdb_printf(gdb_stdout, "current object files:\n");
++                for (objfile *objfile : current_program_space->objfiles ())
++                        gdb_printf(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->m_value.ivalue);
++                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 = expr->evaluate_type();
++
++        type = val->type();
++
++        req->type_name = (char *)TYPE_MAIN_TYPE(type)->name;
++        req->typecode = TYPE_MAIN_TYPE(type)->code;
++        req->length = type->m_length;
++        req->type_tag_name = (char *)TYPE_TAG_NAME(type);
++        target_type = TYPE_MAIN_TYPE(type)->m_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->m_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(current_program_space, name, gdb_kernel_objfile, NULL)).minsym) {
++                if (sym->aclass() == LOC_BLOCK) {
++                        block = (struct block *)(sym->value_block());
++                        block->set_start(msym.value_address());
++                } else
++                        sym->set_value_address(msym.value_address());
++        }
++}
++
++#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->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->m_target_type)
++        m = 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->m_target_type)
++        m = 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->sf)
++        objfile->expand_all_symtabs();
++
++      for (compunit_symtab *cust : objfile->compunits ())
++        {
++          const struct blockvector *bv = cust->blockvector();
++
++          for (int i = GLOBAL_BLOCK; i <= STATIC_BLOCK; ++i)
++            {
++              const struct block *b = bv->block(i);
++
++              for (struct symbol *sym : block_iterator_range (b))
++                {
++                  QUIT;
++
++                  if (sym->aclass() != LOC_TYPEDEF)
++                    continue;
++
++                  if (req->highest &&
++                    !(req->lowest <= sym->type()->m_length && sym->type()->m_length <= req->highest))
++                        continue;
++
++                  req->addr = (ulong)(sym->type()->main_type);
++                  req->name = (char *)(sym->m_name);
++                  req->length = sym->type()->m_length;
++
++                  if (req->member) {
++                    req->value = lookup_struct_contents(req);
++                    if (!req->value)
++                      continue;
++                  }
++                  req->callback(req, req->callback_data);
++                }
++            }
++        }
++    }
++}
++#endif
+--- gdb-16.2/gdb/ui-file.h.orig
++++ gdb-16.2/gdb/ui-file.h
+@@ -273,10 +273,10 @@ class stdio_file : public ui_file
+   int fd () const override
+   { return m_fd; }
+ 
+-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;
+--- gdb-16.2/gdb/xml-syscall.c.orig
++++ gdb-16.2/gdb/xml-syscall.c
+@@ -36,7 +36,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-16.2/libiberty/Makefile.in.orig
++++ gdb-16.2/libiberty/Makefile.in
+@@ -181,6 +181,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)	\
+@@ -214,7 +215,7 @@ CONFIGURED_OFILES = ./asprintf.$(objext) ./atexit.$(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-16.2/opcodes/i386-dis.c.orig
++++ gdb-16.2/opcodes/i386-dis.c
+@@ -9589,6 +9589,10 @@ print_insn (bfd_vma pc, disassemble_info *info, int intel_syntax)
+ 
+       dp = &dis386_twobyte[*ins.codep];
+       ins.need_modrm = twobyte_has_modrm[*ins.codep];
++      if (dp->name && ((strcmp(dp->name, "ud2a") == 0) || (strcmp(dp->name, "ud2") == 0))) {
++        extern int kernel_BUG_encoding_bytes(void);
++        ins.codep += kernel_BUG_encoding_bytes();
++      }
+     }
+   else
+     {
+--- gdb-16.2/readline/readline/misc.c.orig
++++ gdb-16.2/readline/readline/misc.c
+@@ -411,7 +411,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)
+--- gdb-16.2/readline/readline/readline.h.orig
++++ gdb-16.2/readline/readline/readline.h
+@@ -407,7 +407,7 @@ extern int rl_mark_active_p (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 (int);
+--- gdb-16.2/readline/readline/rltypedefs.h.orig
++++ gdb-16.2/readline/readline/rltypedefs.h
+@@ -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 ();
+--- gdb-16.2/readline/readline/util.c.orig
++++ gdb-16.2/readline/readline/util.c
+@@ -489,10 +489,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);
+ }
+ 
+@@ -512,16 +515,17 @@ _rl_tropen (void)
+ #endif
+   snprintf (fnbuf, sizeof (fnbuf), "%s/rltrace.%ld", x, (long)getpid());
+   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;
+ }
+--- gdb-16.2/gdb/completer.c.orig
++++ gdb-16.2/gdb/completer.c
+@@ -3315,6 +3315,8 @@ gdb_display_match_list_1 (char **matches, int len, int max,
+ 
+   /* How many items of MAX length can we fit in the screen window? */
+   cols = gdb_complete_get_screenwidth (displayer);
++  rl_reset_screen_size();
++  rl_get_screen_size(NULL, &cols);
+   max += 2;
+   limit = cols / max;
+   if (limit != 1 && (limit * max == cols))
+--- gdb-16.2/gdb/Makefile.in.orig
++++ gdb-16.2/gdb/Makefile.in
+@@ -2231,7 +2231,7 @@ 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_16_2 library)
++	@$(MAKE) -C ../.. GDB_FLAGS=-DGDB_16_2 library
+ 	$(ECHO_CXXLD) $(CC_LD) $(INTERNAL_LDFLAGS) $(WIN32LDAPP) \
+                 -o $(shell /bin/cat mergeobj) $(LIBGDB_OBS) \
+                 $(TDEPLIBS) $(TUI_LIBRARY) $(CLIBS) $(LOADLIBES) $(shell /bin/cat mergelibs)
+--- gdb-16.2/gdb/c-typeprint.c.orig
++++ gdb-16.2/gdb/c-typeprint.c
+@@ -1066,6 +1066,9 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream,
+ 		= podata->end_bitpos
+ 		  - type->field (i).type ()->length () * TARGET_CHAR_BIT;
+ 	    }
++	  else if (strlen(type->field(i).name()) == 0)
++	    /* crash: Print details for unnamed struct and union. */
++	    newshow = show;
+ 
+ 	  c_print_type_1 (type->field (i).type (),
+ 			  type->field (i).name (),
+--- gdb-16.2/gdb/symfile.c.orig
++++ gdb-16.2/gdb/symfile.c
+@@ -1587,7 +1587,7 @@ find_separate_debug_file_by_debuglink
+   if (debugfile.empty ()) {
+        char *name_copy;
+        name_copy = check_specified_kernel_debug_file();
+-       return std::string (name_copy);
++       return name_copy ? std::string (name_copy) : std::string ();
+   }
+ #endif
+ 
+--- gdb-16.2/gdb/printcmd.c.orig
++++ gdb-16.2/gdb/printcmd.c
+@@ -604,6 +604,10 @@ print_address_symbolic (struct gdbarch *gdbarch, CORE_ADDR addr,
+ 
+ /* See valprint.h.  */
+ 
++#ifdef CRASH_MERGE
++extern "C" char *gdb_lookup_module_symbol(unsigned long, unsigned long *);
++#endif
++
+ int
+ build_address_symbolic (struct gdbarch *gdbarch,
+ 			CORE_ADDR addr,  /* IN */
+@@ -710,7 +714,19 @@ build_address_symbolic (struct gdbarch *gdbarch,
+ 	}
+     }
+   if (symbol == NULL && msymbol.minsym == NULL)
++#ifdef CRASH_MERGE
++  {
++    char *name_ptr = gdb_lookup_module_symbol(addr, (unsigned long *)offset);
++    if (name_ptr) {
++      *name = name_ptr;
++      return 0;
++    } else {
++      return 1;
++    }
++  }
++#else
+     return 1;
++#endif
+ 
+   /* If the nearest symbol is too far away, don't print anything symbolic.  */
+ 
+--- gdb-16.2/gdb/symtab.c.orig
++++ gdb-16.2/gdb/symtab.c
+@@ -7563,8 +7563,8 @@ gdb_get_line_number(struct gnu_request *req)
+ static void
+ gdb_get_datatype(struct gnu_request *req)
+ {
+-        register struct type *type;
+-        register struct type *typedef_type;
++        struct type *type;
++        struct type *typedef_type;
+         expression_up expr;
+         struct symbol *sym;
+         struct value *val;
+@@ -7670,7 +7670,7 @@ gdb_get_datatype(struct gnu_request *req)
+ static void
+ dump_enum(struct type *type, struct gnu_request *req)
+ {
+-        register int i;
++        int i;
+         int len;
+         long long lastval;
+ 
+@@ -7706,7 +7706,7 @@ dump_enum(struct type *type, struct gnu_request *req)
+ static void
+ eval_enum(struct type *type, struct gnu_request *req)
+ {
+-        register int i;
++        int i;
+         int len;
+         long long lastval;
+ 
+@@ -7733,7 +7733,7 @@ eval_enum(struct type *type, struct gnu_request *req)
+ static void
+ get_member_data(struct gnu_request *req, struct type *type, long offset, int is_first)
+ {
+-        register short i;
++        short i;
+         struct field *nextfield;
+         short nfields;
+         struct type *typedef_type, *target_type;
+--- gdb-16.2/gdb/symtab.c.orig
++++ gdb-16.2/gdb/symtab.c
+@@ -7347,7 +7347,7 @@ the use of prologue scanners."),
+ #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 walk_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 *);
+@@ -7556,6 +7556,79 @@ gdb_get_line_number(struct gnu_request *req)
+ }
+ 
+ 
++/*
++ * Follow the type linkage for full member and value type resolution, with callback
++ */
++static void drillDownType(struct gnu_request *req, struct type *type)
++{
++        while (type)
++        {
++                /* check out for stub types and pull in the definition instead */
++                if (type->is_stub() && TYPE_TAG_NAME(type)) {
++                        struct symbol *sym;
++                        sym = lookup_symbol(TYPE_TAG_NAME(type), 0, SEARCH_STRUCT_DOMAIN, 0).symbol;
++                        if (sym)
++                                type = sym->type();
++                }
++                switch (TYPE_CODE(type)) {
++                        drill_ops_t op;
++                        long l1, l2;
++                        int typecode;
++
++                case TYPE_CODE_PTR:
++                        req->tcb(EOP_POINTER, req, 0, 0, 0, 0);
++                        break;
++
++                case TYPE_CODE_TYPEDEF:
++                        req->is_typedef = 1;
++                        req->typecode = TYPE_CODE(type);
++                        if (!req->tcb(EOP_TYPEDEF, req, TYPE_NAME(type), 0, 0, 0))
++                                return;
++                        break;
++
++                case TYPE_CODE_FUNC:
++                        req->tcb(EOP_FUNCTION, req, 0, 0, 0, 0);
++                        break;
++
++                case TYPE_CODE_ARRAY:
++                        l1 = type->length();
++                        l2 = check_typedef(type->target_type())->length();
++                        req->tcb(EOP_ARRAY, req, &l1, &l2, 0, 0);
++                        break;
++
++                case TYPE_CODE_VOID:
++                case TYPE_CODE_INT:
++                case TYPE_CODE_BOOL:
++                        l1 = type->length();
++                        req->tcb(EOP_INT, req, &l1, 0, 0, 0);
++                        break;
++
++                case TYPE_CODE_UNION:
++                        op = EOP_UNION;
++                        goto label;
++
++                case TYPE_CODE_ENUM:
++                        op = EOP_ENUM;
++                        goto label;
++
++                case TYPE_CODE_STRUCT:
++                        op = EOP_STRUCT;
++                        goto label;
++
++                default:
++                        typecode = TYPE_CODE(type);
++                        req->tcb(EOP_OOPS, req, &typecode, "Unknown typecode", 0, 0);
++                        return; /* not reached */
++
++                label:
++                        l1 = type->length();
++                        req->tcb(op, req, &l1, type, TYPE_TAG_NAME(type), 0);
++                }
++                type = type->target_type();
++        }
++        req->tcb(EOP_DONE, req, 0, 0, 0, 0);
++}
++
+ /*
+  *  General purpose routine for determining datatypes.
+  */
+@@ -7584,10 +7657,8 @@ gdb_get_datatype(struct gnu_request *req)
+                 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);
+-                }
++                if (TYPE_CODE(sym->type()) == TYPE_CODE_ENUM)
++                        walk_enum(sym->type(), req);
+ 
+                 return;
+         }
+@@ -7607,17 +7678,25 @@ gdb_get_datatype(struct gnu_request *req)
+                 if (gdb_CRASHDEBUG(2))
+                         console("expr->first_opcode(): OP_VAR_VALUE\n");
+                 type = expr->evaluate_type()->type();
+-                if (req->flags & GNU_VAR_LENGTH_TYPECODE) {
++                if (req->tcb) {
++                        long value = value_as_long(expr->evaluate());
++                        /* callback with symbol value */
+                         req->typecode = TYPE_CODE(type);
+-                        req->length = type->length();
+-                }
+-                if (TYPE_CODE(type) == TYPE_CODE_ENUM) {
+-                        req->typecode = TYPE_CODE(type);
+-                        req->value = value_as_long(expr->evaluate());
+-                        req->tagname = (char *)TYPE_TAG_NAME(type);
+-                        if (!req->tagname) {
+-                                val = expr->evaluate_type();
+-                                eval_enum(val->type(), req);
++                        req->tcb(EOP_VALUE, req, &value, 0, 0, 0);
++                        drillDownType(req, type);
++                } else {
++                        if (req->flags & GNU_VAR_LENGTH_TYPECODE) {
++                                req->typecode = TYPE_CODE(type);
++                                req->length = type->length();
++                        }
++                        if (TYPE_CODE(type) == TYPE_CODE_ENUM) {
++                                req->typecode = TYPE_CODE(type);
++                                req->value = value_as_long(expr->evaluate());
++                                req->tagname = (char *)TYPE_TAG_NAME(type);
++                                if (!req->tagname) {
++                                        val = expr->evaluate_type();
++                                        eval_enum(val->type(), req);
++                                }
+                         }
+                 }
+                 break;
+@@ -7627,26 +7706,21 @@ gdb_get_datatype(struct gnu_request *req)
+                         console("expr->first_opcode(): OP_TYPE\n");
+                     type = expr->evaluate_type()->type();
+ 
+-                req->typecode = TYPE_CODE(type);
+-                req->length = type->length();
+-
+-                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 = typedef_type->length();
+-                                type = typedef_type;
+-                        }
+-                }
+-
+-                if (TYPE_CODE(type) == TYPE_CODE_ENUM) {
+-                        if (req->is_typedef)
+-                        if (req->flags & GNU_PRINT_ENUMERATORS) {
+-                                if (req->is_typedef)
+-                                        gdb_printf(gdb_stdout,
+-                                                "typedef ");
+-                                dump_enum(type, req);
++                if (req->tcb) {
++                        drillDownType(req, type);
++                } else {
++                        req->typecode = TYPE_CODE(type);
++                        req->length = type->length();
++                        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 = typedef_type->length();
++                                        type = typedef_type;
++                                }
+                         }
++                        if (TYPE_CODE(type) == TYPE_CODE_ENUM)
++                                walk_enum(type, req);
+                 }
+ 
+                 if (req->member)
+@@ -7668,36 +7742,38 @@ gdb_get_datatype(struct gnu_request *req)
+  *  identifier, each on its own line.
+  */
+ static void
+-dump_enum(struct type *type, struct gnu_request *req)
++walk_enum(struct type *type, struct gnu_request *req)
+ {
+         int i;
+-        int len;
++        int len, print = (req->flags & GNU_PRINT_ENUMERATORS);
+         long long lastval;
+ 
+-        len = TYPE_NFIELDS (type);
+-        lastval = 0;
+-        if (TYPE_TAG_NAME(type))
+-                gdb_printf(gdb_stdout,
+-                        "enum %s {\n", TYPE_TAG_NAME (type));
+-        else
+-                gdb_printf(gdb_stdout, "enum {\n");
++        if (print) {
++                if (req->is_typedef)
++                        gdb_printf(gdb_stdout, "typedef ");
++                if (TYPE_TAG_NAME(type))
++                        gdb_printf(gdb_stdout, "enum %s {\n", TYPE_TAG_NAME (type));
++                else
++                        gdb_printf(gdb_stdout, "enum {\n");
++        }
+ 
++        len = TYPE_NFIELDS (type);
+         for (i = 0; i < len; i++) {
+-                gdb_printf(gdb_stdout, "  %s",
+-                        type->field(i).name());
+-                if (lastval != type->field(i).loc_enumval()) {
+-                        gdb_printf (gdb_stdout, " = %s",
+-                                plongest(type->field(i).loc_enumval()));
+-                        lastval = type->field(i).loc_enumval();
+-                } else
++                if (print)
++                        gdb_printf(gdb_stdout, "  %s", type->field(i).name());
++                lastval = type->field(i).loc_enumval();
++                if (print) {
+                         gdb_printf(gdb_stdout, " = %s", plongest(lastval));
+-                gdb_printf(gdb_stdout, "\n");
+-                lastval++;
++                        gdb_printf(gdb_stdout, "\n");
++                } else if (req->tcb)
++                        req->tcb(EOP_ENUMVAL, req, type->field(i).name(), &lastval, 0, 0);
++        }
++        if (print) {
++                if (TYPE_TAG_NAME(type))
++                        gdb_printf(gdb_stdout, "};\n");
++                else
++                        gdb_printf(gdb_stdout, "} %s;\n", req->name);
+         }
+-        if (TYPE_TAG_NAME(type))
+-                gdb_printf(gdb_stdout, "};\n");
+-        else
+-                gdb_printf(gdb_stdout, "} %s;\n", req->name);
+ }
+ 
+ /*
+@@ -7755,26 +7831,43 @@ get_member_data(struct gnu_request *req, struct type *type, long offset, int is_
+         }
+ 
+         for (i = 0; i < nfields; i++) {
+-                if (STREQ(req->member, nextfield->m_name)) {
+-                        req->member_offset = offset + nextfield->m_loc.bitpos;
+-                        req->member_length = nextfield->type()->length();
+-                        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 = nextfield->type()->target_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 = typedef_type->length();
+-                        return;
+-                } else if (*nextfield->m_name == 0) { /* Anonymous struct/union */
++                if (*nextfield->m_name == 0) { /* Anonymous struct/union */
+                         get_member_data(req, nextfield->type(),
+                             offset + nextfield->m_loc.bitpos, 0);
+                         if (req->member_offset != -1)
+                                 return;
++                } else {
++                        /* callback may be just looking for a specific member name */
++                        if (req->tcb) {
++                                if (req->tcb(EOP_MEMBER_NAME, req, nextfield->m_name, 0, 0, 0)) {
++                                        long bitpos = nextfield->loc_bitpos();
++                                        long bitsize = nextfield->bitsize();
++                                        long len = nextfield->type()->length();
++                                        long byteOffset;
++                                        offset += nextfield->m_loc.bitpos;
++                                        byteOffset = offset/8;
++                                        console("EOP_MEMBER_SIZES\n");
++                                        req->tcb(EOP_MEMBER_SIZES, req, &byteOffset, &len, &bitpos, &bitsize);
++                                        /* callback with full type info */
++                                        drillDownType(req, nextfield->type());
++                                }
++                        } else if (STREQ(req->member, nextfield->m_name)) {
++                                req->member_offset = offset + nextfield->m_loc.bitpos;
++                                req->member_length = nextfield->type()->length();
++                                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 = nextfield->type()->target_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 = typedef_type->length();
++                                }
++                                return;
++                        }
+                 }
+                 nextfield++;
+         }
+--- gdb-16.2/gdb/symtab.c.orig
++++ gdb-16.2/gdb/symtab.c
+@@ -7911,7 +7911,7 @@ gdb_add_symbol_file(struct gnu_request *req)
+         int i;
+         int allsect = 0;
+         char *secname;
+-        char buf[80];
++        char buf[96];
+ 
+         gdb_current_load_module = lm = (struct load_module *)req->addr;
+ 
+@@ -7950,8 +7950,11 @@ gdb_add_symbol_file(struct gnu_request *req)
+                             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);
++                                    if (lm->mod_section_data[i].addr)
++                                        sprintf(buf, " -s %s 0x%lx", secname, lm->mod_section_data[i].addr);
++                                    else
++                                        sprintf(buf, " -s %s 0x%lx", secname,
++                                            lm->mod_section_data[i].offset + lm->mod_base);
+                                     strcat(req->buf, buf);
+                             }
+                     }
+--- gdb-16.2/gdb/objfiles.h.orig
++++ gdb-16.2/gdb/objfiles.h
+@@ -891,6 +891,8 @@ struct objfile
+      mechanism as ELF should set this flag too.  This flag is used in
+      conjunction with the minimal_symbol::maybe_copied method.  */
+   bool object_format_has_copy_relocs = false;
++
++  bool all_symtabs_expanded = false;
+ };
+ 
+ /* A deleter for objfile.  */
+--- gdb-16.2/gdb/symfile.c.orig
++++ gdb-16.2/gdb/symfile.c
+@@ -1120,6 +1120,7 @@ symbol_file_add_with_addrs (const gdb_bfd_ref_ptr &abfd, const char *name,
+ 		    styled_string (file_name_style.style (), name));
+ 
+       objfile->expand_all_symtabs ();
++      objfile->all_symtabs_expanded = true;
+     }
+ 
+   /* Note that we only print a message if we have no symbols and have
+--- gdb-16.2/gdb/symfile.c.orig
++++ gdb-16.2/gdb/symfile.c
+@@ -2709,6 +2709,7 @@ reread_symbols (int from_tty)
+ 					   objfile_name (objfile)));
+ 
+ 	      objfile->expand_all_symtabs ();
++              objfile->all_symtabs_expanded = true;
+ 	    }
+ 
+ 	  if (!objfile_has_symbols (objfile))
+--- gdb-16.2/gdb/symtab.c.orig
++++ gdb-16.2/gdb/symtab.c
+@@ -7532,8 +7532,9 @@ gdb_get_line_number(struct gnu_request *req)
+                  */
+                 if (req->lm) {
+                         objfile = req->lm->loaded_objfile;
+-                        if (!objfile_has_full_symbols(objfile) && objfile->sf) {
++                        if (!objfile->all_symtabs_expanded && objfile->sf) {
+                                 objfile->expand_all_symtabs();
++				objfile->all_symtabs_expanded = true;
+                                 sal = find_pc_line(pc, 0);
+                         }
+                 }
+@@ -8199,8 +8200,10 @@ iterate_datatypes (struct gnu_request *req)
+ {
+   for (objfile *objfile : current_program_space->objfiles ())
+     {
+-      if (objfile->sf)
++      if (objfile->sf) {
+         objfile->expand_all_symtabs();
++	objfile->all_symtabs_expanded = true;
++      }
+ 
+       for (compunit_symtab *cust : objfile->compunits ())
+         {
+--- gdb-16.2/gdb/minsyms.c.orig
++++ gdb-16.2/gdb/minsyms.c
+@@ -575,6 +575,8 @@ lookup_minimal_symbol_linkage (const char *name, struct objfile *objf,
+ 	  if (strcmp (msymbol->linkage_name (), name) == 0
+ 	      && (msymbol->type () == mst_data
+ 		  || msymbol->type () == mst_bss
++                  || msymbol->type () == mst_file_bss
++                  || msymbol->type () == mst_file_data
+ 		  || (match_static_type
+ 		      && (msymbol->type () == mst_file_data
+ 			  || msymbol->type () == mst_file_bss))))
+--- gdb-16.2/gdb/ui-file.h.orig
++++ gdb-16.2/gdb/ui-file.h
+@@ -273,6 +273,7 @@ class stdio_file : public ui_file
+   int fd () const override
+   { return m_fd; }
+ 
++  FILE *get_stream(void);
+   /* Sets the internal stream to FILE, and saves the FILE's file
+      descriptor in M_FD.  */
+   void set_stream (FILE *file);
+--- gdb-16.2/gdb/ui-file.c.orig
++++ gdb-16.2/gdb/ui-file.c
+@@ -251,6 +251,12 @@ stdio_file::~stdio_file ()
+     fclose (m_file);
+ }
+ 
++FILE*
++stdio_file::get_stream(void)
++{
++  return m_file;
++}
++
+ void
+ stdio_file::set_stream (FILE *file)
+ {
+--- gdb-16.2/gdb/symtab.c.orig
++++ gdb-16.2/gdb/symtab.c
+@@ -7399,8 +7399,12 @@ void
+ gdb_command_funnel_1(struct gnu_request *req)
+ {
+         struct symbol *sym;
++        FILE *original_stdout_stream = nullptr;
++        FILE *original_stderr_stream = nullptr;
+ 
+         if (req->command != GNU_VERSION && req->command != GNU_USER_PRINT_OPTION) {
++                original_stdout_stream = (dynamic_cast< stdio_file * >gdb_stdout)->get_stream();
++                original_stderr_stream = (dynamic_cast< stdio_file * >gdb_stderr)->get_stream();
+                 (dynamic_cast<stdio_file *>gdb_stdout)->set_stream(req->fp);
+                 (dynamic_cast<stdio_file *>gdb_stderr)->set_stream(req->fp);
+         }
+@@ -7503,6 +7507,12 @@ gdb_command_funnel_1(struct gnu_request *req)
+                 req->flags |= GNU_COMMAND_FAILED;
+                 break;
+         }
++
++        /* Restore the streams gdb output was using */
++        if (original_stdout_stream)
++            (dynamic_cast<stdio_file *>gdb_stdout)->set_stream(original_stdout_stream);
++        if (original_stderr_stream)
++            (dynamic_cast<stdio_file *>gdb_stderr)->set_stream(original_stderr_stream);
+ }
+ 
+ /*
+--- gdb-16.2/gdb/stack.c.orig
++++ gdb-16.2/gdb/stack.c
+@@ -1968,6 +1968,11 @@ static frame_command_helper <select_frame_command_core> select_frame_cmd;
+ /* Print briefly all stack frames or just the innermost COUNT_EXP
+    frames.  */
+ 
++#ifdef CRASH_MERGE
++extern "C" int is_kvaddr(ulong);
++extern "C" int gdb_CRASHDEBUG(ulong);
++#endif
++
+ static void
+ backtrace_command_1 (const frame_print_options &fp_opts,
+ 		     const backtrace_cmd_options &bt_opts,
+@@ -2062,6 +2067,17 @@ backtrace_command_1 (const frame_print_options &fp_opts,
+ 	     hand, perhaps the code does or could be fixed to make sure
+ 	     the frame->prev field gets set to NULL in that case).  */
+ 
++#ifdef CRASH_MERGE
++	  CORE_ADDR pc = 0;
++	  get_frame_pc_if_available (fi, &pc);
++	  if (!is_kvaddr(pc)) {
++	    if (gdb_CRASHDEBUG(1)) {
++	       gdb_printf(_("Backtrace stopped: due to non-kernel addr: 0x%lx\n"),pc);
++	    }
++	    fi = NULL;
++	    break;
++	  }
++#endif
+ 	  print_frame_info (fp_opts, fi, 1, LOCATION, 1, 0);
+ 	  if ((flags & PRINT_LOCALS) != 0)
+ 	    print_frame_local_vars (fi, false, NULL, NULL, 1, gdb_stdout);
+--- gdb-16.2/gdb/stack.c.orig
++++ gdb-16.2/gdb/stack.c
+@@ -2097,7 +2097,7 @@ backtrace_command_1 (const frame_print_options &fp_opts,
+ 	  enum unwind_stop_reason reason;
+ 
+ 	  reason = get_frame_unwind_stop_reason (trailing);
+-	  if (reason >= UNWIND_FIRST_ERROR)
++	  if (reason >= UNWIND_FIRST_ERROR && gdb_CRASHDEBUG(1))
+ 	    gdb_printf (_("Backtrace stopped: %s\n"),
+ 			frame_stop_reason_string (trailing));
+ 	}
+--- gdb-16.2/gdb/frame.c.orig
++++ gdb-16.2/gdb/frame.c
+@@ -966,6 +966,10 @@ frame_find_by_id (struct frame_id id)
+   return NULL;
+ }
+
++#if defined(CRASH_MERGE) && defined(ARM64)
++extern "C" void crash_decode_ptrauth_pc(ulong* pc);
++#endif
++
+ static CORE_ADDR
+ frame_unwind_pc (const frame_info_ptr &this_frame)
+ {
+@@ -996,6 +1000,9 @@ frame_unwind_pc (const frame_info_ptr &this_frame)
+       try
+	{
+	  pc = gdbarch_unwind_pc (prev_gdbarch, this_frame);
++#if defined(CRASH_MERGE) && defined(ARM64)
++	  crash_decode_ptrauth_pc(&pc);
++#endif
+	  pc_p = true;
+	}
+       catch (const gdb_exception_error &ex)
+--- gdb-16.2/gdb/event-top.c.orig
++++ gdb-16.2/gdb/event-top.c
+@@ -1558,6 +1558,10 @@
+ {
+   struct ui *ui = current_ui;
+ 
++  if (!batch_silent)
++    gdb_stdout = new stdio_file (ui->outstream);
++  gdb_stderr = new stderr_file (ui->errstream);
++
+   /* If the input stream is connected to a terminal, turn on editing.
+      However, that is only allowed on the main UI, as we can only have
+      one instance of readline.  Also, INSTREAM might be nullptr when
+--- gdb-16.2/gdb/symtab.c.orig
++++ gdb-16.2/gdb/symtab.c
+@@ -3023,7 +3023,7 @@
+   for (objfile *objf : current_program_space->objfiles ())
+     {
+       struct compunit_symtab *result
+-	= objf->find_pc_sect_compunit_symtab (msymbol, pc, section, 1);
++	= objf->find_pc_sect_compunit_symtab (msymbol, pc, section, 0);
+       if (result != NULL)
+ 	return result;
+     }
diff --git a/gdb_interface.c b/gdb_interface.c
index c2e99f5..fa2e85b 100644
--- a/gdb_interface.c
+++ b/gdb_interface.c
@@ -17,7 +17,7 @@
 
 #include "defs.h"
 
-#ifndef GDB_10_2
+#if !defined(GDB_10_2) && !defined(GDB_16_2)
 static void exit_after_gdb_info(void);
 #endif
 static int is_restricted_command(char *, ulong);
@@ -71,7 +71,7 @@ gdb_main_loop(int argc, char **argv)
 	}
 
         optind = 0;
-#ifndef GDB_10_2
+#if !defined(GDB_10_2) && !defined(GDB_16_2)
 #if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1)
         command_loop_hook = main_loop;
 #else
@@ -122,7 +122,7 @@ void
 display_gdb_banner(void)
 {
 	optind = 0;
-#ifndef GDB_10_2
+#if !defined(GDB_10_2) && !defined(GDB_16_2)
 #if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1)
         command_loop_hook = exit_after_gdb_info;
 #else
@@ -134,7 +134,7 @@ display_gdb_banner(void)
 	gdb_main_entry(2, args);
 }
 
-#ifndef GDB_10_2
+#if !defined(GDB_10_2) && !defined(GDB_16_2)
 static void
 exit_after_gdb_info(void)
 {
@@ -159,13 +159,15 @@ get_gdb_version(void)
 	}
 }
 
+extern void *current_program_space;
+
 void
 gdb_session_init(void)
 {
 	struct gnu_request *req;
 	int debug_data_pulled_in;
 
-        if (!have_partial_symbols() && !have_full_symbols())
+        if (!have_partial_symbols(current_program_space) && !have_full_symbols(current_program_space))
 		no_debugging_data(FATAL);
 
 	/*
@@ -300,7 +302,7 @@ retry:
 	sprintf(req->buf, "set width 0");
 	gdb_interface(req);
 
-#ifdef GDB_10_2
+#if defined(GDB_10_2) || defined(GDB_16_2)
 	req->command = GNU_PASS_THROUGH;
 	req->name = NULL, req->flags = 0;
 	sprintf(req->buf, "set max-value-size unlimited");
diff --git a/kernel.c b/kernel.c
index 1adbfab..612b956 100644
--- a/kernel.c
+++ b/kernel.c
@@ -23,7 +23,7 @@
 #include <ctype.h>
 #include <stdbool.h>
 #include "xendump.h"
-#if defined(GDB_7_6) || defined(GDB_10_2)
+#if defined(GDB_7_6) || defined(GDB_10_2) || defined(GDB_16_2)
 #define __CONFIG_H__ 1
 #include "config.h"
 #endif
@@ -1574,8 +1574,8 @@ list_source_code(struct gnu_request *req, int count_entered)
 			error(FATAL, 
 			    "%s: source code is not available\n\n", req->buf);
 
-		sprintf(buf3, "%s: No such file or directory.", file);
-		if (decimal(argv[0], 0) && strstr(buf1, buf3))
+		sprintf(buf3, "%s: No such file or directory", file);
+		if ((decimal(argv[0], 0) || decimal(argv[1], 0)) && strstr(buf1, buf3))
 			error(FATAL, 
 			    "%s: source code is not available\n\n", req->buf);
 
diff --git a/symbols.c b/symbols.c
index f6f52bd..6385d02 100644
--- a/symbols.c
+++ b/symbols.c
@@ -17,7 +17,7 @@
 
 #include "defs.h"
 #include <elf.h>
-#if defined(GDB_7_6) || defined(GDB_10_2)
+#if defined(GDB_7_6) || defined(GDB_10_2) || defined(GDB_16_2)
 #define __CONFIG_H__ 1
 #include "config.h"
 #endif
@@ -479,7 +479,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
-#if defined(GDB_7_6) || defined(GDB_10_2)
+#if defined(GDB_7_6) || defined(GDB_10_2) || defined(GDB_16_2)
     		file_crc = bfd_calc_gnu_debuglink_crc32(file_crc, 
 			(unsigned char *)buffer, count);
 #else
-- 
2.47.0
--
Crash-utility mailing list -- devel@xxxxxxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe send an email to devel-leave@xxxxxxxxxxxxxxxxxxxxxxxxxxx
https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux