From: "Donn Terry" <donnte@microsoft.com>
To: <gdb-patches@sources.redhat.com>
Subject: Patches for Interix
Date: Thu, 01 Aug 2002 13:57:00 -0000 [thread overview]
Message-ID: <FE465D8F724E3F4F811D067203A214AE05C19B6B@red-msg-08.redmond.corp.microsoft.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 248 bytes --]
This is a "for the record" submission of all the patches necessary to
make gdb
work correctly on Interix. These patches were current as of June 7,
2002.
Actual submissions for application will follow; this is a required
niceity.
Donn
[-- Attachment #2: gdball --]
[-- Type: application/octet-stream, Size: 286691 bytes --]
---------------------------------------------------------------------------
ST0 patch should be cross-applied.
This patch contains the "basic, obvious" stuff necessary to support
gdb on interix, given a /proc filesystem interface for debugging.
It alone is not sufficient, but the pieces herein do not affect
anything else. To compile successfully for interix, the /proc
patch is needed as well. (And then, it probably won't run very
well.)
Some compilers don't permit filenames before -D options; reorder.
Some versions of make set -e when they arguably shouldn't; if grep
exits 1 (no match) it will exit the make if init.c too early.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* Makefile.in: add interix case. Put -D before filenames.
Be more robust w.r.t. shell -e option.
* interix.mh: New file.
* interix.mt: New file.
* nm-interix.h: New file.
* tm-i386interix.h: New file.
* xm-interix.h: New file.
* configure.host: add interix case.
* configure.in: add interix procfs case.
* configure.tgt: add interix case.
* i386-tdep.c(get_longjmp_target): turn off in favor of one
in i386interix-nat.c when on Interix.
* i386interix-nat.c: New file.
Index: src/gdb/Makefile.in
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/Makefile.in,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 Makefile.in
--- src/gdb/Makefile.in 2001/12/23 00:34:50 1.1.1.1
+++ src/gdb/Makefile.in 2001/12/23 20:34:46
@@ -845,7 +845,7 @@ init.c: $(INIT_FILES)
-e '/[a-z0-9A-Z_]*-exp.tab.o/d' \
-e 's/\.o/.c/' \
-e 's|\([^ ][^ ]*\)|$(srcdir)/\1|g' | \
- while read f; do grep '^_initialize_[a-z_0-9A-Z]* *(' $$f 2>/dev/null; done | \
+ while read f; do ( grep '^_initialize_[a-z_0-9A-Z]* *(' $$f 2>/dev/null || exit 0) ; done | \
sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/\1/' > init.l-tmp
@echo '/* Do not modify this file. */' >>init.c-tmp
@echo '/* It is created automatically by the Makefile. */'>>init.c-tmp
@@ -1590,6 +1590,8 @@ i386-linux-tdep.o: i386-linux-tdep.c $(d
$(value_h) $(regcache_h)
i386v4-nat.o: i386v4-nat.c $(defs_h) $(regcache_h)
+
+i386interix-nat.o: i386interix-nat.c $(defs_h)
i387-tdep.o: i387-tdep.c $(floatformat_h) $(defs_h) $(gdbcore_h) \
$(inferior_h) $(language_h) $(regcache_h) $(doublest_h) i386-tdep.h
Index: src/gdb/configure.host
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/configure.host,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 configure.host
--- src/gdb/configure.host 2001/12/23 00:34:44 1.1.1.1
+++ src/gdb/configure.host 2001/12/23 20:34:46
@@ -80,6 +80,7 @@ i[3456]86-*-unixware*) gdb_host=i386v4 ;
i[3456]86-*-sysv*) gdb_host=i386v ;;
i[3456]86-*-isc*) gdb_host=i386v32 ;;
i[3456]86-*-cygwin*) gdb_host=cygwin ;;
+i[3456]86-*-interix*) gdb_host=interix ;;
ia64-*-aix*) gdb_host=aix ;;
ia64-*-linux*) gdb_host=linux ;;
Index: src/gdb/configure.in
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/configure.in,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 configure.in
--- src/gdb/configure.in 2001/12/23 00:34:44 1.1.1.1
+++ src/gdb/configure.in 2001/12/23 20:34:46
@@ -263,7 +263,7 @@ if test "${target}" = "${host}"; then
ia64-*-aix*)
AC_DEFINE(NEW_PROC_API)
;;
- *-*-unixware* | *-*-sysv4.2* | *-*-sysv5*)
+ *-*-unixware* | *-*-sysv4.2* | *-*-sysv5* | *-*-interix* )
AC_DEFINE(NEW_PROC_API)
;;
*-*-solaris2.[[678]])
Index: src/gdb/configure.tgt
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/configure.tgt,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 configure.tgt
--- src/gdb/configure.tgt 2001/12/23 00:34:44 1.1.1.1
+++ src/gdb/configure.tgt 2001/12/23 20:34:46
@@ -113,6 +113,7 @@ i[3456]86-*-sco3.2v4*) gdb_target=i386sc
i[3456]86-*-sco3.2v5*) gdb_target=i386sco5 ;;
i[3456]86-*-sco*) gdb_target=i386v ;;
i[3456]86-*-sysv*) gdb_target=i386v ;;
+i[3456]86-*-interix*) gdb_target=interix ;;
i[3456]86-*-linux*) gdb_target=linux
configdirs="${configdirs} gdbserver" ;;
i[3456]86-pc-linux-gnu) gdb_target=linux
Index: src/gdb/i386-tdep.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/i386-tdep.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 i386-tdep.c
--- src/gdb/i386-tdep.c 2001/12/23 00:34:48 1.1.1.1
+++ src/gdb/i386-tdep.c 2001/12/23 20:34:46
@@ -833,6 +833,7 @@ i386_pop_frame (void)
\f
#ifdef GET_LONGJMP_TARGET
+#ifndef __INTERIX /* it needs something different */
/* Figure out where the longjmp will land. Slurp the args out of the
stack. We expect the first arg to be a pointer to the jmp_buf
@@ -863,6 +864,7 @@ get_longjmp_target (CORE_ADDR *pc)
return 1;
}
+#endif /* INTERIX */
#endif /* GET_LONGJMP_TARGET */
\f
Index: src/gdb/i386interix-nat.c
===================================================================
RCS file: i386interix-nat.c
diff -N i386interix-nat.c
--- /dev/null Sun Dec 23 12:43:22 2001
+++ src/gdb/i386interix-nat.c Sun Dec 23 12:34:46 2001
@@ -0,0 +1,413 @@
+/* Native-dependent code for Interix running on i386's, for GDB.
+ Copyright 1988, 1989, 1991, 1992, 1996 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+
+#include <sys/procfs.h>
+#include <ucontext.h>
+#include <frame.h>
+#include <inferior.h>
+
+#include <i386-tdep.h>
+
+typedef unsigned long greg_t; /* Where should this be defined? */
+
+/* See procfs.c and *interix*.h in config/[alpha,i386] */
+CORE_ADDR tramp_start;
+CORE_ADDR tramp_end;
+CORE_ADDR null_start;
+CORE_ADDR null_end;
+
+/* The /proc interface traditionally divides the target machine's register
+ set up into two different sets, the general register set (gregset)
+ and the floating point register set (fpregset). This is reflected
+ in the data structures in <sys/regset.h>.
+
+ However, the read/write /proc for interix treats them all as part
+ of the status subfile.
+
+ These routines provide the packing and unpacking of gregset_t and
+ fpregset_t formatted data.
+
+ */
+
+/* This is a duplicate of the table in i386-xdep.c. */
+
+static int regmap[] =
+{
+ EAX, ECX, EDX, EBX,
+ UESP, EBP, ESI, EDI,
+ EIP, EFL, CS, SS,
+ DS, ES, FS, GS,
+};
+
+/* Given a pointer to a general register set in /proc format (gregset_t *),
+ unpack the register contents and supply them as gdb's idea of the current
+ register values. */
+
+void
+supply_gregset (gregsetp)
+ gregset_t *gregsetp;
+{
+ register int regi;
+ register greg_t *regp = (greg_t *) &gregsetp->gregs;
+
+ for (regi = 0; regi < NUM_GREGS; regi++)
+ {
+ supply_register (regi, (char *) (regp + regmap[regi]));
+ }
+}
+
+/* Fill in a gregset_t object with selected data from a gdb-format
+ register file.
+ - GREGSETP points to the gregset_t object to be filled.
+ - GDB_REGS points to the GDB-style register file providing the data.
+ - VALID is an array indicating which registers in GDB_REGS are
+ valid; the parts of *GREGSETP that would hold registers marked
+ invalid in GDB_REGS are left unchanged. If VALID is zero, all
+ registers are assumed to be valid. */
+void
+convert_to_gregset (gregset_t *gregsetp,
+ char *gdb_regs,
+ signed char *valid)
+{
+ int regi;
+ register greg_t *regp = (greg_t *) gregsetp->gregs;
+
+ for (regi = 0; regi < NUM_GREGS; regi++)
+ if (! valid || valid[regi])
+ *(regp + regmap[regi]) = * (int *) ®isters[REGISTER_BYTE (regi)];
+}
+
+
+/* Store GDB's value for REGNO in *GREGSETP. If REGNO is -1, do all
+ of them. */
+void
+fill_gregset (gregset_t *gregsetp,
+ int regno)
+{
+ if (regno == -1)
+ convert_to_gregset (gregsetp, registers, 0);
+ else if (regno >= 0 && regno < NUM_GREGS)
+ {
+ signed char valid[NUM_GREGS];
+ memset (valid, 0, sizeof (valid));
+ valid[regno] = 1;
+ convert_to_gregset (gregsetp, registers, valid);
+ }
+}
+
+/* Given a pointer to a floating point register set in /proc format
+ (fpregset_t *), unpack the register contents and supply them as gdb's
+ idea of the current floating point register values. */
+
+/* What is the address of st(N) within the fpregset_t structure F? */
+#define FPREGSET_T_FPREG_ADDR(f, n) \
+ ((char *) &(f)->fpstate.fpregs + (n) * 10)
+
+/* Fill GDB's register file with the floating-point register values in
+ *FPREGSETP. */
+void
+supply_fpregset (fpregset_t *fpregsetp)
+{
+ int i;
+ long l;
+
+ /* Supply the floating-point registers. */
+ for (i = 0; i < 8; i++)
+ supply_register (FP0_REGNUM + i, FPREGSET_T_FPREG_ADDR (fpregsetp, i));
+
+ l = fpregsetp->fpstate.control & 0xffff;
+ supply_register (FCTRL_REGNUM, (char *) &l);
+ l = fpregsetp->fpstate.status & 0xffff;
+ supply_register (FSTAT_REGNUM, (char *) &l);
+ l = fpregsetp->fpstate.tag & 0xffff;
+ supply_register (FTAG_REGNUM, (char *) &l);
+ supply_register (FCOFF_REGNUM, (char *) &fpregsetp->fpstate.erroroffset);
+ l = fpregsetp->fpstate.dataselector & 0xffff;
+ supply_register (FDS_REGNUM, (char *) &l);
+ supply_register (FDOFF_REGNUM, (char *) &fpregsetp->fpstate.dataoffset);
+
+ /* Extract the code segment and opcode from the "fcs" member. */
+
+ l = fpregsetp->fpstate.errorselector & 0xffff;
+ supply_register (FCS_REGNUM, (char *) &l);
+
+ l = (fpregsetp->fpstate.errorselector >> 16) & ((1 << 11) - 1);
+ supply_register (FOP_REGNUM, (char *) &l);
+}
+
+
+/* Fill in an fpregset_t structure with selected data from a
+ gdb-format register file.
+ - FPREGSETP points to the structure to be filled.
+ - GDB_REGS points to the GDB-style register file providing the data.
+ - VALID is an array indicating which registers in GDB_REGS are
+ valid; the parts of *FPREGSETP that would hold registers marked
+ invalid in GDB_REGS are left unchanged. If VALID is zero, all
+ registers are assumed to be valid. */
+void
+convert_to_fpregset (fpregset_t *fpregsetp,
+ char *gdb_regs,
+ signed char *valid)
+{
+ int i;
+
+ /* Fill in the floating-point registers. */
+ for (i = 0; i < 8; i++)
+ if (!valid || valid[i])
+ memcpy (FPREGSET_T_FPREG_ADDR (fpregsetp, i),
+ ®isters[REGISTER_BYTE (FP0_REGNUM + i)],
+ REGISTER_RAW_SIZE(FP0_REGNUM + i));
+
+#define fill(MEMBER, REGNO) \
+ if (! valid || valid[(REGNO)]) \
+ memcpy (&fpregsetp->fpstate.MEMBER, ®isters[REGISTER_BYTE (REGNO)], \
+ sizeof (fpregsetp->fpstate.MEMBER))
+
+ fill (control, FCTRL_REGNUM);
+ fill (status, FSTAT_REGNUM);
+ fill (tag, FTAG_REGNUM);
+ fill (erroroffset, FCOFF_REGNUM);
+ fill (dataoffset, FDOFF_REGNUM);
+ fill (dataselector, FDS_REGNUM);
+
+#undef fill
+
+ if (! valid || valid[FCS_REGNUM])
+ fpregsetp->fpstate.errorselector
+ = ((fpregsetp->fpstate.errorselector & ~0xffff)
+ | (* (int *) ®isters[REGISTER_BYTE (FCS_REGNUM)] & 0xffff));
+
+ if (! valid || valid[FOP_REGNUM])
+ fpregsetp->fpstate.errorselector
+ = ((fpregsetp->fpstate.errorselector & 0xffff)
+ | ((*(int *) ®isters[REGISTER_BYTE (FOP_REGNUM)] & ((1 << 11) - 1))
+ << 16));
+}
+
+
+/* Given a pointer to a floating point register set in (fpregset_t *)
+ format, update all of the registers from gdb's idea of the current
+ floating point register set. */
+
+void
+fill_fpregset (fpregset_t *fpregsetp,
+ int regno)
+{
+ convert_to_fpregset (fpregsetp, registers, 0);
+}
+
+
+/* the name of the proc status struct depends on the implementation */
+#ifdef HAVE_PSTATUS_T
+ typedef pstatus_t gdb_prstatus_t;
+#else
+ typedef prstatus_t gdb_prstatus_t;
+#endif
+
+/* We want to find the previous frame, which on Interix is tricky when signals
+ are involved; set frame->frame appropriately, and also get the pc
+ and tweak signal_handler_caller; this replaces a boatload of nested
+ macros, as well. */
+void
+interix_back_one_frame (fromleaf, frame)
+ int fromleaf;
+ struct frame_info *frame;
+{
+ CORE_ADDR ra;
+ CORE_ADDR fm;
+ CORE_ADDR context;
+ long t;
+
+ if (frame == NULL)
+ abort();
+
+ if (fromleaf)
+ {
+ frame->pc = SAVED_PC_AFTER_CALL (frame->next);
+ return;
+ }
+
+ if (!frame->next)
+ {
+ frame->pc = read_pc();
+
+ /* part of the signal stuff... see below */
+ if (stopped_by_random_signal)
+ {
+ /* we know we're in a system call mini-frame; was it
+ NullApi or something else? */
+ ra = SAVED_PC_AFTER_CALL (frame);
+ if (ra >= null_start && ra < null_end)
+ frame->signal_handler_caller = 1;
+ }
+ return;
+ }
+
+ if (!frame->next->signal_handler_caller)
+ {
+ frame->pc = (CORE_ADDR)read_memory_integer (frame->next->frame + 4, 4);
+ return;
+ }
+
+ /* This is messy... (actually AWFUL) the "trampoline" might be 2, 3
+ or all 5 entities on the frame.
+
+ Chunk 1 will be present when we're actually in a signal handler.
+ Chunk 2 will be present when an asynchronous signal (one that
+ didn't come in with a system call) is present.
+ We may not (yet) be in the handler, if we're just returning
+ from the call.
+ When we're actually in a handler taken from an asynchronous
+ signal, both will be present.
+
+ Chunk 1:
+ PdxSignalDeliverer's frame
+ + Context struct -- not accounted for in any frame
+
+ Chunk 2:
+ + PdxNullPosixApi's frame
+ + PdxNullApiCaller's frame
+ + Context struct = 0x230 not accounted for in any frame
+
+ The symbol names come from examining objdumps of psxdll.dll;
+ they don't appear in the runtime image.
+
+ For gdb's purposes, we can pile all this into one frame.
+ */
+
+ ra = frame->next->pc;
+ /* Are we already pointing at PdxNullPosixApi? We are if
+ this is a signal frame, we're at next-to-top, and were stopped
+ by a random signal. (If it wasn't the right address under
+ these circumstances, we wouldn't be here at all by tests above
+ on the prior frame.) */
+ if (frame->next->next == NULL && stopped_by_random_signal)
+ {
+ /* We're pointing at the frame FOR PdxNullApi */
+ fm = frame->frame;
+ }
+ else
+ {
+ /* No... we must be pointing at the frame that
+ was called by PdxSignalDeliverer; back up across the
+ whole mess */
+
+ /* extract the frame for PdxSignalDeliverer; note...FRAME_CHAIN
+ used the "old" frame pointer because we were a deliverer.
+ Get the address of the context record that's on here frameless */
+ context = read_memory_integer (frame->frame, 4); /* an Arg */
+
+ /* Now extract the frame pointer contained in the context */
+ fm = (CORE_ADDR)read_memory_integer
+ (context + offsetof(mcontext_t, gregs.gregs[EBP]), 4);
+
+ ra = (CORE_ADDR)read_memory_integer
+ (context + offsetof(mcontext_t, gregs.gregs[EIP]), 4);
+
+ /* We need to know if we're in a system call because we'll be
+ in a syscall mini-frame, if so, and the rules are different;
+ reserved[1] contains 0 if running free, 1 if blocked on a system
+ call, and 2 if blocked on an exception message (e.g. a trap);
+ we don't expect to get here with a 2. */
+ t = (long)read_memory_integer
+ (context + offsetof(mcontext_t, gregs.reserved[1]), 4);
+ if (t != 1)
+ {
+ /* not at a system call, therefore it can't be NullApi */
+ frame->pc = ra;
+ frame->frame = fm;
+ return;
+ }
+
+ /* It's a system call... mini frame, then look for NullApi */
+ /* Get the RA (on the stack) associated with this... it's
+ a system call mini-frame */
+ ra = (CORE_ADDR)read_memory_integer
+ (context + offsetof(mcontext_t, gregs.gregs[UESP]), 4);
+ ra = (CORE_ADDR)read_memory_integer(ra,4);
+
+ /* We might be done (no Null API if so) */
+ if (!(ra >= null_start && ra < null_end))
+ {
+ /* No Null API present; we're done */
+ frame->pc = ra;
+ frame->frame = fm;
+ return;
+ }
+ }
+ /* At this point, we're looking at the frame for PdxNullPosixApi,
+ in either case. */
+
+ /* extract the frame for PdxNullPosixApi */
+ fm = read_memory_integer (fm, 4);
+
+ /* extract the frame for PdxNullApiCaller */
+ /* The saved frame register for PdxNullApiCaller skips us over the
+ saved context, which is the wrong thing to do, because it skips
+ the interrrupted routine! Instead, get the arg that was passed
+ which has the address of the context (which is really in no frame) */
+
+ fm = (CORE_ADDR)read_memory_integer (fm + 8, 4);
+
+ /* THIS context is accounted for in a frame */
+ /* Extract the second context record */
+
+ ra = (CORE_ADDR)read_memory_integer
+ (fm + offsetof(mcontext_t, gregs.gregs[EIP]), 4);
+ fm = (CORE_ADDR)read_memory_integer
+ (fm + offsetof(mcontext_t, gregs.gregs[EBP]), 4);
+
+ frame->frame = fm;
+ frame->pc = ra;
+
+ return;
+}
+
+/* Figure out where the longjmp will land.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc that we will land at. The pc is copied into PC.
+ This routine returns true on success. */
+
+#include <setjmp.h>
+
+int
+get_longjmp_target (pc)
+ CORE_ADDR *pc;
+{
+ CORE_ADDR sp, jb_addr;
+ char raw_buffer[MAX_REGISTER_RAW_SIZE];
+
+ sp = read_register (SP_REGNUM);
+
+ if (target_read_memory (sp + SP_ARG0, /* Offset of first arg on stack */
+ raw_buffer,
+ TARGET_PTR_BIT / TARGET_CHAR_BIT))
+ return 0;
+
+ jb_addr = extract_address (raw_buffer, TARGET_PTR_BIT / TARGET_CHAR_BIT);
+
+ if (target_read_memory(jb_addr + offsetof(_JUMP_BUFFER,Eip), raw_buffer,
+ sizeof(CORE_ADDR)))
+ return 0;
+
+ *pc = extract_address (raw_buffer, sizeof(CORE_ADDR));
+ return 1;
+}
Index: src/gdb/config/i386/interix.mh
===================================================================
RCS file: interix.mh
diff -N interix.mh
--- /dev/null Sun Dec 23 12:45:15 2001
+++ src/gdb/config/i386/interix.mh Sun Dec 23 12:34:46 2001
@@ -0,0 +1,9 @@
+# Host: Intel 386 running Interix
+XDEPFILES=
+NATDEPFILES= corelow.o core-regset.o fork-child.o i386interix-nat.o \
+ procfs.o proc-api.o proc-events.o proc-flags.o proc-why.o
+XM_FILE= xm-interix.h
+NAT_FILE= nm-interix.h
+# The below may be temporary; mmalloc relies on sbrk() at the moment
+MMALLOC=
+MMALLOC_CFLAGS=-DNO_MMALLOC
Index: src/gdb/config/i386/interix.mt
===================================================================
RCS file: interix.mt
diff -N interix.mt
--- /dev/null Sun Dec 23 12:45:17 2001
+++ src/gdb/config/i386/interix.mt Sun Dec 23 12:34:46 2001
@@ -0,0 +1,3 @@
+# Target: Intel 386 running Interix
+TDEPFILES= i386-tdep.o i387-tdep.o
+TM_FILE= tm-i386interix.h
Index: src/gdb/config/i386/nm-interix.h
===================================================================
RCS file: nm-interix.h
diff -N nm-interix.h
--- /dev/null Sun Dec 23 12:45:17 2001
+++ src/gdb/config/i386/nm-interix.h Sun Dec 23 12:34:46 2001
@@ -0,0 +1,58 @@
+/* Native-dependent definitions for Intel 386 running Interix, for GDB.
+ Copyright 1986, 1987, 1989, 1992, 1996 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef NM_INTERIX_H
+#define NM_INTERIX_H
+
+#define USE_PROC_FS
+
+/* submodes of USE_PROC_FS */
+#define PROCFS_USE_READ_WRITE
+#define HAVE_MULTIPLE_PROC_FDS
+#define UNIXWARE
+#define HAVE_STRUCT_LWP
+
+#define ATTACH_DETACH
+
+/* This is the amount to subtract from u.u_ar0
+ to get the offset in the core file of the register values. */
+
+#if 0
+#include <machine/vmparam.h>
+#define KERNEL_U_ADDR USRSTACK
+#endif
+
+#define REGISTER_U_ADDR(addr, blockend, regno) \
+ (addr) = i386_register_u_addr ((blockend),(regno));
+
+extern int
+i386_register_u_addr PARAMS ((int, int));
+
+#define PTRACE_ARG3_TYPE char*
+
+/* Return sizeof user struct to callers in less machine dependent routines */
+
+#define KERNEL_U_SIZE kernel_u_size()
+extern int kernel_u_size PARAMS ((void));
+
+/* It's ALMOST coff; bfd does the same thing */
+#define COFF_WITH_PE
+#define COFF_IMAGE_WITH_PE
+
+#endif /* NM_INTERIX_H */
Index: src/gdb/config/i386/tm-i386interix.h
===================================================================
RCS file: tm-i386interix.h
diff -N tm-i386interix.h
--- /dev/null Sun Dec 23 12:45:17 2001
+++ src/gdb/config/i386/tm-i386interix.h Sun Dec 23 12:34:46 2001
@@ -0,0 +1,127 @@
+/* Macro definitions for i386 running under Interix
+ Copyright 1998 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef TM_INTERIX_H
+#define TM_INTERIX_H
+
+#define HAVE_I387_REGS
+#include "i386/tm-i386.h"
+
+#undef TARGET_LONG_BIT
+#define TARGET_LONG_BIT 32
+
+/* this is a no-op change, but for the record... */
+#undef TARGET_LONG_LONG_BIT
+#define TARGET_LONG_LONG_BIT 64
+
+/* configure can't be expected to noodle out MS's alternate spelling for
+ 64-bit integers, so we'll tell it. */
+#define PRINTF_HAS_LONG_LONG 1
+#ifdef __GNUC__
+#define BFD_HOST_64_BIT long long
+#define BFD_HOST_U_64_BIT unsigned long long
+#elif defined(_MSC_VER)
+#define BFD_HOST_64_BIT __int64
+#define BFD_HOST_U_64_BIT unsigned __int64
+#else
+#error... OK what compiler is this?
+#endif
+
+#undef LONGEST
+#undef ULONGEST
+
+#define LONGEST BFD_HOST_64_BIT
+#define ULONGEST BFD_HOST_U_64_BIT
+
+#undef TARGET_PTR_BIT
+#define TARGET_PTR_BIT 32
+
+/* Amount PC must be decremented by after a breakpoint. This is often the
+ number of bytes in BREAKPOINT but not always (such as now). */
+
+
+#undef DECR_PC_AFTER_BREAK
+#define DECR_PC_AFTER_BREAK 0
+
+#undef IN_SIGTRAMP
+/* SIGTRAMP is in a DLL where we don't have any symbols. However,
+ procfs tells us where it is. */
+
+extern CORE_ADDR tramp_start;
+extern CORE_ADDR tramp_end;
+extern CORE_ADDR null_start;
+extern CORE_ADDR null_end;
+
+/* This is sufficient, where used, but is NOT a complete test; there's more
+ in INIT_EXTRA_FRAME_INFO (a.k.a. interix_back_one_frame) */
+#define IN_SIGTRAMP(p,f) ((((p)>=tramp_start && (p)<tramp_end)) \
+ || (((p)>=null_start && (p)<null_end)))
+
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) skip_trampoline_code (pc, name)
+#define SKIP_TRAMPOLINE_CODE(pc) skip_trampoline_code (pc, 0)
+extern CORE_ADDR skip_trampoline_code PARAMS ((CORE_ADDR pc, char *name));
+
+void interix_back_one_frame (int fromleaf, struct frame_info *frame);
+/* Actually... do a full unwind */
+#define INIT_EXTRA_FRAME_INFO(fromleaf, prev) \
+ interix_back_one_frame(fromleaf, prev);
+
+/* This becomes a no-op because of the above */
+#define INIT_FRAME_PC(a,b)
+
+/* In the context where this is used, we get the saved PC before we've
+ successfully unwound far enough to be sure what we've got (it may
+ be a signal handler caller). If we're dealing with a signal
+ handler caller, this will return valid, which is fine. If not,
+ it'll make the correct test. */
+
+#undef FRAME_CHAIN_VALID
+#define FRAME_CHAIN_VALID(CHAIN, FRAME) \
+ ((FRAME)->signal_handler_caller ||\
+ ((CHAIN) != 0 \
+ && !inside_entry_file (read_memory_integer ((FRAME)->frame + 4, 4))))
+
+/* Assume that we've already unwound enough to have the caller's address
+ if we're dealing with a signal handler caller. (And if that fails,
+ return 0.) */
+#undef FRAME_SAVED_PC
+#define FRAME_SAVED_PC(FRAME) \
+ (((FRAME)->signal_handler_caller) \
+ ? ((FRAME)->next ? (FRAME)->next->pc : 0) \
+ : (CORE_ADDR)read_memory_integer ((FRAME)->frame + 4, 4))
+
+#define I386_FLOATS_RETURN_IN_ST0
+
+/* Interix has a minimal sbrk() (but not what's wanted for this usage),
+ and it's relationship to environ[] is not what's usually expected
+ (as in, there is no specific relationship at all). Just pretend we don't
+ have an sbrk(). */
+#undef HAVE_SBRK
+
+/* Figure out where the longjmp will land. Slurp the args out of the stack.
+ We expect the first arg to be a pointer to the jmp_buf structure from which
+ we extract the pc that we will land at. The pc is copied into ADDR.
+ This routine returns true on success */
+
+extern int
+get_longjmp_target PARAMS ((CORE_ADDR *));
+
+#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+
+#endif /* TM_INTERIX_H */
Index: src/gdb/config/i386/xm-interix.h
===================================================================
RCS file: xm-interix.h
diff -N xm-interix.h
--- /dev/null Sun Dec 23 12:45:17 2001
+++ src/gdb/config/i386/xm-interix.h Sun Dec 23 12:34:46 2001
@@ -0,0 +1,22 @@
+/* Host-dependent definitions for Intel 386 running Interix, for GDB.
+ Copyright 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#define HOST_BYTE_ORDER LITTLE_ENDIAN
+
+#include <limits.h> /* for INT_MIN */
---------------------------------------------------------------------------
TEXT MOSTLY WRONG... rewrite when done
Look for // comments.
/proc docs are somewhat ambiguous in defintion of the command word;
in the case of getting/sending registers, on the Alpha the gregset_t
struct will be 64-bit aligned, so there will be a 32-bit pad
between cmd and gregset in greg_ctl. However, the kernel wasn't
expecing that pad. Adjust to avoid the issue portably. (Applies
to fpreg_ctl too.)
The signal trampoline
is not in the symbol table, but the OS knows where it is.
/proc modified to return the address range, create_procinfo to
capture the values. i386interix-nat.c moded to hold the values.
tm-i386interix.h moded to use new globals. *interix-nat.c also uses.
procfs.c/close_proc_file: open_proc_file can be called with
"control" == 0 which causes pip->ctl_fd to not be opened (and
thus be zero). This was unconditionally closing it, which
actually closed stdin.
procfs.c/proc_set_exec_trap: why did we just clear PR_FORK and set
it again? Causes the gdb "shell" command to hang up.
testsuite/gdb.base/info-proc.exp was failing because offset was always
zero, and $#X returns 0, not 0x0!
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* procfs.c(procfs_kill_inferior, proc_set_exec_trap,
procfs_prepare_to_store,procfs_mourn_inferior,
procfs_can_run, procfs_stop): explicit void to shut up some compilers.
* procfs.c(global, proc_set_exec_trap, proc_interate_over_mappings,
do_attach, do_detach, set_proc_siginfo, procfs_resume,
procfs_fetch_registers, info_proc_syscalls, info_proc_signals,
info_proc_faults): clarify use of PROCFS_USE_READ_WRITE,
untangle from UNIXWARE
* procfs.c(???): Ditto HAVE_NO_PRRUN_T, HAVE_STRUCT_LWP
* procfs.c(procfs_to_fd): Not needed if PROCFS_USE_READ_WRITE.
* procfs.c(???): Add PROCFS_USE_READ_WRITE cases where needed (some were
missing or incomplete).
* procfs.c(wait_fd): fix bug in LOSING_POLL case.
* procfs.c(global, procfs_store_registers): allow for 64 bit alignment.
* procfs.c(procfs_read_current_status): New. (PART OF FP PACK!)
* procfs.c(procfs_kill_inferior): Better diagnostics in case of
unexpected failure.
* procfs.c(create_procinfo): Report address of signal trampoline
for Interix.
* procfs.c(procfs_init_inferior): ??? See trap?
* procfs.c(procfs_init_inferior): Reflect new counting rules
for synchronizer. (Goes with something else.)
* procfs.c(procfs_find_allocation_base): New.
* procfs.c(procfs_wait): Assure pi is NULL at start, gets
initialized.
* procfs.c(close_proc_file, open_proc_file): close only files
we opened.
* procfs.c(proc_set_exec_trap): fix clear/set of PR_FORK.
* procfs.c (modify_run_on_last_close_flag): Why RLC? ??????
* procfs.c (procfs_clear_syscall_trap, procfs_set_syscall_trap):
Tighter use of types.
Better diagnostics for procfs_xfer_memory()
Remove redundant open of procfs map file.
Index: src/gdb/proc-api.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/proc-api.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 proc-api.c
--- src/gdb/proc-api.c 2001/12/23 00:34:52 1.1.1.1
+++ src/gdb/proc-api.c 2001/12/23 21:21:16
@@ -36,7 +36,9 @@ Inc., 59 Temple Place - Suite 330, Bosto
#include <stdio.h>
#include <sys/types.h>
#include <sys/procfs.h>
+#ifndef __INTERIX
#include <sys/proc.h> /* for struct proc */
+#endif
#ifdef HAVE_SYS_USER_H
#include <sys/user.h> /* for struct user */
#endif
@@ -395,9 +397,13 @@ static struct trans rw_table[] = {
#ifdef PCCSIG /* solaris */
{ PCCSIG, "PCCSIG", "clear current signal" },
#endif
+#ifdef PCDSTOP /* solaris */
{ PCDSTOP, "PCDSTOP", "post stop request" },
+#endif
{ PCKILL, "PCKILL", "post a signal" },
+#ifdef PCNICE /* solaris */
{ PCNICE, "PCNICE", "set nice priority" },
+#endif
#ifdef PCREAD /* solaris */
{ PCREAD, "PCREAD", "read from the address space" },
{ PCWRITE, "PCWRITE", "write to the address space" },
@@ -417,7 +423,9 @@ static struct trans rw_table[] = {
{ PCSEXIT, "PCSEXIT", "set traced syscall exit set" },
{ PCSFAULT, "PCSFAULT", "set traced fault set" },
{ PCSFPREG, "PCSFPREG", "set floating point registers" },
+#ifdef PCHOLD /* solaris */
{ PCSHOLD, "PCSHOLD", "set signal mask" },
+#endif
{ PCSREG, "PCSREG", "set general registers" },
{ PCSSIG, "PCSSIG", "set current signal" },
{ PCSTOP, "PCSTOP", "post stop request and wait" },
@@ -431,7 +439,9 @@ static struct trans rw_table[] = {
#ifdef PCTWSTOP /* solaris */
{ PCTWSTOP, "PCTWSTOP", "wait for stop, with timeout arg" },
#endif
+#ifdef PCUNKILL /* solaris */
{ PCUNKILL, "PCUNKILL", "delete a pending signal" },
+#endif
#ifdef PCUNSET /* solaris */
{ PCUNSET, "PCUNSET", "unset modes" },
#endif
@@ -516,12 +526,14 @@ write_with_trace (int fd, void *varg, si
proc_prettyfprint_syscalls (procfs_file ? procfs_file : stdout,
(sysset_t *) &arg[1], 0);
break;
+#ifdef PCSHOLD
case PCSHOLD:
fprintf (procfs_file ? procfs_file : stdout,
"write (PCSHOLD) ");
proc_prettyfprint_signalset (procfs_file ? procfs_file : stdout,
(sigset_t *) &arg[1], 0);
break;
+#endif
case PCSSIG:
fprintf (procfs_file ? procfs_file : stdout,
"write (PCSSIG) ");
@@ -540,10 +552,14 @@ write_with_trace (int fd, void *varg, si
fprintf (procfs_file ? procfs_file : stdout, "clearFlt ");
if (arg[1] & PRSTEP)
fprintf (procfs_file ? procfs_file : stdout, "step ");
+#ifdef PRSABORT
if (arg[1] & PRSABORT)
fprintf (procfs_file ? procfs_file : stdout, "syscallAbort ");
+#endif
+#ifdef PRSTOP
if (arg[1] & PRSTOP)
fprintf (procfs_file ? procfs_file : stdout, "stopReq ");
+#endif
fprintf (procfs_file ? procfs_file : stdout, "\n");
break;
Index: src/gdb/procfs.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/procfs.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 procfs.c
--- procfs.c.old Sat Mar 2 10:33:42 2002
+++ procfs.c Thu Feb 28 15:42:51 2002
@@ -518,7 +518,7 @@ open_procinfo_files (procinfo *pi, int w
* This function is getting ALMOST long enough to break up into several.
* Here is some rationale:
*
- * NEW_PROC_API (Solaris 2.6, Solaris 2.7, Unixware):
+ * NEW_PROC_API (Solaris 2.6, Solaris 2.7, Unixware, Interix):
* There are several file descriptors that may need to be open
* for any given process or LWP. The ones we're intereted in are:
* - control (ctl) write-only change the state
@@ -533,7 +533,7 @@ open_procinfo_files (procinfo *pi, int w
* /proc/<proc-id>/status
* /proc/<proc-id>/as
* /proc/<proc-id>/map
- * Pathnames for an LWP (lwp-id):
+ * Pathnames for an LWP (lwp-id) (not on Interix):
* /proc/<proc-id>/lwp/<lwp-id>/lwpctl
* /proc/<proc-id>/lwp/<lwp-id>/lwpstatus
* An LWP has no map or address space file descriptor, since
@@ -665,8 +665,8 @@ open_procinfo_files (procinfo *pi, int w
static procinfo *
create_procinfo (int pid, int tid)
{
- procinfo *pi, *parent;
-
+ procinfo *pi, *parent = NULL;
+
if ((pi = find_procinfo (pid, tid)))
return pi; /* Already exists, nothing to do. */
@@ -1132,6 +1132,20 @@ proc_get_status (procinfo *pi)
sizeof (gdb_prstatus_t))
== sizeof (gdb_prstatus_t));
#endif /* UNIXWARE */
+
+#ifdef __INTERIX
+ /* On Interix, the location of the trampoline code can float, and it's
+ not part of the symbol table (because it's internal to a DLL).
+ However, the system knows where it is, and tells us, so we capture
+ that info here. */
+// THIS MAY NOT BE THE BEST PLACE to read
+// IT MAY BE BEST TO MAKE THESE FIELDS PER-PROC
+ tramp_start = (CORE_ADDR)pi->prstatus.pr_signaldeliverer;
+ tramp_end = (CORE_ADDR)pi->prstatus.pr_endsignaldeliverer;
+ null_start = (CORE_ADDR)pi->prstatus.pr_nullapi;
+ null_end = (CORE_ADDR)pi->prstatus.pr_endnullapi;
+#endif
+
}
}
#else /* ioctl method */
@@ -1252,7 +1266,8 @@ proc_what (procinfo *pi)
#endif
}
-#ifndef PIOCSSPCACT /* The following is not supported on OSF. */
+#if !defined(PIOCSSPCACT) && !defined(__INTERIX)
+/* The following is not supported on OSF. Or Interix. */
/*
* Function: proc_nsysarg
*
@@ -1960,8 +1975,8 @@ proc_set_traced_sysexit (procinfo *pi, s
int
proc_set_held_signals (procinfo *pi, gdb_sigset_t *sighold)
{
- int win;
-
+ int win = 1; /* No PCSHOLD == No LWPs; just succeed. */
+
/*
* We should never have to apply this operation to any procinfo
* except the one for the main process. If that ever changes
@@ -1973,7 +1988,8 @@ proc_set_held_signals (procinfo *pi, gdb
pi = find_procinfo_or_die (pi->pid, 0);
#ifdef NEW_PROC_API
+#ifdef PCSHOLD
{
struct {
procfs_ctl_t cmd;
/* Use char array to avoid alignment issues. */
@@ -1984,6 +2001,7 @@ proc_set_held_signals (procinfo *pi, gdb
memcpy (&arg.hold, sighold, sizeof (gdb_sigset_t));
win = (write (pi->ctl_fd, (void *) &arg, sizeof (arg)) == sizeof (arg));
}
+#endif
#else
win = (ioctl (pi->ctl_fd, PIOCSHOLD, sighold) >= 0);
#endif
@@ -2798,7 +2816,13 @@ proc_kill (procinfo *pi, int signo)
cmd[0] = PCKILL;
cmd[1] = signo;
+#ifdef __INTERIX
+ /* Work around system bug; for now. */
+ write (pi->ctl_fd, (char *) &cmd, sizeof (cmd));
+ win = 1;
+#else
win = (write (pi->ctl_fd, (char *) &cmd, sizeof (cmd)) == sizeof (cmd));
+#endif
#else /* ioctl method */
/* FIXME: do I need the Alpha OSF fixups present in
procfs.c/unconditionally_kill_inferior? Perhaps only for SIGKILL? */
@@ -2880,6 +2904,53 @@ proc_set_watchpoint (procinfo *pi, CORE_
#endif
}
+// NEEDS REINTERFACE
+#ifdef __INTERIX
+/* Find the allocation base (an NT concept) containing the address */
+CORE_ADDR
+proc_allocation_base(CORE_ADDR addr)
+{
+ int nmap;
+ prmap_t *prmaps;
+ prmap_t *prmap;
+ struct procinfo *pi;
+ struct stat sbuf;
+ char pathname[MAX_PROC_NAME_SIZE];
+ int map_fd;
+
+ pi = find_procinfo_or_die (PIDGET (inferior_ptid), 0);
+
+ /* Open map fd. */
+ sprintf (pathname, "/proc/%d/map", pi->pid);
+ if ((map_fd = open (pathname, O_RDONLY)) < 0)
+ proc_error (pi, "proc_iterate_over_mappings (open)", __LINE__);
+
+ /* Make sure it gets closed again. */
+ make_cleanup_close (map_fd);
+
+ if (fstat (map_fd, &sbuf) < 0)
+ return 0;
+
+ nmap = sbuf.st_size / sizeof (prmap_t);
+ prmaps = (prmap_t *) alloca (nmap * sizeof(prmap_t));
+ if ((lseek (map_fd, 0, SEEK_SET) == 0) &&
+ (read (map_fd, (char *) prmaps, nmap * sizeof (prmap_t)) ==
+ (nmap * sizeof (prmap_t))))
+ {
+ int i = 0;
+ for (prmap = prmaps; i < nmap; ++prmap, ++i)
+ {
+ if (((CORE_ADDR)prmap->pr_vaddr <= addr) &&
+ ((CORE_ADDR)prmap->pr_vaddr + prmap->pr_size > addr))
+ {
+ return (CORE_ADDR)prmap->AllocationBase;
+ }
+ }
+ }
+ return (CORE_ADDR)-1;
+}
+#endif /* __INTERIX */
+
#ifdef TM_I386SOL2_H /* Is it hokey to use this? */
#include <sys/sysi86.h>
@@ -3993,7 +4064,7 @@ wait_again:
printf_filtered ("procfs: trapped on entry to ");
proc_prettyprint_syscall (proc_what (pi), 0);
printf_filtered ("\n");
-#ifndef PIOCSSPCACT
+#if !defined(PIOCSSPCACT) && !defined(__INTERIX)
{
long i, nsysargs, *sysargs;
@@ -4081,7 +4152,7 @@ wait_again:
printf_filtered ("procfs: trapped on exit from ");
proc_prettyprint_syscall (proc_what (pi), 0);
printf_filtered ("\n");
-#ifndef PIOCSSPCACT
+#if !defined(PIOCSSPCACT) && !defined(__INTERIX)
{
long i, nsysargs, *sysargs;
@@ -4277,15 +4348,21 @@ procfs_xfer_memory (CORE_ADDR memaddr, c
PROCFS_NOTE ("write memory: \n");
#endif
nbytes = write (pi->as_fd, myaddr, len);
+ if (nbytes < 0)
+ {
+ perror("procfs write of memory:");
+ nbytes = 0;
+ }
}
else
{
PROCFS_NOTE ("read memory: \n");
nbytes = read (pi->as_fd, myaddr, len);
- }
- if (nbytes < 0)
- {
- nbytes = 0;
+ if (nbytes < 0)
+ {
+ perror("procfs read of memory:");
+ nbytes = 0;
+ }
}
}
return nbytes;
@@ -5722,7 +5799,7 @@ procfs_first_available (void)
}
/* =================== GCORE .NOTE "MODULE" =================== */
-#if defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT)
+#if (defined (UNIXWARE) || defined (PIOCOPENLWP) || defined (PCAGENT)) && !defined(__INTERIX)
/* gcore only implemented on solaris and unixware (so far) */
static char *
diff -drupP --exclude-from=/M/donn/diffs/exclude.files gdb.saved/testsuite/gdb.base/info-proc.exp gdb/testsuite/gdb.base/info-proc.exp
--- src/gdb.saved/testsuite/gdb.base/info-proc.exp Tue Mar 5 14:56:06 2002
+++ src/gdb/testsuite/gdb.base/info-proc.exp Tue Mar 5 20:53:44 2002
@@ -71,5 +71,5 @@ if { ! [ runto main ] } then {
gdb_test "info proc" "process ${decimal}.*" "info proc with process"
gdb_test "info proc mapping" \
- ".*Mapped address spaces:.*${hex}${ws}${hex}${ws}${hex}${ws}${hex}.*" \
+ ".*Mapped address spaces:.*${hex}${ws}${hex}${ws}${hex}${ws}\(${hex}|0\).*" \
"info proc mapping"
---------------------------------------------------------------------------
Miscellanous small changes specific to Interix.
There might be a better way to determine that there is an
overriding function for get_longjmp_target.
poll() is present but not fully functional on Interix.
The poll test really belongs in configure, but lacking
that it probably belongs in the manually configured
header files. (Something along the lines of
(for the default):
#ifdef HAVE_POLL
#define USE_POLL_ON_PROC
#define USE_POLL_ON_TTY
#else
#undef USE_POLL_ON_PROC
#undef USE_POLL_ON_TTY
#endif
For special cases (using mine as an example):
#undef USE_POLL_ON_TTY
#undef USE_POLL_ON_PROC // Just for error prevention
#define USE_POLL_ON_PROC
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* top.c(use_windows): default is to not use on Interix.
* defs.h(HAVE_POLL): override for Interix.
Index: src/gdb/defs.h
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/defs.h,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 defs.h
--- src/gdb/defs.h 2001/12/23 00:34:45 1.1.1.1
+++ src/gdb/defs.h 2001/12/23 22:58:13
@@ -39,6 +39,11 @@
#include <unistd.h>
#endif
+#ifdef __INTERIX
+#undef HAVE_POLL /* Only partially implemented so far */
+#undef HAVE_VFORK /* Only partially implemented so far */ // CHECK
+#endif
+
/* Just in case they're not defined in stdio.h. */
#ifndef SEEK_SET
Index: src/gdb/top.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/top.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 top.c
--- src/gdb/top.c 2001/12/23 00:34:56 1.1.1.1
+++ src/gdb/top.c 2001/12/23 22:58:13
@@ -81,7 +81,11 @@ int inhibit_gdbinit = 0;
/* If nonzero, and GDB has been configured to be able to use windows,
attempt to open them upon startup. */
+#ifdef __INTERIX
+int use_windows = 0;
+#else
int use_windows = 1;
+#endif
extern char lang_frame_mismatch_warn[]; /* language.c */
---------------------------------------------------------------------------
Miscellaneous small fixes that are generally applicable.
TEST_GDB variable allows retargeting of tests.
MSVC 4.0 (MSC 10.0) still doesn't handle unsigned __int64.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* testsuite/gdb.base/selftest.exp: honor TEST_GDB var.
* event-top.c (command_handler): Missed test for sbrk();
if maint space not implemented say something.
* gdb.base/maint.exp: To match above.
Index: src/gdb/event-top.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/event-top.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 event-top.c
--- src/gdb/event-top.c 2001/12/23 00:34:46 1.1.1.1
+++ src/gdb/event-top.c 2001/12/23 23:04:31
@@ -523,7 +523,9 @@ command_handler (char *command)
arg1->next = arg2;
arg2->next = NULL;
arg1->data.integer = time_at_cmd_start;
+#ifdef HAVE_SBRK
arg2->data.integer = space_at_cmd_start;
+#endif
add_continuation (command_line_handler_continuation, arg1);
}
@@ -555,6 +557,8 @@ command_handler (char *command)
space_now,
(space_diff >= 0 ? '+' : '-'),
space_diff);
+#else
+ printf_unfiltered ("Space used: <unimplemented> (+<unimplemented> for this command)\n");
#endif
}
}
Index: src/gdb/testsuite/gdb.base/maint.exp
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/maint.exp,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 maint.exp
--- src/gdb/testsuite/gdb.base/maint.exp 2001/12/23 00:35:17 1.1.1.1
+++ src/gdb/testsuite/gdb.base/maint.exp 2001/12/23 23:04:31
@@ -119,9 +119,11 @@ gdb_expect {
timeout { fail "(timeout) maint space" }
}
+set decOrUnimp ($decimal|<unimplemented>)
+
send_gdb "maint space 1\n"
gdb_expect {
- -re "Space used: $decimal \\(\\+$decimal for this command\\).*$gdb_prompt $"\
+ -re "Space used: $decOrUnimp \\(\\+$decOrUnimp for this command\\).*$gdb_prompt $"\
{ pass "maint space 1" }
-re ".*$gdb_prompt $" { fail "maint space 1" }
timeout { fail "(timeout) maint space 1" }
@@ -130,7 +132,7 @@ gdb_expect {
send_gdb "maint time\n"
gdb_expect {
- -re "\"maintenance time\" takes a numeric argument\\..*Space used: $decimal \\(\\+$decimal for this command\\).*$gdb_prompt $"\
+ -re "\"maintenance time\" takes a numeric argument\\..*Space used: $decOrUnimp \\(\\+$decOrUnimp for this command\\).*$gdb_prompt $"\
{ pass "maint time" }
-re ".*$gdb_prompt $" { fail "maint time" }
timeout { fail "(timeout) maint time" }
@@ -138,7 +140,7 @@ gdb_expect {
send_gdb "maint time 1\n"
gdb_expect {
- -re "Command execution time: $decimal.*Space used: $decimal \\(\\+$decimal for this command\\).*$gdb_prompt $"\
+ -re "Command execution time: $decimal.*Space used: $decOrUnimp \\(\\+$decOrUnimp for this command\\).*$gdb_prompt $"\
{ pass "maint time 1" }
-re ".*$gdb_prompt $" { fail "maint time 1" }
timeout { fail "(timeout) maint time 1" }
@@ -146,7 +148,7 @@ gdb_expect {
send_gdb "maint time 0\n"
gdb_expect {
- -re "Space used: $decimal \\(\\+$decimal for this command\\).*$gdb_prompt $"\
+ -re "Space used: $decOrUnimp \\(\\+$decOrUnimp for this command\\).*$gdb_prompt $"\
{ pass "maint time 0" }
-re ".*$gdb_prompt $" { fail "maint time 0" }
timeout { fail "(timeout) maint time 0" }
Index: src/gdb/testsuite/gdb.base/selftest.exp
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/selftest.exp,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 selftest.exp
--- src/gdb/testsuite/gdb.base/selftest.exp 2001/12/23 00:35:18 1.1.1.1
+++ src/gdb/testsuite/gdb.base/selftest.exp 2001/12/23 23:04:31
@@ -435,7 +435,13 @@ set GDB_FULLPATH [find_gdb $GDB]
remote_file host delete x$tool
gdb_start
-set file [remote_download host $GDB_FULLPATH x$tool]
+
+global TEST_GDB
+if [info exists TEST_GDB] {
+ set file $TEST_GDB
+} else {
+ set file [remote_download host $GDB_FULLPATH x$tool]
+}
set result [test_with_self $file];
gdb_exit;
catch "remote_file host delete $file";
---------------------------------------------------------------------------
On Interix (and on PE systems in general, when PE is fully supported)
the value of ImageBase is in principle variable. This patch applies
the value of ImageBase in the right places and reports it as required.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* coffread.c (coff_symfile_read): Apply Image Base
* exec.c (print_section_info): Print entry point with ImageBase.
* maint.c (maintenance_info_sections): Print ImageBase.
* symfile.c (init_entry_point): Apply ImageBase.
Index: src/gdb/coffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/coffread.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 coffread.c
--- src/gdb/coffread.c 2001/12/23 00:34:43 1.1.1.1
+++ src/gdb/coffread.c 2001/12/23 23:17:03
@@ -47,6 +47,14 @@
extern void _initialize_coffread (void);
+#ifndef ADJUST_OBJFILE_OFFSETS
+#define ADJUST_OBJFILE_OFFSETS(objfile, type) \
+ gnu_pei_adjust_objfile_offsets(objfile, type)
+#endif
+
+/* This little tapdance gives us a declaration. Until this is more
+ pervasive, the enum isn't in scope at the right time. */
+void ADJUST_OBJFILE_OFFSETS(struct objfile *, enum objfile_adjusts);
struct coff_symfile_info
{
file_ptr min_lineno_offset; /* Where in file lowest line#s are */
@@ -347,25 +355,6 @@ cs_to_section (struct coff_symbol *cs, s
return off;
}
-/* Return the address of the section of a COFF symbol. */
-
-static CORE_ADDR cs_section_address (struct coff_symbol *, bfd *);
-
-static CORE_ADDR
-cs_section_address (struct coff_symbol *cs, bfd *abfd)
-{
- asection *sect = NULL;
- struct find_targ_sec_arg args;
- CORE_ADDR addr = 0;
-
- args.targ_index = cs->c_secnum;
- args.resultp = §
- bfd_map_over_sections (abfd, find_targ_sec, &args);
- if (sect != NULL)
- addr = bfd_get_section_vma (objfile->obfd, sect);
- return addr;
-}
-
/* Look up a coff type-number index. Return the address of the slot
where the type for that index is stored.
The type-number is in INDEX.
@@ -646,8 +635,16 @@ coff_symfile_read (struct objfile *objfi
/* Now that the executable file is positioned at symbol table,
process it and define symbols accordingly. */
+ /* Some implementations (e.g. PE) have their symbols stored as
+ relative to some base other than zero. Adjust the offset
+ array to compensate. (And then put things back like we found
+ them.) (Doing this here saves lots of execution time while
+ reading the symbols, because it's automatic.) */
+
+ ADJUST_OBJFILE_OFFSETS(objfile, adjust_for_symtab);
coff_symtab_read ((long) symtab_offset, num_symbols, objfile);
-
+ ADJUST_OBJFILE_OFFSETS(objfile, adjust_for_symtab_restore);
+
/* Sort symbols alphabetically within each block. */
{
@@ -680,16 +677,21 @@ coff_symfile_read (struct objfile *objfi
stabstrsize = bfd_section_size (abfd, info->stabstrsect);
+ ADJUST_OBJFILE_OFFSETS(objfile, adjust_for_stabs);
coffstab_build_psymtabs (objfile,
mainline,
info->textaddr, info->textsize,
info->stabsects,
info->stabstrsect->filepos, stabstrsize);
+ ADJUST_OBJFILE_OFFSETS(objfile, adjust_for_stabs_restore);
+
}
if (dwarf2_has_info (abfd))
{
/* DWARF2 sections. */
+ ADJUST_OBJFILE_OFFSETS(objfile, adjust_for_dwarf);
dwarf2_build_psymtabs (objfile, mainline);
+ ADJUST_OBJFILE_OFFSETS(objfile, adjust_for_dwarf_restore);
}
do_cleanups (back_to);
@@ -1173,36 +1175,8 @@ read_one_sym (register struct coff_symbo
#endif
symnum += 1 + cs->c_naux;
-
- /* The PE file format stores symbol values as offsets within the
- section, rather than as absolute addresses. We correct that
- here, if the symbol has an appropriate storage class. FIXME: We
- should use BFD to read the symbols, rather than duplicating the
- work here. */
- if (pe_file)
- {
- switch (cs->c_sclass)
- {
- case C_EXT:
- case C_THUMBEXT:
- case C_THUMBEXTFUNC:
- case C_SECTION:
- case C_NT_WEAK:
- case C_STAT:
- case C_THUMBSTAT:
- case C_THUMBSTATFUNC:
- case C_LABEL:
- case C_THUMBLABEL:
- case C_BLOCK:
- case C_FCN:
- case C_EFCN:
- if (cs->c_secnum != 0)
- cs->c_value += cs_section_address (cs, symfile_bfd);
- break;
- }
- }
-}
-\f
+}
+\f
/* Support for string table handling */
static char *stringtab = NULL;
@@ -2500,6 +2555,67 @@ init_lineno (bfd *abfd, long offset, int
abort();
/* We could realloc the table, but it probably loses for most files. */
return 0;
+}
+
+
+/* This does the equivalent of what older code did (but both more
+ efficiently and with a finer grain of control), but I'm not
+ convinced this was right to begin with: the offset of a symbol
+ is NOT the offset of its section, but rather of the image base. */
+
+struct adjust_sec_objfile
+ {
+ struct objfile *objfile;
+ int sign;
+ };
+
+static void
+adjust_sec_objfile_offset (bfd *abfd, asection *sect, PTR obj)
+{
+ struct adjust_sec_objfile *args = (struct adjust_sec_objfile *) obj;
+ int off;
+ CORE_ADDR symbols_offset;
+
+ /* This is the section. Figure out what SECT_OFF_* code it is. */
+ if (bfd_get_section_flags (abfd, sect) & SEC_CODE)
+ off = SECT_OFF_TEXT (args->objfile);
+ else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
+ off = SECT_OFF_DATA (args->objfile);
+ else
+ off = sect->index;
+
+ symbols_offset = bfd_get_section_vma (objfile->obfd, sect) * args->sign;
+
+ args->objfile->section_offsets->offsets[off] += symbols_offset;
+}
+
+static void
+gnu_pei_adjust_objfile_offsets(struct objfile *objfile,
+ enum objfile_adjusts type)
+{
+ struct adjust_sec_objfile args;
+
+ if (!pe_file)
+ return;
+
+ args.objfile = objfile;
+
+ switch (type) {
+ case adjust_for_symtab:
+ args.sign = 1;
+ break;
+ case adjust_for_symtab_restore:
+ args.sign = -1;
+ break;
+ case adjust_for_stabs:
+ case adjust_for_stabs_restore:
+ case adjust_for_dwarf:
+ case adjust_for_dwarf_restore:
+ default:
+ return;
+ }
+
+ bfd_map_over_sections (objfile->obfd, adjust_sec_objfile_offset, &args);
}
/* Register our ability to parse symbols for coff BFD files. */
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files defs.h defs.h
--- a/b/defs.h Thu Mar 7 09:18:59 2002
+++ a/b/defs.h Tue Mar 12 14:14:32 2002
@@ -1407,4 +1407,11 @@ extern int use_windows;
#define ISATTY(FP) (isatty (fileno (FP)))
#endif
+/* If the header provides this, then the linker allows (or requires)
+ that files be linked at other than zero, and this is how to get that
+ value. */
+#ifndef NONZERO_LINK_BASE
+#define NONZERO_LINK_BASE(abfd) 0
+#endif
+
#endif /* #ifndef DEFS_H */
Index: src/gdb/exec.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/exec.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 exec.c
--- src/gdb/exec.c 2001/12/23 00:34:46 1.1.1.1
+++ src/gdb/exec.c 2001/12/23 23:17:03
@@ -549,7 +549,7 @@ print_section_info (struct target_ops *t
if (abfd == exec_bfd)
{
printf_filtered ("\tEntry point: ");
- print_address_numeric (bfd_get_start_address (abfd), 1, gdb_stdout);
+ print_address_numeric (bfd_get_start_address (abfd) + NONZERO_LINK_BASE(abfd), 1, gdb_stdout);
printf_filtered ("\n");
}
for (p = t->to_sections; p < t->to_sections_end; p++)
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files config/i386/tm-i386interix.h config/i386/tm-i386interix.h
--- a/b/config/i386/tm-i386interix.h Thu Mar 7 09:18:43 2002
+++ a/b/config/i386/tm-i386interix.h Tue Mar 12 14:19:44 2002
@@ -124,4 +124,11 @@ get_longjmp_target PARAMS ((CORE_ADDR *)
#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+
+#define ADJUST_OBJFILE_OFFSETS(objfile, type) \
+ pei_adjust_objfile_offsets(objfile, type)
+
+extern CORE_ADDR bfd_getImageBase(bfd *abfd);
+#define NONZERO_LINK_BASE(abfd) bfd_getImageBase(abfd)
+
#endif /* TM_INTERIX_H */
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files exec.c exec.c
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files i386interix-nat.c i386interix-nat.c
--- a/b/i386interix-nat.c Thu Mar 7 09:19:00 2002
+++ a/b/i386interix-nat.c Tue Mar 12 14:10:35 2002
@@ -25,7 +25,10 @@ Foundation, Inc., 59 Temple Place - Suit
#include <inferior.h>
#include <i386-tdep.h>
-
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+
typedef unsigned long greg_t; /* Where should this be defined? */
/* See procfs.c and *interix*.h in config/[alpha,i386] */
@@ -410,4 +413,37 @@ get_longjmp_target (pc)
*pc = extract_address (raw_buffer, sizeof(CORE_ADDR));
return 1;
+}
+
+/* Adjust the section offsets in an objfile structure so that it's correct
+ for the type of symbols being read (or undo it with the _restore
+ arguments).
+
+ If main programs ever start showing up at other than the default Image
+ Base, this is where that would likely be applied. */
+void
+pei_adjust_objfile_offsets(struct objfile *objfile, enum objfile_adjusts type)
+{
+ int i;
+ CORE_ADDR symbols_offset;
+
+ switch (type) {
+ case adjust_for_symtab:
+ symbols_offset = NONZERO_LINK_BASE(objfile->obfd);
+ break;
+ case adjust_for_symtab_restore:
+ symbols_offset = -NONZERO_LINK_BASE(objfile->obfd);
+ break;
+ case adjust_for_stabs:
+ case adjust_for_stabs_restore:
+ case adjust_for_dwarf:
+ case adjust_for_dwarf_restore:
+ default:
+ return;
+ }
+
+ for (i = 0; i < SECT_OFF_MAX; i++)
+ {
+ (objfile->section_offsets)->offsets[i] += symbols_offset;
+ }
}
Index: src/gdb/maint.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/maint.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 maint.c
--- src/gdb/maint.c 2001/12/23 00:34:50 1.1.1.1
+++ src/gdb/maint.c 2001/12/23 23:20:35
@@ -349,7 +349,15 @@ maintenance_info_sections (char *arg, in
printf_filtered ("Exec file:\n");
printf_filtered (" `%s', ", bfd_get_filename (exec_bfd));
wrap_here (" ");
- printf_filtered ("file type %s.\n", bfd_get_target (exec_bfd));
+ printf_filtered ("file type %s.", bfd_get_target (exec_bfd));
+#ifdef COFF_IMAGE_WITH_PE
+ if (NONZERO_LINK_BASE(exec_bfd))
+ {
+ wrap_here (" ");
+ printf_filtered (" Image base 0x%lx\n", (unsigned long)NONZERO_LINK_BASE(exec_bfd));
+ }
+#endif
+ printf_filtered ("\n");
if (arg && *arg && match_substring (arg, "ALLOBJ"))
{
struct objfile *ofile;
@@ -381,7 +389,15 @@ maintenance_info_sections (char *arg, in
printf_filtered ("Core file:\n");
printf_filtered (" `%s', ", bfd_get_filename (core_bfd));
wrap_here (" ");
- printf_filtered ("file type %s.\n", bfd_get_target (core_bfd));
+ printf_filtered ("file type %s.", bfd_get_target(core_bfd));
+#ifdef COFF_IMAGE_WITH_PE
+ if (NONZERO_LINK_BASE(exec_bfd))
+ {
+ wrap_here (" ");
+ printf_filtered (" Image base 0x%lx\n", (unsigned long)NONZERO_LINK_BASE(core_bfd));
+ }
+#endif
+ printf_filtered ("\n");
bfd_map_over_sections (core_bfd, print_bfd_section_info, arg);
}
}
Index: src/gdb/symfile.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/symfile.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 symfile.c
--- src/gdb/symfile.c 2001/12/23 00:34:56 1.1.1.1
+++ src/gdb/symfile.c 2001/12/23 23:17:03
@@ -386,7 +386,9 @@ init_entry_point_info (struct objfile *o
{
/* Executable file -- record its entry point so we'll recognize
the startup file because it contains the entry point. */
- objfile->ei.entry_point = bfd_get_start_address (objfile->obfd);
+ objfile->ei.entry_point =
+ bfd_get_start_address (objfile->obfd) +
+ NONZERO_LINK_BASE(objfile->obfd);
}
else
{
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files symfile.h symfile.h
--- a/b/symfile.h Thu Mar 7 09:19:01 2002
+++ a/b/symfile.h Fri Mar 8 11:05:43 2002
@@ -323,4 +323,21 @@ extern void
elfmdebug_build_psymtabs (struct objfile *,
const struct ecoff_debug_swap *, asection *);
+/* Let the "back end" adjust the section relocations for the type of
+ symbols being read.
+ Note; this currently is only applied to coffread, but the other readers
+ may find it useful. */
+enum objfile_adjusts {
+ adjust_for_symtab,
+ adjust_for_symtab_restore,
+ adjust_for_stabs,
+ adjust_for_stabs_restore,
+ adjust_for_dwarf,
+ adjust_for_dwarf_restore,
+};
+
+/* A default value for ADJUST_OBFILE_OFFSETS could go here, but for now
+ we let the individual files using this define the default, until all
+ the places that need to provide special ones are found. */
+
#endif /* !defined(SYMFILE_H) */
---------------------------------------------------------------------------
Removed "breakpoint" change: now it does what it's told.
Several minor corrections to the internal documentation (English,
spelling, content) and corresponding regression changes.
Experimentally and from code reading, breakpoint at address aligns
to a line number, rather than occurring anywhere. (It's arguable
which it should do, particularly on variable length instruction
machines where being sure the bp is on an instruction boundary
is hard. Go with the actual implementation.)
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* thread.c(restore_current_thread): fix comment.
(_initialize_thread): Clearer help; apply applies to ALL
classes.
Index: src/gdb/thread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/thread.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 thread.c
--- src/gdb/thread.c 2001/12/23 00:34:56 1.1.1.1
+++ src/gdb/thread.c 2001/12/23 23:23:13
@@ -539,7 +539,7 @@ make_cleanup_restore_current_thread (pti
thread apply 1 2 7 4 backtrace Apply backtrace cmd to threads 1,2,7,4
thread apply 2-7 9 p foo(1) Apply p foo(1) cmd to threads 2->7 & 9
- thread apply all p x/i $pc Apply x/i $pc cmd to all threads
+ thread apply all x/i $pc Apply x/i $pc cmd to all threads
*/
static void
@@ -761,11 +761,12 @@ _initialize_thread (void)
The new thread ID must be currently known.", &thread_cmd_list, "thread ", 1,
&cmdlist);
- add_prefix_cmd ("apply", class_run, thread_apply_command,
- "Apply a command to a list of threads.",
- &thread_apply_list, "apply ", 1, &thread_cmd_list);
+ add_prefix_cmd ("apply", no_class, thread_apply_command,
+ "Apply a command to a list of threads.\n\
+apply thread [n|m-n|all] <command>",
+ &thread_apply_list, "thread apply ", 1, &thread_cmd_list);
- add_cmd ("all", class_run, thread_apply_all_command,
+ add_cmd ("all", no_class, thread_apply_all_command,
"Apply a command to all threads.",
&thread_apply_list);
---------------------------------------------------------------------------
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* c-exp.y(direct_abs_decl): type cast to shut up compiler.
Index: src/gdb/c-exp.y
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/c-exp.y,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 c-exp.y
--- src/gdb/c-exp.y 2001/12/23 00:34:41 1.1.1.1
+++ src/gdb/c-exp.y 2001/12/23 23:38:57
@@ -755,12 +755,12 @@ direct_abs_decl: '(' abs_decl ')'
{ $$ = $2; }
| direct_abs_decl array_mod
{
- push_type_int ($2);
+ push_type_int ((int)$2);
push_type (tp_array);
}
| array_mod
{
- push_type_int ($1);
+ push_type_int ((int)$1);
push_type (tp_array);
$$ = 0;
}
---------------------------------------------------------------------------
Expand a comment about unwind. The actual changes implied by this
comment are in the Interix patch files submitted elsewhere, but
this is not Interix specific.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* blockframe.c(get_prev_frame_info): comment, add explanatory
warning.
Index: src/gdb/blockframe.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/blockframe.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 blockframe.c
--- src/gdb/blockframe.c 2001/12/23 00:34:41 1.1.1.1
+++ src/gdb/blockframe.c 2001/12/23 23:41:11
@@ -433,8 +433,26 @@ get_prev_frame (struct frame_info *next_
the default INIT_FRAME_PC does. Some machines will call it from
INIT_PREV_FRAME (either at the beginning, the end, or in the middle).
Some machines won't use it.
- kingdon@cygnus.com, 13Apr93, 31Jan94, 14Dec94. */
+ kingdon@cygnus.com, 13Apr93, 31Jan94, 14Dec94.
+
+ Actually, this problem CANNOT be solved, in general, with macros because
+ there are machines (Interix, e.g.) that require interleaved extraction of
+ BOTH fp and pc, and which require sometimes fairly complex operations to
+ find the next pc. It might make more sense to replace most of this section
+ of code with a SINGLE macro, which defaults to something like a copy of
+ the current code, but which might be replaced with something suitable
+ for those which need pc before fp, or a custom routine for the really
+ complex cases. (The macro should compute all the parameters of the
+ next frame, including fp, pc, signal_handler_caller; it might want
+ to return the local NAME in case it needs the value before it's needed
+ here. (In the short term, this can be achieved by putting all the load
+ on INIT_EXTRA_FRAME_INFO, and appropriately defining other macros; however,
+ the "appropriate" definition of some of those macros is "iffy" because
+ they are used in other places.
+
+ */
+
INIT_FRAME_PC_FIRST (fromleaf, prev);
if (INIT_EXTRA_FRAME_INFO_P ())
@@ -454,6 +472,7 @@ get_prev_frame (struct frame_info *next_
if (prev->frame == next_frame->frame
&& prev->pc == next_frame->pc)
{
+ warning("Stack Unwind is not progressing; quitting unwind\n");
next_frame->prev = NULL;
obstack_free (&frame_cache_obstack, prev);
return NULL;
---------------------------------------------------------------------------
In fork-child.c, startup_inferior(): The loop which counts down
until the beginning of the target executable is reached treats
unexpected signals (etc.) specially, and continues without counting
them. Such signals CAN cause surprises if something else goes wrong,
so report that they occurred to the user. (In particular, if
SIGTTIN or SIGTTOUT should occur, there could be some blockage of
I/O.) Count them, and if way too many, quit. Also...
Avoid infinite loop: startup_inferior() should test for non-negative
pending_execs, not exactly zero. It has been observed to go negative
with other errors.
inflow.c/terminal_inferior(): it's possible for startup_inferior()
to call resume() (under the conditions above) before it
calls terminal_init_inferior(). This can cause terminal_inferior
to be called with inferior_ttystate == NULL. Add code to simply
return if inferior_ttystate is NULL.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* fork-child.c (startup_inferior): Count/report unexpected traps.
Be sure pending_execs < 0 won't loop forever.
* inflow.c (terminal_inferior): if arg is NULL, return.
Index: src/gdb/fork-child.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/fork-child.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 fork-child.c
--- src/gdb/fork-child.c 2001/12/23 00:34:46 1.1.1.1
+++ src/gdb/fork-child.c 2001/12/23 23:43:06
@@ -508,7 +508,9 @@ startup_inferior (int ntraps)
{
int pending_execs = ntraps;
int terminal_initted;
+ int bad_traps = 0;
+
/* The process was started by the fork that created it,
but it will have stopped one instruction after execing the shell.
Here we must get it up to actual execution of the real program. */
@@ -535,8 +537,15 @@ startup_inferior (int ntraps)
wait_for_inferior ();
if (stop_signal != TARGET_SIGNAL_TRAP)
{
+ fprintf_unfiltered (gdb_stderr,
+ "Got unexpected stop signal %d during inferior startup; ignoring\n",
+ stop_signal);
/* Let shell child handle its own signals in its own way */
/* FIXME, what if child has exit()ed? Must exit loop somehow */
+ if (bad_traps++ > 2*ntraps) {
+ fprintf_unfiltered(gdb_stderr, "... giving up... too many\n");
+ break;
+ }
resume (0, stop_signal);
}
else
@@ -559,7 +568,7 @@ startup_inferior (int ntraps)
}
pending_execs = pending_execs - 1;
- if (0 == pending_execs)
+ if (0 >= pending_execs)
break;
resume (0, TARGET_SIGNAL_0); /* Just make it go on */
Index: src/gdb/inflow.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/inflow.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 inflow.c
--- src/gdb/inflow.c 2001/12/23 00:34:49 1.1.1.1
+++ src/gdb/inflow.c 2001/12/23 23:43:06
@@ -220,6 +220,12 @@ terminal_init_inferior (void)
void
terminal_inferior (void)
{
+
+ /* not yet initialized; called before init was called. This is reasonable:
+ startup_inferior can do this if it gets an unexpected signal (directed
+ at the intermediate shell). Ignore it until we're initialized */
+ if (inferior_ttystate == NULL) return;
+
if (gdb_has_a_terminal () && terminal_is_ours
&& inferior_thisrun_terminal == 0)
{
---------------------------------------------------------------------------
The bfd_section is needed to enable searching in some cases ("info
sym" for a .bss symbol, e.g.); record the section pointer for
later use. prim_record_minimal_symbol_and_info already had a place
for it; just bring to higher levels. In
lookup_minimal_symbol_by_pc_section use to avoid overlong searches.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* symtab.h(record_minimal_symbol): add section arg.
* minsyms.c(prim_record_minimal_symbol): add section arg.
(lookup_minimal_symbol_by_pc_section): Use section info.
* coffread.c(record_minimal_symbol): add section arg.
(coff_symfile_finish, coff_symtab_read): Use it.
* dbxread.c(read_dbx_dymamic_symtab): provide dummy arg.
* dwarf2read.c(add_partial_symbol): provide dummy arg.
* mdebugread.c(parse_partial_symbols): provide dummy arg.
* mipsread.c(read_alphacoff_dynamic_symtab): provide dummy arg.
* nlmread.c(nlm_record_minimal_symbol): provide dummy arg.
* os9kread.c(record_minimal_symbol): provide dummy arg.
Index: src/gdb/coffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/coffread.c,v
retrieving revision 1.2
diff -p -u -r1.2 coffread.c
--- src/gdb/coffread.c 2001/12/23 23:22:12 1.2
+++ src/gdb/coffread.c 2001/12/23 23:44:57
@@ -483,15 +484,16 @@ coff_end_symtab (struct objfile *objfile
\f
static void
record_minimal_symbol (char *name, CORE_ADDR address,
- enum minimal_symbol_type type, struct objfile *objfile)
-{
+ enum minimal_symbol_type type, struct objfile *objfile,
+ asection *bfd_section)
+{
/* We don't want TDESC entry points in the minimal symbol table */
if (name[0] == '@')
return;
- prim_record_minimal_symbol (name, address, type, objfile);
-}
-\f
+ prim_record_minimal_symbol (name, address, type, objfile, bfd_section);
+}
+\f
/* coff_symfile_init ()
is the coff-specific initialization routine for reading symbols.
It is passed a struct objfile which contains, among other things,
@@ -817,8 +819,9 @@ coff_symtab_read (long symtab_offset, un
{
/* Record all functions -- external and static -- in minsyms. */
tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- record_minimal_symbol (cs->c_name, tmpaddr, mst_text, objfile);
-
+ record_minimal_symbol (cs->c_name, tmpaddr, mst_text, objfile,
+ coff_section_from_bfd_index(objfile->obfd, cs->c_secnum));
+
fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
fcn_start_addr = tmpaddr;
fcn_cs_saved = *cs;
@@ -977,8 +980,9 @@ coff_symtab_read (long symtab_offset, un
welcome. */
gdb_assert (sizeof (void *) >= sizeof (cs->c_sclass));
msym = prim_record_minimal_symbol_and_info
- (cs->c_name, tmpaddr, ms_type, (void *) (long) cs->c_sclass,
- sec, NULL, objfile);
+ (cs->c_name, tmpaddr, ms_type, (void *) (long) cs->c_sclass,
+ sec, coff_section_from_bfd_index (objfile->obfd, cs->c_secnum),
+ objfile);
if (msym)
COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
}
Index: src/gdb/dbxread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/dbxread.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 dbxread.c
--- src/gdb/dbxread.c 2001/12/23 00:34:45 1.1.1.1
+++ src/gdb/dbxread.c 2001/12/23 23:44:57
@@ -1224,7 +1224,7 @@ read_dbx_dynamic_symtab (struct objfile
name = (char *) bfd_asymbol_name (*rel->sym_ptr_ptr);
prim_record_minimal_symbol (name, address, mst_solib_trampoline,
- objfile);
+ objfile, NULL);
}
do_cleanups (back_to);
Index: src/gdb/dwarf2read.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/dwarf2read.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 dwarf2read.c
--- src/gdb/dwarf2read.c 2001/12/23 00:34:46 1.1.1.1
+++ src/gdb/dwarf2read.c 2001/12/23 23:44:58
@@ -1268,7 +1268,7 @@ add_partial_symbol (struct partial_die_i
if (pdi->is_external)
{
/*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
- mst_text, objfile); */
+ mst_text, objfile, NULL); */
add_psymbol_to_list (pdi->name, strlen (pdi->name),
VAR_NAMESPACE, LOC_BLOCK,
&objfile->global_psymbols,
@@ -1277,7 +1277,7 @@ add_partial_symbol (struct partial_die_i
else
{
/*prim_record_minimal_symbol (pdi->name, pdi->lowpc + baseaddr,
- mst_file_text, objfile); */
+ mst_file_text, objfile, NULL); */
add_psymbol_to_list (pdi->name, strlen (pdi->name),
VAR_NAMESPACE, LOC_BLOCK,
&objfile->static_psymbols,
@@ -1315,7 +1315,7 @@ add_partial_symbol (struct partial_die_i
return;
addr = decode_locdesc (pdi->locdesc, objfile, cu_header);
/*prim_record_minimal_symbol (pdi->name, addr + baseaddr,
- mst_file_data, objfile); */
+ mst_file_data, objfile, NULL); */
add_psymbol_to_list (pdi->name, strlen (pdi->name),
VAR_NAMESPACE, LOC_STATIC,
&objfile->static_psymbols,
Index: src/gdb/mdebugread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/mdebugread.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 mdebugread.c
--- src/gdb/mdebugread.c 2001/12/23 00:34:50 1.1.1.1
+++ src/gdb/mdebugread.c 2001/12/23 23:44:58
@@ -2485,7 +2485,7 @@ parse_partial_symbols (struct objfile *o
complain (&unknown_ext_complaint, name);
}
if (!ECOFF_IN_ELF (cur_bfd))
- prim_record_minimal_symbol (name, svalue, ms_type, objfile);
+ prim_record_minimal_symbol (name, svalue, ms_type, objfile, NULL);
}
/* Pass 3 over files, over local syms: fill in static symbols */
Index: src/gdb/minsyms.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/minsyms.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 minsyms.c
--- src/gdb/minsyms.c 2001/12/23 00:34:51 1.1.1.1
+++ src/gdb/minsyms.c 2001/12/23 23:44:58
@@ -484,13 +484,17 @@ lookup_minimal_symbol_by_pc_section (COR
/* If "section" specified, skip any symbol from wrong section */
/* This is the new code that distinguishes it from the old function */
+ /* If the symbols are already in section order, we may end up
+ linearly backing up thru the whole table, so quit if the
+ symbol value gets weird. */
if (section)
while (hi >= 0
/* Some types of debug info, such as COFF,
don't fill the bfd_section member, so don't
throw away symbols on those platforms. */
&& SYMBOL_BFD_SECTION (&msymbol[hi]) != NULL
- && SYMBOL_BFD_SECTION (&msymbol[hi]) != section)
+ && SYMBOL_BFD_SECTION (&msymbol[hi]) != section
+ && SYMBOL_VALUE_ADDRESS (&msymbol[hi]) >= pc)
--hi;
if (hi >= 0
@@ -592,7 +596,7 @@ init_minimal_symbol_collection (void)
void
prim_record_minimal_symbol (const char *name, CORE_ADDR address,
enum minimal_symbol_type ms_type,
- struct objfile *objfile)
+ struct objfile *objfile, asection *bfd_section)
{
int section;
@@ -616,7 +620,7 @@ prim_record_minimal_symbol (const char *
}
prim_record_minimal_symbol_and_info (name, address, ms_type,
- NULL, section, NULL, objfile);
+ NULL, section, bfd_section, objfile);
}
/* Record a minimal symbol in the msym bunches. Returns the symbol
Index: src/gdb/mipsread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/mipsread.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 mipsread.c
--- src/gdb/mipsread.c 2001/12/23 00:34:51 1.1.1.1
+++ src/gdb/mipsread.c 2001/12/23 23:44:58
@@ -421,7 +421,7 @@ read_alphacoff_dynamic_symtab (struct se
}
}
- prim_record_minimal_symbol (name, sym_value, ms_type, objfile);
+ prim_record_minimal_symbol (name, sym_value, ms_type, objfile, NULL);
}
do_cleanups (cleanups);
Index: src/gdb/nlmread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/nlmread.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 nlmread.c
--- src/gdb/nlmread.c 2001/12/23 00:34:51 1.1.1.1
+++ src/gdb/nlmread.c 2001/12/23 23:44:58
@@ -135,7 +135,7 @@ nlm_symtab_read (bfd *abfd, CORE_ADDR ad
ms_type = mst_unknown;
prim_record_minimal_symbol (sym->name, symaddr, ms_type,
- objfile);
+ objfile, NULL);
}
}
do_cleanups (back_to);
Index: src/gdb/os9kread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/os9kread.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 os9kread.c
--- src/gdb/os9kread.c 2001/12/23 00:34:51 1.1.1.1
+++ src/gdb/os9kread.c 2001/12/23 23:44:58
@@ -215,7 +215,7 @@ record_minimal_symbol (char *name, CORE_
break;
}
- prim_record_minimal_symbol (name, address, ms_type, objfile);
+ prim_record_minimal_symbol (name, address, ms_type, objfile, NULL);
}
/* read and process .stb file and store in minimal symbol table */
Index: src/gdb/symtab.h
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/symtab.h,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 symtab.h
--- src/gdb/symtab.h 2001/12/23 00:34:56 1.1.1.1
+++ src/gdb/symtab.h 2001/12/23 23:44:58
@@ -1186,7 +1186,8 @@ extern struct type *lookup_transparent_t
extern void prim_record_minimal_symbol (const char *, CORE_ADDR,
enum minimal_symbol_type,
- struct objfile *);
+ struct objfile *,
+ asection *);
extern struct minimal_symbol *prim_record_minimal_symbol_and_info
(const char *, CORE_ADDR,
---------------------------------------------------------------------------
One more alignment rule is needed for structure values
(not in their fixes, yet).
Also, fix bug with BLOCK_GCC_COMPILED: it simply doesn't work
right at this point and breaks some systems. See comment below.
Index: src/gdb/valops.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/valops.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 valops.c
--- src/gdb/valops.c 2001/12/23 00:34:57 1.1.1.1
+++ src/gdb/valops.c 2001/12/23 23:58:39
@@ -1356,11 +1356,20 @@ hand_function_call (value_ptr function,
funaddr = find_function_addr (function, &value_type);
CHECK_TYPEDEF (value_type);
+#ifdef CARE_IF_GCC
{
struct block *b = block_for_pc (funaddr);
/* If compiled without -g, assume GCC 2. */
using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b));
}
+#else
+ /* If we don't care if we're using gcc or not on this system,
+ then default to 2. Note that there appears to be NO code
+ that actually sets up BLOCK_GCC_COMPILED (gcc_compile_flag)
+ so this is all pretty much meaningless anyway, but it
+ breaks the regressions (callfunc). */
+ using_gcc = 2;
+#endif
/* Are we returning a value using a structure return or a normal
value return? */
@@ -1557,6 +1566,7 @@ You must use a pointer to function type
/* Reserve space for the return structure to be written on the
stack, if necessary */
+#if 0
if (struct_return)
{
int len = TYPE_LENGTH (value_type);
@@ -1578,6 +1588,39 @@ You must use a pointer to function type
sp += len;
}
}
+#else
+ if (struct_return)
+ {
+ register int len = TYPE_LENGTH (value_type);
+ register int container_len = len;
+ register int offset;
+
+ /* How big is the container we're going to put this value in? */
+ if (PARM_BOUNDARY)
+ container_len = ((len + PARM_BOUNDARY / TARGET_CHAR_BIT - 1)
+ & ~(PARM_BOUNDARY / TARGET_CHAR_BIT - 1));
+
+ /* Are we going to put it at the high or low end of the container? */
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ offset = container_len - len;
+ else
+ offset = 0;
+
+ if (INNER_THAN (1, 2))
+ {
+ /* stack grows downward */
+ sp -= container_len;
+ struct_addr = sp;
+ }
+ else
+ {
+ /* stack grows upward */
+ struct_addr = sp;
+ sp += container_len;
+ }
+ }
+
+#endif
/* elz: on HPPA no need for this extra alignment, maybe it is needed
on other architectures. This is because all the alignment is
---------------------------------------------------------------------------
Remove some of the confusion around CORE_ADDR vs. long vs.
long long vs. LONGEST. On Alpha NT, ints are 32 bits, addresses
(pointers, in memory) are 32 bits, but registers and long long are
64 bits. This implies care in getting these types right.
See also a patch concerning CC_HAS_LONG_LONG.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* i386-tdep.c(i386_saved_pc_after_call, i386_frame_saved_pc):
add CORE_ADDR casts.
* findvar.c(read_register, read_register_pid): Change to LONGEST.
* gdbtypes.c(create_range_type): Change args to LONGEST.
* gdbtypes.h(create_range_type): Likewise.
* valarith.c(value_subscripted_rvalue, value_bit_index): Likewise.
* valopts.c(value_slice): Likewise.
* scm-lang.c(scm_get_field, scm_lookup_name, scm_evaluate_string):
cast to CORE_ADDR.
* scm-valprint.c(scm_scmval_print): cast to/from CORE_ADDR.
* value.h (value_bit_index, value_ptr): arg becomes CORE_ADDR.
(read_register, read_register_pid): result type becomes LONGEST.
Index: src/gdb/gdbtypes.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/gdbtypes.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 gdbtypes.c
--- src/gdb/gdbtypes.c 2001/12/23 00:34:47 1.1.1.1
+++ src/gdb/gdbtypes.c 2001/12/24 00:55:52
@@ -561,7 +561,7 @@ allocate_stub_method (struct type *type)
struct type *
create_range_type (struct type *result_type, struct type *index_type,
- int low_bound, int high_bound)
+ LONGEST low_bound, LONGEST high_bound)
{
if (result_type == NULL)
{
Index: src/gdb/gdbtypes.h
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/gdbtypes.h,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 gdbtypes.h
--- src/gdb/gdbtypes.h 2001/12/23 00:34:47 1.1.1.1
+++ src/gdb/gdbtypes.h 2001/12/24 00:55:52
@@ -1083,8 +1083,8 @@ extern struct type *make_function_type (
extern struct type *lookup_function_type (struct type *);
-extern struct type *create_range_type (struct type *, struct type *, int,
- int);
+extern struct type *create_range_type (struct type *, struct type *, LONGEST,
+ LONGEST);
extern struct type *create_array_type (struct type *, struct type *,
struct type *);
Index: src/gdb/i386-tdep.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/i386-tdep.c,v
retrieving revision 1.2
diff -p -u -r1.2 i386-tdep.c
--- src/gdb/i386-tdep.c 2001/12/23 20:46:14 1.2
+++ src/gdb/i386-tdep.c 2001/12/24 00:55:52
@@ -505,7 +505,7 @@ i386_frame_saved_pc (struct frame_info *
return sigtramp_saved_pc (frame);
#endif
- return read_memory_unsigned_integer (frame->frame + 4, 4);
+ return (CORE_ADDR) read_memory_unsigned_integer (frame->frame + 4, 4);
}
CORE_ADDR
@@ -519,7 +519,7 @@ i386go32_frame_saved_pc (struct frame_in
CORE_ADDR
i386_saved_pc_after_call (struct frame_info *frame)
{
- return read_memory_unsigned_integer (read_register (SP_REGNUM), 4);
+ return read_memory_unsigned_integer ((CORE_ADDR) read_register (SP_REGNUM), 4);
}
/* Return number of args passed to a frame.
Index: src/gdb/scm-lang.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/scm-lang.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 scm-lang.c
--- src/gdb/scm-lang.c 2001/12/23 00:34:54 1.1.1.1
+++ src/gdb/scm-lang.c 2001/12/24 00:55:52
@@ -76,7 +76,7 @@ LONGEST
scm_get_field (LONGEST svalue, int index)
{
char buffer[20];
- read_memory (SCM2PTR (svalue) + index * TYPE_LENGTH (builtin_type_scm),
+ read_memory ((CORE_ADDR)(SCM2PTR (svalue) + index * TYPE_LENGTH (builtin_type_scm)),
buffer, TYPE_LENGTH (builtin_type_scm));
return extract_signed_integer (buffer, TYPE_LENGTH (builtin_type_scm));
}
@@ -157,7 +157,7 @@ scm_lookup_name (char *str)
struct symbol *sym;
args[0] = value_allocate_space_in_inferior (len);
args[1] = value_from_longest (builtin_type_int, len);
- write_memory (value_as_long (args[0]), str, len);
+ write_memory ((CORE_ADDR)value_as_long (args[0]), str, len);
if (in_eval_c ()
&& (sym = lookup_symbol ("env",
@@ -189,9 +189,9 @@ scm_evaluate_string (char *str, int len)
struct value *func;
struct value *addr = value_allocate_space_in_inferior (len + 1);
LONGEST iaddr = value_as_long (addr);
- write_memory (iaddr, str, len);
+ write_memory ((CORE_ADDR)iaddr, str, len);
/* FIXME - should find and pass env */
- write_memory (iaddr + len, "", 1);
+ write_memory ((CORE_ADDR)iaddr + len, "", 1);
func = find_function_in_inferior ("scm_evstr");
return call_function_by_hand (func, 1, &addr);
}
Index: src/gdb/scm-valprint.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/scm-valprint.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 scm-valprint.c
--- src/gdb/scm-valprint.c 2001/12/23 00:34:54 1.1.1.1
+++ src/gdb/scm-valprint.c 2001/12/24 00:55:52
@@ -151,7 +151,7 @@ taloop:
if (SCM_ICHRP (svalue))
{
svalue = SCM_ICHR (svalue);
- scm_printchar (svalue, stream);
+ scm_printchar ((int)svalue, stream);
break;
}
else if (SCM_IFLAGP (svalue)
@@ -252,7 +252,7 @@ taloop:
int len = SCM_LENGTH (svalue);
char *str = (char *) alloca (len);
- read_memory (SCM_CDR (svalue), str, len + 1);
+ read_memory ((CORE_ADDR)SCM_CDR (svalue), str, len + 1);
/* Should handle weird characters FIXME */
str[len] = '\0';
fputs_filtered (str, stream);
Index: src/gdb/valarith.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/valarith.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 valarith.c
--- src/gdb/valarith.c 2001/12/23 00:34:57 1.1.1.1
+++ src/gdb/valarith.c 2001/12/24 00:55:52
@@ -38,8 +38,8 @@
#define TRUNCATION_TOWARDS_ZERO ((-5 / 2) == -2)
#endif
-static struct value *value_subscripted_rvalue (struct value *, struct value *, int);
-
+static struct value *value_subscripted_rvalue (struct value *, struct value *, LONGEST);
+
void _initialize_valarith (void);
\f
@@ -213,8 +213,8 @@ value_subscript (struct value *array, st
to doubles, but no longer does. */
static struct value *
-value_subscripted_rvalue (struct value *array, struct value *idx, int lowerbound)
-{
+value_subscripted_rvalue (struct value *array, struct value *idx, LONGEST lowerbound)
+{
struct type *array_type = check_typedef (VALUE_TYPE (array));
struct type *elt_type = check_typedef (TYPE_TARGET_TYPE (array_type));
unsigned int elt_size = TYPE_LENGTH (elt_type);
@@ -1342,7 +1342,7 @@ value_complement (struct value *arg1)
Return -1 if out of range, -2 other error. */
int
-value_bit_index (struct type *type, char *valaddr, int index)
+value_bit_index (struct type *type, char *valaddr, LONGEST index)
{
LONGEST low_bound, high_bound;
LONGEST word;
Index: src/gdb/valops.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/valops.c,v
retrieving revision 1.2
diff -p -u -r1.2 valops.c
--- src/gdb/valops.c 2001/12/23 00:34:57 1.1.1.1
+++ src/gdb/valops.c 2001/12/24 00:55:52
@@ -3313,7 +3313,7 @@ value_of_this (int complain)
the original ARRAY. */
struct value *
-value_slice (struct value *array, int lowbound, int length)
+value_slice (struct value *array, LONGEST lowbound, LONGEST length)
{
struct type *slice_range_type, *slice_type, *range_type;
LONGEST lowerbound, upperbound, offset;
Index: src/gdb/value.h
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/value.h,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 value.h
--- src/gdb/value.h 2001/12/23 00:34:57 1.1.1.1
+++ src/gdb/value.h 2001/12/24 00:55:52
@@ -419,8 +419,8 @@ extern struct value *value_being_returne
extern struct value *value_in (struct value *element, struct value *set);
-extern int value_bit_index (struct type *type, char *addr, int index);
-
+extern int value_bit_index (struct type *type, char *addr, LONGEST index);
+
extern int using_struct_return (struct value *function, CORE_ADDR funcaddr,
struct type *value_type, int gcc_p);
@@ -549,7 +549,7 @@ extern struct value *value_copy (struct
extern struct value *varying_to_slice (struct value *);
-extern struct value *value_slice (struct value *, int, int);
+extern struct value *value_slice (struct value *, LONGEST, LONGEST);
extern struct value *call_function_by_hand (struct value *, int,
struct value **);
---------------------------------------------------------------------------
PRINTF_HAS_LONG_LONG can be true when CC_HAS_LONG_LONG isn't,
because the symbol for 64-bit integer isn't "long long"
(__int64 on MSVC). (CC_HAS_LONG_LONG seems to have more to
do with the spelling of the symbol than the presence of the
abstract type.)
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* expprint.c(dump_expression): Use PRINTF_HAS_LONG_LONG appropriately.
* printcmd.c(print_command): Likewise.
* valprint.c(print_longest): Likewise.
Index: src/gdb/printcmd.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/printcmd.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 printcmd.c
--- src/gdb/printcmd.c 2001/12/23 00:34:52 1.1.1.1
+++ src/gdb/printcmd.c 2001/12/24 00:58:14
@@ -2274,9 +2274,9 @@ printf_command (char *arg, int from_tty)
break;
}
case long_long_arg:
-#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG)
+#if defined (PRINTF_HAS_LONG_LONG)
{
- long long val = value_as_long (val_args[i]);
+ LONGEST val = value_as_long (val_args[i]);
printf_filtered (current_substring, val);
break;
}
Index: src/gdb/valprint.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/valprint.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 valprint.c
--- src/gdb/valprint.c 2001/12/23 00:34:57 1.1.1.1
+++ src/gdb/valprint.c 2001/12/24 00:58:14
@@ -325,7 +325,9 @@ print_longest (struct ui_file *stream, i
}
#endif
-#if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG)
+#if defined (PRINTF_HAS_LONG_LONG)
+ /* which implies cc has SOME form of 64-bit integer, but not necessary
+ spelled "long long". */
switch (format)
{
case 'd':
@@ -364,7 +366,9 @@ print_longest (struct ui_file *stream, i
default:
internal_error (__FILE__, __LINE__, "failed internal consistency check");
}
-#else /* !CC_HAS_LONG_LONG || !PRINTF_HAS_LONG_LONG */
+#endif
+
+#if !defined (CC_HAS_LONG_LONG) && !defined (PRINTF_HAS_LONG_LONG)
/* In the following it is important to coerce (val_long) to a long. It does
nothing if !LONG_LONG, but it will chop off the top half (which we know
we can ignore) if the host supports long longs. */
---------------------------------------------------------------------------
Problem: calls to the inferior's malloc() (as needed by gdb itself
upon occasion) weren't working. Cause: the (coff) symbol table
thought it was of return type T_NULL, which is equivalent to T_VOID.
(Occurs when linking stripped, MSVC-generated .o files, because
MSVC doesn't fill in the function type.)
Fix: change coffread.c to recognize T_NULL functions and make them
T_INT functions (which is in general more likely anyway.)
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* coffread.c(process_coff_symbol): Treat T_NULL function as
T_INT for internal calls.
Index: src/gdb/coffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/coffread.c,v
retrieving revision 1.3
diff -p -u -r1.3 coffread.c
--- src/gdb/coffread.c 2001/12/23 23:50:50 1.3
+++ src/gdb/coffread.c 2001/12/24 01:10:46
@@ -1532,8 +1532,21 @@ process_coff_symbol (register struct cof
if (ISFCN (cs->c_type))
{
SYMBOL_VALUE (sym) += ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- SYMBOL_TYPE (sym) =
- lookup_function_type (decode_function_type (cs, cs->c_type, aux));
+#ifdef COFF_IMAGE_WITH_PE
+ /* If we get a "function returning T_NULL" it's probably from
+ MSVC, and altho we can't say much about it, it's unlikely
+ that it really returns nothing; so we'll guess and say it
+ returns an integer (or pointer). This would mostly be a
+ nuisance except that value_allocate_space_in_inferior
+ needs somewhat meaningful type information (at least a size)
+ to successfully do things such as 'print "foo"'. */
+ if (cs->c_type == (T_NULL | (DT_FCN << N_BTSHFT)))
+ SYMBOL_TYPE(sym) = lookup_function_type (
+ decode_function_type (cs, (T_INT | (DT_FCN << N_BTSHFT)), aux));
+ else
+#endif
+ SYMBOL_TYPE (sym) =
+ lookup_function_type (decode_function_type (cs, cs->c_type, aux));
SYMBOL_CLASS (sym) = LOC_BLOCK;
if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
---------------------------------------------------------------------------
In coff_symtab_read a number of types are funneled together in a
the 'case' for C_EXT; several, but not all, need to have their
ms_type set. Add code to sort this out for PE. The
change may be applicable to other systems. (This also simplifies
some cases for C_THUMB*.)
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* coffread.c(coff_symtab_read): use symbolic name for N_DEBUG.
(coff_symtab_read): For PE, recognize several storage classes
as external for purposes of setting ms_type.
Index: src/gdb/coffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/coffread.c,v
retrieving revision 1.4
diff -p -u -r1.4 coffread.c
--- src/gdb/coffread.c 2001/12/24 01:11:37 1.4
+++ src/gdb/coffread.c 2001/12/24 01:12:11
@@ -935,24 +935,36 @@ coff_symtab_read (long symtab_offset, un
tmpaddr = reladdr;
/* The address has already been relocated; make sure that
objfile_relocate doesn't relocate it again. */
- sec = -2;
+ sec = N_DEBUG;
ms_type = cs->c_sclass == C_EXT
|| cs->c_sclass == C_THUMBEXT ?
mst_bss : mst_file_bss;
}
else
{
+ int external_class = 0;
sec = cs_to_section (cs, objfile);
tmpaddr = cs->c_value;
if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
|| cs->c_sclass == C_THUMBEXT)
- tmpaddr += ANOFFSET (objfile->section_offsets, sec);
+ {
+ tmpaddr += ANOFFSET (objfile->section_offsets, sec);
+ external_class = 1;
+ }
+#ifdef COFF_IMAGE_WITH_PE
+ /* this may be a general change */
+ if (cs->c_sclass == C_STAT || cs->c_sclass == C_LABEL ||
+ cs->c_sclass == C_SECTION)
+ {
+ tmpaddr += ANOFFSET (objfile->section_offsets, sec);
+ external_class = 1;
+ }
+#endif
if (sec == SECT_OFF_TEXT (objfile))
{
ms_type =
- cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
- || cs->c_sclass == C_THUMBEXT ?
+ cs->c_sclass == external_class ?
mst_text : mst_file_text;
#ifdef SMASH_TEXT_ADDRESS
if (tmpaddr & 1) /* FIXME: delete this line */
@@ -962,13 +974,13 @@ coff_symtab_read (long symtab_offset, un
else if (sec == SECT_OFF_DATA (objfile))
{
ms_type =
- cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
+ cs->c_sclass == external_class ?
mst_data : mst_file_data;
}
else if (sec == SECT_OFF_BSS (objfile))
{
ms_type =
- cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
+ cs->c_sclass == external_class ?
mst_data : mst_file_data;
}
else
---------------------------------------------------------------------------
PE format specific patches.
THIS MAY BE A SEP PATCH:
coffread.c/decode_function_type(): Always (why was this
ever conditional?) step on the aux symbols when decoding
the return type of a function; the aux entry always refers
to the function itself. (Interaction with the above fix; with
the aux entries present, the function type was being decoded as
a pointer to an undefined structure!)
If PE is done correctly, there is no need to handle a special case
for offsets. (This interacts with the Ian patch.)
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* coffread.c(coff_symtab_read): PE doesn't co C_LINE, C_ALIAS,
Add C_SECTION for DLLs.
(enter_linenos): MS Line numbers are off by one.
(decode_function_type): don't mis-decode function types.
(read_one_sym): Remove special case for PE
Index: src/gdb/coffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/coffread.c,v
retrieving revision 1.5
diff -p -u -r1.5 coffread.c
--- src/gdb/coffread.c 2001/12/24 01:13:11 1.5
+++ src/gdb/coffread.c 2001/12/24 01:13:39
@@ -839,8 +839,10 @@ coff_symtab_read (long symtab_offset, un
case C_EXTDEF:
case C_ULABEL:
case C_USTATIC:
+#ifndef COFF_IMAGE_WITH_PE
case C_LINE:
case C_ALIAS:
+#endif
case C_HIDDEN:
complain (&bad_sclass_complaint, cs->c_name);
break;
@@ -872,6 +874,9 @@ coff_symtab_read (long symtab_offset, un
so filter them out (from phdm@macqel.be). */
if (within_function)
break;
+#ifdef COFF_IMAGE_WITH_PE
+ case C_SECTION: /* found in some DLL libs */
+#endif
case C_STAT:
case C_THUMBLABEL:
case C_THUMBSTAT:
@@ -1416,8 +1423,14 @@ enter_linenos (long file_offset, registe
/* skip first line entry for each function */
rawptr += local_linesz;
+#ifdef COFF_IMAGE_WITH_PE
+ /* MS PE format has the last line (in .ef) as a file line number, not
+ a relative one; compensate. Also, the start is 0 based already. */
+ last_line = (last_line - first_line) + 1;
+#else
/* line numbers start at one for the first line of the function */
first_line--;
+#endif
for (;;)
{
@@ -1840,8 +1853,9 @@ static struct type *
decode_function_type (register struct coff_symbol *cs, unsigned int c_type,
register union internal_auxent *aux)
{
- if (aux->x_sym.x_tagndx.l == 0)
- cs->c_naux = 0; /* auxent refers to function, not base type */
+ /* if (aux->x_sym.x_tagndx.l == 0) */
+ cs->c_naux = 0; /* auxent refers to function, not base type;
+ don't get confused by the line numbers, etc. */
return decode_type (cs, DECREF (c_type), aux);
}
---------------------------------------------------------------------------
C_FILE entries in MSVC are multiple AUX entries, rather than
a string table entry. Handle that.
Note incidental fix of \ file separators.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* coffread.c(coff_symfile_read): Add AUX count, use to get
filename. (read_one_sym): Use aux count for C_FILE.
(coff_get_filename): Use aux count, to get to filename in
AUX entries. Also recognize \ separators.
Index: src/gdb/coffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/coffread.c,v
retrieving revision 1.6
diff -p -u -r1.6 coffread.c
--- src/gdb/coffread.c 2001/12/24 01:15:46 1.6
+++ src/gdb/coffread.c 2001/12/24 01:16:27
@@ -207,7 +207,7 @@ static int init_lineno (bfd *, long, int
static char *getsymname (struct internal_syment *);
-static char *coff_getfilename (union internal_auxent *);
+static char *coff_getfilename (union internal_auxent *, int);
static void free_stringtab (void);
@@ -612,8 +612,9 @@ coff_symfile_read (struct objfile *objfi
/* Allocate space for raw symbol and aux entries, based on their
space requirements as reported by BFD. */
+ /* allocate BUFSIZ worth more entries... see C_FILE for why */
temp_sym = (char *) xmalloc
- (cdata->local_symesz + cdata->local_auxesz);
+ (cdata->local_symesz + local_auxesz*(BUFSIZ/local_auxesz+1));
temp_aux = temp_sym + cdata->local_symesz;
back_to = make_cleanup (free_current_contents, &temp_sym);
@@ -852,7 +853,7 @@ coff_symtab_read (long symtab_offset, un
or symnum of first global after last .file. */
next_file_symnum = cs->c_value;
if (cs->c_naux > 0)
- filestring = coff_getfilename (&main_aux);
+ filestring = coff_getfilename (&main_aux, cs->c_naux);
else
filestring = "";
@@ -1189,8 +1190,10 @@ read_one_sym (register struct coff_symbo
0, cs->c_naux, (char *) aux);
/* If more than one aux entry, read past it (only the first aux
is important). */
+ /* not really... put the rest where we can find them for the moment,
+ see C_FILE */
for (i = 1; i < cs->c_naux; i++)
- bfd_bread (temp_aux, local_auxesz, nlist_bfd_global);
+ bfd_bread (&temp_aux[i*local_auxesz], local_auxesz, nlist_bfd_global);
}
cs->c_name = getsymname (sym);
cs->c_value = sym->n_value;
@@ -1321,27 +1324,35 @@ getsymname (struct internal_syment *symb
only the last component of the name. Result is in static storage and
is only good for temporary use. */
+/* The MSVC C might choose to use more than one AUX entry ! */
+
static char *
-coff_getfilename (union internal_auxent *aux_entry)
+coff_getfilename (union internal_auxent *aux_entry, int naux)
{
static char buffer[BUFSIZ];
- register char *temp;
+ char *temp1, *temp2;
char *result;
if (aux_entry->x_file.x_n.x_zeroes == 0)
strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_offset);
else
{
- strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);
- buffer[FILNMLEN] = '\0';
+ /* MS C stuffs multiple AUX entries rather than adding
+ to the string table. Fish it out of temp_aux */
+ strncpy (buffer, temp_aux, local_auxesz*naux);
+ buffer[local_auxesz*naux] = '\0';
}
result = buffer;
/* FIXME: We should not be throwing away the information about what
directory. It should go into dirname of the symtab, or some such
place. */
- if ((temp = strrchr (result, '/')) != NULL)
- result = temp + 1;
+ temp1 = strrchr (result, '/');
+ temp2 = strrchr (result, '\\');
+ if (temp2 != NULL && (temp1 == NULL || temp2 > temp1))
+ temp1 = temp2;
+ if (temp1 != NULL)
+ result = temp1 + 1;
return (result);
}
\f
---------------------------------------------------------------------------
Relinking the result of ld -r did not take kindly to having
multiple .text symbols, as required by coffread/coff_symtab_read().
Change coff_symtab_read() to not require .text; it was being
used to separate the various input "files" in the symbol table,
and to provide the "section" size for that file. Use C_FILE
and the information in the AUX record for the functions to determine
the same information without reference to the .text. (Multiple
instances of the same symbol do seem wrong, so the fix was made
here.)
Inferring the range of symbols for a "file" (C_FILE entry) needed
to be smarter to get Alpha unwind working around crt0. (Specifically,
identifying the full size of entry_file). We need to keep the range
from the first function in a file until we find another file, and
make the range of the prior file be from that saved entry until
the first function in the new file. Yes, this is guesswork,
but it works.
(range_symtab is a convenience function.)
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
*coffread.c(range_symtab): New, for below.
(complete_symtab): Use (incidentally).
(coff_symtab_read): use C_FILE to separate modules; uses above.
Index: src/gdb/coffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/coffread.c,v
retrieving revision 1.7
diff -p -u -r1.7 coffread.c
--- src/gdb/coffread.c 2001/12/24 01:17:33 1.7
+++ src/gdb/coffread.c 2001/12/24 01:18:05
@@ -439,6 +439,18 @@ coff_start_symtab (char *name)
record_debugformat ("COFF");
}
+static void
+range_symtab(start_addr, end_addr)
+ CORE_ADDR start_addr;
+ CORE_ADDR end_addr;
+{
+ if (current_objfile->ei.entry_point >= start_addr &&
+ current_objfile->ei.entry_point < end_addr)
+ {
+ current_objfile->ei.entry_file_lowpc = start_addr;
+ current_objfile->ei.entry_file_highpc = end_addr;
+ }
+}
/* Save the vital information from when starting to read a file,
for use when closing off the current file.
NAME is the file name the symbols came from, START_ADDR is the first
@@ -453,12 +465,7 @@ complete_symtab (char *name, CORE_ADDR s
current_source_start_addr = start_addr;
current_source_end_addr = start_addr + size;
- if (current_objfile->ei.entry_point >= current_source_start_addr &&
- current_objfile->ei.entry_point < current_source_end_addr)
- {
- current_objfile->ei.entry_file_lowpc = current_source_start_addr;
- current_objfile->ei.entry_file_highpc = current_source_end_addr;
- }
+ range_symtab(current_source_start_addr,current_source_end_addr);
}
/* Finish the symbol definitions for one main source file,
@@ -760,6 +767,33 @@ coff_symtab_read (long symtab_offset, un
int val;
CORE_ADDR tmpaddr;
+ /* On the use of the following symbols: Earlier versions of this routine
+ tried to key off .text entries to determine the size of a "file"
+ (an original source file). This implied that there were as many
+ .text entries as there were .o files in the link. That was OK as
+ long as ld -r wasn't involved. Linking the result of ld -r requires
+ that there be only one .text symbol (otherwise, which one do you
+ relocate against?) (There was also a FIXME against using the symbol
+ ".text" for that comparison.) The only information used from the
+ multiple .text symbols was the section size to determine where the
+ code ended. With the .text symbols gone, some other way to determine
+ the size had to be found. The three symbols below accomplish that
+ based on the function symbols themselves (and the .ef, if present).
+ first_function_this_file is the RVA of the first function
+ found after a C_FILE entry. most_recent_function_end is the
+ RVA of the end of the most recent function found. The size
+ of the "file" can be determined from the difference between
+ most_recent_function_end and first_function_this_file.
+
+ A zero value for first_function_this_file indicates that no function
+ has been found since the last C_FILE . That's used both to capture
+ the first one, and to indicate a "file" with no content, which needs
+ to be handled slightly specially. (More on that below.) */
+
+ CORE_ADDR first_function_this_file;
+ CORE_ADDR first_function_last_file;
+ CORE_ADDR most_recent_function_end;
+
/* Work around a stdio bug in SunOS4.1.1 (this makes me nervous....
it's hard to know I've really worked around it. The fix should be
harmless, anyway). The symptom of the bug is that the first
@@ -794,8 +828,16 @@ coff_symtab_read (long symtab_offset, un
xmalloc (type_vector_length * sizeof (struct type *));
memset (type_vector, 0, type_vector_length * sizeof (struct type *));
+ /* If the first line isn't a C_FILE, it's benign to create an empty symtab;
+ it'll get discarded almost immediately, so if it simplifies the code.... */
coff_start_symtab ("");
+ first_function_this_file = most_recent_function_end = 0;
+ /* If the first file (crt0.o) is not debuggable (which is probably
+ the case) and starts with static functions (also likely), we'll
+ want to use the beginning of the text section instead. */
+ first_function_last_file = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT(objfile));
+
symnum = 0;
while (symnum < nsyms)
{
@@ -803,8 +845,18 @@ coff_symtab_read (long symtab_offset, un
read_one_sym (cs, &main_sym, &main_aux);
+ /* Global symbols after the last C_FILE */
if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
{
+ if (first_function_this_file != 0)
+ complete_symtab (filestring,
+ first_function_this_file
+ + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT(objfile)),
+ most_recent_function_end == 0
+ ? 0:most_recent_function_end - first_function_this_file);
+ else
+ complete_symtab (filestring, 0, 0);
+
if (last_source_file)
coff_end_symtab (objfile);
@@ -821,16 +873,70 @@ coff_symtab_read (long symtab_offset, un
/* Typedefs should not be treated as symbol definitions. */
if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
{
+
+ if (first_function_this_file == 0)
+ first_function_this_file = cs->c_value;
+ else
+ {
+ /* most_recent_function _nd should be AT LEAST the beginning
+ of the current function if we're on other than the first
+ function in the file. We'll try to do better below. */
+ most_recent_function_end = cs->c_value;
+ }
+
/* Record all functions -- external and static -- in minsyms. */
tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
record_minimal_symbol (cs->c_name, tmpaddr, mst_text, objfile,
coff_section_from_bfd_index(objfile->obfd, cs->c_secnum));
+ if (cs->c_naux > 0)
+ {
+ fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
+ fcn_aux_saved = main_aux;
+ most_recent_function_end = cs->c_value +
+ main_aux.x_sym.x_misc.x_fsize;
+ }
+ else
+ {
+ /* Aux is trash; pretend it's zeros; this can happen
+ if debugging is turned off (at least on MSVC); for
+ most_recent_function_end we'll use zero (as a flag).
+ In some cases, we use the beginning as it's good enough,
+ but when we can infer a better size at the beginning of
+ the next function, we'll use that. That's OK since we can't
+ debug symbolically anyway. (In some instances (PE) a size
+ might be in an .ef record, but so far, .ef and this aux go
+ together so there's no point in trying that.)
+
+ FIXME: if/when we start parsing .pdata, we can do MUCH
+ better if it's available. */
+
+ fcn_line_ptr = 0;
+ memset((void *)&fcn_aux_saved, 0, sizeof(fcn_aux_saved));
+ }
+
fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
fcn_start_addr = tmpaddr;
fcn_cs_saved = *cs;
fcn_sym_saved = main_sym;
fcn_aux_saved = main_aux;
+
+ /* If first_function_last file is nonzero, we had gotten a sizeless
+ function earlier; we keep going until we DO get a size, and
+ presume that everthing in the range up to the current function
+ is a single file. */
+ if (most_recent_function_end != 0)
+ {
+ if (first_function_last_file != 0)
+ range_symtab(first_function_last_file, tmpaddr-1);
+ first_function_last_file = 0;
+ }
+ else
+ {
+ if (first_function_last_file == 0)
+ first_function_last_file = tmpaddr;
+ }
+
continue;
}
@@ -849,6 +955,18 @@ coff_symtab_read (long symtab_offset, un
break;
case C_FILE:
+ /* Complete symbol table for last object file
+ containing debugging information. */
+ if (first_function_this_file != 0)
+ complete_symtab (filestring,
+ first_function_this_file
+ + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
+ most_recent_function_end == 0
+ ? 0:most_recent_function_end - first_function_this_file);
+ else
+ complete_symtab (filestring, 0, 0);
+ coff_end_symtab (objfile);
+
/* c_value field contains symnum of next .file entry in table
or symnum of first global after last .file. */
next_file_symnum = cs->c_value;
@@ -857,14 +975,9 @@ coff_symtab_read (long symtab_offset, un
else
filestring = "";
- /* Complete symbol table for last object file
- containing debugging information. */
- if (last_source_file)
- {
- coff_end_symtab (objfile);
- coff_start_symtab (filestring);
- }
- in_source_file = 1;
+ coff_start_symtab (filestring);
+
+ first_function_this_file = 0;
break;
/* C_LABEL is used for labels and static functions. Including
@@ -884,20 +997,7 @@ coff_symtab_read (long symtab_offset, un
case C_THUMBSTATFUNC:
if (cs->c_name[0] == '.')
{
- if (STREQ (cs->c_name, ".text"))
- {
- /* FIXME: don't wire in ".text" as section name
- or symbol name! */
- /* Check for in_source_file deals with case of
- a file with debugging symbols
- followed by a later file with no symbols. */
- if (in_source_file)
- complete_symtab (filestring,
- cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile)),
- main_aux.x_scn.x_scnlen);
- in_source_file = 0;
- }
- /* flush rest of '.' symbols */
+ /* flush '.' symbols */
break;
}
else if (!SDB_TYPE (cs->c_type)
@@ -1155,8 +1255,14 @@ coff_symtab_read (long symtab_offset, un
}
}
- if (last_source_file)
- coff_end_symtab (objfile);
+ if (first_function_this_file != 0)
+ complete_symtab (filestring,
+ first_function_this_file
+ + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT(objfile)),
+ most_recent_function_end == 0
+ ? 0:most_recent_function_end - first_function_this_file);
+ else
+ complete_symtab (filestring, 0, 0);
/* Patch up any opaque types (references to types that are not defined
in the file where they are referenced, e.g. "struct foo *bar"). */
---------------------------------------------------------------------------
Get rid of local labels on Intel/coff/PE.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* coffread.c (coff_symtab_read): don't record L... symbols.
Index: src/gdb/coffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/coffread.c,v
retrieving revision 1.8
diff -p -u -r1.8 coffread.c
--- src/gdb/coffread.c 2001/12/24 01:18:57 1.8
+++ src/gdb/coffread.c 2001/12/24 01:28:20
@@ -1013,6 +1013,11 @@ coff_symtab_read (long symtab_offset, un
/* At least on a 3b1, gcc generates swbeg and string labels
that look like this. Ignore them. */
break;
+ /* On Intel, local names can be Lnnn; we can discard them
+ (and lots of other junk) if there's a leading char. */
+ if (bfd_get_symbol_leading_char(objfile->obfd) &&
+ cs->c_name[0] != bfd_get_symbol_leading_char(objfile->obfd))
+ break;
/* fall in for static symbols that don't start with '.' */
case C_THUMBEXT:
case C_THUMBEXTFUNC:
---------------------------------------------------------------------------
Recognize absolute symbols and mark them as such; some
absolutes were coming in the middle of code space, confusing bt
badly.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* coffread.c(coff_symtab_read): recognize absolute symbols.
Index: src/gdb/coffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/coffread.c,v
retrieving revision 1.9
diff -p -u -r1.9 coffread.c
--- src/gdb/coffread.c 2001/12/24 01:29:07 1.9
+++ src/gdb/coffread.c 2001/12/24 01:30:09
@@ -1029,11 +1029,16 @@ coff_symtab_read (long symtab_offset, un
print_address_symbolic work right without the (now
gone) "set fast-symbolic-addr off" kludge. */
- /* FIXME: should use mst_abs, and not relocate, if absolute. */
enum minimal_symbol_type ms_type;
int sec;
- if (cs->c_secnum == N_UNDEF)
+ if (cs->c_secnum == N_ABS)
+ {
+ tmpaddr = cs->c_value;
+ sec = N_ABS;
+ ms_type = mst_abs;
+ }
+ else if (cs->c_secnum == N_UNDEF)
{
/* This is a common symbol. See if the target
environment knows where it has been relocated to. */
---------------------------------------------------------------------------
On the 386 architecture (at least for NT), large frames are created
by an implied call to _alloca. To determine the frame size, we must
decode the call instead of the inline instructions.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* i386-tdep.c(i386_get_frame_setup): Recognize/interpret
_alloca called for stack growth. Remove unused "buf".
Index: src/gdb/i386-tdep.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/i386-tdep.c,v
retrieving revision 1.3
diff -p -u -r1.3 i386-tdep.c
--- src/gdb/i386-tdep.c 2001/12/24 00:57:24 1.3
+++ src/gdb/i386-tdep.c 2001/12/24 01:31:42
@@ -324,6 +324,10 @@ static long
i386_get_frame_setup (CORE_ADDR pc)
{
unsigned char op;
+ boolean saw_size_setup = false;
+ int size = 0;
+ char buf[4];
+ int saved_pc = 0;
codestream_seek (pc);
@@ -396,19 +400,37 @@ i386_get_frame_setup (CORE_ADDR pc)
if (op == 0x55) /* pushl %ebp */
{
- /* Check for "movl %esp, %ebp" -- can be written in two ways. */
- switch (codestream_get ())
+ while(1)
{
- case 0x8b:
- if (codestream_get () != 0xec)
- return -1;
- break;
- case 0x89:
- if (codestream_get () != 0xe5)
- return -1;
- break;
- default:
- return -1;
+ switch (codestream_get ())
+ {
+ /* check for "movl %esp, %ebp" -- can be written two ways */
+ case 0x8b:
+ if (codestream_get () != 0xec)
+ return -1;
+ break;
+ case 0x89:
+ if (codestream_get () != 0xe5)
+ return -1;
+ break;
+
+ /* Could be a setup for a "big" stack frame, pushed up
+ before the movl %esp,%ebp; big frames push the frame
+ size and then call _alloca to do the stack probes. */
+ case 0xb8:
+ /* get the frame size from the instruction; we're NOT
+ yet sure we have this kind of frame, but it seems
+ likely. */
+ saved_pc = codestream_tell();
+ codestream_read ((unsigned char *)buf, 4);
+ size = extract_signed_integer (buf, 4);
+ saw_size_setup = true;
+ continue;
+
+ default:
+ return -1;
+ }
+ break;
}
/* Check for stack adjustment
@@ -417,8 +439,9 @@ i386_get_frame_setup (CORE_ADDR pc)
NOTE: You can't subtract a 16 bit immediate from a 32 bit
reg, so we don't have to worry about a data16 prefix. */
op = codestream_peek ();
- if (op == 0x83)
+ switch(op)
{
+ case 0x83:
/* `subl' with 8 bit immediate. */
codestream_get ();
if (codestream_get () != 0xec)
@@ -430,9 +453,8 @@ i386_get_frame_setup (CORE_ADDR pc)
/* `subl' with signed byte immediate (though it wouldn't
make sense to be negative). */
return (codestream_get ());
- }
- else if (op == 0x81)
- {
+ case 0x81:
+ {
char buf[4];
/* Maybe it is `subl' with a 32 bit immedediate. */
codestream_get ();
@@ -445,15 +467,52 @@ i386_get_frame_setup (CORE_ADDR pc)
/* It is `subl' with a 32 bit immediate. */
codestream_read ((unsigned char *) buf, 4);
return extract_signed_integer (buf, 4);
- }
- else
- {
+ }
+
+ case 0xb8:
+ /* Could be a setup for a "big" stack frame; big frames push the
+ frame size and then call _alloca to do the stack probes. */
+ /* get the frame size from the instruction; we're NOT
+ yet sure we have this kind of frame, but it seems
+ likely. */
+ saved_pc = codestream_tell ();
+ codestream_read ((unsigned char *)buf, 4);
+ size = extract_signed_integer (buf, 4);
+ saw_size_setup = true;
+ if (codestream_peek () != 0xe8)
+ {
+ codestream_seek(saved_pc);
+ return 0;
+ }
+ /* drop thru */
+
+ case 0xe8:
+ {
+ CORE_ADDR pc;
+ char *name;
+ if (!saw_size_setup)
+ return 0;
+ /* now we're sure it's a "big" frame */
+ codestream_get();
+ /* get target of putative alloca call */
+ codestream_read ((unsigned char *)buf, 4);
+ pc = extract_signed_integer (buf, 4) + codestream_tell();
+ find_pc_partial_function(pc, &name, NULL, NULL);
+ if (! name || ! STREQ (name, "_alloca"))
+ {
+ /* oops, not a call to _alloca... back out */
+ codestream_seek(saved_pc);
+ return -1;
+ }
+ return size;
+ }
+
+ default:
return 0;
- }
+ }
}
else if (op == 0xc8)
{
- char buf[2];
/* `enter' with 16 bit unsigned immediate. */
codestream_read ((unsigned char *) buf, 2);
codestream_get (); /* Flush final byte of enter instruction. */
---------------------------------------------------------------------------
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* coffread.c(enter_linenos): if no line numbers, just skip.
Index: src/gdb/coffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/coffread.c,v
retrieving revision 1.10
diff -p -u -r1.10 coffread.c
--- src/gdb/coffread.c 2001/12/24 01:31:02 1.10
+++ src/gdb/coffread.c 2001/12/24 01:35:28
@@ -1538,6 +1538,9 @@ enter_linenos (long file_offset, registe
if (!linetab)
return;
+ /* no line numbers recorded in the function (-g1) */
+ if (file_offset == 0)
+ return;
if (file_offset < linetab_offset)
{
complain (&lineno_complaint, file_offset);
---------------------------------------------------------------------------
The first change turned off (but not removed) pending regression results;
it looks as if it's already happening correctly.
Better diagnostics; distinguish between program not being run
and floating point not present (in running application).
(The change might also be applicable to non-default cases.)
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* arch_utils.c(default_print_float_info): report no inferior separately.
* default.exp: adjust expected message in info float.
Index: src/gdb/arch-utils.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/arch-utils.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 arch-utils.c
--- src/gdb/arch-utils.c 2001/12/23 00:34:49 1.1.1.1
+++ src/gdb/arch-utils.c 2001/12/24 01:36:53
@@ -232,6 +232,8 @@ default_print_float_info (void)
#if GDB_MULTI_ARCH > GDB_MULTI_ARCH_PARTIAL
#error "FLOAT_INFO defined in multi-arch"
#endif
+ //if (!target_has_execution)
+ //noprocess ();
FLOAT_INFO;
#else
printf_filtered ("No floating point info available for this processor.\n");
Index: src/gdb/testsuite/gdb.base/default.exp
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/default.exp,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 default.exp
--- src/gdb/testsuite/gdb.base/default.exp 2001/12/23 00:35:16 1.1.1.1
+++ src/gdb/testsuite/gdb.base/default.exp 2001/12/24 01:36:53
@@ -308,7 +308,15 @@ if [istarget "arm*-*-*"] then {
} elseif [istarget "i\[3456\]86-*-*"] then {
gdb_test "info float" "R7:.*Status Word:.*Opcode:.*" "info float"
} else {
- gdb_test "info float" "No floating point info available for this processor." "info float"
+ send_gdb "info float\n"
+ gdb_expect {
+ -re "No floating point info available for this processor.*$gdb_prompt $" \
+ { pass "info float (none available)" }
+ -re "The program is not being run.*$gdb_prompt $" \
+ { pass "info float (no current process)" }
+ -re ".*$gdb_prompt $" { fail "info float (unexpcted)" }
+ timeout { fail "info float (timeout)" }
+ }
}
#test info functions
gdb_test "info functions" "All defined functions:" "info functions"
---------------------------------------------------------------------------
The value that appears residually in an "empty" floating point
register can sometimes be a help in intuiting the nature of a bug,
so print it even if the register is empty.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* i387-tdep.c (i387_float_info): Remove condition.
Index: src/gdb/i387-tdep.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/i387-tdep.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 i387-tdep.c
--- src/gdb/i387-tdep.c 2001/12/23 00:34:48 1.1.1.1
+++ src/gdb/i387-tdep.c 2001/12/24 01:39:44
@@ -367,8 +367,7 @@ i387_float_info (void)
for (i = 9; i >= 0; i--)
printf_filtered ("%02x", raw[i]);
- if (tag != 3)
- print_i387_ext (raw);
+ print_i387_ext (raw);
puts_filtered ("\n");
}
---------------------------------------------------------------------------
Various changes to pretty printing the register display; on
the Alpha the register display was nearly unreadable due to
ragged columns, and with a large number of registers, a key
is needed. It helps a bit on other machines as well.
print_scalar_formated(): treat the new format letters
'b', 'h', 'w', 'g' as synonyms for 'xb', etc. The path from
do_registers_info to here has no way to carry the size of the
register directly, so we encode it in the format. (Yeah, it's
not beautiful, but it works.) This may have the side
effect of occasionally allowing (at the command level) a size
to be substituted for a format, but that seems benign.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* infcmd.c(do_registers_info): print register number,
supply format to get constant width output.
* printcmd.c(print_scalar_formatted): honor formats for
constant width.
Index: src/gdb/infcmd.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/infcmd.c,v
retrieving revision 1.2
diff -p -u -r1.2 infcmd.c
--- src/gdb/infcmd.c 2001/12/24 01:39:10 1.2
+++ src/gdb/infcmd.c 2001/12/24 01:41:24
@@ -1593,6 +1593,11 @@ do_registers_info (int regnum, int fpreg
int numregs = NUM_REGS + NUM_PSEUDO_REGS;
char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE);
char *virtual_buffer = (char*) alloca (MAX_REGISTER_VIRTUAL_SIZE);
+ static const char sizenames[] =
+ {'b', 'b', /* 0-1 */
+ 'h', /* 2-2 */
+ 'w', 'w', /* 3-4 */
+ 'g', 'g', 'g', 'g' /* 5-8 */};
for (i = 0; i < numregs; i++)
{
@@ -1614,7 +1619,8 @@ do_registers_info (int regnum, int fpreg
continue;
fputs_filtered (REGISTER_NAME (i), gdb_stdout);
- print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), gdb_stdout);
+ print_spaces_filtered (6 - strlen (REGISTER_NAME (i)), gdb_stdout);
+ printf_filtered("(%2d) ",i);
/* Get the data in raw format. */
if (read_relative_register_raw_bytes (i, raw_buffer))
@@ -1660,8 +1666,11 @@ do_registers_info (int regnum, int fpreg
/* Else print as integer in hex and in decimal. */
else
{
+ /* by using sizenames, we get constant width numbers for each
+ register type, which keeps the columns from being as ragged */
val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
- gdb_stdout, 'x', 1, 0, Val_pretty_default);
+ gdb_stdout, sizenames[REGISTER_VIRTUAL_SIZE(i)],
+ 1, 0, Val_pretty_default);
printf_filtered ("\t");
val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, 0,
gdb_stdout, 0, 1, 0, Val_pretty_default);
Index: src/gdb/printcmd.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/printcmd.c,v
retrieving revision 1.2
diff -p -u -r1.2 printcmd.c
--- src/gdb/printcmd.c 2001/12/24 01:10:20 1.2
+++ src/gdb/printcmd.c 2001/12/24 01:41:24
@@ -407,6 +407,14 @@ print_scalar_formatted (char *valaddr, s
switch (format)
{
+ case 'b':
+ case 'h':
+ case 'w':
+ case 'g':
+ /* to allow a fixed width hex format; not intended for command line
+ use, but from the "info reg" command and the like. */
+ size = format;
+ /* drop thru */
case 'x':
if (!size)
{
---------------------------------------------------------------------------
This has gotten trimmed further; further testing indicated.
CONSIDER SPLIT INTO 2 PARTS.
Long signal names caused ragged columns and linewraps, making "handle
all print" output difficult to read. (And corresponding regression changes.)
(See particularly the MACH_ stuff.)
If there is a mismatch between the system and the debugger on the
list of supported signals, the user doesn't get any information about
the host signal number. Provide at least the host number (so labeled).
Don't try to deal with signals not supported by the host. (And
corresponding regression changes.)
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* infrun.c(sig_print_header): New column alignment so that longer
signal names print without tabs messing up.
(sig_print_info): Likewise.
(handle_command): Report unsupported signals, don't try to print
info about them (and die).
(signals_info): Likewise.
* target.c(target_signal_to_name): Provide host number for
unknown signals. (target_signal_from_host): save host number.
(do_target_signal_to_host): if no realtime signals, don't
pretend that 32 exists.
* gdb.base/sigall.exp: Update for new messages from above.
Index: src/gdb/infrun.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/infrun.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 infrun.c
--- src/gdb/infrun.c 2001/12/23 00:34:49 1.1.1.1
+++ src/gdb/infrun.c 2001/12/24 01:42:41
@@ -3630,14 +3630,14 @@ static void
sig_print_header (void)
{
printf_filtered ("\
-Signal Stop\tPrint\tPass to program\tDescription\n");
+Signal Stop Print -> program Description\n");
}
static void
sig_print_info (enum target_signal oursig)
{
char *name = target_signal_to_name (oursig);
- int name_padding = 13 - strlen (name);
+ int name_padding = 20 - strlen (name);
if (name_padding <= 0)
name_padding = 0;
@@ -3645,9 +3645,9 @@ sig_print_info (enum target_signal oursi
printf_filtered ("%s", name);
printf_filtered ("%*.*s ", name_padding, name_padding,
" ");
- printf_filtered ("%s\t", signal_stop[oursig] ? "Yes" : "No");
- printf_filtered ("%s\t", signal_print[oursig] ? "Yes" : "No");
- printf_filtered ("%s\t\t", signal_program[oursig] ? "Yes" : "No");
+ printf_filtered ("%s ", signal_stop[oursig] ? "Yes" : "No ");
+ printf_filtered ("%s ", signal_print[oursig] ? "Yes" : "No ");
+ printf_filtered ("%s ", signal_program[oursig] ? "Yes" : "No ");
printf_filtered ("%s\n", target_signal_to_string (oursig));
}
@@ -3809,6 +3809,9 @@ Are you sure you want to change it? ",
/* Make sure that "all" doesn't print these. */
break;
default:
+ if (!allsigs && !sigs[signum] &&
+ !target_signal_to_host_p(signum))
+ error("Signal %d not supported by this machine\n", signum);
sigs[signum] = 1;
break;
}
@@ -3825,7 +3828,7 @@ Are you sure you want to change it? ",
sig_print_header ();
for (signum = 0; signum < nsigs; signum++)
{
- if (sigs[signum])
+ if (sigs[signum] && target_signal_to_host_p(signum))
{
sig_print_info (signum);
}
@@ -3923,7 +3926,10 @@ signals_info (char *signum_exp, int from
oursig =
target_signal_from_command (parse_and_eval_long (signum_exp));
}
- sig_print_info (oursig);
+ if (!target_signal_to_host_p(oursig))
+ printf_filtered("That signal is not defined on this system\n");
+ else
+ sig_print_info (oursig);
return;
}
@@ -3935,9 +3941,7 @@ signals_info (char *signum_exp, int from
{
QUIT;
- if (oursig != TARGET_SIGNAL_UNKNOWN
- && oursig != TARGET_SIGNAL_DEFAULT
- && oursig != TARGET_SIGNAL_0)
+ if (target_signal_to_host_p(oursig))
sig_print_info (oursig);
}
Index: src/gdb/signals/signals.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/signals/signals.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 signals.c
--- src/gdb/signals/signals.c 2001/12/23 00:34:55 1.1.1.1
+++ src/gdb/signals/signals.c 2001/12/24 01:42:41
@@ -206,16 +206,24 @@ target_signal_to_string (enum target_sig
return signals[TARGET_SIGNAL_UNKNOWN].string;
}
+int saved_hostsig = 0;
+
/* Return the name for a signal. */
char *
target_signal_to_name (enum target_signal sig)
{
+ static char buf[10];
+
if ((sig >= TARGET_SIGNAL_FIRST) && (sig <= TARGET_SIGNAL_LAST)
&& signals[sig].name != NULL)
return signals[sig].name;
else
- /* I think the code which prints this will always print it along
- with the string, so no need to be verbose (very old comment). */
+ {
+ /* I think the code which prints this will always print it along
+ with the string, so no need to be verbose (very old comment). */
+ sprintf(buf, "?(host#=%d)", saved_hostsig);
+ return buf;
+ }
return "?";
}
@@ -499,6 +507,7 @@ target_signal_from_host (int hostsig)
error ("GDB bug: target.c (target_signal_from_host): unrecognized real-time signal");
}
#endif
+ saved_hostsig = hostsig;
return TARGET_SIGNAL_UNKNOWN;
}
Index: src/gdb/testsuite/gdb.base/sigall.exp
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/sigall.exp,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 sigall.exp
--- src/gdb/testsuite/gdb.base/sigall.exp 2001/12/23 00:35:18 1.1.1.1
+++ src/gdb/testsuite/gdb.base/sigall.exp 2001/12/24 01:42:41
@@ -46,14 +46,24 @@ proc test_one_sig {nextsig} {
global gdb_prompt
global thissig
+ set need_another_continue 1
+ set missed_handler 0
set this_sig_supported $sig_supported
- gdb_test "handle SIG$thissig stop print" \
- "SIG$thissig\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes.*"
+
+ send_gdb "handle SIG$thissig stop print\n"
+ gdb_expect {
+ -re "SIG$thissig\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes.*$gdb_prompt $" {
+ pass "signal SIG$thissig handled"
+ }
+ -re "Signal \[0-9\]+ not supported by this machine.*$gdb_prompt $" {
+ set this_sig_supported 0
+ pass "signal SIG$thissig reports not supported"
+ }
+ }
+
gdb_test "b handle_$thissig" "Breakpoint \[0-9\]+ .*"
gdb_test "b gen_$nextsig" "Breakpoint \[0-9\]+ .*"
- set need_another_continue 1
- set missed_handler 0
if $this_sig_supported then {
send_gdb "continue\n"
if { $thissig == "IO" } {
Index: src/gdb/testsuite/gdb.base/signals.exp
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/signals.exp,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 signals.exp
--- src/gdb/testsuite/gdb.base/signals.exp 2001/12/23 00:35:18 1.1.1.1
+++ src/gdb/testsuite/gdb.base/signals.exp 2001/12/24 01:42:41
@@ -337,6 +337,7 @@ gdb_start
# TARGET_SIGNAL_UNKNOWN are skipped.
proc test_handle_all_print {} {
global timeout
+ global gdb_prompt
# Increase timeout and expect input buffer for large output from gdb.
# Allow blank or TAB as whitespace characters.
set oldtimeout $timeout
@@ -345,10 +346,31 @@ proc test_handle_all_print {} {
if { ![istarget "*-*-linux*"]
&& ( [istarget "*-*-gnu*"]
|| [istarget "*-*-mach*"] ) } {
- gdb_test "handle all print" "Signal\[ \]+Stop\[ \]+Print\[ \]+Pass to program\[ \]+Description\r\nSIGHUP\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Hangup.*SIG63\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Real-time event 63.*EXC_BREAKPOINT\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Breakpoint"
+ gdb_test "handle all print" "Signal\[ \]+Stop\[ \]+Print\[ \]+-> program\[ \]+Description\r\nSIGHUP\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Hangup\r\n.*SIG63\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Real-time event 63.*EXC_BREAKPOINT\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Breakpoint"
} else {
- gdb_test "handle all print" "Signal\[ \]+Stop\[ \]+Print\[ \]+Pass to program\[ \]+Description\r\nSIGHUP\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Hangup.*SIG63\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Real-time event 63.*"
+ gdb_test "handle all print" "Signal\[ \]+Stop\[ \]+Print\[ \]+-> program\[ \]+Description\r\nSIGHUP\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Hangup\r\n.*SIGUSR2\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+User defined signal 2\r\n.*"
}
+
+ send_gdb "handle all print\n"
+
+ # test for the prefix that we always require
+ gdb_expect {
+ -re "Signal\[ \]+Stop\[ \]+Print\[ \]+-> program\[ \]+Description\r\nSIGHUP\[ \]+Yes\[ \]+Yes\[ \]+Yes\[ \]+Hangup\r\n.*$gdb_prompt $" { pass "Signal list prefix" }
+ -re ".*$gdb_prompt $" { fail "No signal list" }
+ timeout { fail "No signal list; (timeout)" }
+ }
+
+ # Now test for some things we DON'T want, as well as looking for
+ # the next prompt.
+ send_gdb "handle all print\n"
+ gdb_expect {
+ -re ".*TARGET_SIGNAL_0.*$gdb_prompt $" { fail "TARGET_SIGNAL_0 should not be found" }
+ -re ".*TARGET_SIGNAL_DEFAULT.*$gdb_prompt $" { fail "TARGET_SIGNAL_DEFAULT should not be found" }
+ -re ".*TARGET_SIGNAL_UNKNOWN.*$gdb_prompt $" { fail "TARGET_SIGNAL_UNKNOWN should not be found" }
+ -re ".*$gdb_prompt $" { pass "handle print all" }
+ timeout { fail "Junk in signal list; (timeout)" }
+ }
+
set timeout $oldtimeout
verbose "Timeout restored to $timeout seconds" 2
}
@@ -422,15 +444,39 @@ The program being debugged stopped while
gdb_test "p count" "= 5" "p count #2 in signals.exp"
-# Verify that "info signals" produces reasonable output.
-#
+# Verify that "info signals" produces reasonable output. We're confirming
+# that there are no suprise signal names, but want to allow the nonportable
+# signals to be omitted. Note that some signals are expected to always
+# be present; whether this is exactly the right set I'm not sure. Making
+# them all optional seems very wrong.
+
+# Workaround bug in expect: the single RE that should be able to do this
+# is (probably) too long, so we use 3 shorter gdb_expect calls, each looking
+# for part of it.
+
send_gdb "info signals\n"
+ gdb_expect {
+ -re ".*SIGHUP\[^\r]*\r\nSIGINT\[^\r]*\r\nSIGQUIT\[^\r]*\r\nSIGILL\[^\r]*\r\nSIGTRAP\[^\r]*\r\nSIGABRT\[^\r]*\r\n(SIGEMT\[^\r]*\r\n|)SIGFPE\[^\r]*\r\nSIGKILL\[^\r]*\r\nSIGBUS\[^\r]*\r\nSIGSEGV\[^\r]*\r\nSIGSYS\[^\r]*\r\nSIGPIPE\[^\r]*\r\nSIGALRM\[^\r]*\r\nSIGTERM\[^\r]*\r\nSIGURG\[^\r]*\r\nSIGSTOP\[^\r]*\r\nSIGTSTP\[^\r]*\r\nSIGCONT\[^\r]*\r\nSIGCHLD\[^\r]*\r\nSIGTTIN\[^\r]*\r\nSIGTTOU\[^\r]*\r\nSIGIO\[^\r]*\r\nSIGXCPU\[^\r]*\r\nSIGXFSZ\[^\r]*\r\nSIGVTALRM\[^\r]*\r\nSIGPROF\[^\r]*\r\nSIGWINCH\[^\r]*\r\n(SIGLOST\[^\r]*\r\n|)SIGUSR1\[^\r]*\r\nSIGUSR2\[^\r]*\r\n(SIGPWR\[^\r]*\r\n|)(SIGPOLL\[^\r]*\r\n|)(SIGWIND\[^\r]*\r\n|)(SIGPHONE\[^\r]*\r\n|)(SIGWAITING\[^\r]*\r\n|)(SIGLWP\[^\r]*\r\n|)(SIGDANGER\[^\r]*\r\n|)(SIGGRANT\[^\r]*\r\n|)(SIGRETRACT\[^\r]*\r\n|)(SIGMSG\[^\r]*\r\n|)(SIGSOUND\[^\r]*\r\n|)(SIGSAK\[^\r]*\r\n|)(SIGPRIO\[^\r]*\r\n|)" \
+ {pass "info signals part 1"}
+ -re "$gdb_prompt $"\
+ {fail "info signals part 1"}
+ timeout {fail "(timeout) info signals part 1"}
+ }
+
+ gdb_expect {
+ -re "(SIG33\[^\r]*\r\n|)(SIG34\[^\r]*\r\n|)(SIG35\[^\r]*\r\n|)(SIG36\[^\r]*\r\n|)(SIG37\[^\r]*\r\n|)(SIG38\[^\r]*\r\n|)(SIG39\[^\r]*\r\n|)(SIG40\[^\r]*\r\n|)(SIG41\[^\r]*\r\n|)(SIG42\[^\r]*\r\n|)(SIG43\[^\r]*\r\n|)(SIG44\[^\r]*\r\n|)(SIG45\[^\r]*\r\n|)(SIG46\[^\r]*\r\n|)(SIG47\[^\r]*\r\n|)(SIG48\[^\r]*\r\n|)(SIG49\[^\r]*\r\n|)" \
+ {pass "info signals part 2"}
+ -re "$gdb_prompt $"\
+ {fail "info signals part 2"}
+ timeout {fail "(timeout) info signals part 2"}
+ }
+
gdb_expect {
- -re "SIGHUP.*SIGINT.*SIGQUIT.*SIGILL.*SIGTRAP.*SIGABRT.*SIGEMT.*SIGFPE.*SIGKILL.*SIGBUS.*SIGSEGV.*SIGSYS.*SIGPIPE.*SIGALRM.*SIGTERM.*SIGURG.*SIGSTOP.*SIGTSTP.*SIGCONT.*SIGCHLD.*SIGTTIN.*SIGTTOU.*SIGIO.*SIGXCPU.*SIGXFSZ.*SIGVTALRM.*SIGPROF.*SIGWINCH.*SIGLOST.*SIGUSR1.*SIGUSR2.*SIGPWR.*SIGPOLL.*SIGWIND.*SIGPHONE.*SIGWAITING.*SIGLWP.*SIGDANGER.*SIGGRANT.*SIGRETRACT.*SIGMSG.*SIGSOUND.*SIGSAK.*SIGPRIO.*SIG33.*SIG34.*SIG35.*SIG36.*SIG37.*SIG38.*SIG39.*SIG40.*SIG41.*SIG42.*SIG43.*SIG44.*SIG45.*SIG46.*SIG47.*SIG48.*SIG49.*SIG50.*SIG51.*SIG52.*SIG53.*SIG54.*SIG55.*SIG56.*SIG57.*SIG58.*SIG59.*SIG60.*SIG61.*SIG62.*SIG63.*Use the \"handle\" command to change these tables.*$gdb_prompt $"\
- {pass "info signals"}
+ -re "(SIG50\[^\r]*\r\n|)(SIG51\[^\r]*\r\n|)(SIG52\[^\r]*\r\n|)(SIG53\[^\r]*\r\n|)(SIG54\[^\r]*\r\n|)(SIG55\[^\r]*\r\n|)(SIG56\[^\r]*\r\n|)(SIG57\[^\r]*\r\n|)(SIG58\[^\r]*\r\n|)(SIG59\[^\r]*\r\n|)(SIG60\[^\r]*\r\n|)(SIG61\[^\r]*\r\n|)(SIG62\[^\r]*\r\n|)(SIG63\[^\r]*\r\n|).*Use the \"handle\" command to change these tables.*$gdb_prompt $" \
+ {pass "info signals part 3"}
-re "$gdb_prompt $"\
- {fail "info signals"}
- timeout {fail "(timeout) info signals"}
+ {fail "info signals part 3"}
+ timeout {fail "(timeout) info signals part 2"}
}
# Verify that "info signal" correctly handles an argument, be it a
@@ -510,9 +556,9 @@ The program being debugged stopped while
# Verify that we can "handle" multiple signals at once, interspersed
# with actions.
#
- send_gdb "handle SIG63 print SIGILL\n"
+ send_gdb "handle SIGSEGV print SIGILL\n"
gdb_expect {
- -re ".*SIGILL\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Illegal instruction.*SIG63\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Real-time event 63.*$gdb_prompt $"\
+ -re ".*SIGILL\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Illegal instruction.*SIGSEGV\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Yes\[ \t\]*Segmentation fault.*$gdb_prompt $"\
{pass "handle multiple SIGs"}
-re "$gdb_prompt $"\
{fail "handle multiple SIGs"}
---------------------------------------------------------------------------
Gdb wasn't searching the STATIC_BLOCK symtab, causing it not to
find some static functions (reporting "no linenumbers known" when
there were perfectly good line numbers in the a.out file.) The
bulk of the change is indentation changes.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* symtab.c(find_pc_sect_symtab): search STATIC_BLOCK, too,
for static functions.
Index: src/gdb/symtab.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/symtab.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 symtab.c
--- src/gdb/symtab.c 2001/12/23 00:34:56 1.1.1.1
+++ src/gdb/symtab.c 2001/12/24 02:07:12
@@ -1403,9 +1403,14 @@ find_pc_sect_symtab (CORE_ADDR pc, asect
ALL_SYMTABS (objfile, s)
{
+ int blocknum;
+
bv = BLOCKVECTOR (s);
- b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+ for (blocknum = GLOBAL_BLOCK; blocknum <= STATIC_BLOCK; blocknum++)
+ {
+// INDENTATION FIX DELAYED (until final merge).
+ b = BLOCKVECTOR_BLOCK (bv, blocknum);
if (BLOCK_START (b) <= pc
&& BLOCK_END (b) > pc
&& (distance == 0
@@ -1439,6 +1444,7 @@ find_pc_sect_symtab (CORE_ADDR pc, asect
distance = BLOCK_END (b) - BLOCK_START (b);
best_s = s;
}
+ }
}
if (best_s != NULL)
---------------------------------------------------------------------------
Normally it's a bad idea that breakpoints are left in shared libraries
while the shared library initialization is going on (for example, a
breakpoint could be set on something that's relocated). That's turned
off elsewhere. However, when debugging the shared library initialization
itself, it's desireable to leave them (and enable them one at a time
by hand, if necessary).
Debugging trampoline code and signal handler callers presents the
same sort of problem.
Wizard mode informs the debugger that you really (really, really!)
know what you're doing, and that it shouldn't protect you from
yourself (as much).
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* defs.h(wizard_mode): define.
* infrun.c(wait_for_inferior, step_into_function): allow single
step thru trampoline when in wizard mode.
* stack.c(print_frame_info): show dummys and signal handler
callers in stack for wizard mode.
* top.c(init_main): init wizard_mode, print appropriate help.
* breakpoint.c(disable_breakpoints_in_shlibs): Honor wizard mode.
Index: src/gdb/breakpoint.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/breakpoint.c,v
retrieving revision 1.2
diff -p -u -r1.2 breakpoint.c
--- src/gdb/breakpoint.c 2001/12/23 23:31:08 1.2
+++ src/gdb/breakpoint.c 2001/12/24 02:09:01
@@ -4098,6 +4098,12 @@ disable_breakpoints_in_shlibs (int silen
struct breakpoint *b;
int disabled_shlib_breaks = 0;
+ if (wizard_mode)
+ {
+ printf_filtered ("Breakpoints NOT DISABLED during relocation.\n");
+ return;
+ }
+
/* See also: insert_breakpoints, under DISABLE_UNSETTABLE_BREAK. */
ALL_BREAKPOINTS (b)
{
Index: src/gdb/defs.h
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/defs.h,v
retrieving revision 1.2
diff -p -u -r1.2 defs.h
--- src/gdb/defs.h 2001/12/23 23:01:19 1.2
+++ src/gdb/defs.h 2001/12/24 02:09:01
@@ -175,6 +175,7 @@ extern int dbx_commands;
extern int quit_flag;
extern int immediate_quit;
extern int sevenbit_strings;
+extern int wizard_mode;
extern void quit (void);
Index: src/gdb/infrun.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/infrun.c,v
retrieving revision 1.2
diff -p -u -r1.2 infrun.c
--- src/gdb/infrun.c 2001/12/24 01:44:40 1.2
+++ src/gdb/infrun.c 2001/12/24 02:09:01
@@ -2642,6 +2642,7 @@ handle_inferior_event (struct execution_
/* Did we just take a signal? */
if (PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
&& !PC_IN_SIGTRAMP (prev_pc, prev_func_name)
+ && !wizard_mode
&& INNER_THAN (read_sp (), step_sp))
{
/* We've just taken a signal; go until we are back to
@@ -2778,7 +2779,7 @@ handle_inferior_event (struct execution_
function. That's what tells us (a) whether we want to step
into it at all, and (b) what prologue we want to run to
the end of, if we do step into it. */
- tmp = SKIP_TRAMPOLINE_CODE (stop_pc);
+ tmp = wizard_mode ? 0 : SKIP_TRAMPOLINE_CODE (stop_pc);
if (tmp != 0)
ecs->stop_func_start = tmp;
else
@@ -2856,7 +2857,7 @@ handle_inferior_event (struct execution_
CORE_ADDR tmp;
/* Determine where this trampoline returns. */
- tmp = SKIP_TRAMPOLINE_CODE (stop_pc);
+ tmp = wizard_mode ? 0 : SKIP_TRAMPOLINE_CODE (stop_pc);
/* Only proceed through if we know where it's going. */
if (tmp)
@@ -4427,6 +4428,12 @@ function without debug line information
instruction of that function. Otherwise, the function is skipped and\n\
the step command stops at a different source line.",
&setlist);
+ add_show_from_set (c, &showlist);
+
+ c = add_set_cmd ("wizard-mode", class_support,
+ var_boolean, (char *) &wizard_mode,
+ "Set debugging of trampolines and other infrastructure.",
+ &setlist);
add_show_from_set (c, &showlist);
/* ptid initializations */
Index: src/gdb/stack.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/stack.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 stack.c
--- src/gdb/stack.c 2001/12/23 00:34:56 1.1.1.1
+++ src/gdb/stack.c 2001/12/24 02:09:01
@@ -340,7 +340,7 @@ print_frame_info_base (struct frame_info
to check for a bp_call_dummy breakpoint. */
if (PC_IN_CALL_DUMMY (fi->pc, sp, fi->frame))
#else
- if (frame_in_dummy (fi))
+ if (!wizard_mode && frame_in_dummy (fi))
#endif
{
annotate_frame_begin (level == -1 ? 0 : level, fi->pc);
@@ -354,7 +354,7 @@ print_frame_info_base (struct frame_info
annotate_frame_end ();
return;
}
- if (fi->signal_handler_caller)
+ if (!wizard_mode && fi->signal_handler_caller)
{
annotate_frame_begin (level == -1 ? 0 : level, fi->pc);
Index: src/gdb/top.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/top.c,v
retrieving revision 1.2
diff -p -u -r1.2 top.c
--- src/gdb/top.c 2001/12/23 23:01:19 1.2
+++ src/gdb/top.c 2001/12/24 02:09:01
@@ -93,6 +93,12 @@ extern char lang_frame_mismatch_warn[];
int caution = 1; /* Default is yes, sigh. */
+/* This is non-zero when we want to debug the infrastructure, such as
+ single-step trampoline code (either signal or function call), see the
+ stack unwind thru a signal trampoline, etc. */
+
+int wizard_mode = 0;
+
/* stdio stream that command input is being read from. Set to stdin normally.
Set by source_command to the file we are sourcing. Set to NULL if we are
executing a user-defined command or interacting via a GUI. */
diff -drupP --exclude-from=/M/donn/diffs/exclude.files src/gdb.saved/doc/gdb.texinfo src/gdb/doc/gdb.texinfo
--- src/gdb.saved/doc/gdb.texinfo Wed Mar 13 14:25:02 2002
+++ src/gdb/doc/gdb.texinfo Wed Mar 13 16:09:36 2002
@@ -2586,6 +2586,29 @@ starting with @code{-1}; @samp{info brea
You can see these breakpoints with the @value{GDBN} maintenance command
@samp{maint info breakpoints} (@pxref{maint info breakpoints}).
+@cindex wizard mode
+@cindex shared libraries
+@cindex dynamic loading
+@cindex dlopen
+@kindex set wizard-mode
+@item set wizard-mode @var{mode}
+@value{GDBN} will normally disable and re-enable breakpoints when loading and
+unloading shared libraries and during process initialization. If
+you need to debug the shared library mechanism or otherwise want to
+completely manage your own breakpoints, @code{set wizard-mode on} tells
+@value{GDBN} to simply leave breakpoints alone at such times. This will cause
+@value{GDBN} to complain that it cannot set breakpoints at addresses
+in shared libraries that are not yet loaded. However, by using the
+@code{enable} and @code{disable} commands, you can control the breakpoints
+manually. This is best used by setting a breakpoint just after a shared
+library is loaded into memory, but before the code you are debugging
+runs, and then setting or enabling the breakpoints in the shared library
+upon reaching the first breakpoint.
+
+@emph(NOTE): Unless you are working on the shared library or other
+"under the covers" mechanisms provided by the operating system or the
+compiler, you almost assuredly do not need this, and using it will
+make your life much more difficult.
@node Set Watchpoints
@subsection Setting watchpoints
---------------------------------------------------------------------------
In a long function, asking for a full disassembly is often far
too much. Allow disassembling a single line. In optimized code,
it disassembles the first "chunk" of the line, but if you're doing
disassemblys you should be prepared for that.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* printcmd.c(disassemble_command): support "disassemble line".
(_initialize_printcmd): reflect in help.
* help.exp: add help here.
Index: src/gdb/printcmd.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/printcmd.c,v
retrieving revision 1.3
diff -p -u -r1.3 printcmd.c
--- src/gdb/printcmd.c 2001/12/24 01:42:08 1.3
+++ src/gdb/printcmd.c 2001/12/24 02:10:29
@@ -2370,7 +2370,32 @@ disassemble_command (char *arg, int from
#endif
low += FUNCTION_START_OFFSET;
}
- else
+ else if (strncmp("line", arg, space_index-arg) == 0)
+ {
+ /* Two args, the first is (abbreviated) "line" */
+ struct symtab_and_line sal;
+ struct symtabs_and_lines sals;
+
+ sals = decode_line_spec_1 (space_index + 1, 0);
+ if (sals.nelts <= 0)
+ {
+ error ("Invalid line spec.\n");
+ }
+ if (sals.nelts > 1)
+ {
+ printf_filtered ("More than one line resulted; doing first.\n");
+ }
+ sal = sals.sals[0];
+ if (!(sal.line > 0 && find_line_pc_range (sal, &low, &high)))
+ {
+ error ("Line not found.\n");
+ }
+ if (low == high)
+ {
+ error ("Line contains no code.\n");
+ }
+ }
+ else
{
/* Two arguments. */
*space_index = '\0';
@@ -2443,7 +2468,8 @@ with this command or \"print\".", NULL))
"Disassemble a specified section of memory.\n\
Default is the function surrounding the pc of the selected frame.\n\
With a single argument, the function surrounding that address is dumped.\n\
-Two arguments are taken as a range of memory to dump.");
+If the first argument is \"line\" (or \"l\") dump that line.\n\
+Two other arguments are taken as a range of memory to dump.");
set_cmd_completer (c, location_completer);
if (xdb_commands)
add_com_alias ("va", "disassemble", class_xdb, 0);
Index: src/gdb/testsuite/gdb.base/help.exp
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/help.exp,v
retrieving revision 1.2
diff -p -u -r1.2 help.exp
--- src/gdb/testsuite/gdb.base/help.exp 2001/12/23 23:31:12 1.2
+++ src/gdb/testsuite/gdb.base/help.exp 2001/12/24 02:10:29
@@ -108,7 +108,7 @@ gdb_test "help disable breakpoints" "Dis
# test help disable display
gdb_test "help disable display" "Disable some expressions to be displayed when program stops\.\[\r\n\]+Arguments are the code numbers of the expressions to stop displaying\.\[\r\n\]+No argument means disable all automatic-display expressions\.\[\r\n\]+Do \"info display\" to see current list of code numbers\." "help disable display"
# test help disassemble
-gdb_test "help disassemble" "Disassemble a specified section of memory\.\[\r\n\]+Default is the function surrounding the pc of the selected frame\.\[\r\n\]+With a single argument, the function surrounding that address is dumped\.\[\r\n\]+Two arguments are taken as a range of memory to dump\." "help disassemble"
+gdb_test "help disassemble" "Disassemble a specified section of memory\.\[\r\n\]+Default is the function surrounding the pc of the selected frame\.\[\r\n\]+With a single argument, the function surrounding that address is dumped\.\[\r\n\]+If the first argument is \"line\" .or \"l\". dump that line\.\[\r\n\]+Two other arguments are taken as a range of memory to dump\." "help disassemble"
# test help display
gdb_test "help display" "Print value of expression EXP each time the program stops\.\[\r\n\]+/FMT may be used before EXP as in the \"print\" command\.\[\r\n\]+/FMT \"i\" or \"s\" or including a size-letter is allowed,\[\r\n\]+as in the \"x\" command, and then EXP is used to get the address to examine\[\r\n\]+and examining is done as in the \"x\" command\.\[\r\n\]+With no argument, display all currently requested auto-display expressions\.\[\r\n\]+Use \"undisplay\" to cancel display requests previously made\." "help display"
# test help do
---------------------------------------------------------------------------
When storing to memory (using p with =), check the target
section for read-only. It may be possible for gdb to write into a
section that the application has set up as read-only. The gdb
user should be warned.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* valops.c(check_mem_access_internal, check_mem_access): New.
(value_assign): Use.
Index: src/gdb/valops.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/valops.c,v
retrieving revision 1.3
diff -p -u -r1.3 valops.c
--- src/gdb/valops.c 2001/12/24 00:57:25 1.3
+++ src/gdb/valops.c 2001/12/24 02:11:41
@@ -529,7 +529,80 @@ value_fetch_lazy (register value_ptr val
return 0;
}
+struct _check_info {
+ CORE_ADDR start_addr;
+ CORE_ADDR end_addr;
+ int mode;
+ int matched;
+};
+
+/* Look to see if the specified flags are set in the section containing
+ the address range. If the address range spans section boundaries,
+ the flags must apply to all parts. */
+static void
+check_mem_access_internal PARAMS((bfd *, asection *, PTR));
+
+static void
+check_mem_access_internal(abfd, asect, inf)
+bfd *abfd;
+asection *asect;
+PTR inf;
+{
+ register struct _check_info *check_info = inf;
+ CORE_ADDR section_start, section_end;
+ int flags;
+ int page_size = getpagesize();
+
+ flags = bfd_get_section_flags(abfd, asect);
+
+ /* is it really in the image? */
+ if ((flags & (SEC_LOAD|SEC_ALLOC)) == 0)
+ return;
+
+ section_start = bfd_section_vma (abfd, asect) + NONZERO_LINK_BASE(abfd);
+ section_end = bfd_section_size(abfd, asect);
+ section_end = ((section_end+page_size-1) & ~(page_size-1))
+ + section_start;
+
+ if (section_start <= check_info->start_addr
+ && check_info->start_addr < section_end)
+ {
+ check_info->matched = ((flags & check_info->mode) != 0);
+ }
+ /* do it separately so we check when it spans sections */
+ if (section_start <= check_info->end_addr
+ && check_info->end_addr < section_end)
+ {
+ check_info->matched &= ((flags & check_info->mode) != 0);
+ }
+}
+
+
+int
+check_mem_access PARAMS((CORE_ADDR, LONGEST, int));
+
+int
+check_mem_access(start, length, mode)
+CORE_ADDR start;
+LONGEST length;
+int mode;
+{
+ struct _check_info check_info;
+ check_info.start_addr = start;
+ check_info.end_addr = start + length;
+ check_info.mode = mode;
+ check_info.matched = 0;
+ if (exec_bfd)
+ {
+ bfd_map_over_sections(exec_bfd, check_mem_access_internal,
+ (PTR)&check_info);
+ return check_info.matched;
+ }
+ else
+ return 0; /* no target, allow other protections to deal with it */
+}
+
/* Store the contents of FROMVAL into the location of TOVAL.
Return a new value with the location of TOVAL and contents of FROMVAL. */
@@ -593,6 +666,21 @@ value_assign (register value_ptr toval,
char *dest_buffer;
CORE_ADDR changed_addr;
int changed_len;
+
+ /* if this is in readonly memory, don't proceed without a complaint:
+ We might be able to read/write memory the application thinks is
+ readonly (e.g. when writing breakpoints when text is readonly,
+ we must be able to do that). However, if the user tries to change
+ something the application thinks is readonly data, we should warn.
+ (It'd be too heavy-handed to reject.) */
+
+ if (check_mem_access(VALUE_ADDRESS (toval) + VALUE_OFFSET (toval),
+ (use_buffer ? use_buffer : TYPE_LENGTH (type)) - 1,
+ SEC_READONLY)
+ && !query("This would modify target's read-only memory; proceed?"))
+ {
+ break;
+ }
if (VALUE_BITSIZE (toval))
{
---------------------------------------------------------------------------
NEEDS THOUGHT
Calls to dlclose() were confusing things: a complaint about
memory not being writeable was being generated, and breakpoints
were left active and pointing to nonexistent memory.
- breakpoint.c/breakpoint_1: report shlib_disabled breakpoints
as s, not n.
ABOVE MAY NO LONGER APPLY??? (patch being applied, check semantics.)
- breakpoint.c/re_enable_breakpoints_in_shlibs(): don't do it
if global solib_is_deleting is set (and define that variable
initially to zero.)
In pei-solib.c/solib_add: set solib_is_deleting when something
is being deleted, and clear when we're told things are consistent
again. Disable breakpoints in shlibs while deleteing a shared
library. (Other *solib.c may wish to follow.) (pei-solib.c to
follow in another patch.)
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* breakpoint.c(bpenables): report shared-lib suspended breakpoints
as "s". (solib_is_deleting): declare.
(re_enable_breakpoints_in_shlibs): do nothing if still deleting
shared libs.
Index: src/gdb/breakpoint.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/breakpoint.c,v
retrieving revision 1.3
diff -p -u -r1.3 breakpoint.c
--- src/gdb/breakpoint.c 2001/12/24 02:09:51 1.3
+++ src/gdb/breakpoint.c 2001/12/24 02:12:48
@@ -3139,7 +3139,7 @@ print_one_breakpoint (struct breakpoint
static char *bpdisps[] =
{"del", "dstp", "dis", "keep"};
- static char bpenables[] = "nynny";
+ static char bpenables[] = "nysny";
char wrap_indent[80];
#ifdef UI_OUT
struct ui_stream *stb = ui_out_stream_new (uiout);
@@ -4130,11 +4130,19 @@ disable_breakpoints_in_shlibs (int silen
}
}
+int solib_is_deleting = 0;
+
/* Try to reenable any breakpoints in shared libraries. */
void
re_enable_breakpoints_in_shlibs (void)
{
struct breakpoint *b;
+
+ /* If this is a dlclose(), we don't want to reenable yet, but there
+ are several places that can't tell from their state which it is,
+ so we (yetch) use a global. */
+ if (solib_is_deleting)
+ return;
ALL_BREAKPOINTS (b)
if (b->enable_state == bp_shlib_disabled)
---------------------------------------------------------------------------
This is needed for core and shared libs.
Sun Nov 2 14:16:25 MST 1997
Yesterday's changes to bfd (to simplify the handling of
ImageBase significantly) needed to be reflected here.
Apply ImageBase to the internal section tables for both
the exec, and symbol tables. One invalid assumption in
gdb had to be addressed: it's assumed that stabs symbols
and regular symbols are relocated the same way, which they
aren't in PE. (Stabs symbols have ImageBase applied,
regular coff (minimal) symbols don't.) (It might be possible
to fix this by using the REFLONGNB relocation in the
assembler's parse of .stabs? lines, but the assembler isn't
currently set up to do that. It's far easier to fix here,
altho there are good reasons to do it in the assembler, and
that may happen.)
Change:
symfile.h: add a new function pointer build_section_table; it's
intended to be called from the exec side of things to do file
format specific things, such as apply ImageBase to the section
VMAs. This helps keep the format issues separate from the access
mechanism (target) issues.
coffread.c: create a new section_offsets table with ImageBase
backed out to pass to the stabs-reading code.
Make a coff-private symfile_offsets() routine that applies
ImageBase to the initial section_offsets table.
Make coff-private build_section_table() which does the analogous
thing on the exec file side.
Add body to coff_symfile_init to apply ImageBase to the
section tables.
exec.c: use the new build_section_table function pointer; rename
old version (and it's helper) to default....
corelow.c: also use the new build_section_table entry.
dbxread.c: Init some uninitialized statics that were being relied
upon to be zero (it DID make a difference).
PE format does NOT use relative addresses for begin/end block.
(And it looks tricky to get the compiler right to do that, for
little benefit.)
symfile.c: rewrite find_sym_fns() to use new function lookup_sym_fns();
lookup_sym_fns is like the old find_sym_fns but returns
a value rather than changing a structure. Useable now
in exec.c and corelow.c to find the function pointer
needed for build_section_table().
Code marked as #ifndef IBM6000_TARGET had comments that it seemd a
specific hack... it appears to have been as it also broke NT/PE.
Turn it off completely, and let those who care make a better ifdef.
(Or use symfile_offsets or symfile_init, which look as if it could
do the right thing, if one were written for targets that need this
hack.) (The PE changes were quite similar, but not identical.)
target.h: remove declaration for build_section_table.
----------------------
In preparation for adding Interix core files, we need to have a
private version of build_section_table. Also, find_sym_fns is
more useful if it returns a value rather than changing a structure,
so restructure into find_sym_fns to do the old thing, which calls
lookup_sym_fns to do the work. lookup_sym_fns can then be called
directly as well.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* symfile.h(sym_fns): add build_section_table field.
* corelow.h(core_open): Use instead of direct call.
* exec.c(exec_file_command): Likewise.
(add_to_section_table): Rename to default_add_to_section_table.
(build_section_table): Rename to default_build_section_table,
use defauilt_add_to_section_table.
* target.h(build_section_table): Remove declaration.
* symfile.c(lookup_sym_fns): New, contains most of...
(find_sym_fns): use lookup_sym_fns to do most of work.
Index: src/gdb/corelow.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/corelow.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 corelow.c
--- src/gdb/corelow.c 2001/12/23 00:34:44 1.1.1.1
+++ src/gdb/corelow.c 2001/12/24 02:15:44
@@ -31,6 +31,7 @@
#include "frame.h" /* required by inferior.h */
#include "inferior.h"
#include "symtab.h"
+#include "symfile.h"
#include "command.h"
#include "bfd.h"
#include "target.h"
@@ -316,8 +317,8 @@ core_open (char *filename, int from_tty)
validate_files ();
/* Find the data section */
- if (build_section_table (core_bfd, &core_ops.to_sections,
- &core_ops.to_sections_end))
+ if ((*lookup_sym_fns(exec_bfd)->sym_build_sect_table)
+ (core_bfd, &core_ops.to_sections, &core_ops.to_sections_end))
error ("\"%s\": Can't find sections: %s",
bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
Index: src/gdb/dbxread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/dbxread.c,v
retrieving revision 1.2
diff -p -u -r1.2 dbxread.c
--- src/gdb/dbxread.c 2001/12/23 23:50:50 1.2
+++ src/gdb/dbxread.c 2001/12/24 02:15:44
@@ -3531,6 +3531,7 @@ static struct sym_fns aout_sym_fns =
dbx_symfile_read, /* sym_read: read a symbol file into symtab */
dbx_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
+ default_build_section_table, /* sym_build_sect_table: build section table */
NULL /* next: pointer to next struct sym_fns */
};
Index: src/gdb/dstread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/dstread.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 dstread.c
--- src/gdb/dstread.c 2001/12/23 00:34:45 1.1.1.1
+++ src/gdb/dstread.c 2001/12/24 02:15:44
@@ -1597,6 +1597,7 @@ static struct sym_fns dst_sym_fns =
dst_symfile_read, /* sym_read: read a symbol file into symtab */
dst_symfile_finish, /* sym_finish: finished with file, cleanup */
dst_symfile_offsets, /* sym_offsets: xlate external to internal form */
+ default_build_section_table, /* sym_build_sect_table: build section table */
NULL /* next: pointer to next struct sym_fns */
};
Index: src/gdb/elfread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/elfread.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 elfread.c
--- src/gdb/elfread.c 2001/12/23 00:34:46 1.1.1.1
+++ src/gdb/elfread.c 2001/12/24 02:15:44
@@ -805,6 +805,7 @@ static struct sym_fns elf_sym_fns =
elf_symfile_read, /* sym_read: read a symbol file into symtab */
elf_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
+ default_build_section_table, /* sym_build_sect_table: build section table */
NULL /* next: pointer to next struct sym_fns */
};
Index: src/gdb/exec.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/exec.c,v
retrieving revision 1.2
diff -p -u -r1.2 exec.c
--- src/gdb/exec.c 2001/12/23 23:22:12 1.2
+++ src/gdb/exec.c 2001/12/24 02:15:43
@@ -256,8 +256,8 @@ exec_file_attach (char *filename, int fr
}
#endif /* IBM6000_TARGET */
- if (build_section_table (exec_bfd, &exec_ops.to_sections,
- &exec_ops.to_sections_end))
+ if ((*lookup_sym_fns(exec_bfd)->sym_build_sect_table)
+ (exec_bfd, &exec_ops.to_sections, &exec_ops.to_sections_end))
{
/* Make sure to close exec_bfd, or else "run" might try to use
it. */
@@ -365,7 +365,7 @@ file_command (char *arg, int from_tty)
we cast it back to its proper type. */
static void
-add_to_section_table (bfd *abfd, sec_ptr asect, PTR table_pp_char)
+default_add_to_section_table (bfd *abfd, sec_ptr asect, PTR table_pp_char)
{
struct section_table **table_pp = (struct section_table **) table_pp_char;
flagword aflag;
@@ -386,7 +386,7 @@ add_to_section_table (bfd *abfd, sec_ptr
Returns 0 if OK, 1 on error. */
int
-build_section_table (bfd *some_bfd, struct section_table **start,
+default_build_section_table (bfd *some_bfd, struct section_table **start,
struct section_table **end)
{
unsigned count;
@@ -396,7 +396,7 @@ build_section_table (bfd *some_bfd, stru
xfree (* start);
*start = (struct section_table *) xmalloc (count * sizeof (**start));
*end = *start;
- bfd_map_over_sections (some_bfd, add_to_section_table, (char *) end);
+ bfd_map_over_sections (some_bfd, default_add_to_section_table, (char *)end);
if (*end > *start + count)
internal_error (__FILE__, __LINE__, "failed internal consistency check");
/* We could realloc the table, but it probably loses for most files. */
Index: src/gdb/irix5-nat.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/irix5-nat.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 irix5-nat.c
--- src/gdb/irix5-nat.c 2001/12/23 00:34:49 1.1.1.1
+++ src/gdb/irix5-nat.c 2001/12/24 02:15:43
@@ -441,7 +441,7 @@ solib_map_sections (void *arg)
error ("\"%s\": not in executable format: %s.",
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
- if (build_section_table (abfd, &so->sections, &so->sections_end))
+ if ((*lookup_sym_fns (abfd)->sym_build_sect_table) (abfd, &so->sections, &so->sections_end))
{
error ("Can't find the file sections in `%s': %s",
bfd_get_filename (exec_bfd), bfd_errmsg (bfd_get_error ()));
Index: src/gdb/mipsread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/mipsread.c,v
retrieving revision 1.2
diff -p -u -r1.2 mipsread.c
--- src/gdb/mipsread.c 2001/12/23 23:50:51 1.2
+++ src/gdb/mipsread.c 2001/12/24 02:15:43
@@ -437,6 +437,7 @@ static struct sym_fns ecoff_sym_fns =
mipscoff_symfile_read, /* sym_read: read a symbol file into symtab */
mipscoff_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: dummy FIXME til implem sym reloc */
+ default_build_section_table, /* sym_build_sect_table: build section table */
NULL /* next: pointer to next struct sym_fns */
};
Index: src/gdb/nlmread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/nlmread.c,v
retrieving revision 1.2
diff -p -u -r1.2 nlmread.c
--- src/gdb/nlmread.c 2001/12/23 23:50:51 1.2
+++ src/gdb/nlmread.c 2001/12/24 02:15:43
@@ -238,6 +238,7 @@ static struct sym_fns nlm_sym_fns =
nlm_symfile_read, /* sym_read: read a symbol file into symtab */
nlm_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
+ default_build_section_table, /* sym_build_sect_table: build section table */
NULL /* next: pointer to next struct sym_fns */
};
Index: src/gdb/os9kread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/os9kread.c,v
retrieving revision 1.2
diff -p -u -r1.2 os9kread.c
--- src/gdb/os9kread.c 2001/12/23 23:50:51 1.2
+++ src/gdb/os9kread.c 2001/12/24 02:15:43
@@ -1611,6 +1611,7 @@ static struct sym_fns os9k_sym_fns =
os9k_symfile_read, /* sym_read: read a symbol file into symtab */
os9k_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
+ default_build_section_table, /* sym_build_sect_table: build section table */
NULL /* next: pointer to next struct sym_fns */
};
Index: src/gdb/osfsolib.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/osfsolib.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 osfsolib.c
--- src/gdb/osfsolib.c 2001/12/23 00:34:51 1.1.1.1
+++ src/gdb/osfsolib.c 2001/12/24 02:15:43
@@ -260,7 +260,7 @@ solib_map_sections (char *arg)
error ("\"%s\": not in executable format: %s.",
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
- if (build_section_table (abfd, &so->sections, &so->sections_end))
+ if ((*lookup_sym_fns (abfd)->sym_build_sect_table) (abfd, &so->sections, &so->sections_end))
{
error ("Can't find the file sections in `%s': %s",
bfd_get_filename (exec_bfd), bfd_errmsg (bfd_get_error ()));
Index: src/gdb/pa64solib.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/pa64solib.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 pa64solib.c
--- src/gdb/pa64solib.c 2001/12/23 00:34:52 1.1.1.1
+++ src/gdb/pa64solib.c 2001/12/24 02:15:44
@@ -312,9 +312,8 @@ pa64_solib_load_symbols (struct so_list
/* Now we need to build a section table for this library since
we might be debugging a core file from a dynamically linked
executable in which the libraries were not privately mapped. */
- if (build_section_table (so->abfd,
- &so->sections,
- &so->sections_end))
+ if ((*lookup_sym_fns (so->abfd)->sym_build_sect_table)
+ (so->abfd, &so->sections, &so->sections_end))
{
error ("Unable to build section table for shared library\n.");
return;
Index: src/gdb/solib.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/solib.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 solib.c
--- src/gdb/solib.c 2001/12/23 00:34:55 1.1.1.1
+++ src/gdb/solib.c 2001/12/24 02:15:43
@@ -250,7 +250,7 @@ solib_map_sections (PTR arg)
error ("\"%s\": not in executable format: %s.",
scratch_pathname, bfd_errmsg (bfd_get_error ()));
}
- if (build_section_table (abfd, &so->sections, &so->sections_end))
+ if ((*lookup_sym_fns (abfd)->sym_build_sect_table) (abfd, &so->sections, &so->sections_end))
{
error ("Can't find the file sections in `%s': %s",
bfd_get_filename (abfd), bfd_errmsg (bfd_get_error ()));
Index: src/gdb/somread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/somread.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 somread.c
--- src/gdb/somread.c 2001/12/23 00:34:55 1.1.1.1
+++ src/gdb/somread.c 2001/12/24 02:15:43
@@ -745,6 +745,7 @@ static struct sym_fns som_sym_fns =
som_symfile_read, /* sym_read: read a symbol file into symtab */
som_symfile_finish, /* sym_finish: finished with file, cleanup */
som_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
+ default_build_section_table, /* sym_build_sect_table: build section table */
NULL /* next: pointer to next struct sym_fns */
};
Index: src/gdb/somsolib.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/somsolib.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 somsolib.c
--- src/gdb/somsolib.c 2001/12/23 00:34:55 1.1.1.1
+++ src/gdb/somsolib.c 2001/12/24 02:15:43
@@ -351,9 +351,8 @@ som_solib_load_symbols (struct so_list *
/* Now we need to build a section table for this library since
we might be debugging a core file from a dynamically linked
executable in which the libraries were not privately mapped. */
- if (build_section_table (so->abfd,
- &so->sections,
- &so->sections_end))
+ if ((*lookup_sym_fns (abfd)->sym_build_sect_table)
+ (so->abfd, &so->sections, &so->sections_end))
{
error ("Unable to build section table for shared library\n.");
return;
Index: src/gdb/symfile.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/symfile.c,v
retrieving revision 1.2
diff -p -u -r1.2 symfile.c
--- src/gdb/symfile.c 2001/12/23 23:22:13 1.2
+++ src/gdb/symfile.c 2001/12/24 02:15:43
@@ -1118,17 +1118,17 @@ add_symtab_fns (struct sym_fns *sf)
}
-/* Initialize to read symbols from the symbol file sym_bfd. It either
- returns or calls error(). The result is an initialized struct sym_fns
- in the objfile structure, that contains cached information about the
- symbol file. */
+/* Get format dependent information. It either returns or calls error().
+ The result is a pointer to a struct sym_fns. This allows us to get
+ to the format dependent stuff from elsewhere (specifically exec)
+ when we need it. */
-static void
-find_sym_fns (struct objfile *objfile)
+struct sym_fns*
+lookup_sym_fns (bfd* abfd)
{
struct sym_fns *sf;
- enum bfd_flavour our_flavour = bfd_get_flavour (objfile->obfd);
- char *our_target = bfd_get_target (objfile->obfd);
+ enum bfd_flavour our_flavour = bfd_get_flavour (abfd);
+ char *our_target = bfd_get_target (abfd);
/* Special kludge for apollo. See dstread.c. */
if (STREQN (our_target, "apollo", 6))
@@ -1138,12 +1138,23 @@ find_sym_fns (struct objfile *objfile)
{
if (our_flavour == sf->sym_flavour)
{
- objfile->sf = sf;
- return;
+ return sf;
}
}
- error ("I'm sorry, Dave, I can't do that. Symbol format `%s' unknown.",
- bfd_get_target (objfile->obfd));
+ error ("Object format `%s' unknown.",
+ bfd_get_target (abfd));
+}
+
+/* Initialize to read symbols from the symbol file sym_bfd. It either
+ returns or calls error(). The result is an initialized struct sym_fns
+ in the objfile structure, that contains cached information about the
+ symbol file. */
+
+static void
+find_sym_fns (objfile)
+ struct objfile *objfile;
+{
+ objfile->sf = lookup_sym_fns(objfile->obfd);
}
\f
/* This function runs the load command of our current target. */
Index: src/gdb/symfile.h
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/symfile.h,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 symfile.h
--- src/gdb/symfile.h 2001/12/23 00:34:56 1.1.1.1
+++ src/gdb/symfile.h 2001/12/24 02:15:43
@@ -74,6 +74,9 @@ struct section_addr_info
} other[MAX_SECTIONS];
};
+/* Forward declaration */
+struct section_table;
+
/* Structure to keep track of symbol reading functions for various
object file types. */
@@ -121,6 +124,15 @@ struct sym_fns
void (*sym_offsets) (struct objfile *, struct section_addr_info *);
+ /* This isn't strictly a symbol routine, but there may be format-
+ sensitive information that the "exec" side of gdb needs to have
+ dealt with. Used (at least) for Interix */
+ /* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
+ Returns 0 if OK, 1 on error. */
+
+ int (*sym_build_sect_table) (bfd *, struct section_table **,
+ struct section_table **);
+
/* Finds the next struct sym_fns. They are allocated and initialized
in whatever module implements the functions pointed to; an
initializer calls add_symtab_fns to add them to the global chain. */
@@ -135,6 +147,11 @@ struct sym_fns
extern void
default_symfile_offsets (struct objfile *objfile, struct section_addr_info *);
+/* The default version of sym_fns.sym_build_sect_table. */
+
+extern int
+default_build_section_table (bfd *some_bfd, struct section_table **start,
+ struct section_table **end);
extern void
extend_psymbol_list (struct psymbol_allocation_list *, struct objfile *);
@@ -318,5 +335,8 @@ mdebug_build_psymtabs (struct objfile *,
extern void
elfmdebug_build_psymtabs (struct objfile *,
const struct ecoff_debug_swap *, asection *);
+
+extern struct sym_fns*
+lookup_sym_fns (bfd* abfd);
#endif /* !defined(SYMFILE_H) */
Index: src/gdb/target.h
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/target.h,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 target.h
--- src/gdb/target.h 2001/12/23 00:34:56 1.1.1.1
+++ src/gdb/target.h 2001/12/24 02:15:43
@@ -1145,12 +1145,6 @@ struct section_table
bfd *bfd; /* BFD file pointer */
};
-/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
- Returns 0 if OK, 1 on error. */
-
-extern int
-build_section_table (bfd *, struct section_table **, struct section_table **);
-
/* From mem-break.c */
extern int memory_remove_breakpoint (CORE_ADDR, char *);
Index: src/gdb/xcoffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/xcoffread.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 xcoffread.c
--- src/gdb/xcoffread.c 2001/12/23 00:34:58 1.1.1.1
+++ src/gdb/xcoffread.c 2001/12/24 02:15:43
@@ -3029,6 +3029,7 @@ static struct sym_fns xcoff_sym_fns =
xcoff_initial_scan, /* sym_read: read a symbol file into symtab */
xcoff_symfile_finish, /* sym_finish: finished with file, cleanup */
xcoff_symfile_offsets, /* sym_offsets: xlate offsets ext->int form */
+ default_build_section_table, /* sym_build_sect_table: build section table */
NULL /* next: pointer to next struct sym_fns */
};
---------------------------------------------------------------------------
coff_symfile_offsets: this changed significantly; is it right???
Use symfile offsets entry point for shared libraries.
Also use new build_section_table function pointer.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* coffread.c (coff_symfile_offsets, coff_build_section_table,
coff_add_to_section_table): New.
(coff_sym_funs): Use.
Index: src/gdb/coffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/coffread.c,v
retrieving revision 1.11
diff -p -u -r1.11 coffread.c
--- src/gdb/coffread.c 2001/12/24 01:36:32 1.11
+++ src/gdb/coffread.c 2001/12/24 02:16:57
@@ -2343,6 +2343,122 @@ coff_read_enum_type (int index, int leng
return type;
}
+/* Parse the user's idea of an offset for dynamic linking, into our idea
+ of how to represent it for fast symbol reading. This is essentially
+ the same as the default version of the function, but it adds in ImageBase.*/
+
+void
+coff_symfile_offsets (objfile, addrs)
+ struct objfile *objfile;
+ struct section_addr_info *addrs;
+{
+ asection *sect = NULL;
+ struct section_offsets *section_offsets;
+ struct obj_section *s;
+ int i;
+
+#ifdef COFF_IMAGE_WITH_PE
+ CORE_ADDR image_base;
+
+ /* We must make sure that symbol lookup uses the same idea of offsets
+ that everyone else does. */
+ image_base = NONZERO_LINK_BASE(objfile->obfd);
+ for (s = objfile->sections; s < objfile->sections_end; ++s)
+ {
+ s->addr += image_base;
+ s->endaddr += image_base;
+ }
+#endif
+
+ objfile->num_sections = SECT_OFF_MAX;
+ objfile->section_offsets = (struct section_offsets *)
+ obstack_alloc (&objfile -> psymbol_obstack, SIZEOF_SECTION_OFFSETS);
+ memset (objfile->section_offsets, 0, SIZEOF_SECTION_OFFSETS);
+
+ /* Initialize the section indexes for future use. */
+ sect = bfd_get_section_by_name (objfile->obfd, ".text");
+ if (sect)
+ objfile->sect_index_text = sect->index;
+
+ sect = bfd_get_section_by_name (objfile->obfd, ".data");
+ if (sect)
+ objfile->sect_index_data = sect->index;
+
+ sect = bfd_get_section_by_name (objfile->obfd, ".bss");
+ if (sect)
+ objfile->sect_index_bss = sect->index;
+
+ sect = bfd_get_section_by_name (objfile->obfd, ".rodata");
+ if (sect)
+ objfile->sect_index_rodata = sect->index;
+ else
+ /* Doesn't always have to exist, so fake out the sanity test. */
+ objfile->sect_index_rodata = -2;
+
+
+ /* Now calculate offsets for other sections. */
+ for (i = 0; i < MAX_SECTIONS && addrs->other[i].name; i++)
+ {
+ struct other_sections *osp ;
+
+ osp = &addrs->other[i] ;
+ if (addrs->other[i].addr == 0)
+ continue;
+ /* The section_offsets in the objfile are here filled in using
+ the BFD index. */
+ (objfile->section_offsets)->offsets[osp->sectindex] = osp->addr;
+ }
+}
+
+/* Used for "exec"; the same mapping of ImageBase needs to be done here */
+
+/* Locate all mappable sections of a BFD file.
+ table_pp_char is a char * to get it through bfd_map_over_sections;
+ we cast it back to its proper type. */
+
+static void
+coff_add_to_section_table (abfd, asect, table_pp_char)
+ bfd *abfd;
+ sec_ptr asect;
+ PTR table_pp_char;
+{
+ struct section_table **table_pp = (struct section_table **)table_pp_char;
+ flagword aflag;
+
+ aflag = bfd_get_section_flags (abfd, asect);
+ if (!(aflag & SEC_ALLOC))
+ return;
+ if (0 == bfd_section_size (abfd, asect))
+ return;
+
+ (*table_pp)->bfd = abfd;
+ (*table_pp)->the_bfd_section = asect;
+ (*table_pp)->addr = bfd_section_vma (abfd, asect) + NONZERO_LINK_BASE(abfd);
+ (*table_pp)->endaddr = (*table_pp)->addr + bfd_section_size (abfd, asect);
+ (*table_pp)++;
+}
+
+/* Builds a section table, given args BFD, SECTABLE_PTR, SECEND_PTR.
+ Returns 0 if OK, 1 on error. */
+
+int
+coff_build_section_table (some_bfd, start, end)
+ bfd *some_bfd;
+ struct section_table **start, **end;
+{
+ unsigned count;
+ count = bfd_count_sections (some_bfd);
+ if (*start)
+ free ((PTR)*start);
+ *start = (struct section_table *) xmalloc (count * sizeof (**start));
+ *end = *start;
+ bfd_map_over_sections (some_bfd, coff_add_to_section_table, (char *)end);
+ if (*end > *start + count)
+ abort();
+ /* We could realloc the table, but it probably loses for most files. */
+ return 0;
+}
+
/* Register our ability to parse symbols for coff BFD files. */
static struct sym_fns coff_sym_fns =
@@ -2352,7 +2473,8 @@ static struct sym_fns coff_sym_fns =
coff_symfile_init, /* sym_init: read initial info, setup for sym_read() */
coff_symfile_read, /* sym_read: read a symbol file into symtab */
coff_symfile_finish, /* sym_finish: finished with file, cleanup */
- default_symfile_offsets, /* sym_offsets: xlate external to internal form */
+ coff_symfile_offsets, /* sym_offsets: xlate external to internal form */
+ coff_build_section_table, /* build_section_table: exec time section offsets */
NULL /* next: pointer to next struct sym_fns */
};
---------------------------------------------------------------------------
Fix link.h header!
Support Interix shared libraries:
Add new files, remove lieing comment from solib.c, modify
build_section_addr_info_from_section_table to take a third offset
for the adjustment needed if the shared lib was not linked at 0 offset.
NOTE! In working on this, I was unable to find any regressions that test
the interaction of gdb with dlopen(). I have hand-tested this code for
that, and it's more-or-less correct (and further fixes are probably generic).
I have not done the work to add catch operations for shared lib load
and unload, but enable_break() has all the pieces needed to do that,
it's a matter of getting the proper header and a few functions correct.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* solib-pei.c: new file.
* solib-pei.h: new file.
* Makefile.in: add pei-solib.c support.
* interix.mt: Use.
* coffread.c (coff_symtab_read): Flag undefined symbols as trampolines.
Index: src/gdb/Makefile.in
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/Makefile.in,v
retrieving revision 1.2
diff -p -u -r1.2 Makefile.in
--- src/gdb/Makefile.in 2001/12/23 20:46:13 1.2
+++ src/gdb/Makefile.in 2001/12/24 02:18:04
@@ -2023,6 +2023,9 @@ solib.o: solib.c $(command_h) $(defs_h)
solib-sunos.o: solib-sunos.c $(defs_h) $(symfile_h) $(objfiles_h) \
$(gdbcore_h) $(inferior_h) $(solist_h)
+solib-pei.o: solib-pei.c $(defs_h) $(gdbcore_h) $(inferior_h) $(objfiles_h) \
+ $(symfile_h) $(target_h) $(solist_h) solib-pei.h
+
solib-svr4.o: solib-svr4.c $(defs_h) $(gdbcore_h) $(inferior_h) $(objfiles_h) \
$(symfile_h) $(target_h) $(solist_h) solib-svr4.h
Index: src/gdb/coffread.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/coffread.c,v
retrieving revision 1.12
diff -p -u -r1.12 coffread.c
--- src/gdb/coffread.c 2001/12/24 02:17:37 1.12
+++ src/gdb/coffread.c 2001/12/24 02:18:04
@@ -886,7 +886,12 @@ coff_symtab_read (long symtab_offset, un
/* Record all functions -- external and static -- in minsyms. */
tmpaddr = cs->c_value + ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- record_minimal_symbol (cs->c_name, tmpaddr, mst_text, objfile,
+ /* We also need to flag dynamic symbols, which are undefined
+ functions (usually) so that the special handling of them
+ works correctly. At this point, dynamic == undefined;
+ if it's really undefined, we deal with that later. */
+ record_minimal_symbol (cs->c_name, tmpaddr,
+ cs->c_secnum == 0 ? mst_solib_trampoline : mst_text, objfile,
coff_section_from_bfd_index(objfile->obfd, cs->c_secnum));
if (cs->c_naux > 0)
Index: src/gdb/solib-pei.c
===================================================================
RCS file: solib-pei.c
diff -N solib-pei.c
--- /dev/null Sun Dec 23 16:47:34 2001
+++ solib-pei.c Sun Dec 23 18:18:04 2001
@@ -0,0 +1,666 @@
+/* Handle Interix (pei) shared libraries for GDB, the GNU Debugger.
+ Derived from the similar (but rather different) PEI variant.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000,
+ 2001, 2002
+ Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "defs.h"
+
+#include "symtab.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "inferior.h"
+
+#include "solist.h"
+#include "solib-pei.h"
+
+static struct r_debug debug_copy;
+
+static CORE_ADDR debug_base; /* Base of dynamic linker structures */
+static CORE_ADDR breakpoint_addr; /* Address where end bkpt is set */
+
+static int enable_break (int mode);
+
+/*
+
+LOCAL FUNCTION
+ locate_base -- locate the base address of dynamic linker structs
+ and set debug_base to it (if it finds it!)
+
+SYNOPSIS
+ CORE_ADDR locate_base (void)
+
+DESCRIPTION
+ If the inferior executable has been linked dynamically,
+ there is a single address somewhere in the inferior's data
+ space which is the key to locating all of the dynamic
+ linker's runtime structures. This address is the value of
+ the debug base symbol. The job of this function is to find
+ and return that address, or to return 0 if there is no such
+ address (the executable is statically linked for example).
+
+ The address of the dynamic linker's runtime structure is
+ contained within the dynamic info section in the executable
+ file. The dynamic section is also mapped into the inferior
+ address space. Because the runtime loader fills in the
+ real address before starting the inferior, we have to read
+ in the dynamic info section from the inferior address space.
+
+ If we find a condition indicating that there is no dynamic debug
+ info, we return ERROR_ADDR. If it's there, but the address isn't
+ filled in yet, we return 0. If it's damaged or incorrect, we
+ report an error and return ERROR_ADDR. (In effect, 0 means
+ "try again later".)
+*/
+
+static CORE_ADDR
+locate_base ()
+{
+ sec_ptr dyninfo_sect;
+ int dyninfo_sect_size;
+ CORE_ADDR dyninfo_addr;
+ char *buf;
+ char *bufend;
+
+ /* Check to see if we have a currently valid address, and if so, avoid
+ doing all this work again and just return the cached address. If
+ we have no cached address, try to locate it in the dynamic info
+ section. */
+
+ if (debug_base != 0)
+ return debug_base;
+
+ if (exec_bfd == NULL
+ || bfd_get_flavour (exec_bfd) != bfd_target_coff_flavour)
+ {
+ error("locate_base: file of wrong type; cannot look up shared libs.\n");
+ return ERROR_ADDR;
+ }
+
+ /* Find the start address of the .dynamic section. */
+ dyninfo_sect = bfd_get_section_by_name (exec_bfd, ".dynamic");
+ if (dyninfo_sect == NULL)
+ return ERROR_ADDR;
+
+ dyninfo_addr = bfd_section_vma (exec_bfd, dyninfo_sect)
+ + NONZERO_LINK_BASE(exec_bfd);
+
+ /* Read in .dynamic section; if we got here, it's an error if we couldn't
+ read it. */
+ dyninfo_sect_size = bfd_section_size (exec_bfd, dyninfo_sect);
+ buf = alloca (dyninfo_sect_size);
+ if (target_read_memory (dyninfo_addr, buf, dyninfo_sect_size))
+ {
+ error ("locate_base: Can't read dynamic section\n");
+ return ERROR_ADDR;
+ }
+
+ /* Find the DT_DEBUG entry in the the .dynamic section. */
+ for (bufend = buf + dyninfo_sect_size;
+ buf < bufend;
+ buf += sizeof (PE_dyn))
+ {
+ PE_dyn *x_dynp = (PE_dyn *)buf;
+ long dyn_tag;
+ CORE_ADDR dyn_ptr;
+
+ dyn_tag = bfd_h_get_32 (exec_bfd, (bfd_byte *) &x_dynp->d_tag);
+ if (dyn_tag == DT_NULL)
+ {
+ /* last entry; if we get here we didn't find it */
+ break;
+ }
+ else if (dyn_tag == DT_DEBUG)
+ {
+ debug_base =
+ bfd_h_get_32 (exec_bfd, (bfd_byte *) &x_dynp->d_un.d_ptr);
+ return
+ debug_base;
+ }
+ }
+ return ERROR_ADDR;
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ first_link_map_member -- locate first member in dynamic linker's map
+
+ SYNOPSIS
+
+ static CORE_ADDR first_link_map_member (void)
+
+ DESCRIPTION
+
+ Find the first element in the inferior's dynamic link map, and
+ return its address in the inferior. This function doesn't copy the
+ link map entry itself into our address space; current_sos actually
+ does the reading. */
+
+static int debug_sl_state = 0; /* to be set with the debugger, 'natch. */
+
+static CORE_ADDR
+first_link_map_member (void)
+{
+ CORE_ADDR lm = 0;
+
+ read_memory (debug_base, (char *) &debug_copy, sizeof (debug_copy));
+ if (debug_copy.r_version != DYNAMIC_VERSION)
+ warning("Mismatched runtime loader version; attempting to proceed\n");
+
+ switch(debug_copy.r_state)
+ {
+ case RT_ADD:
+ if (debug_sl_state)
+ fprintf(stderr, "Add state reported\n");
+ disable_breakpoints_in_shlibs(1);
+ break;
+ case RT_DELETE:
+ if (debug_sl_state)
+ fprintf(stderr, "Delete state reported\n");
+ disable_breakpoints_in_shlibs(1);
+ break;
+ case RT_CONSISTENT:
+ if (debug_sl_state)
+ fprintf(stderr, "Consistent state reported; rebuilding\n");
+ re_enable_breakpoints_in_shlibs();
+ break;
+ default:
+ if (debug_sl_state)
+ fprintf(stderr, "No state reported\n");
+ break;
+ }
+
+ lm = (CORE_ADDR) debug_copy.r_map;
+
+ return (lm);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ open_symbol_file_object
+
+ SYNOPSIS
+
+ void open_symbol_file_object (void *from_tty)
+
+ DESCRIPTION
+
+ If no open symbol file, attempt to locate and open the main symbol
+ file. On PEI systems, this is the first link map entry. If its
+ name is here, we can open it. Useful when attaching to a process
+ without first loading its symbol file.
+
+ If FROM_TTYP dereferences to a non-zero integer, allow messages to
+ be printed. This parameter is a pointer rather than an int because
+ open_symbol_file_object() is called via catch_errors() and
+ catch_errors() requires a pointer argument. */
+
+static int
+open_symbol_file_object (void *from_ttyp)
+{
+ CORE_ADDR lm, l_name;
+ CORE_ADDR t;
+ char *filename;
+ int errcode;
+ int from_tty = *(int *)from_ttyp;
+ struct link_map *tm; /* Needed, but not really used. */
+ CORE_ADDR res;
+
+ if (symfile_objfile)
+ if (!query ("Attempt to reload symbols from process? "))
+ return 0;
+
+ res = locate_base ();
+ if (res == ERROR_ADDR)
+ return 0; /* failed somehow... */
+
+ /* First link map member should be the executable. */ // ?????
+ lm = first_link_map_member ();
+ if (lm == 0)
+ return 0; /* failed somehow... */
+
+ /* Read address of name from target memory to GDB. */
+ read_memory (lm + offsetof(struct link_map, l_name),
+ (void *)&l_name, sizeof(tm->l_name));
+
+ if (l_name == 0)
+ return 0; /* No filename. */
+
+ /* Now fetch the filename from target memory. */
+ target_read_string (l_name, &filename, SO_NAME_MAX_PATH_SIZE - 1, &errcode);
+
+ if (errcode)
+ {
+ warning ("failed to read exec filename from attached file: %s",
+ safe_strerror (errcode));
+ return 0;
+ }
+
+ make_cleanup (xfree, filename);
+ /* Have a pathname: read the symbol file. */
+ symbol_file_add_main (filename, from_tty);
+
+ return 1;
+}
+
+/* LOCAL FUNCTION
+
+ current_sos -- build a list of currently loaded shared objects
+
+ SYNOPSIS
+
+ struct so_list *current_sos ()
+
+ DESCRIPTION
+
+ Build a list of `struct so_list' objects describing the shared
+ objects currently loaded in the inferior. This list does not
+ include an entry for the main executable file.
+
+ Note that we only gather information directly available from the
+ inferior --- we don't examine any of the shared library files
+ themselves. The declaration of `struct so_list' says which fields
+ we provide values for. */
+
+static struct so_list *
+pei_current_sos (void)
+{
+ CORE_ADDR lm;
+ CORE_ADDR res;
+ struct so_list *head = 0;
+ struct so_list **link_ptr = &head;
+
+ /* Make sure we've looked up the inferior's dynamic linker's base
+ structure. */
+ res = locate_base ();
+
+ if (res == ERROR_ADDR)
+ return 0;
+
+ /* Walk the inferior's link map list, and build our list of
+ `struct so_list' nodes. */
+ lm = first_link_map_member ();
+ while (lm != 0)
+ {
+ struct so_list *new
+ = (struct so_list *) xmalloc (sizeof (struct so_list));
+ struct cleanup *old_chain = make_cleanup (xfree, new);
+ int errcode;
+ char *buffer;
+ struct link_map lm_entry;
+
+ memset (new, 0, sizeof (*new));
+
+ new->lm_info = xmalloc (sizeof (struct lm_info));
+ make_cleanup (xfree, new->lm_info);
+
+ read_memory (lm, (void *)&lm_entry, sizeof(struct link_map));
+
+ /* Extract this shared object's name. */
+ target_read_string ((CORE_ADDR)lm_entry.l_name, &buffer,
+ SO_NAME_MAX_PATH_SIZE - 1, &errcode);
+ if (errcode != 0)
+ {
+ warning ("current_sos: Can't read pathname for load map: %s\n",
+ safe_strerror (errcode));
+ }
+ else
+ {
+ strncpy (new->so_name, buffer, SO_NAME_MAX_PATH_SIZE - 1);
+ new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
+ xfree (buffer);
+ strcpy (new->so_original_name, new->so_name);
+ }
+
+ /* Get the next pointer now. */
+ lm = (CORE_ADDR)lm_entry.l_next;
+
+ new->lm_info->lmoffset = (CORE_ADDR)lm_entry.l_offs;
+
+ /* If this entry has no name, include it in the list. It's the one
+ for the main program. */
+ if (new->so_name[0] == 0)
+ {
+ free_so (new);
+ }
+ else
+ {
+ new->next = 0;
+ *link_ptr = new;
+ link_ptr = &new->next;
+ }
+
+ discard_cleanups (old_chain);
+
+ }
+
+ /* Set up so we'll be told that dlopen() calls have occurred. */
+ enable_break(1);
+
+ return head;
+}
+
+
+/* Return 1 if PC lies in the dynamic symbol resolution code of the
+ run time loader. */
+static CORE_ADDR interp_text_sect_low;
+static CORE_ADDR interp_text_sect_high;
+static CORE_ADDR interp_plt_sect_low;
+static CORE_ADDR interp_plt_sect_high;
+
+static int
+pei_in_dynsym_resolve_code (CORE_ADDR pc)
+{
+ return ((pc >= interp_text_sect_low && pc < interp_text_sect_high)
+ || (pc >= interp_plt_sect_low && pc < interp_plt_sect_high)
+ || in_plt_section (pc, NULL));
+}
+
+/*
+
+LOCAL FUNCTION
+ enable_break -- arrange for dynamic linker to hit breakpoint
+ solib_add_xyzzy will be called when that breakpoint is hit;
+ infrun.c "knows" this.
+
+SYNOPSIS
+ int enable_break (mode)
+
+DESCRIPTION
+ The dynamic linker has, as part of the debugger interface,
+ support for arranging for the inferior to hit a breakpoint
+ after mapping in the shared libraries. This function
+ enables that breakpoint.
+
+ The debugger interface structure contains a member (r_brk)
+ which is statically initialized at the time the shared library is
+ built, to the offset of a function (_r_debug_state) which is guaran-
+ teed to be called once before mapping in a library, and again when
+ the mapping is complete. At the time we are examining this member,
+ it contains only the unrelocated offset of the function, so we have
+ to do our own relocation. Later, when the dynamic linker actually
+ runs, it relocates r_brk to be the actual address of _r_debug_state().
+
+ The debugger interface structure also contains an enumeration which
+ is set to either RT_ADD or RT_DELETE prior to changing the mapping,
+ depending upon whether or not the library is being mapped or unmapped,
+ and then set to RT_CONSISTENT after the library is mapped/unmapped.
+
+ MODE indicates whether the break should be at _mainCRTstartup (for
+ the very first time) or at the location the dynamic linker set up.
+ Extra calls in mode 1 (without mode 0) are turned into noops.
+*/
+
+static int
+enable_break (int mode)
+{
+ struct minimal_symbol *msymbol;
+
+ /* First, remove all the solib event breakpoints. Their addresses
+ may have changed since the last time we ran the program. */
+ remove_solib_event_breakpoints ();
+
+ /* If we have a meaningful r_brk, use it; if not, use main on the
+ assumption that it's the first time and r_brk isn't set up yet. */
+
+ msymbol = lookup_minimal_symbol("_mainCRTStartup", NULL, symfile_objfile);
+ if (mode == 0 && msymbol != NULL && SYMBOL_VALUE_ADDRESS (msymbol) != 0)
+ {
+ disable_breakpoints_in_shlibs(0);
+ create_solib_event_breakpoint (SYMBOL_VALUE_ADDRESS (msymbol));
+ }
+ else if (mode == 1 && debug_copy.r_brk != 0)
+ {
+ create_solib_event_breakpoint (debug_copy.r_brk);
+ }
+ else
+ {
+ /* For whatever reason we couldn't set a breakpoint in the dynamic
+ linker. Warn. */
+ warning ("Unable to find dynamic linker breakpoint function.\nGDB will be unable to debug shared library initializers\nand track explicitly loaded dynamic code.");
+ }
+
+ return (1);
+}
+
+/*
+
+ LOCAL FUNCTION
+
+ special_symbol_handling -- additional shared library symbol handling
+
+ SYNOPSIS
+
+ void special_symbol_handling ()
+
+ DESCRIPTION
+
+ Once the symbols from a shared object have been loaded in the usual
+ way, we are called to do any system specific symbol handling that
+ is needed.
+
+ For SunOS4, this consisted of grunging around in the dynamic
+ linkers structures to find symbol definitions for "common" symbols
+ and adding them to the minimal symbol table for the runtime common
+ objfile.
+
+ However, for PEI, there's nothing to do.
+
+ */
+
+static void
+pei_special_symbol_handling (void)
+{
+}
+
+/* Relocate the main executable. This function should be called upon
+ stopping the inferior process at the entry point to the program.
+ The entry point from BFD is compared to the PC and if they are
+ different, the main executable is relocated by the proper amount.
+
+ As written it will only attempt to relocate executables which
+ lack interpreter sections. It seems likely that only dynamic
+ linker executables will get relocated, though it should work
+ properly for a position-independent static executable as well. */
+
+static void
+pei_relocate_main_executable (void)
+{
+#if 0 /// poss. a no-op.; however may make life simpler w.r.t. "free" relocs
+ asection *interp_sect;
+ CORE_ADDR pc = read_pc ();
+
+ /* Decide if the objfile needs to be relocated. As indicated above,
+ we will only be here when execution is stopped at the beginning
+ of the program. Relocation is necessary if the address at which
+ we are presently stopped differs from the start address stored in
+ the executable AND there's no interpreter section. The condition
+ regarding the interpreter section is very important because if
+ there *is* an interpreter section, execution will begin there
+ instead. When there is an interpreter section, the start address
+ is (presumably) used by the interpreter at some point to start
+ execution of the program.
+
+ If there is an interpreter, it is normal for it to be set to an
+ arbitrary address at the outset. The job of finding it is
+ handled in enable_break().
+
+ So, to summarize, relocations are necessary when there is no
+ interpreter section and the start address obtained from the
+ executable is different from the address at which GDB is
+ currently stopped.
+
+ [ The astute reader will note that we also test to make sure that
+ the executable in question has the DYNAMIC flag set. It is my
+ opinion that this test is unnecessary (undesirable even). It
+ was added to avoid inadvertent relocation of an executable
+ whose e_type member in the ELF header is not ET_DYN. There may
+ be a time in the future when it is desirable to do relocations
+ on other types of files as well in which case this condition
+ should either be removed or modified to accomodate the new file
+ type. (E.g, an ET_EXEC executable which has been built to be
+ position-independent could safely be relocated by the OS if
+ desired. It is true that this violates the ABI, but the ABI
+ has been known to be bent from time to time.) - Kevin, Nov 2000. ]
+ */
+
+ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
+ if (interp_sect == NULL
+ && (bfd_get_file_flags (exec_bfd) & DYNAMIC) != 0
+ && bfd_get_start_address (exec_bfd) != pc)
+ {
+ struct cleanup *old_chain;
+ struct section_offsets *new_offsets;
+ int i, changed;
+ CORE_ADDR displacement;
+
+ /* It is necessary to relocate the objfile. The amount to
+ relocate by is simply the address at which we are stopped
+ minus the starting address from the executable.
+
+ We relocate all of the sections by the same amount. This
+ behavior is mandated by recent editions of the System V ABI.
+ According to the System V Application Binary Interface,
+ Edition 4.1, page 5-5:
+
+ ... Though the system chooses virtual addresses for
+ individual processes, it maintains the segments' relative
+ positions. Because position-independent code uses relative
+ addressesing between segments, the difference between
+ virtual addresses in memory must match the difference
+ between virtual addresses in the file. The difference
+ between the virtual address of any segment in memory and
+ the corresponding virtual address in the file is thus a
+ single constant value for any one executable or shared
+ object in a given process. This difference is the base
+ address. One use of the base address is to relocate the
+ memory image of the program during dynamic linking.
+
+ The same language also appears in Edition 4.0 of the System V
+ ABI and is left unspecified in some of the earlier editions. */
+
+ displacement = pc - bfd_get_start_address (exec_bfd);
+ changed = 0;
+
+ new_offsets = xcalloc (symfile_objfile->num_sections,
+ sizeof (struct section_offsets));
+ old_chain = make_cleanup (xfree, new_offsets);
+
+ for (i = 0; i < symfile_objfile->num_sections; i++)
+ {
+ if (displacement != ANOFFSET (symfile_objfile->section_offsets, i))
+ changed = 1;
+ new_offsets->offsets[i] = displacement;
+ }
+
+ if (changed)
+ objfile_relocate (symfile_objfile, new_offsets);
+
+ do_cleanups (old_chain);
+ }
+#endif
+}
+
+/*
+
+ GLOBAL FUNCTION
+
+ pei_solib_create_inferior_hook -- shared library startup support
+
+ SYNOPSIS
+
+ void pei_solib_create_inferior_hook()
+
+ DESCRIPTION
+
+ When gdb starts up the inferior, it nurses it along (through the
+ shell) until it is ready to execute it's first instruction. At this
+ point, this function gets called via expansion of the macro
+ SOLIB_CREATE_INFERIOR_HOOK.
+
+ This is at __mainCRTstartup.
+
+ We arrange to cooperate with the dynamic linker to discover the
+ names of shared libraries that are dynamically linked, and the
+ base addresses to which they are linked.
+
+ */
+
+static void
+pei_solib_create_inferior_hook (void)
+{
+ /* Relocate the main executable if necessary. */
+ pei_relocate_main_executable ();
+
+ if (!enable_break (0))
+ {
+ warning ("shared library handler failed to enable breakpoint");
+ return;
+ }
+}
+
+/* This works because of the side-effects of setting debug_base to zero */
+static void
+pei_clear_solib (void)
+{
+ debug_base = 0;
+}
+
+static void
+pei_free_so (struct so_list *so)
+{
+ xfree (so->lm_info);
+}
+
+static void
+pei_relocate_section_addresses (struct so_list *so,
+ struct section_table *sec)
+{
+ /* Since when reading symbols we put the ImageBase into them
+ (which is required for statically linked programs), we need to
+ back it out here, so it doesn't get added twice. */
+ sec->addr += so->lm_info->lmoffset;
+ sec->endaddr += so->lm_info->lmoffset;
+}
+
+static struct target_so_ops pei_so_ops;
+
+void
+_initialize_pei_solib (void)
+{
+ pei_so_ops.relocate_section_addresses = pei_relocate_section_addresses;
+ pei_so_ops.free_so = pei_free_so;
+ pei_so_ops.clear_solib = pei_clear_solib;
+ pei_so_ops.solib_create_inferior_hook = pei_solib_create_inferior_hook;
+ pei_so_ops.special_symbol_handling = pei_special_symbol_handling;
+ pei_so_ops.current_sos = pei_current_sos;
+ pei_so_ops.open_symbol_file_object = open_symbol_file_object;
+ pei_so_ops.in_dynsym_resolve_code = pei_in_dynsym_resolve_code;
+
+ /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */
+ current_target_so_ops = &pei_so_ops;
+}
Index: src/gdb/solib-pei.h
===================================================================
RCS file: solib-pei.h
diff -N solib-pei.h
@@ -0,0 +1,29 @@
+/* Handle shared libraries for GDB, the GNU Debugger.
+ Copyright 2000
+ Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include "../libexec/libdl/include/link.h" // in libexec for now, whence?
+
+#define ERROR_ADDR 0xffffffff /* a non-zero address that's an error */
+
+struct lm_info {
+ CORE_ADDR lmoffset; /* Offset between Image base and real */
+};
+
Index: src/gdb/config/i386/interix.mt
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/config/i386/interix.mt,v
retrieving revision 1.1
diff -p -u -r1.1 interix.mt
--- src/gdb/config/i386/interix.mt 2001/12/23 20:46:23 1.1
+++ src/gdb/config/i386/interix.mt 2001/12/24 02:18:04
@@ -1,3 +1,3 @@
# Target: Intel 386 running Interix
-TDEPFILES= i386-tdep.o i387-tdep.o
+TDEPFILES= i386-tdep.o i387-tdep.o solib.o solib-pei.o
TM_FILE= tm-i386interix.h
Index: src/gdb/config/i386/nm-interix.h
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/config/i386/nm-interix.h,v
retrieving revision 1.1
diff -p -u -r1.1 nm-interix.h
--- src/gdb/config/i386/nm-interix.h 2001/12/23 20:46:23 1.1
+++ src/gdb/config/i386/nm-interix.h 2001/12/24 02:18:04
@@ -30,6 +30,9 @@ Foundation, Inc., 59 Temple Place - Suit
#define ATTACH_DETACH
+/* Be shared lib aware */
+#include "solib.h"
+
/* This is the amount to subtract from u.u_ar0
to get the offset in the core file of the register values. */
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.before/solib.c gdb/solib.c
--- gdb.before/solib.c Thu Mar 7 09:19:01 2002
+++ gdb/solib.c Tue Mar 12 14:11:11 2002
@@ -336,8 +336,9 @@ symbol_add_stub (PTR arg)
}
sap = build_section_addr_info_from_section_table (so->sections,
- so->sections_end);
-
+ so->sections_end,
+ -NONZERO_LINK_BASE(so->abfd));
+
so->objfile = symbol_file_add (so->so_name, so->from_tty,
sap, 0, OBJF_SHARED);
free_section_addr_info (sap);
@@ -369,11 +370,7 @@ symbol_add_stub (PTR arg)
we're doing.
If TARGET is non-null, add the sections of all new shared objects
- to TARGET's section table. Note that this doesn't remove any
- sections for shared objects that have been unloaded, and it
- doesn't check to see if the new shared objects are already present in
- the section table. But we only use this for core files and
- processes we've just attached to, so that's okay. */
+ to TARGET's section table. */
void
update_solib_list (int from_tty, struct target_ops *target)
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.before/symfile.c gdb/symfile.c
--- gdb.before/symfile.c Thu Mar 7 09:19:01 2002
+++ gdb/symfile.c Tue Mar 12 14:11:17 2002
@@ -443,10 +443,11 @@ find_lowest_section (bfd *abfd, asection
/* Build (allocate and populate) a section_addr_info struct from
an existing section table. */
-extern struct section_addr_info *
+struct section_addr_info *
build_section_addr_info_from_section_table (const struct section_table *start,
- const struct section_table *end)
-{
+ const struct section_table *end,
+ CORE_ADDR offset)
+{
struct section_addr_info *sap;
const struct section_table *stp;
int oidx;
@@ -460,7 +461,7 @@ build_section_addr_info_from_section_tab
stp->the_bfd_section) & (SEC_ALLOC | SEC_LOAD)
&& oidx < MAX_SECTIONS)
{
- sap->other[oidx].addr = stp->addr;
+ sap->other[oidx].addr = stp->addr + offset;
sap->other[oidx].name
= xstrdup (bfd_section_name (stp->bfd, stp->the_bfd_section));
sap->other[oidx].sectindex = stp->the_bfd_section->index;
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.before/symfile.h gdb/symfile.h
--- gdb.before/symfile.h Thu Mar 7 09:19:01 2002
+++ gdb/symfile.h Fri Mar 8 11:05:43 2002
@@ -200,9 +200,10 @@ extern struct objfile *symbol_file_add (
struct section_table;
extern struct section_addr_info *
-build_section_addr_info_from_section_table (const struct section_table *start,
- const struct section_table *end);
-
+build_section_addr_info_from_section_table (const struct section_table *,
+ const struct section_table *,
+ CORE_ADDR);
+
/* Free all memory allocated by build_section_addr_info_from_section_table. */
extern void
---------------------------------------------------------------------------
REEVALUATE corelow changes for neccessity; changes to interix-nat are
definitely needed.
Core file support for Interix (assumes corresponding BFD patches
have been applied). In core_open, we need to get to the magic
pstatus info for the unwind stuff.
PATCH BUG: there seem to be 2 copies where only one is needed!
Is there a better place to put the include?
Is this all corefile support or is some of it trampoline fixes???
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* corelow.c: include procfs.h for Interix.
(core_open): for Interix only, get signal trampoline address,
use core tables for core file (not exec tables; the formats
may be different).
Index: src/gdb/corelow.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/corelow.c,v
retrieving revision 1.2
diff -p -u -r1.2 corelow.c
--- src/gdb/corelow.c 2001/12/24 02:16:26 1.2
+++ src/gdb/corelow.c 2001/12/24 02:20:09
@@ -44,6 +44,11 @@
#define O_BINARY 0
#endif
+/* See below */
+#ifdef __INTERIX
+#include <sys/procfs.h>
+#endif
+
/* List of all available core_fns. On gdb startup, each core file register
reader calls add_core_fns() to register information on each core format it
is prepared to read. */
@@ -309,6 +314,36 @@ core_open (char *filename, int from_tty)
discard_cleanups (old_chain); /* Don't free filename any more */
unpush_target (&core_ops);
core_bfd = temp_bfd;
+
+#ifdef __INTERIX
+ {
+ /* This is painful, but there doesn't seem to be a better way.
+ See interix tm.h, IN_SIGTRAMP, and procfs.c for more details. */
+ asection *section;
+ pstatus_t *p;
+
+ section = bfd_get_section_by_name (core_bfd, ".pstatus");
+ if (section != NULL) {
+ p = (pstatus_t *)section->contents;
+
+ if (p == NULL) {
+ p = (pstatus_t *)bfd_alloc(core_bfd, section->_raw_size);
+ bfd_get_section_contents (core_bfd, section, p, 0,
+ section->_raw_size);
+ }
+ tramp_start = (CORE_ADDR)p->pr_signaldeliverer;
+ tramp_end = (CORE_ADDR)p->pr_endsignaldeliverer;
+ null_start = (CORE_ADDR)p->pr_nullapi;
+ null_end = (CORE_ADDR)p->pr_endnullapi;
+ }
+ /* else, just ignore it; it shouldn't ever happen. */
+
+ /* The stack unwind stuff needs to know this; presumably it's always
+ true for a corefile. */
+ stopped_by_random_signal = 1;
+ }
+#endif
+
old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/);
/* Find a suitable core file handler to munch on core_bfd */
@@ -317,7 +352,7 @@ core_open (char *filename, int from_tty)
validate_files ();
/* Find the data section */
- if ((*lookup_sym_fns(exec_bfd)->sym_build_sect_table)
+ if ((*lookup_sym_fns(core_bfd)->sym_build_sect_table)
(core_bfd, &core_ops.to_sections, &core_ops.to_sections_end))
error ("\"%s\": Can't find sections: %s",
bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
@@ -368,6 +403,31 @@ core_open (char *filename, int from_tty)
"you won't be able to access this core file until you terminate\n\
your %s; do ``info files''", target_longname);
}
+
+#ifdef __INTERIX
+ {
+ /* This is painful, but there doesn't seem to be a better way.
+ See interix tm.h, IN_SIGTRAMP, and procfs.c for more details. */
+ asection *section;
+ pstatus_t *p;
+
+ section = bfd_get_section_by_name (core_bfd, ".pstatus");
+ if (section != NULL) {
+ p = (pstatus_t *)section->contents;
+
+ if (p == NULL) {
+ p = (pstatus_t *)bfd_alloc(core_bfd, section->_raw_size);
+ bfd_get_section_contents (core_bfd, section, p, 0,
+ section->_raw_size);
+ }
+ tramp_start = (CORE_ADDR)p->pr_signaldeliverer;
+ tramp_end = (CORE_ADDR)p->pr_endsignaldeliverer;
+ null_start = (CORE_ADDR)p->pr_nullapi;
+ null_end = (CORE_ADDR)p->pr_endnullapi;
+ }
+ /* else, just ignore it; it shouldn't ever happen. */
+ }
+#endif
}
static void
diff -drupP --exclude-from=/M/donn/diffs/exclude.files gdb.saved/i386interix-nat.c gdb/i386interix-nat.c
--- gdb.saved/i386interix-nat.c Tue Mar 5 14:56:13 2002
+++ gdb/i386interix-nat.c Wed Mar 6 19:25:32 2002
@@ -28,7 +28,10 @@ Foundation, Inc., 59 Temple Place - Suit
#include "symfile.h"
#include "objfiles.h"
#include "gdb-stabs.h"
-
+#include "gdbcore.h"
+#include "gregset.h"
+
+
typedef unsigned long greg_t; /* Where should this be defined? */
/* See procfs.c and *interix*.h in config/[alpha,i386] */
@@ -214,7 +216,64 @@ fill_fpregset (fpregset_t *fpregsetp,
convert_to_fpregset (fpregsetp, registers, 0);
}
-
+/*
+
+ GLOBAL FUNCTION
+
+ fetch_core_registers -- fetch current registers from core file
+
+ SYNOPSIS
+
+ void fetch_core_registers (char *core_reg_sect,
+ unsigned core_reg_size,
+ int which, CORE_ADDR reg_addr)
+
+ DESCRIPTION
+
+ Read the values of either the general register set (WHICH equals 0)
+ or the floating point register set (WHICH equals 2) from the core
+ file data (pointed to by CORE_REG_SECT), and update gdb's idea of
+ their current values. The CORE_REG_SIZE parameter is compared to
+ the size of the gregset or fpgregset structures (as appropriate) to
+ validate the size of the structure from the core file. The
+ REG_ADDR parameter is ignored.
+
+ */
+
+static void
+fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR reg_addr)
+{
+ gdb_gregset_t gregset;
+ gdb_fpregset_t fpregset;
+
+ if (which == 0)
+ {
+ if (core_reg_size != sizeof (gregset))
+ {
+ warning ("wrong size gregset struct in core file");
+ }
+ else
+ {
+ memcpy ((char *) &gregset, core_reg_sect, sizeof (gregset));
+ supply_gregset (&gregset);
+ }
+ }
+ else if (which == 2)
+ {
+ if (core_reg_size != sizeof (fpregset))
+ {
+ warning ("wrong size fpregset struct in core file");
+ }
+ else
+ {
+ memcpy ((char *) &fpregset, core_reg_sect, sizeof (fpregset));
+ if (FP0_REGNUM >= 0)
+ supply_fpregset (&fpregset);
+ }
+ }
+}
+
/* the name of the proc status struct depends on the implementation */
#ifdef HAVE_PSTATUS_T
typedef pstatus_t gdb_prstatus_t;
@@ -410,4 +469,19 @@ get_longjmp_target (pc)
*pc = extract_address (raw_buffer, sizeof(CORE_ADDR));
return 1;
+}
+
+static struct core_fns interix_core_fns =
+{
+ bfd_target_coff_flavour, /* core_flavour (more or less) */
+ default_check_format, /* check_format */
+ default_core_sniffer, /* core_sniffer */
+ fetch_core_registers, /* core_read_registers */
+ NULL /* next */
+};
+
+void
+_initialize_core_interix (void)
+{
+ add_core_fns (&interix_core_fns);
}
---------------------------------------------------------------------------
Note the if (0 &&... there was a reason for this, but I can't remember
it, and it breaks setting breakpoints on shared lib entry points; probably
the test is too weak to filter the exact reason for the problem, whatever
it was.
This probably should be applied before dynsyms, but the patches collide
at one point, so for now...
NT weak symbols are really an alias; ld handles those properly but
gdb must also deal with them.
Just keep a list of the symbols so we can look up the direct symbol
and load it into the indirect one.
RECHECK THIS...
Weak symbols report as t, not T, confusing the tests. Allow either.
(Or is that static?)
diff -drupP --exclude-from=/M/donn/diffs/exclude.files gdb.before/coffread.c gdb/coffread.c
--- gdb.before/coffread.c Sun Mar 3 10:31:51 2002
+++ gdb/coffread.c Mon Mar 4 19:41:36 2002
@@ -489,18 +489,19 @@ coff_end_symtab (struct objfile *objfile
last_source_file = NULL;
}
\f
-static void
+static struct minimal_symbol *
record_minimal_symbol (char *name, CORE_ADDR address,
enum minimal_symbol_type type, struct objfile *objfile,
asection *bfd_section)
{
/* We don't want TDESC entry points in the minimal symbol table */
if (name[0] == '@')
- return;
-
- prim_record_minimal_symbol (name, address, type, objfile, bfd_section);
-}
-\f
+ return NULL;
+
+ return prim_record_minimal_symbol (name, address, type,
+ objfile, bfd_section);
+}
+\f
/* coff_symfile_init ()
is the coff-specific initialization routine for reading symbols.
It is passed a struct objfile which contains, among other things,
@@ -763,7 +785,9 @@ coff_symtab_read (long symtab_offset, un
long fcn_line_ptr = 0;
int val;
CORE_ADDR tmpaddr;
-
+ struct minimal_symbol **msyms; /* A temporary array of the results,
+ see C_NT_WEAK. */
+
/* On the use of the following symbols: Earlier versions of this routine
tried to key off .text entries to determine the size of a "file"
(an original source file). This implied that there were as many
@@ -836,6 +860,9 @@ coff_symtab_read (long symtab_offset, un
first_function_last_file = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT(objfile));
symnum = 0;
+ msyms = xmalloc (sizeof(struct msymbol *) * nsyms);
+ memset(msyms, 0, sizeof(struct msymbol *) * nsyms);
+
while (symnum < nsyms)
{
QUIT; /* Make this command interruptable. */
@@ -870,12 +897,13 @@ coff_symtab_read (long symtab_offset, un
/* Typedefs should not be treated as symbol definitions. */
if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
{
-
+ struct minimal_symbol *msym;
+
if (first_function_this_file == 0)
first_function_this_file = cs->c_value;
else
{
- /* most_recent_function _nd should be AT LEAST the beginning
+ /* most_recent_function_end should be AT LEAST the beginning
of the current function if we're on other than the first
function in the file. We'll try to do better below. */
most_recent_function_end = cs->c_value;
@@ -887,10 +915,11 @@ coff_symtab_read (long symtab_offset, un
functions (usually) so that the special handling of them
works correctly. At this point, dynamic == undefined;
if it's really undefined, we deal with that later. */
- record_minimal_symbol (cs->c_name, tmpaddr,
+ msym = record_minimal_symbol (cs->c_name, tmpaddr,
cs->c_secnum == 0 ? mst_solib_trampoline : mst_text, objfile,
coff_section_from_bfd_index(objfile->obfd, cs->c_secnum));
-
+ msyms[cs->c_symnum] = msym;
+
if (cs->c_naux > 0)
{
fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
@@ -1048,6 +1077,7 @@ coff_symtab_read (long symtab_offset, un
if (target_lookup_symbol (cs->c_name, &reladdr))
{
/* Error in lookup; ignore symbol. */
+ msyms[cs->c_symnum] = (struct minimal_symbol *)-1;
break;
}
tmpaddr = reladdr;
@@ -1116,6 +1146,7 @@ coff_symtab_read (long symtab_offset, un
(cs->c_name, tmpaddr, ms_type, (void *) (long) cs->c_sclass,
sec, coff_section_from_bfd_index (objfile->obfd, cs->c_secnum),
objfile);
+ msyms[cs->c_symnum] = msym;
if (msym)
COFF_MAKE_MSYMBOL_SPECIAL (cs->c_sclass, msym);
}
@@ -1256,12 +1287,52 @@ coff_symtab_read (long symtab_offset, un
}
break;
+ case C_NT_WEAK:
+ {
+ /* NT Weaks are really indirect symbols; aux contains the target. */
+ int realsym;
+ struct minimal_symbol *msym;
+
+ realsym = main_aux.x_sym.x_tagndx.l;
+ if (0 && cs->c_secnum == 0) // breaks b printf; absence breaks ?
+ {
+ /* nothing; ignore it (it's an undefined weak; the definition
+ will take care of things later.) */
+ }
+ else if (realsym < 0 || realsym >= nsyms || msyms[realsym] == NULL)
+ {
+ warning ("\"%s\": indirect symbol does not have real one (%d)\n",
+ cs->c_name, realsym);
+ }
+ else if (msyms[realsym] == (struct minimal_symbol *)-1)
+ {
+ /* nothing; just ignore it. (We discarded the undefined
+ real symbol, so do the same with this.) */
+ }
+ else
+ {
+ msym = prim_record_minimal_symbol_and_info
+ (cs->c_name,
+ SYMBOL_VALUE_ADDRESS(msyms[realsym]),
+ MSYMBOL_TYPE (msyms[realsym]),
+ MSYMBOL_INFO (msyms[realsym]), /* c_sclass for us. */
+ SYMBOL_SECTION (msyms[realsym]),
+ SYMBOL_BFD_SECTION (msyms[realsym]),
+ objfile);
+ msyms[cs->c_symnum] = msym;
+ }
+ break;
+ }
+
default:
process_coff_symbol (cs, &main_aux, objfile);
break;
}
}
+ /* All we needed these for was a lookup, we're done now. */
+ xfree (msyms);
+
if (first_function_this_file != 0)
complete_symtab (filestring,
first_function_this_file
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.saved/minsyms.c gdb/minsyms.c
--- gdb.saved/minsyms.c Thu Mar 14 10:33:08 2002
+++ gdb/minsyms.c Thu Mar 14 17:47:22 2002
@@ -593,7 +593,7 @@ init_minimal_symbol_collection (void)
msym_bunch_index = BUNCH_SIZE;
}
-void
+struct minimal_symbol *
prim_record_minimal_symbol (const char *name, CORE_ADDR address,
enum minimal_symbol_type ms_type,
struct objfile *objfile, asection *bfd_section)
@@ -619,7 +619,7 @@ prim_record_minimal_symbol (const char *
section = -1;
}
- prim_record_minimal_symbol_and_info (name, address, ms_type,
+ return prim_record_minimal_symbol_and_info (name, address, ms_type,
NULL, section, bfd_section, objfile);
}
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.saved/symtab.h gdb/symtab.h
--- gdb.saved/symtab.h Thu Mar 14 10:33:10 2002
+++ gdb/symtab.h Thu Mar 14 17:48:26 2002
@@ -1187,7 +1187,9 @@ extern struct type *lookup_transparent_t
/* Functions for dealing with the minimal symbol table, really a misc
address<->symbol mapping for things we don't have debug symbols for. */
-extern void prim_record_minimal_symbol (const char *, CORE_ADDR,
+extern struct minimal_symbol * prim_record_minimal_symbol (
+ const char *,
+ CORE_ADDR,
enum minimal_symbol_type,
struct objfile *,
asection *);
diff -drupP --exclude-from=/M/donn/diffs/exclude.files gdb.saved/testsuite/gdb.base/maint.exp gdb/testsuite/gdb.base/maint.exp
--- gdb.saved/testsuite/gdb.base/maint.exp Tue Mar 5 14:56:07 2002
+++ gdb/testsuite/gdb.base/maint.exp Tue Mar 5 22:33:16 2002
@@ -284,7 +284,7 @@ gdb_expect {
{
send_gdb "shell grep factorial msymbols_output\n"
gdb_expect {
- -re "\\\[ *$decimal\\\] T\[ \t\]+$hex factorial.*$gdb_prompt $"\
+ -re "\\\[ *$decimal\\\] \[Tt\]\[ \t\]+$hex factorial.*$gdb_prompt $"\
{ pass "maint print msymbols" }
-re ".*$gdb_prompt $" { fail "maint print msymbols" }
timeout { fail "(timeout) maint print msymbols" }
---------------------------------------------------------------------------
When inferring where file breaks occur, don't consider .so thunk symbols.
This should be merged with the base shared lib stuff at some point.
The bulk of this change is an indentation change. New lines are just an
if and its {}.
diff -drupP --exclude-from=/M/donn/diffs/exclude.files gdb.saved/coffread.c gdb/coffread.c
--- gdb.saved/coffread.c Tue Mar 5 14:56:12 2002
+++ gdb/coffread.c Wed Mar 6 11:46:19 2002
@@ -952,21 +952,25 @@ coff_symtab_read (long symtab_offset, un
fcn_sym_saved = main_sym;
fcn_aux_saved = main_aux;
- /* If first_function_last file is nonzero, we had gotten a sizeless
- function earlier; we keep going until we DO get a size, and
- presume that everthing in the range up to the current function
- is a single file. */
- if (most_recent_function_end != 0)
- {
- if (first_function_last_file != 0)
- range_symtab(first_function_last_file, tmpaddr-1);
- first_function_last_file = 0;
- }
- else
- {
- if (first_function_last_file == 0)
- first_function_last_file = tmpaddr;
- }
+ /* Shared lib symbols need not apply. */
+ if (cs->c_secnum != 0)
+ {
+ /* If first_function_last_file != zero, we had gotten a sizeless
+ function earlier; we keep going until we DO get a size, and
+ presume that everthing in the range up to the current function
+ is a single file. */
+ if (most_recent_function_end != 0)
+ {
+ if (first_function_last_file != 0)
+ range_symtab(first_function_last_file, tmpaddr-1);
+ first_function_last_file = 0;
+ }
+ else
+ {
+ if (first_function_last_file == 0)
+ first_function_last_file = tmpaddr;
+ }
+ }
continue;
}
---------------------------------------------------------------------------
Interix uses the same convention as BSD for passing structs of up to 8 bytes:
use registers if the size is "round" enough.
diff -drupP --exclude-from=/M/donn/diffs/exclude.files gdb.saved/config/i386/interix.mt gdb/config/i386/interix.mt
--- gdb.saved/config/i386/interix.mt Tue Mar 5 14:56:01 2002
+++ gdb/config/i386/interix.mt Tue Mar 5 15:01:03 2002
@@ -1,3 +1,3 @@
# Target: Intel 386 running Interix
-TDEPFILES= i386-tdep.o i387-tdep.o solib.o solib-pei.o
+TDEPFILES= i386-tdep.o i387-tdep.o solib.o solib-pei.o i386nbsd-tdep.o
TM_FILE= tm-i386interix.h
diff -drupP --exclude-from=/M/donn/diffs/exclude.files gdb.saved/config/i386/tm-i386interix.h gdb/config/i386/tm-i386interix.h
--- gdb.saved/config/i386/tm-i386interix.h Tue Mar 5 14:56:01 2002
+++ gdb/config/i386/tm-i386interix.h Tue Mar 5 21:24:09 2002
@@ -30,6 +30,11 @@ Foundation, Inc., 59 Temple Place - Suit
#undef TARGET_LONG_LONG_BIT
#define TARGET_LONG_LONG_BIT 64
+/* We do the same as i386nbsd, so use that function. */
+extern use_struct_convention_fn i386nbsd_aout_use_struct_convention;
+#define USE_STRUCT_CONVENTION(gcc_p, type) \
+ i386nbsd_aout_use_struct_convention(gcc_p, type)
+
/* configure can't be expected to noodle out MS's alternate spelling for
64-bit integers, so we'll tell it. */
#define PRINTF_HAS_LONG_LONG 1
---------------------------------------------------------------------------
Miscellaneous small fixes:
virtfunc.exp was failing with timouts; gdb was crashing. The change to
buildsym.h improves things so it reports the underlying error (which is
apparently a gcc problem; the stabs records aren't properly nested.)
templates.exp was failing because the compiler emitted a "const" keyword
that it wasn't expecting.
coffread.c: indentation, recognize RODATA as special, too.
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.before/buildsym.h gdb/buildsym.h
--- gdb.before/buildsym.h Thu Mar 7 09:18:59 2002
+++ gdb/buildsym.h Mon Mar 11 18:41:22 2002
@@ -177,7 +177,9 @@ EXTERN int context_stack_size;
done by a real function, push_context. This returns a pointer to a
struct context_stack. */
-#define pop_context() (&context_stack[--context_stack_depth]);
+#define pop_context() ( \
+ (context_stack_depth <= 0) ? error("Context stack underflow") : 0, \
+ &context_stack[--context_stack_depth]);
/* Nonzero if within a function (so symbols should be local, if
nothing says specifically). */
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.before/coffread.c gdb/coffread.c
--- gdb.before/coffread.c Thu Mar 7 09:18:59 2002
+++ gdb/coffread.c Tue Mar 12 14:10:13 2002
@@ -1006,18 +1007,18 @@ coff_symtab_read (long symtab_offset, un
or symnum of first global after last .file. */
next_file_symnum = cs->c_value;
if (cs->c_naux > 0)
- filestring = coff_getfilename (&main_aux, cs->c_naux);
+ filestring = coff_getfilename (&main_aux, cs->c_naux);
else
filestring = "";
coff_start_symtab (filestring);
first_function_this_file = 0;
break;
- /* C_LABEL is used for labels and static functions. Including
- it here allows gdb to see static functions when no debug
- info is available. */
+ /* C_LABEL is used for labels and static functions. Including
+ it here allows gdb to see static functions when no debug
+ info is available. */
case C_LABEL:
/* However, labels within a function can make weird backtraces,
so filter them out (from phdm@macqel.be). */
@@ -1113,7 +1115,9 @@ coff_symtab_read (long symtab_offset, un
}
#endif
- if (sec == SECT_OFF_TEXT (objfile))
+ if (sec == SECT_OFF_TEXT (objfile)
+ || sec == SECT_OFF_RODATA (objfile)
+ )
{
ms_type =
cs->c_sclass == external_class ?
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.before/testsuite/gdb.c++/templates.exp gdb/testsuite/gdb.c++/templates.exp
--- gdb.before/testsuite/gdb.c++/templates.exp Thu Mar 7 09:18:50 2002
+++ gdb/testsuite/gdb.c++/templates.exp Mon Mar 11 18:23:32 2002
@@ -440,7 +440,7 @@ gdb_expect {
send_gdb "print Garply<Garply<char> >::garply\n"
gdb_expect {
- -re "\\$\[0-9\]* = \\{(class |)Garply<char> \\((class |)Garply<Garply<char> > \\*, int, (class |)Garply<char>\\)\\} $hex <Garply<Garply<char>\[ \t\]*>::garply\\(int, (class |)Garply<char>\\)>\r\n$gdb_prompt $" { pass "print Garply<Garply<char> >::garply" }
+ -re "\\$\[0-9\]* = \\{(class |)Garply<char> \\((class |)Garply<Garply<char> > \\*( const|), int, (class |)Garply<char>\\)\\} $hex <Garply<Garply<char>\[ \t\]*>::garply\\(int, (class |)Garply<char>\\)>\r\n$gdb_prompt $" { pass "print Garply<Garply<char> >::garply" }
-re ".*$gdb_prompt $" { fail "print Garply<Garply<char> >::garply" }
timeout { fail "print Garply<Garply<char> >::garply (timeout)" }
}
---------------------------------------------------------------------------
In WinXP, stack unwind wasn't always recognizing trampolines because
there was another possible level of indirection. For NT 5.1 (XP) and
above, recognize that. (To identify 5.1, we get the info from utsname.)
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.before/config/i386/tm-i386interix.h gdb/config/i386/tm-i386interix.h
--- gdb.before/config/i386/tm-i386interix.h Thu Mar 7 09:18:43 2002
+++ gdb/config/i386/tm-i386interix.h Tue Mar 12 14:19:44 2002
@@ -72,7 +72,8 @@ extern CORE_ADDR tramp_start;
extern CORE_ADDR tramp_end;
extern CORE_ADDR null_start;
extern CORE_ADDR null_end;
-
+extern int winver;
+
/* This is sufficient, where used, but is NOT a complete test; there's more
in INIT_EXTRA_FRAME_INFO (a.k.a. interix_back_one_frame) */
#define IN_SIGTRAMP(p,f) ((((p)>=tramp_start && (p)<tramp_end)) \
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.before/exec.c gdb/exec.c
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.before/i386interix-nat.c gdb/i386interix-nat.c
--- gdb.before/i386interix-nat.c Thu Mar 7 09:19:00 2002
+++ gdb/i386interix-nat.c Tue Mar 12 14:10:35 2002
@@ -35,7 +38,8 @@ CORE_ADDR tramp_start;
CORE_ADDR tramp_end;
CORE_ADDR null_start;
CORE_ADDR null_end;
-
+int winver; /* Windows NT version number */
+
/* The /proc interface traditionally divides the target machine's register
set up into two different sets, the general register set (gregset)
and the floating point register set (fpregset). This is reflected
@@ -316,6 +320,15 @@ interix_back_one_frame (fromleaf, frame)
ra = SAVED_PC_AFTER_CALL (frame);
if (ra >= null_start && ra < null_end)
frame->signal_handler_caller = 1;
+ /* There might also be an indirect call to the mini-frame,
+ putting one more return address on the stack. (XP only,
+ I think?) This can't (reasonably) return the address of the
+ signal handler caller unless it's that situation, so this
+ is safe. */
+ ra = read_memory_unsigned_integer (
+ (CORE_ADDR) read_register (SP_REGNUM)+4, 4);
+ if (ra >= null_start && ra < null_end)
+ frame->signal_handler_caller = 1;
}
return;
}
@@ -401,6 +414,14 @@ interix_back_one_frame (fromleaf, frame)
a system call mini-frame */
ra = (CORE_ADDR)read_memory_integer
(context + offsetof(mcontext_t, gregs.gregs[UESP]), 4);
+
+ if (winver>=51) {
+ /* Newer versions of Windows NT interpose another return
+ address (but no other "stack frame" stuff) that we need
+ to simply ignore here. */
+ ra+=4;
+ }
+
ra = (CORE_ADDR)read_memory_integer(ra,4);
/* We might be done (no Null API if so) */
@@ -413,20 +434,25 @@ interix_back_one_frame (fromleaf, frame)
}
}
/* At this point, we're looking at the frame for PdxNullPosixApi,
- in either case. */
-
- /* extract the frame for PdxNullPosixApi */
- fm = read_memory_integer (fm, 4);
-
- /* extract the frame for PdxNullApiCaller */
- /* The saved frame register for PdxNullApiCaller skips us over the
- saved context, which is the wrong thing to do, because it skips
- the interrrupted routine! Instead, get the arg that was passed
- which has the address of the context (which is really in no frame) */
-
- fm = (CORE_ADDR)read_memory_integer (fm + 8, 4);
-
- /* THIS context is accounted for in a frame */
+ in either case.
+
+ PdxNullPosixApi is called by PdxNullApiCaller (which in turn
+ is called by _PdxNullApiCaller (note the _).)
+ PdxNullPosixApiCaller (no _) is a frameless function.
+
+ The saved frame pointer is as fm, but it's not of interest
+ to us because it skips us over the saved context, which is
+ the wrong thing to do, because it skips the interrrupted
+ routine! PdxNullApiCaller takes as its only argument the
+ address of the context of the interrupded function (which
+ is really in no frame, but jammed on the stack by the system)
+
+ So: fm+0: saved bp
+ fm+4: return address to _PdxNullApiCaller
+ fm+8: arg to PdxNullApiCaller pushed by _Pdx... */
+
+ fm = (CORE_ADDR)read_memory_integer (fm+0x8, 4);
+
/* Extract the second context record */
ra = (CORE_ADDR)read_memory_integer
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.before/procfs.c gdb/procfs.c
--- gdb.before/procfs.c Thu Mar 7 09:19:01 2002
+++ gdb/procfs.c Fri Mar 8 15:45:42 2002
@@ -26,7 +26,8 @@ Inc., 59 Temple Place - Suite 330, Bosto
#include "elf-bfd.h" /* for elfcore_write_* */
#include "gdbcmd.h"
#include "gdbthread.h"
-
+#include <sys/utsname.h>
+
#if defined (NEW_PROC_API)
#define _STRUCTURED_PROC 1 /* Should be done by configure script. */
#endif
@@ -1140,10 +1141,23 @@ proc_get_status (procinfo *pi)
that info here. */
// THIS MAY NOT BE THE BEST PLACE to read
// IT MAY BE BEST TO MAKE THESE FIELDS PER-PROC
+// Agreed... tell me how for /proc stuff? DT
tramp_start = (CORE_ADDR)pi->prstatus.pr_signaldeliverer;
tramp_end = (CORE_ADDR)pi->prstatus.pr_endsignaldeliverer;
null_start = (CORE_ADDR)pi->prstatus.pr_nullapi;
null_end = (CORE_ADDR)pi->prstatus.pr_endnullapi;
+ {
+ /* While we're doing such ugly things, find out which version of
+ NT this is, so we can change our unwind rules a bit. */
+ struct utsname info;
+ // N.B. If we move this, move the include of utsname.h, too.
+
+ (void)uname(&info);
+ /* Convert the first two digits (skip the decimal point) into
+ a number. E.g. 5.0 -> 50. We'll test this later to know
+ how to unwind. */
+ winver=(info.release_host[0]-'0')*10 + info.release_host[2]-'0';
+ }
#endif
}
---------------------------------------------------------------------------
Add new tests to confirm that longjmp works as expected.
Other minor housekeeping.
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* gdb.base/misc.exp: New file.
* gdb.base/longjmp.c: New file.
* gdb.base/list.exp: remove list0.h before copy (just in case).
* gdb.base/twice.exp: remove twice.c before copy (just in case).
Index: src/gdb/testsuite/gdb.base/list.exp
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/list.exp,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 list.exp
--- src/gdb/testsuite/gdb.base/list.exp 2001/12/23 00:35:17 1.1.1.1
+++ src/gdb/testsuite/gdb.base/list.exp 2001/12/24 02:22:18
@@ -31,6 +31,7 @@ set testfile "list"
set binfile ${objdir}/${subdir}/${testfile}
# Need to download the header to the host.
+standard_file host delete list0.h
remote_download host ${srcdir}/${subdir}/list0.h list0.h
Index: src/gdb/testsuite/gdb.base/longjmp.c
===================================================================
RCS file: longjmp.c
diff -N longjmp.c
--- /dev/null Sun Dec 23 18:18:47 2001
+++ longjmp.c Sun Dec 23 18:22:18 2001
@@ -0,0 +1,45 @@
+#include <setjmp.h>
+#include <stdio.h>
+
+int v1, v2;
+
+setjmp_f(jmp_buf jb)
+{
+ longjmp(jb, 99);
+ fprintf(stderr, "shouldn't get here\n");
+}
+
+sigsetjmp_f(jmp_buf jb)
+{
+ siglongjmp(jb, 98);
+ fprintf(stderr, "shouldn't get here\n");
+}
+
+dummy(){}
+
+int i=0;
+
+main()
+{
+ jmp_buf env;
+ int val;
+
+ if ((val = setjmp(env)) == 0) {
+ setjmp_f(env);
+ fprintf(stderr, "shouldn't get here, either\n");
+ }
+ else {
+ v1 = val;
+ }
+
+ if ((val = sigsetjmp(env,1)) == 0) {
+ sigsetjmp_f(env);
+ fprintf(stderr, "shouldn't get here, either\n");
+ }
+ else {
+ v2 = val;
+ }
+
+ dummy();
+ exit(0);
+}
Index: src/gdb/testsuite/gdb.base/misc.exp
===================================================================
RCS file: misc.exp
diff -N misc.exp
--- /dev/null Sun Dec 23 18:24:01 2001
+++ misc.exp Sun Dec 23 18:22:18 2001
@@ -0,0 +1,87 @@
+# Copyright (C) 1992, 1994, 1995, 1997 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Please email any bugs, comments, and/or additions to this file to:
+# bug-gdb@prep.ai.mit.edu
+
+# This file was written by Donn Terry (donn@interix.com) derived from a
+# similar file by Fred Fish. (fnf@cygnus.com)
+
+if $tracelevel {
+ strace $tracelevel
+}
+
+set prms_id 0
+set bug_id 0
+
+# Create and source the file that provides information about the compiler
+# used to compile the test case.
+if [get_compiler_info ${binfile}] {
+ return -1;
+}
+
+
+#
+# Test for setjmp()/longjmp()
+#
+proc longjmp_func { } {
+ global gdb_prompt
+ global hex
+ global decimal
+ global gcc_compiled
+
+ if { ! [ runto main ] } then { gdb_suppress_tests; }
+
+ # single step until we get to dummy
+ # break doesn't work inside the -re's (tcl/expect bug?)
+ set done 0;
+ while (1) {
+ send_gdb "step\n";
+ gdb_expect {
+ -re ".*dummy.*$gdb_prompt $" { set done 1}
+ -re ".*The program is not being run.*" { set done 1 }
+ -re ".*$gdb_prompt $" { }
+ default { fail "single step to dummy"; set done 1 }
+
+ }
+ if { $done } break;
+ }
+
+ gdb_test "print v1" " = 99" "setjmp: print v1"
+ gdb_test "print v2" " = 98" "setjmp: print v2"
+
+ gdb_stop_suppressing_tests;
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+set testfile "longjmp"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/${testfile}
+if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+ perror "Couldn't compile ${srcfile}"
+ return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir $srcdir/$subdir
+gdb_load ${binfile}
+
+longjmp_func
Index: src/gdb/testsuite/gdb.base/twice.exp
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/twice.exp,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 twice.exp
--- src/gdb/testsuite/gdb.base/twice.exp 2001/12/23 00:35:19 1.1.1.1
+++ src/gdb/testsuite/gdb.base/twice.exp 2001/12/24 02:22:18
@@ -34,6 +34,7 @@ set fileid [open ${objdir}/${subdir}/${s
puts $fileid "#include \"twice.c\"";
close $fileid;
+standard_file host delete twice.c
remote_download host ${srcdir}/${subdir}/twice.c twice.c
if { [gdb_compile "${objdir}/${subdir}/${srcfile}" "${binfile}" executable $options] != "" } {
---------------------------------------------------------------------------
Test additional conditions for signal vs. backtrace command. All
architectures should pass, but it may find a bug in some implementations.
(Nested handlers, e.g.)
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* gdb.base/signals.c: add more possible test cases.
* gdb.base/signals.exp: Use them.
Index: src/gdb/testsuite/gdb.base/signals.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/signals.c,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 signals.c
--- src/gdb/testsuite/gdb.base/signals.c 2001/12/23 00:35:18 1.1.1.1
+++ src/gdb/testsuite/gdb.base/signals.c 2001/12/24 02:38:40
@@ -9,6 +9,7 @@
#endif
static int count = 0;
+static int i, quit;
#ifdef PROTOTYPES
static void
@@ -24,6 +25,14 @@ handler (sig)
}
static void
+handler2 (sig)
+ int sig;
+{
+ signal (sig, handler2);
+ quit = 1;
+}
+
+static void
func1 ()
{
++count;
@@ -55,5 +64,35 @@ main ()
func1 ();
alarm (1);
func2 ();
+ alarm (0); /* Just to be sure */
+
+ /* Now test strange unwind cases: make sure we can unwind over all
+ these conditions */
+
+ quit = 0; /* This way, so if alarm(2) ever takes 0 time */
+#ifdef SIGALRM
+ signal (SIGALRM, handler2);
+#endif
+ /* while computing */
+ alarm (2);
+ for (i=1;i>0 && quit==0;i++);
+
+ alarm(0); /* Just to be sure */
+
+ /* while paused */
+ alarm (2);
+ pause();
+
+ alarm(0); /* Just to be sure */
+
+ quit=0; /* This way, so if signal occurs too early... */
+ /* SIGINT while computing, paused; gdb will "see" the signal */
+#ifdef SIGINT
+ signal (SIGINT, handler2);
+#endif
+
+ for (i=1;i>0 && quit==0;i++);
+ pause();
+
return count;
}
Index: src/gdb/testsuite/gdb.base/signals.exp
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/signals.exp,v
retrieving revision 1.2
diff -p -u -r1.2 signals.exp
--- src/gdb/testsuite/gdb.base/signals.exp 2001/12/24 01:44:44 1.2
+++ src/gdb/testsuite/gdb.base/signals.exp 2001/12/24 02:38:40
@@ -158,6 +158,9 @@ proc signal_tests_1 {} {
}
gdb_test "break handler" "Breakpoint \[0-9\]+ .*"
+ # We don't need handler2 until later, but it's convienient to do
+ # it now.
+ gdb_test "break handler2" "Breakpoint \[0-9\]+ .*"
gdb_test "next" "\\+\\+count; /\\* second \\*/" \
"next to 2nd ++count in signals_tests_1"
# An alarm has been signaled, give the signal time to get delivered.
@@ -297,6 +300,106 @@ proc signal_tests_1 {} {
if {$bash_bug} then {
clear_xfail "m68*-*-sunos4*"
}
+
+ # Now test some more exotic backtrace cases that might even have
+ # a chance of failing on only some machines.
+
+ # This test could fail on a blindingly fast machine, or one
+ # with default optimizations that remove null loops. Adjust
+ # signals.c accordingly to make the loop actually loop long enough.
+
+ # We handle getting re-synced here, too.
+ send_gdb "continue\n"
+ gdb_expect {
+ -re "Breakpoint.*func2.*$gdb_prompt $" {
+ fail "first continue to handler2"
+ gdb_test "continue" "Breakpoint.*handler2.*" \
+ "extra first continue to handler2"
+ }
+ -re "Breakpoint.*handler2.*$gdb_prompt $" { pass "continue to first handler2" }
+ default { fail "continue to first handler2" }
+ }
+
+ # This doesn't test that main is frame #2, just that main is frame
+ # #2, #3, or higher. At some point this should be fixed (but
+ # it quite possibly would introduce new FAILs on some systems).
+ setup_xfail "i*86-pc-linux-gnu" "i*86-*-bsdi2.0"
+ gdb_test "backtrace" "#0.*handler2.*#1.*#2.*main.*" \
+ "backtrace from computing in signals_tests_1"
+
+ gdb_test "continue" "Breakpoint.*handler2.*" \
+ "continue to handler2 while pause()d"
+
+ # This doesn't test that main is frame #2, just that main is frame
+ # #2, #3, or higher. At some point this should be fixed (but
+ # it quite possibly would introduce new FAILs on some systems).
+ setup_xfail "i*86-pc-linux-gnu" "i*86-*-bsdi2.0"
+ gdb_test "backtrace" "#0.*handler2.*#1.*#2.*main.*" \
+ "ALARM: backtrace from pause() in signals_tests_1"
+
+ # Now test keyboard interrupts
+ # enter a compute bound loop
+ send_gdb "continue\n"
+ sleep 2
+
+ # interrupt it.
+ send_gdb "\003"
+ gdb_expect {
+ -re ".*Program received signal SIGINT, Interrupt.*$gdb_prompt $" {
+ pass "Interrupt while computing"
+ }
+ default { fail "Interrupt while computing" }
+ }
+
+ # This test could fail on a blindingly fast machine, or one
+ # with default optimizations that remove null loops. Adjust
+ # signals.c accordingly to make the loop actually loop long enough.
+
+ # This doesn't test that main is frame #0, just that main is
+ # on the stack at all.
+ setup_xfail "i*86-pc-linux-gnu" "i*86-*-bsdi2.0"
+ gdb_test "backtrace" ".*#0.*main.*" \
+ "backtrace #1 from SIGINT while computing in signals_tests_1"
+
+ gdb_test "signal SIGINT" "Breakpoint.*handler2.*" \
+ "signal SIGINT into handler2 after SIGINT of computing."
+
+ # This doesn't test that main is frame #2, just that main is frame
+ # #2, #3, or higher. At some point this should be fixed (but
+ # it quite possibly would introduce new FAILs on some systems).
+ setup_xfail "i*86-pc-linux-gnu" "i*86-*-bsdi2.0"
+ gdb_test "backtrace" "#0.*handler2.*#1.*#2.*main.*" \
+ "INT: backtrace from compute in signals_tests_1"
+
+ # enter a pause() call
+ send_gdb "continue\n"
+ sleep 2
+
+ # interrupt it.
+ send_gdb "\003"
+ gdb_expect {
+ -re ".*Program received signal SIGINT, Interrupt.*$gdb_prompt $" {
+ pass "Interrupt while pause()d"
+ }
+ default { fail "Interrupt while pause()d" }
+ }
+
+ # This doesn't test that main is frame #0, just that main is
+ # on the stack at all.
+ setup_xfail "i*86-pc-linux-gnu" "i*86-*-bsdi2.0"
+ gdb_test "backtrace" ".*#0.*main.*" \
+ "backtrace #2 from SIGINT while computing in signals_tests_1"
+
+ gdb_test "signal SIGINT" "Breakpoint.*handler2.*" \
+ "signal SIGINT into handler2 after SIGINT of pause()."
+
+ # This doesn't test that main is frame #2, just that main is frame
+ # #2, #3, or higher. At some point this should be fixed (but
+ # it quite possibly would introduce new FAILs on some systems).
+ setup_xfail "i*86-pc-linux-gnu" "i*86-*-bsdi2.0"
+ gdb_test "backtrace" "#0.*handler2.*#1.*#2.*main.*" \
+ "backtrace from pause() in signals_tests_1"
+
gdb_test "continue" "Program exited with code 010\\." \
"continue to exit in signals_tests_1 "
}
@@ -437,6 +540,15 @@ The program being debugged stopped while
# But we should be able to backtrace...
# On alpha-*-osf2.0 this test works when run manually but sometime fails when
# run under dejagnu, making it very hard to debug the problem. Weird...
+ #
+ # Part of the problem is that we can end up having not completed the
+ # prolog of func1, thus causing unwind to quit/fail. This will occur
+ # when the signal is delivered during the execution of the first
+ # instruction of func1.
+ #
+ # The above failure mode is pretty much guaranteed on alpha-pc-interix,
+ # and seems an unavoidable corner case.
+ #
gdb_test "bt 10" "#0.*handler.*#1.*#2.*main.*" "bt in signals.exp"
# ...and continue...
gdb_test "continue" "Continuing\\." "continue in signals.exp"
---------------------------------------------------------------------------
Fri Dec 3 10:07:20 PST 1999 Donn Terry <donnte@microsoft.com>
* gdb.base/commands.exp: Line number changed in source file.
* gdb.base/ending-run.exp: Allow cap S in entry point name.
* gdb.base/step-test.exp: Step a couple of times to avoid prologue,
Index: src/gdb/testsuite/gdb.base/commands.exp
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/commands.exp,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 commands.exp
--- src/gdb/testsuite/gdb.base/commands.exp 2001/12/23 00:35:16 1.1.1.1
+++ src/gdb/testsuite/gdb.base/commands.exp 2001/12/24 02:42:40
@@ -331,7 +331,7 @@ proc watchpoint_command_test {} {
}
send_gdb "continue\n"
gdb_expect {
- -re "Continuing.*\[Ww\]atchpoint $wp_id deleted because the program has left the block in.*which its expression is valid.*run.c:57.*$gdb_prompt $" {
+ -re "Continuing.*\[Ww\]atchpoint $wp_id deleted because the program has left the block in.*which its expression is valid.*run.c:82.*$gdb_prompt $" {
pass "continue with watch"
}
-re "$gdb_prompt $" {fail "continue with watch"}
Index: src/gdb/testsuite/gdb.base/ending-run.exp
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/ending-run.exp,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 ending-run.exp
--- src/gdb/testsuite/gdb.base/ending-run.exp 2001/12/23 00:35:16 1.1.1.1
+++ src/gdb/testsuite/gdb.base/ending-run.exp 2001/12/24 02:42:40
@@ -151,7 +151,7 @@ gdb_expect {
fail "Old bug came back!"
gdb_test "n" ".*" ""
}
- -re ".*in.*start.*$gdb_prompt $" {
+ -re ".*in.*\[Ss\]tart.*$gdb_prompt $" {
pass "step out of main"
}
-re ".*in.*bsp_trap.*$gdb_prompt $" {
Index: src/gdb/testsuite/gdb.base/step-test.exp
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/testsuite/gdb.base/step-test.exp,v
retrieving revision 1.1.1.1
diff -p -u -r1.1.1.1 step-test.exp
--- src/gdb/testsuite/gdb.base/step-test.exp 2001/12/23 00:35:19 1.1.1.1
+++ src/gdb/testsuite/gdb.base/step-test.exp 2001/12/24 02:42:40
@@ -167,7 +167,7 @@ gdb_expect {
fail "Can't run to line 45"
return 0
}
- fail "stepi: finish call"
+ fail "stepi: finish call (unexpected exit)"
}
-re ".*${decimal}.*callee.*NEXTI.*$gdb_prompt $" {
pass "stepi: finish call"
@@ -185,7 +185,7 @@ gdb_expect {
}
-re "$gdb_prompt $" {
# We got something else. Fail.
- fail "stepi: finish call"
+ fail "stepi: finish call (unexpected result)"
return
}
timeout {
---------------------------------------------------------------------------
On some systems, malloc is a weak symbol, and if the application
doesn't actually call something that uses malloc by that name, the
call-from-keyboard stuff will fail. However, if we inform gdb of
the strong (and hidden) name of malloc (that usually will be present)
we increase the odds of call from keyboard "just working".
ChangeLog
* defs.h (NAME_OF_MALLOC): define a default.
* valops.c (value_allocate_space_in_inferior): use it.
* tm-i386interix.h (NAME_OF_MALLOC): define specific value.
Index: src/gdb/defs.h
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/defs.h,v
retrieving revision 1.3
diff -p -u -r1.3 defs.h
--- src/gdb/defs.h 2001/12/24 02:09:51 1.3
+++ src/gdb/defs.h 2001/12/24 02:44:33
@@ -987,6 +987,10 @@ typedef struct ptid ptid_t;
#define CONST_PTR const
+#ifndef NAME_OF_MALLOC
+#define NAME_OF_MALLOC "malloc"
+#endif
+
/* Defaults for system-wide constants (if not defined by xm.h, we fake it).
FIXME: Assumes 2's complement arithmetic */
Index: src/gdb/valops.c
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/valops.c,v
retrieving revision 1.4
diff -p -u -r1.4 valops.c
--- src/gdb/valops.c 2001/12/24 02:12:19 1.4
+++ src/gdb/valops.c 2001/12/24 02:44:34
@@ -136,7 +136,7 @@ struct value *
value_allocate_space_in_inferior (int len)
{
struct value *blocklen;
- struct value *val = find_function_in_inferior ("malloc");
+ struct value *val = find_function_in_inferior (NAME_OF_MALLOC);
blocklen = value_from_longest (builtin_type_int, (LONGEST) len);
val = call_function_by_hand (val, 1, &blocklen);
Index: src/gdb/config/i386/tm-i386interix.h
===================================================================
RCS file: /dev/fs/H/rupp/devel-local-repository/src/gdb/config/i386/tm-i386interix.h,v
retrieving revision 1.1
diff -p -u -r1.1 tm-i386interix.h
--- src/gdb/config/i386/tm-i386interix.h 2001/12/23 20:46:23 1.1
+++ src/gdb/config/i386/tm-i386interix.h 2001/12/24 02:44:34
@@ -116,4 +116,6 @@ get_longjmp_target PARAMS ((CORE_ADDR *)
#define GET_LONGJMP_TARGET(ADDR) get_longjmp_target(ADDR)
+#define NAME_OF_MALLOC "_malloc"
+
#endif /* TM_INTERIX_H */
---------------------------------------------------------------------------
The assembler debug tests make a lot of assumptions that are false
at least some of the time. Make the assumptions explicit build requirements
and more machines can pass.
The imbedded comment gives the details.
Also, add a comment to dbxread.c resolving an unknown related to this.
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/Makefile.in testsuite/gdb.asm/Makefile.in
--- /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/Makefile.in Thu Apr 15 18:34:29 1999
+++ testsuite/gdb.asm/Makefile.in Tue Mar 12 22:13:42 2002
@@ -25,7 +25,7 @@ clean mostlyclean:
distclean maintainer-clean realclean: clean
-rm -f *~ core
-rm -f Makefile config.status config.log
- -rm -f arch.inc
+ -rm -f arch.inc object.inc
-rm -f *-init.exp
-rm -fr *.log summary detail *.plog *.sum *.psum site.*
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/asm-source.exp testsuite/gdb.asm/asm-source.exp
--- /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/asm-source.exp Wed Feb 27 13:05:50 2002
+++ testsuite/gdb.asm/asm-source.exp Tue Mar 12 22:13:42 2002
@@ -27,7 +27,32 @@ if $tracelevel then {
# Test debugging assembly level programs.
# This file uses asmsrc[12].s for input.
#
-
+# Some comments on "corner cases": On some systems it's not possible to
+# link an application without both crt0.o and the default libc, because
+# they mutually refer. For this test to work, it must either use crt0 and libc
+# or stand completely alone. Since there are good reasons not to use crt0,
+# it needs to stand completely alone. Since the stabs entries generated
+# by the assembler are mostly SLINE entries (no functions or blocks), there's
+# nothing but the "next" SO entry to terminate the blocks (and thus generate
+# partial symtabs with a proper end value). That happens "accidentally"
+# if linking with more complete libraries, but not in this case. (This
+# would also not be a problem if FUN entries were generated.) To cause
+# the insertion of a "next" SO entry follwing asmsrc2.o, we use the (nearly)
+# empty asmsrc4.o. (Ref: read_dbx_symtab.)
+#
+# Additionally, the stack unwinder logic (at least for COFF) looks to see
+# if the PC is in the "entry file". Putting _start (which identifies
+# the entry file) in the same file as main confuses the unwinder, and it
+# omits unwinding main as well, causing test failures. Thus, asmsrc3.s
+# contains _start (alone).
+#
+# Not all systems have their default entry point as _start, so we set it.
+#
+# Everything appears to work correctly for "leading underscore" machines,
+# but there is some risk that it might not under some circumstances; if
+# this test is failing by not finding symbols, look for that.
+#
+
set prms_id 0
set bug_id 0
@@ -47,6 +72,10 @@ if [istarget "d10v-*-*"] then {
if [istarget "s390-*-*"] then {
set asm-arch s390
}
+if [istarget "i386-*-interix*"] then {
+ set asm-arch i386
+ set asm-obj coff
+}
if [istarget "i\[3456\]86-*-*"] then {
set asm-arch i386
}
@@ -94,10 +123,15 @@ set testfile "asm-source"
set binfile ${objdir}/${subdir}/${testfile}
set src1 ${srcdir}/${subdir}/asmsrc1.s
set src2 ${srcdir}/${subdir}/asmsrc2.s
-
+set src3 ${srcdir}/${subdir}/asmsrc3.s
+set src4 ${srcdir}/${subdir}/asmsrc4.s
+
remote_exec build "rm -f ${subdir}/arch.inc"
remote_download host ${srcdir}/${subdir}/${asm-arch}.inc ${subdir}/arch.inc
+remote_exec build "rm -f ${subdir}/object.inc"
+remote_download host ${srcdir}/${subdir}/${asm-obj}.inc ${subdir}/object.inc
+
if { "${asm-flags}" == "" } {
#set asm-flags "-Wa,-gstabs,-I${srcdir}/${subdir},-I${objdir}/${subdir}"
set asm-flags "-gstabs -I${srcdir}/${subdir} -I${objdir}/${subdir}"
@@ -109,18 +143,27 @@ if {[target_assemble ${src1} asmsrc1.o "
if {[target_assemble ${src2} asmsrc2.o "${asm-flags}"] != ""} then {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
+if {[target_assemble ${src3} asmsrc3.o "${asm-flags}"] != ""} then {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
+if {[target_assemble ${src4} asmsrc4.o "${asm-flags}"] != ""} then {
+ gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
+}
-set opts "debug ldflags=-nostartfiles"
+# Some shared libs won't stand alone (without the startup file), so be sure
+# it's static. And not all systems start at _start.
+
+set opts "debug ldflags=-nostartfiles ldflags=-nostdlib ldflags=-Wl,-entry,_start ldflags=--static "
foreach i ${link-flags} {
append opts " ldflags=$i"
}
-if { [gdb_compile "asmsrc1.o asmsrc2.o" "${binfile}" executable $opts] != "" } {
+if { [gdb_compile "asmsrc1.o asmsrc2.o asmsrc3.o asmsrc4.o" "${binfile}" executable $opts] != "" } {
gdb_suppress_entire_file "Testcase compile failed, so all tests in this file will automatically fail."
}
-remote_exec build "mv asmsrc1.o asmsrc2.o ${objdir}/${subdir}"
-
-
+remote_exec build "mv asmsrc1.o asmsrc2.o asmsrc3.o asmsrc4.o ${objdir}/${subdir}"
+
+
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
@@ -189,8 +232,8 @@ gdb_expect {
gdb_test "list $entry_symbol" ".*gdbasm_startup.*" "list"
# Now try a source file search
-gdb_test "search A routine for foo2 to call" \
- "39\[ \t\]+comment \"A routine for foo2 to call.\"" "search"
+gdb_test "search Provide something to search for" \
+ "20\[ \t\]+comment \"Provide something to search for\"" "search"
# See if `f' prints the right source file.
gdb_test "f" ".*asmsrc2\[.\]s:8.*" "f in foo2"
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/asmsrc1.s testsuite/gdb.asm/asmsrc1.s
--- /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/asmsrc1.s Tue Dec 4 11:45:57 2001
+++ testsuite/gdb.asm/asmsrc1.s Tue Mar 12 22:13:42 2002
@@ -1,6 +1,6 @@
.include "common.inc"
.include "arch.inc"
-
+ .include "object.inc"
comment "WARNING: asm-source.exp checks for line numbers printed by gdb."
comment "Be careful about changing this file without also changing"
comment "asm-source.exp."
@@ -9,19 +9,19 @@ comment "asm-source.exp."
comment "This file is not linked with crt0."
comment "Provide very simplistic equivalent."
- .global _start
-_start:
- gdbasm_startup
- gdbasm_call main
- gdbasm_exit0
-
-
+comment " .global _start"
+comment " function _start"
+comment " gdbasm_startup"
+comment " gdbasm_call main"
+comment " gdbasm_exit0"
+
+
comment "main routine for assembly source debugging test"
comment "This particular testcase uses macros in <arch>.inc to achieve"
comment "machine independence."
.global main
-main:
+ function main
gdbasm_enter
comment "Call a macro that consists of several lines of assembler code."
@@ -39,25 +39,25 @@ comment "All done."
comment "A routine for foo2 to call."
.global foo3
-foo3:
+ function foo3
gdbasm_enter
gdbasm_leave
.global exit
-exit:
+ function exit
gdbasm_exit0
comment "A static function"
-foostatic:
+ function _foostatic
gdbasm_enter
gdbasm_leave
comment "A global variable"
- .global globalvar
-gdbasm_datavar globalvar 11
-
+ .global _globalvar
+gdbasm_datavar _globalvar 11
+
comment "A static variable"
-gdbasm_datavar staticvar 5
+gdbasm_datavar _staticvar 5
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/asmsrc2.s testsuite/gdb.asm/asmsrc2.s
--- /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/asmsrc2.s Tue Dec 4 11:45:57 2001
+++ testsuite/gdb.asm/asmsrc2.s Tue Mar 12 22:13:42 2002
@@ -1,10 +1,10 @@
.include "common.inc"
.include "arch.inc"
-
+ .include "object.inc"
+
comment "Second file in assembly source debugging testcase."
-
.global foo2
-foo2:
+ function foo2
gdbasm_enter
comment "Call someplace else (several times)."
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/asmsrc3.s testsuite/gdb.asm/asmsrc3.s
--- /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/asmsrc3.s Wed Dec 31 16:00:00 1969
+++ testsuite/gdb.asm/asmsrc3.s Tue Mar 12 22:13:42 2002
@@ -0,0 +1,21 @@
+ .include "common.inc"
+ .include "arch.inc"
+ .include "object.inc"
+ comment "empty file, to provide EOF entry in stabs"
+
+comment "This file is not linked with crt0."
+comment "Provide very simplistic equivalent."
+
+ .global _start
+ function _start
+ gdbasm_startup
+ gdbasm_call main
+ gdbasm_exit0
+
+comment "The next nonblank line must be 'offscreen' w.r.t. start"
+comment "and it must not be the last line in the file (I don't know why)"
+
+
+
+comment "Provide something to search for"
+
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/asmsrc4.s testsuite/gdb.asm/asmsrc4.s
--- /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/asmsrc4.s Wed Dec 31 16:00:00 1969
+++ testsuite/gdb.asm/asmsrc4.s Tue Mar 12 22:13:42 2002
@@ -0,0 +1,6 @@
+ .include "common.inc"
+ .include "arch.inc"
+ .include "object.inc"
+ comment "empty file, to provide EOF entry in stabs"
+
+ function ender
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/coff.inc testsuite/gdb.asm/coff.inc
--- /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/coff.inc Wed Dec 31 16:00:00 1969
+++ testsuite/gdb.asm/coff.inc Tue Mar 12 22:13:42 2002
@@ -0,0 +1,6 @@
+ comment "For COFF, functions should be flagged as such"
+
+ .macro function name
+ .def \name; .val \name; .scl 2; .type 040; .endef
+\name:
+ .endm
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/common.inc testsuite/gdb.asm/common.inc
--- /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/common.inc Tue Dec 4 11:45:57 2001
+++ testsuite/gdb.asm/common.inc Tue Mar 12 22:13:42 2002
@@ -26,3 +26,4 @@ comment "datavar - define a data variabl
comment "macros to label a subroutine may also eventually be needed"
comment "i.e. .global foo\nfoo:\n"
+
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/otherobj.inc testsuite/gdb.asm/otherobj.inc
--- /C/CVS/binutils.baseline/src/gdb/testsuite/gdb.asm/otherobj.inc Wed Dec 31 16:00:00 1969
+++ testsuite/gdb.asm/otherobj.inc Tue Mar 12 22:13:42 2002
@@ -0,0 +1,5 @@
+ comment "Just define the label"
+
+ .macro function name
+\name:
+ .endm
diff -drupP --exclude-from=/dev/fs/M/donn/diffs/exclude.files gdb.before/dbxread.c gdb/dbxread.c
--- dbxread.c Thu Mar 7 09:18:59 2002
+++ dbxread.c Sat Mar 9 20:13:58 2002
@@ -2568,8 +2568,9 @@ read_ofile_symtab (struct partial_symtab
else
{
/* The N_SO starting this symtab is the first symbol, so we
- better not check the symbol before it. I'm not this can
- happen, but it doesn't hurt to check for it. */
+ better not check the symbol before it. This is rare, but it
+ does occur, particularly with debug symbols from the assembler,
+ which would not (of course) have a compiler name entry. */
bfd_seek (symfile_bfd, sym_offset, SEEK_CUR);
processing_gcc_compilation = 0;
}
---------------------------------------------------------------------------
Use smarter REs so that systems that mark .text as DATA or .data as CODE
will pass without having to force an XFAIL (and still fail if something
serious goes wrong.)
diff -drupP --exclude-from=/M/donn/diffs/exclude.files gdb.saved/testsuite/gdb.base/maint.exp gdb/testsuite/gdb.base/maint.exp
--- gdb.saved/testsuite/gdb.base/maint.exp Tue Mar 5 14:56:07 2002
+++ gdb/testsuite/gdb.base/maint.exp Tue Mar 5 22:33:16 2002
@@ -398,20 +398,30 @@ gdb_expect {
}
# Test for new option: CODE section flag
-# If your data section is tagged CODE, xfail this test.
send_gdb "maint info sections CODE\n"
gdb_expect {
- -re ".* .data .*$gdb_prompt $" { fail "maint info sections CODE" }
- -re ".* .text .*$gdb_prompt $" { pass "maint info sections CODE" }
+ -re ".* .data \[^\n\]*CODE\[^\n\]*\n" { exp_continue }
+ -re ".* .data .*\n" { fail "maint info sections CODE (.data unexpected)" }
+ -re ".* .text .*\n" { pass "maint info sections CODE" }
+ -re ".*$gdb_prompt $" { fail "maint info sections CODE (no .text)" }
+ timeout { fail "(timeout) maint info sections CODE (no output)" }
+}
+gdb_expect {
+ -re ".*$gdb_prompt $" { }
timeout { fail "(timeout) maint info sections CODE" }
}
# Test for new option: DATA section flag
-# If your text section is tagged DATA, xfail this test.
send_gdb "maint info sections DATA\n"
gdb_expect {
- -re ".* .text .*$gdb_prompt $" { fail "maint info sections DATA" }
- -re ".* .data .*$gdb_prompt $" { pass "maint info sections DATA" }
+ -re ".* .text \[^\n\]*DATA\[^\n\]*\n" { exp_continue }
+ -re ".* .text .*\n" { fail "maint info sections DATA (.text unexpected)" }
+ -re ".* .data .*\n" { pass "maint info sections DATA" }
+ -re ".*$gdb_prompt $" {fail "maint info sections DATA 2 (no .text)" }
+ timeout { fail "(timeout) maint info sections DATA (no output)" }
+}
+gdb_expect {
+ -re ".*$gdb_prompt $" { }
timeout { fail "(timeout) maint info sections DATA" }
}
---------------------------------------------------------------------------
The newly "enabled for everything" tests for attach have a number
of problems for /proc based gdb, and also has an HP-UX specific test
that is not so marked. Because of this it leaves a cpu-eating
process behind slowing down all subsequent tests significantly.
See 2002-03-25 Fred Fish <fnf@redhat.com>.
1) /proc generates different messages.
2) /proc chatters more (which is a different issue) and consequently
some patterns fail to match. (It looks to me as if the unmodified
patterns should match, but they don't while the shortened ones do.)
3) If the name of the executable is not found, automatic symbol loads
don't happen. Add recovery code so the subsequent tests don't lose
sync and leave the dangling process around. (Without symbols,
the dangling process doesn't get killed, even though there appear
to be some efforts to dot that.)
4) One test is clearly HP-UX specific. Not having "i r" hang in the
attach case is a useful test, but the exact test is too specific.
The fix is a bit "bandaidy" (the original author here would be
better able to fix it.)
--- testsuite/gdb.base/attach.exp Fri Apr 5 02:58:08 2002
+++ testsuite/gdb.base.new/attach.exp Fri Apr 5 02:31:11 2002
@@ -113,6 +113,9 @@
gdb_expect {
-re ".*Illegal process-id: abc.*$gdb_prompt $"\
{pass "attach to nonsense is prohibited"}
+ # This response is expected from /proc-based systems.
+ -re "Attaching to.*, process .*couldn't open /proc file.*$gdb_prompt $"\
+ {pass "attach to nonsense is prohibited"}
-re "Attaching to.*$gdb_prompt $"\
{fail "attach to nonsense is prohibited (bogus pid allowed)"}
-re "$gdb_prompt $" {fail "attach to nonsense is prohibited"}
@@ -133,6 +136,9 @@
{pass "attach to nonexistent process is prohibited"}
-re "Attaching to.*, process 0.*denied.*$gdb_prompt $"\
{pass "attach to nonexistent process is prohibited"}
+ # This response is expected from /proc-based systems.
+ -re "Attaching to.*, process .*couldn't open /proc file.*$gdb_prompt $"\
+ {pass "attach to nonexistent process is prohibited"}
-re "$gdb_prompt $" {fail "attach to nonexistent process is prohibited"}
timeout {fail "(timeout) attach to nonexistent process is prohibited"}
}
@@ -164,7 +170,7 @@
send_gdb "attach $testpid\n"
gdb_expect {
- -re "Attaching to program.*$binfile, process $testpid.*main.*at .*$srcfile:.*$gdb_prompt $"\
+ -re "Attaching to program.*`?$binfile'?, process $testpid.*main.*at .*$srcfile:.*$gdb_prompt $"\
{pass "attach1, after setting file"}
-re "$gdb_prompt $" {fail "attach1, after setting file"}
timeout {fail "(timeout) attach1, after setting file"}
@@ -229,10 +235,48 @@
gdb_expect {
-re "Attaching to process $testpid.*Reading symbols from $binfile.*main.*at .*$gdb_prompt $"\
{pass "attach2"}
+ -re "Attaching to process $testpid.*main.*at .*$gdb_prompt $"\
+ {setup_xfail "*-*-interix*"
+ fail "attach2" }
-re "$gdb_prompt $" {fail "attach2"}
timeout {fail "(timeout) attach2"}
}
+ # Verify that we can still "see" the variable "should_exit" in the
+ # program, and that it is zero. If we can't, recover with a 'symbol-file'
+ # command so the rest of the tests here run correctly.
+ #
+ send_gdb "print should_exit\n"
+ gdb_expect {
+ -re "No symbol table.*$gdb_prompt $" {
+
+ setup_xfail "*-*-interix*"
+ fail "after attach2, print should_exit (no symbols)"
+
+ send_gdb "symbol-file $binfile\n"
+ gdb_expect {
+ -re "Load new symbol table from.*y or n.*$" {
+ send_gdb "y\n"
+ gdb_expect {
+ -re "Reading .*done.*$gdb_prompt $"\
+ {pass "(re)set file, before attach2a"}
+ -re "$gdb_prompt $" {fail "(re)set file, after attach2a"}
+ timeout {fail "(timeout) (re)set file, after attach2a"}
+ }
+ }
+ -re "Reading symbols from .*done.*$gdb_prompt $"\
+ {pass "set file, after attach2a"}
+ -re "$gdb_prompt $" {fail "set file, after attach2a"}
+ timeout {fail "(timeout) set file, after attach2a"}
+ }
+ }
+
+ -re ".* = 0.*$gdb_prompt $"\
+ {pass "after attach2, print should_exit"}
+ -re "$gdb_prompt $" {fail "after attach2, print should_exit"}
+ timeout {fail "(timeout) after attach2, print should_exit"}
+ }
+
# Verify that we can modify the variable "should_exit" in the
# program.
#
@@ -373,6 +417,8 @@
timeout {fail "(timeout) attach call"}
}
+ # This appears to be painfully HP-UX specific.
+
# See if other registers are problems
#
send_gdb "i r r3\n"
@@ -382,6 +428,9 @@
}
-re ".*r3.*$gdb_prompt $" {
pass "Bug fixed, Yayyy!"
+ }
+ -re "$gdb_prompt $" {
+ pass "Apparent pass."
}
timeout { fail "timeout on info reg" }
}
---------------------------------------------------------------------------
Enable lookup of the name the program was started with.
--- i386interix-nat.c.saved Fri Apr 5 15:13:58 2002
+++ i386interix-nat.c Fri Apr 5 15:29:54 2002
@@ -23,7 +23,8 @@ Foundation, Inc., 59 Temple Place - Suit
#include <ucontext.h>
#include <frame.h>
#include <inferior.h>
-
+#include <fcntl.h>
+
#include <i386-tdep.h>
#include "symfile.h"
#include "objfiles.h"
@@ -545,3 +545,41 @@ pei_adjust_objfile_offsets(struct objfil
(objfile->section_offsets)->offsets[i] += symbols_offset;
}
}
+
+/* We don't have a /proc/pid/file or /proc/pid/exe to read a link from,
+ so read it from the same place ps gets the name. */
+
+char *
+child_pid_to_exec_file (int pid)
+{
+ char *path;
+ char *buf;
+ int fd, c;
+ char *p;
+
+ asprintf (&path, "/proc/%d/stat", pid);
+ buf = xcalloc (MAXPATHLEN+1, sizeof (char));
+ make_cleanup (xfree, path);
+ make_cleanup (xfree, buf);
+
+ fd = open (path, O_RDONLY);
+
+ if (fd < 0)
+ return NULL;
+
+ /* Skip over "Argv0\t" */
+ lseek (fd, 6, SEEK_SET);
+
+ c = read (fd, buf, MAXPATHLEN);
+ close (fd);
+
+ if (c < 0)
+ return NULL;
+
+ buf[c] = '\0'; /* Ensure null termintion. */
+ p = strchr(buf, '\n');
+ if (p != NULL)
+ *p = '\0';
+
+ return buf;
+}
--- config/i386/nm-interix.h.saved Fri Apr 5 15:31:35 2002
+++ config/i386/nm-interix.h Fri Apr 5 15:31:08 2002
@@ -58,4 +58,7 @@ extern int kernel_u_size PARAMS ((void))
#define COFF_WITH_PE
#define COFF_IMAGE_WITH_PE
+/* Turn on our own child_pid_to_exec_file. */
+#define CHILD_PID_TO_EXEC_FILE
+
#endif /* NM_INTERIX_H */
--- procfs.c.saved Mon Apr 8 18:18:19 2002
+++ procfs.c Sat Apr 6 12:50:10 2002
@@ -185,8 +185,9 @@ init_procfs_ops (void)
procfs_ops.to_find_memory_regions = proc_find_memory_regions;
procfs_ops.to_make_corefile_notes = procfs_make_note_section;
procfs_ops.to_magic = OPS_MAGIC;
-}
-
+ procfs_ops.to_pid_to_exec_file = child_pid_to_exec_file;
+}
+
/* =================== END, TARGET_OPS "MODULE" =================== */
/*
next reply other threads:[~2002-08-01 20:57 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-08-01 13:57 Donn Terry [this message]
2002-08-01 14:39 ` Andrew Cagney
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=FE465D8F724E3F4F811D067203A214AE05C19B6B@red-msg-08.redmond.corp.microsoft.com \
--to=donnte@microsoft.com \
--cc=gdb-patches@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox