mirror of
https://github.com/crash-utility/crash
synced 2024-12-13 12:44:34 +00:00
1564 lines
46 KiB
Diff
1564 lines
46 KiB
Diff
--- 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))
|
|
{
|