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>
This commit is contained in:
Fred Fish 1996-05-26 21:41:40 +00:00
parent 9b61d62b9f
commit 9391c9977e
12 changed files with 246 additions and 62 deletions

View File

@ -1,3 +1,80 @@
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.

View File

@ -1,6 +1,12 @@
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

View File

@ -22,7 +22,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#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 */

View File

@ -131,6 +131,110 @@ struct linked_proc_info
struct linked_proc_info *next;
} *linked_proc_desc_table = NULL;
/* 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;
}
/* 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;
}
/* 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);
}
/* Guaranteed to set frame->saved_regs to some values (it never leaves it
NULL). */
@ -161,14 +265,9 @@ alpha_find_saved_regs (frame)
#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;
@ -285,7 +384,10 @@ alpha_saved_pc_after_call (frame)
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);
}
@ -471,6 +573,9 @@ after_prologue (pc, proc_desc)
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
@ -493,7 +598,7 @@ after_prologue (pc, proc_desc)
}
/* 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)
@ -599,6 +704,8 @@ find_proc_desc (pc, next_frame)
}
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,
@ -610,6 +717,12 @@ find_proc_desc (pc, next_frame)
&& 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);
@ -650,17 +763,7 @@ alpha_frame_chain(frame)
/* 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);
@ -696,7 +799,8 @@ init_extra_frame_info (frame)
/* 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))
@ -984,7 +1088,8 @@ alpha_pop_frame()
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;

View File

@ -1,29 +0,0 @@
/* 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

View File

@ -32,8 +32,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
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. */

View File

@ -52,8 +52,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* 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. */

View File

@ -63,8 +63,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* 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. */

2
gdb/configure vendored
View File

@ -3194,6 +3194,7 @@ case "${host}" in
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 ;;
@ -3351,6 +3352,7 @@ a29k-*-sym1*) gdb_target=ultra3 ;;
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

View File

@ -305,6 +305,7 @@ a29k-*-*) gdb_host=ultra3 ;;
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 ;;
@ -460,6 +461,7 @@ a29k-*-udi*) gdb_target=a29k-udi ;;
a29k-*-vxworks*) gdb_target=vx29k ;;
alpha-*-osf*) gdb_target=alpha-osf1 ;;
alpha-*-linux*) gdb_target=alpha-linux ;;
# start-sanitize-arc
arc-*-*) gdb_target=arc ;;

View File

@ -111,7 +111,7 @@
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 */
@ -155,7 +155,7 @@ static int
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));
@ -207,7 +207,7 @@ dcache_flush (dcache)
static struct dcache_block *
dcache_hit (dcache, addr)
DCACHE *dcache;
unsigned int addr;
CORE_ADDR addr;
{
register struct dcache_block *db;
@ -338,7 +338,7 @@ dcache_peek_byte (dcache, addr, ptr)
else
db = dcache_alloc (dcache);
immediate_quit++;
db->addr = MASK (addr);
db->addr = MASK (addr);
while (done < LINE_SIZE)
{
int try =

View File

@ -835,7 +835,23 @@ parse_symbol (sh, ax, ext_sh, bigend, section_offsets)
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)
{