* NEWS: Add Alpha Linux as a new native configuration.
* mdebugread.c (parse_symbol): When we find a malloc() symbol with
return type VOID, assume no debugging info is available for that
object file and patch the return value into VOID *. Otherwise,
operations requiring an implicit call to malloc() will fail.
* infrun.c (wait_for_inferior): The criterion to detect entering a
sigtramp handler is now: (a) the current pc is inside a sigtramp
handler, (b) the previous pc is not in a sigtramp handler, and (c)
the current stack pointer is "inner" than the old one. Condition
(c) is new to avoid mistaking a return from a signal handler into
sigtramp as a new sigtramp invocation.
* dcache.c (struct dcache_block): Declare addr as CORE_ADDR. An
int may not be big enough to hold an address.
(dcache_hit): Ditto.
(dcache_peek_byte): Fix indentation.
* configure.in (alpha-*-linux*): Add target.
* configure: Rebuild
* config/alpha/tm-alpha.h (PROC_DESC_IS_DYN_SIGTRAMP): New macro.
(SET_PROC_DESC_IS_DYN_SIGTRAMP): Ditto.
(DYNAMIC_SIGTRAMP_OFFSET): Ditto.
(SIGCONTEXT_ADDR): Ditto.
(FRAME_PAST_SIGTRAMP_FRAME): Ditto.
* config/alpha/alpha-linux.mh: New file.
* config/alpha/alpha-linux.mt: Ditto.
* config/alpha/nm-linux.h: Ditto.
* config/alpha/tm-alphalinux.h: Ditto.
* config/alpha/xm-alphalinux.h: Ditto.
* config/alpha/xm-alphaosf.h: Renamed from xm-alpha.h.
* config/alpha/alpha-osf1.mh (XM_FILE): Change from xm-alpha.h to
xm-alphaosf.h.
* config/alpha/alpha-osf2.mh: Ditto.
* blockframe.c (find_pc_partial_function): Pass PC to
SIGTRAMP_START and SIGTRAMP_END macros for the benefit of systems
that detect sigtramp code via designated code sequences (as is the
case for Linux/Alpha, for example).
* config/i386/tm-i386bsd.h: Change SIGTRAMP_START and SIGTRAMP_END
to ignore new PC argument.
* config/m68k/tm-hp300bsd.h: Ditto.
* config/vax/tm-vax.h: Ditto.
* alpha-tdep.c (alpha_linux_sigtramp_offset): New function.
(alpha_osf_skip_sigtramp_frame): Ditto.
(push_sigtramp_desc): Ditto.
(alpha_find_saved_regs): Use SIGCONTEXT_ADDR macro to extract
sigcontext address from frame.
(alpha_saved_pc_after_call): When in sigtramp, use
alpha_frame_saved_pc() instead of read-register().
(after_prologue): When inside a dynamically generated sigtramp
function, there is no prologue, so return address of first
instruction.
(alpha_in_prologue): Fix typo in comment.
(find_proc_desc): Use macro DYNAMIC_SIGTRAMP_OFFSET to determine
whether we're inside a dynamicaly generated sigtramp function. If
so, create and push and appropriate procedure descriptor.
(alpha_frame_chain): Use macro FRAME_PAST_SIGTRAMP_FRAME to obtain
the frame past a sigtramp frame (if the current frame is indeed a
sigtramp function).
(init_extra_frame_info): Don't read next frame register off of
stack-pointer when inside a dynamiccaly generated sigtramp.
(alpha_pop_frame): Also unlink and destroy procedure descriptors
created for dynamically generated sigtramp functions.
* alpha-nat.c: When compiling under Linux, include <asm/reg.h> and
<alpha/ptrace.h> instead of <machine/reg.h>
+Sun May 26 14:14:49 1996 Fred Fish <fnf@cygnus.com>
+
+ Changes from: David Mosberger-Tang <davidm@azstarnet.com>
+
+ * NEWS: Add Alpha Linux as a new native configuration.
+
+ * mdebugread.c (parse_symbol): When we find a malloc() symbol with
+ return type VOID, assume no debugging info is available for that
+ object file and patch the return value into VOID *. Otherwise,
+ operations requiring an implicit call to malloc() will fail.
+
+ * infrun.c (wait_for_inferior): The criterion to detect entering a
+ sigtramp handler is now: (a) the current pc is inside a sigtramp
+ handler, (b) the previous pc is not in a sigtramp handler, and (c)
+ the current stack pointer is "inner" than the old one. Condition
+ (c) is new to avoid mistaking a return from a signal handler into
+ sigtramp as a new sigtramp invocation.
+
+ * dcache.c (struct dcache_block): Declare addr as CORE_ADDR. An
+ int may not be big enough to hold an address.
+ (dcache_hit): Ditto.
+ (dcache_peek_byte): Fix indentation.
+
+ * configure.in (alpha-*-linux*): Add target.
+ * configure: Rebuild
+
+ * config/alpha/tm-alpha.h (PROC_DESC_IS_DYN_SIGTRAMP): New macro.
+ (SET_PROC_DESC_IS_DYN_SIGTRAMP): Ditto.
+ (DYNAMIC_SIGTRAMP_OFFSET): Ditto.
+ (SIGCONTEXT_ADDR): Ditto.
+ (FRAME_PAST_SIGTRAMP_FRAME): Ditto.
+
+ * config/alpha/alpha-linux.mh: New file.
+ * config/alpha/alpha-linux.mt: Ditto.
+ * config/alpha/nm-linux.h: Ditto.
+ * config/alpha/tm-alphalinux.h: Ditto.
+ * config/alpha/xm-alphalinux.h: Ditto.
+ * config/alpha/xm-alphaosf.h: Renamed from xm-alpha.h.
+ * config/alpha/alpha-osf1.mh (XM_FILE): Change from xm-alpha.h to
+ xm-alphaosf.h.
+ * config/alpha/alpha-osf2.mh: Ditto.
+
+ * blockframe.c (find_pc_partial_function): Pass PC to
+ SIGTRAMP_START and SIGTRAMP_END macros for the benefit of systems
+ that detect sigtramp code via designated code sequences (as is the
+ case for Linux/Alpha, for example).
+
+ * config/i386/tm-i386bsd.h: Change SIGTRAMP_START and SIGTRAMP_END
+ to ignore new PC argument.
+ * config/m68k/tm-hp300bsd.h: Ditto.
+ * config/vax/tm-vax.h: Ditto.
+
+ * alpha-tdep.c (alpha_linux_sigtramp_offset): New function.
+ (alpha_osf_skip_sigtramp_frame): Ditto.
+ (push_sigtramp_desc): Ditto.
+ (alpha_find_saved_regs): Use SIGCONTEXT_ADDR macro to extract
+ sigcontext address from frame.
+ (alpha_saved_pc_after_call): When in sigtramp, use
+ alpha_frame_saved_pc() instead of read-register().
+ (after_prologue): When inside a dynamically generated sigtramp
+ function, there is no prologue, so return address of first
+ instruction.
+ (alpha_in_prologue): Fix typo in comment.
+ (find_proc_desc): Use macro DYNAMIC_SIGTRAMP_OFFSET to determine
+ whether we're inside a dynamicaly generated sigtramp function. If
+ so, create and push and appropriate procedure descriptor.
+ (alpha_frame_chain): Use macro FRAME_PAST_SIGTRAMP_FRAME to obtain
+ the frame past a sigtramp frame (if the current frame is indeed a
+ sigtramp function).
+ (init_extra_frame_info): Don't read next frame register off of
+ stack-pointer when inside a dynamiccaly generated sigtramp.
+ (alpha_pop_frame): Also unlink and destroy procedure descriptors
+ created for dynamically generated sigtramp functions.
+
+ * alpha-nat.c: When compiling under Linux, include <asm/reg.h> and
+ <alpha/ptrace.h> instead of <machine/reg.h>
+
Thu May 23 15:13:56 1996 Jeffrey A Law (law@cygnus.com)
* h8300-tdep.c (IS_PUSH): Refine.
What has changed in GDB?
(Organized release by release)
+*** Changes since GDB-4.16:
+
+* New native configurations
+
+Alpha Linux alpha-*-linux*
+
*** Changes in GDB-4.16:
* New native configurations
#include "gdbcore.h"
#include "target.h"
#include <sys/ptrace.h>
-#include <machine/reg.h>
+#ifdef __linux__
+# include <asm/reg.h>
+# include <alpha/ptrace.h>
+#else
+# include <machine/reg.h>
+#endif
#include <sys/user.h>
/* Size of elements in jmpbuf */
struct linked_proc_info *next;
} *linked_proc_desc_table = NULL;
+\f
+/* Under Linux, signal handler invocations can be identified by the
+ designated code sequence that is used to return from a signal
+ handler. In particular, the return address of a signal handler
+ points to the following sequence (the first instruction is quadword
+ aligned):
+
+ bis $30,$30,$16
+ addq $31,0x67,$0
+ call_pal callsys
+
+ Each instruction has a unique encoding, so we simply attempt to
+ match the instruction the pc is pointing to with any of the above
+ instructions. If there is a hit, we know the offset to the start
+ of the designated sequence and can then check whether we really are
+ executing in a designated sequence. If not, -1 is returned,
+ otherwise the offset from the start of the desingated sequence is
+ returned.
+
+ There is a slight chance of false hits: code could jump into the
+ middle of the designated sequence, in which case there is no
+ guarantee that we are in the middle of a sigreturn syscall. Don't
+ think this will be a problem in praxis, though.
+*/
+long
+alpha_linux_sigtramp_offset (CORE_ADDR pc)
+{
+ unsigned int i[3], w;
+ long off, res;
+
+ if (read_memory_nobpt(pc, (char *) &w, 4) != 0)
+ return -1;
+
+ off = -1;
+ switch (w)
+ {
+ case 0x47de0410: off = 0; break; /* bis $30,$30,$16 */
+ case 0x43ecf400: off = 4; break; /* addq $31,0x67,$0 */
+ case 0x00000083: off = 8; break; /* call_pal callsys */
+ default: return -1;
+ }
+ pc -= off;
+ if (pc & 0x7)
+ {
+ /* designated sequence is not quadword aligned */
+ return -1;
+ }
+
+ if (read_memory_nobpt(pc, (char *) i, sizeof(i)) != 0)
+ return -1;
+
+ if (i[0] == 0x47de0410 && i[1] == 0x43ecf400 && i[2] == 0x00000083)
+ return off;
+
+ return -1;
+}
+
+\f
+/* Under OSF/1, the __sigtramp routine is frameless and has a frame
+ size of zero, but we are able to backtrace through it. */
+CORE_ADDR
+alpha_osf_skip_sigtramp_frame (frame, pc)
+ struct frame_info *frame;
+ CORE_ADDR pc;
+{
+ char *name;
+ find_pc_partial_function (pc, &name, (CORE_ADDR *)NULL, (CORE_ADDR *)NULL);
+ if (IN_SIGTRAMP (pc, name))
+ return frame->frame;
+ else
+ return 0;
+}
+
+\f
+/* Dynamically create a signal-handler caller procedure descriptor for
+ the signal-handler return code starting at address LOW_ADDR. The
+ descriptor is added to the linked_proc_desc_table. */
+
+alpha_extra_func_info_t
+push_sigtramp_desc (CORE_ADDR low_addr)
+{
+ struct linked_proc_info *link;
+ alpha_extra_func_info_t proc_desc;
+
+ link = (struct linked_proc_info *)
+ xmalloc (sizeof (struct linked_proc_info));
+ link->next = linked_proc_desc_table;
+ linked_proc_desc_table = link;
+
+ proc_desc = &link->info;
+
+ proc_desc->numargs = 0;
+ PROC_LOW_ADDR (proc_desc) = low_addr;
+ PROC_HIGH_ADDR (proc_desc) = low_addr + 3 * 4;
+ PROC_DUMMY_FRAME (proc_desc) = 0;
+ PROC_FRAME_OFFSET (proc_desc) = 0x298; /* sizeof(struct sigcontext_struct) */
+ PROC_FRAME_REG (proc_desc) = SP_REGNUM;
+ PROC_REG_MASK (proc_desc) = 0xffff;
+ PROC_FREG_MASK (proc_desc) = 0xffff;
+ PROC_PC_REG (proc_desc) = 26;
+ PROC_LOCALOFF (proc_desc) = 0;
+ SET_PROC_DESC_IS_DYN_SIGTRAMP (proc_desc);
+}
+
\f
/* Guaranteed to set frame->saved_regs to some values (it never leaves it
NULL). */
#endif
if (frame->signal_handler_caller)
{
- CORE_ADDR sigcontext_pointer_addr;
CORE_ADDR sigcontext_addr;
- if (frame->next)
- sigcontext_pointer_addr = frame->next->frame;
- else
- sigcontext_pointer_addr = frame->frame;
- sigcontext_addr = read_memory_integer(sigcontext_pointer_addr, 8);
+ sigcontext_addr = SIGCONTEXT_ADDR (frame);
for (ireg = 0; ireg < 32; ireg++)
{
reg_position = sigcontext_addr + SIGFRAME_REGSAVE_OFF + ireg * 8;
proc_desc = find_proc_desc (pc, frame->next);
pcreg = proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM;
- return read_register (pcreg);
+ if (frame->signal_handler_caller)
+ return alpha_frame_saved_pc (frame);
+ else
+ return read_register (pcreg);
}
if (proc_desc)
{
+ if (PROC_DESC_IS_DYN_SIGTRAMP (proc_desc))
+ return PROC_LOW_ADDR (proc_desc); /* "prologue" is in kernel */
+
/* If function is frameless, then we need to do it the hard way. I
strongly suspect that frameless always means prologueless... */
if (PROC_FRAME_REG (proc_desc) == SP_REGNUM
}
/* Return non-zero if we *might* be in a function prologue. Return zero if we
- are definatly *not* in a function prologue. */
+ are definitively *not* in a function prologue. */
static int
alpha_in_prologue (pc, proc_desc)
}
else
{
+ long offset;
+
/* Is linked_proc_desc_table really necessary? It only seems to be used
by procedure call dummys. However, the procedures being called ought
to have their own proc_descs, and even if they don't,
&& PROC_HIGH_ADDR(&link->info) > pc)
return &link->info;
+ /* If PC is inside a dynamically generated sigtramp handler,
+ create and push a procedure descriptor for that code: */
+ offset = DYNAMIC_SIGTRAMP_OFFSET (pc);
+ if (offset >= 0)
+ return push_sigtramp_desc (pc - offset);
+
if (startaddr == 0)
startaddr = heuristic_proc_start (pc);
/* The previous frame from a sigtramp frame might be frameless
and have frame size zero. */
&& !frame->signal_handler_caller)
- {
- /* The alpha __sigtramp routine is frameless and has a frame size
- of zero, but we are able to backtrace through it. */
- char *name;
- find_pc_partial_function (saved_pc, &name,
- (CORE_ADDR *)NULL, (CORE_ADDR *)NULL);
- if (IN_SIGTRAMP (saved_pc, name))
- return frame->frame;
- else
- return 0;
- }
+ return FRAME_PAST_SIGTRAMP_FRAME (frame, saved_pc);
else
return read_next_frame_reg(frame, PROC_FRAME_REG(proc_desc))
+ PROC_FRAME_OFFSET(proc_desc);
/* This may not be quite right, if proc has a real frame register.
Get the value of the frame relative sp, procedure might have been
interrupted by a signal at it's very start. */
- else if (frame->pc == PROC_LOW_ADDR (proc_desc) && !PROC_DESC_IS_DUMMY (proc_desc))
+ else if (frame->pc == PROC_LOW_ADDR (proc_desc)
+ && !PROC_DESC_IS_DYN_SIGTRAMP (proc_desc))
frame->frame = read_next_frame_reg (frame->next, SP_REGNUM);
else
frame->frame = read_next_frame_reg (frame->next, PROC_FRAME_REG (proc_desc))
write_register (SP_REGNUM, new_sp);
flush_cached_frames ();
- if (proc_desc && PROC_DESC_IS_DUMMY(proc_desc))
+ if (proc_desc && (PROC_DESC_IS_DUMMY(proc_desc)
+ || PROC_DESC_IS_DYN_SIGTRAMP (proc_desc)))
{
struct linked_proc_info *pi_ptr, *prev_ptr;
+++ /dev/null
-/* Host definitions for GDB running on an alpha under OSF/1
- Copyright (C) 1992, 1993 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. */
-
-#if !defined (HOST_BYTE_ORDER)
-#define HOST_BYTE_ORDER LITTLE_ENDIAN
-#endif
-
-/* The alpha has no siginterrupt routine. */
-#define NO_SIGINTERRUPT
-
-/* HAVE_SGTTY also works, but we have termios, so use it. */
-
-#define HAVE_TERMIOS
the user area. Using constants here allows for cross debugging.
These are tested for BSDI but should work on 386BSD. */
-#define SIGTRAMP_START 0xfdbfdfc0
-#define SIGTRAMP_END 0xfdbfe000
+#define SIGTRAMP_START(pc) 0xfdbfdfc0
+#define SIGTRAMP_END(pc) 0xfdbfe000
/* Saved Pc. Get it from sigcontext if within sigtramp. */
/* For 4.4, it is actually right 20 bytes *before* STACK_END_ADDR, so
include that in the area we test for. */
-#define SIGTRAMP_START (STACK_END_ADDR - 20)
-#define SIGTRAMP_END (STACK_END_ADDR + TARGET_UPAGES * TARGET_NBPG)
+#define SIGTRAMP_START(pc) (STACK_END_ADDR - 20)
+#define SIGTRAMP_END(pc) (STACK_END_ADDR + TARGET_UPAGES * TARGET_NBPG)
/* Address of end of stack space. */
/* On the VAX, sigtramp is in the u area. Can't check the exact
addresses because for cross-debugging we don't have VAX include
files around. This should be close enough. */
-#define SIGTRAMP_START STACK_END_ADDR
-#define SIGTRAMP_END 0x80000000
+#define SIGTRAMP_START(pc) STACK_END_ADDR
+#define SIGTRAMP_END(pc) 0x80000000
/* Stack grows downward. */
a29k-*-*) gdb_host=ultra3 ;;
+alpha-*-linux*) gdb_host=alpha-linux ;;
alpha-*-osf1*) gdb_host=alpha-osf1 ;;
alpha-*-osf2*) gdb_host=alpha-osf2 ;;
alpha-*-osf[3456789]*) gdb_host=alpha-osf3 ;;
a29k-*-udi*) gdb_target=a29k-udi ;;
a29k-*-vxworks*) gdb_target=vx29k ;;
+alpha-*-linux*) gdb_target=alpha-linux ;;
alpha-*-osf*) gdb_target=alpha-osf1 ;;
# start-sanitize-arc
alpha-*-osf1*) gdb_host=alpha-osf1 ;;
alpha-*-osf2*) gdb_host=alpha-osf2 ;;
alpha-*-osf[3456789]*) gdb_host=alpha-osf3 ;;
+alpha-*-linux*) gdb_host=alpha-linux ;;
arm-*-*) gdb_host=arm ;;
a29k-*-vxworks*) gdb_target=vx29k ;;
alpha-*-osf*) gdb_target=alpha-osf1 ;;
+alpha-*-linux*) gdb_target=alpha-linux ;;
# start-sanitize-arc
arc-*-*) gdb_target=arc ;;
struct dcache_block
{
struct dcache_block *p; /* next in list */
- unsigned int addr; /* Address for which data is recorded. */
+ CORE_ADDR addr; /* Address for which data is recorded. */
char data[LINE_SIZE]; /* bytes at given address */
unsigned char state[LINE_SIZE]; /* what state the data is in */
dcache_peek_byte PARAMS ((DCACHE *dcache, CORE_ADDR addr, char *ptr));
static struct dcache_block *
-dcache_hit PARAMS ((DCACHE *dcache, unsigned int addr));
+dcache_hit PARAMS ((DCACHE *dcache, CORE_ADDR addr));
static int dcache_write_line PARAMS ((DCACHE *dcache,struct dcache_block *db));
static struct dcache_block *
dcache_hit (dcache, addr)
DCACHE *dcache;
- unsigned int addr;
+ CORE_ADDR addr;
{
register struct dcache_block *db;
else
db = dcache_alloc (dcache);
immediate_quit++;
- db->addr = MASK (addr);
+ db->addr = MASK (addr);
while (done < LINE_SIZE)
{
int try =
if (sh->sc == scUndefined || sh->sc == scNil)
t = mdebug_type_int;
else
- t = parse_type (cur_fd, ax, sh->index + 1, 0, bigend, name);
+ {
+ t = parse_type (cur_fd, ax, sh->index + 1, 0, bigend, name);
+ if (STREQ(name, "malloc") && t->code == TYPE_CODE_VOID)
+ {
+ /* I don't know why, but, at least under Linux/Alpha,
+ when linking against a malloc without debugging
+ symbols, its read as a function returning void---this
+ is bad because it means we cannot call functions with
+ string arguments interactively; i.e., "call
+ printf("howdy\n")" would fail with the error message
+ "program has no memory available". To avoid this, we
+ patch up the type and make it void*
+ instead. (davidm@azstarnet.com)
+ */
+ t = t->pointer_type;
+ }
+ }
b = top_stack->cur_block;
if (sh->st == stProc)
{