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