crash/gdb-7.6.patch
Dave Anderson e980093166 Fix for the "dis" command to support three new x86 instruction
extensions that have been added to the Intel instruction set for
hardware platforms that support them.  The newly-added instructions
"clflushopt", "clwb", and "pcommit" prepend 0x66 as a prefix byte to
the "clflush", "xsaveopt" and "sfence" instructions respectively.
Without the patch:

  "clflushopt" is disassembled as: "data16" followed by "clflush"
  "clwb" is disassembled as: "data16" followed by "xsaveopt"
  "pcommit" is disassembled as: "data16" followed by "sfence"

The "clflushopt" instruction was introduced in Linux 3.15 in the
clflushopt() function.  The "clwb" and "pcommit" instructions were
introduced in Linux 4.1 in the clwb() and pcommit_sfence() functions.
(anderson@redhat.com)
2015-09-21 16:56:32 -04:00

1879 lines
56 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))
{
--- 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 (" ");