diff options
Diffstat (limited to 'sys-devel')
-rw-r--r-- | sys-devel/gdb/Manifest | 22 | ||||
-rw-r--r-- | sys-devel/gdb/files/gdb-5.3-hppa-01.patch | 5579 | ||||
-rw-r--r-- | sys-devel/gdb/files/gdb-5.3-hppa-02.patch | 24 | ||||
-rw-r--r-- | sys-devel/gdb/files/gdb-5.3-hppa-03.patch | 67 | ||||
-rw-r--r-- | sys-devel/gdb/gdb-5.3-r1.ebuild | 8 | ||||
-rw-r--r-- | sys-devel/gdb/gdb-5.3.90.ebuild | 23 | ||||
-rw-r--r-- | sys-devel/gdb/gdb-5.3.ebuild | 30 |
7 files changed, 30 insertions, 5723 deletions
diff --git a/sys-devel/gdb/Manifest b/sys-devel/gdb/Manifest index 675de3b4f36e..2d3f3dd3286f 100644 --- a/sys-devel/gdb/Manifest +++ b/sys-devel/gdb/Manifest @@ -1,16 +1,13 @@ ------BEGIN PGP SIGNED MESSAGE----- -Hash: SHA1 - MD5 1aef2f75c2e86b680319434fbe27f3b7 ChangeLog 6833 MD5 288d0dcab72dd3b4dbe5804c50a77505 gdb-5.1.1-r2.ebuild 1876 MD5 e6fe8a5f0e0edea4a7c31d5f51751ca0 gdb-5.2.1.ebuild 1611 -MD5 5636716eb7a6c9c0ed57ab298de6d2c6 gdb-5.3.90.ebuild 3028 -MD5 7d53620e578fe5ca1f544e9544dfad61 gdb-5.3.ebuild 2408 +MD5 7e49579dc1b212aa76d33b61158e10e5 gdb-5.3.90.ebuild 2958 +MD5 b55e194f0f7d4e9daa8de0b42e1ce949 gdb-5.3.ebuild 2318 MD5 f4e6b93754d71bafc7489a3b7898f2af gdb-6.0.ebuild 1738 MD5 9a09f8d531c582e78977dbfd96edc1f2 metadata.xml 164 MD5 a4e52f911791fb4fca2aad989eaace25 gdb-6.0-r1.ebuild 1946 MD5 8f3f6a7991170a6e76e217f415e2c278 gdb-6.1.ebuild 1611 -MD5 973be9a886a48884bb892fa7b092a225 gdb-5.3-r1.ebuild 2497 +MD5 018e0849bf62a64f210cf5e04fd6ee95 gdb-5.3-r1.ebuild 2550 MD5 b10a0412514689ca09e82691abc23c4b gdb-6.1.1.ebuild 1571 MD5 c9906583fd4286272dff5fd2503ebe39 files/digest-gdb-5.1.1-r2 63 MD5 263738287571b63dd7bb69d3d5d50e04 files/digest-gdb-5.2.1 64 @@ -18,9 +15,6 @@ MD5 2e43a9ed1afd8f8047e7b752b95f0c12 files/digest-gdb-5.3 128 MD5 9b0c6e2a754a741a6cd20cacea4f408b files/digest-gdb-5.3.90 158 MD5 420712ede2a47fedcae76b6f6215b9d4 files/digest-gdb-6.0 62 MD5 734c7bb9c66275fa7982d104905234da files/gdb-5.1.1-ppc-booltypes.patch 994 -MD5 ca7cf8e4b2eba16df1842e0a453e2b32 files/gdb-5.3-hppa-01.patch 182179 -MD5 d5314bcbc29fb3ce8351caa3a501c351 files/gdb-5.3-hppa-02.patch 926 -MD5 5b0433c121b92f2a35c2106bbf45bbb9 files/gdb-5.3-hppa-03.patch 2678 MD5 1de0e1b91ac150426719e904f0e1a5cd files/gdb-5.3-sparc-nat-asm.patch 521 MD5 e497ab2f05d847bde74f4e3441e2c7a2 files/gdb-6.0-coreutils.patch 1964 MD5 c6dfff1373e52fef5872c1bdca4cb706 files/gdb-6.0-info.patch 1108 @@ -34,10 +28,6 @@ MD5 a4a80b477c6a8d7de101a73bbbf83b21 files/digest-gdb-6.1.1 64 MD5 1da0dcdbff7ba48a06350a28ecdd238e files/gdb-6.1-ppc64-01.patch 359 MD5 dbfdcb19db1cd221d8730821cadd37cf files/gdb-6.1-hppa-01.patch 202602 MD5 224b82738dbbfa74c0bd1619a145998d files/gdb-6.1-uclibc.patch 6129 ------BEGIN PGP SIGNATURE----- -Version: GnuPG v1.9.8 (GNU/Linux) - -iD8DBQFBDw5WHTu7gpaalycRAtjPAKDtFAnzoYWhnYw4DjhVzWW+eWcQSACcD1CQ -cTKgau71Wsrusi5Yq4+6Ke0= -=6lbY ------END PGP SIGNATURE----- +MD5 d5314bcbc29fb3ce8351caa3a501c351 files/hppa/02_hppa_gdb-5.3.patch 926 +MD5 5b0433c121b92f2a35c2106bbf45bbb9 files/hppa/03_hppa_gdb-5.3.patch 2678 +MD5 ca7cf8e4b2eba16df1842e0a453e2b32 files/hppa/01_hppa_gdb-5.3.patch 182179 diff --git a/sys-devel/gdb/files/gdb-5.3-hppa-01.patch b/sys-devel/gdb/files/gdb-5.3-hppa-01.patch deleted file mode 100644 index 7c3f79929152..000000000000 --- a/sys-devel/gdb/files/gdb-5.3-hppa-01.patch +++ /dev/null @@ -1,5579 +0,0 @@ -Currently Debian local - Add HPPA/Linux support. Should be submitted -upstream "eventually" by "someone". - -[Note that it contains some changes since what the PA folks last sent me, in -order to continue applying to current CVS] - -diff -Npur gdb-5.2.cvs20020818.orig/gdb/config/pa/nm-linux.h gdb-5.2.cvs20020818/gdb/config/pa/nm-linux.h ---- gdb-5.2.cvs20020818.orig/gdb/config/pa/nm-linux.h 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/config/pa/nm-linux.h 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,66 @@ -+/* Native support for GNU/Linux, for GDB, the GNU debugger. -+ Copyright (C) 2000, 2001 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 PA_NM_LINUX_H -+#define PA_NM_LINUX_H -+ -+#include "nm-linux.h" -+ -+#define CANNOT_FETCH_REGISTER(regno) pa_cannot_fetch_register(regno) -+extern int pa_cannot_fetch_register (int regno); -+ -+#define CANNOT_STORE_REGISTER(regno) pa_cannot_store_register(regno) -+extern int pa_cannot_store_register (int regno); -+ -+#ifdef GDBSERVER -+#define REGISTER_U_ADDR(addr, blockend, regno) \ -+ (addr) = pa_register_u_addr ((blockend),(regno)); -+ -+extern int pa_register_u_addr(int, int); -+#endif /* GDBSERVER */ -+ -+#define U_REGS_OFFSET 0 -+ -+#define PTRACE_ARG3_TYPE long -+#define PTRACE_XFER_TYPE long -+ -+/* Hardware watchpoints */ -+ -+#define TARGET_HAS_HARDWARE_WATCHPOINTS -+ -+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \ -+ (type == bp_hardware_watchpoint) -+ -+#define HAVE_STEPPABLE_WATCHPOINT 1 -+ -+#define STOPPED_BY_WATCHPOINT(W) \ -+ pa_linux_stopped_by_watchpoint (PIDGET(inferior_ptid)) -+extern CORE_ADDR pa_linux_stopped_by_watchpoint (int); -+ -+#define target_insert_watchpoint(addr, len, type) \ -+ pa_linux_insert_watchpoint (PIDGET(inferior_ptid), addr, len, type) -+extern int pa_linux_insert_watchpoint (int pid, CORE_ADDR addr, -+ int len, int rw); -+ -+#define target_remove_watchpoint(addr, len, type) \ -+ pa_linux_remove_watchpoint (PIDGET(inferior_ptid), addr, len) -+extern int pa_linux_remove_watchpoint (int pid, CORE_ADDR addr, int len); -+ -+#endif -diff -Npur gdb-5.2.cvs20020818.orig/gdb/config/pa/pa-hpux.mh gdb-5.2.cvs20020818/gdb/config/pa/pa-hpux.mh ---- gdb-5.2.cvs20020818.orig/gdb/config/pa/pa-hpux.mh 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/config/pa/pa-hpux.mh 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,9 @@ -+# Host: Hewlett-Packard PA-RISC machine, running HPUX -+ -+XM_FILE= xm-hppah.h -+XDEPFILES= -+ -+NAT_FILE= nm-hppah.h -+NATDEPFILES= hppah-nat.o corelow.o core-aout.o inftarg.o fork-child.o somread.o infptrace.o hp-psymtab-read.o hp-symtab-read.o somsolib.o -+ -+HOST_IPC=-DBSD_IPC -DPOSIX_WAIT -diff -Npur gdb-5.2.cvs20020818.orig/gdb/config/pa/pa-hpux.mt gdb-5.2.cvs20020818/gdb/config/pa/pa-hpux.mt ---- gdb-5.2.cvs20020818.orig/gdb/config/pa/pa-hpux.mt 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/config/pa/pa-hpux.mt 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,3 @@ -+# Target: HP PA-RISC running hpux -+TDEPFILES= pa-tdep.o pa-hpux-tdep.o -+TM_FILE= tm-hpux.h -diff -Npur gdb-5.2.cvs20020818.orig/gdb/config/pa/pa-linux.mh gdb-5.2.cvs20020818/gdb/config/pa/pa-linux.mh ---- gdb-5.2.cvs20020818.orig/gdb/config/pa/pa-linux.mh 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/config/pa/pa-linux.mh 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,10 @@ -+# Host: Hewlett-Packard PA-RISC machine, running Linux -+XDEPFILES= -+XM_FILE= xm-linux.h -+NAT_FILE= nm-linux.h -+NATDEPFILES= pa-linux-nat.o corelow.o core-aout.o core-regset.o linux-proc.o \ -+ fork-child.o infptrace.o inftarg.o lin-lwp.o proc-service.o thread-db.o gcore.o -+ -+GDBSERVER_DEPFILES= low-hppalinux.o -+ -+XM_CLIBS= -ldl -diff -Npur gdb-5.2.cvs20020818.orig/gdb/config/pa/pa-linux.mt gdb-5.2.cvs20020818/gdb/config/pa/pa-linux.mt ---- gdb-5.2.cvs20020818.orig/gdb/config/pa/pa-linux.mt 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/config/pa/pa-linux.mt 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,5 @@ -+# Target: HP PA-RISC running linux -+TDEPFILES= pa-tdep.o pa-linux-tdep.o solib.o solib-svr4.o solib-legacy.o -+TM_FILE= tm-linux.h -+ -+GDBSERVER_DEPFILES= low-linux.o -diff -Npur gdb-5.2.cvs20020818.orig/gdb/config/pa/tm-hpux.h gdb-5.2.cvs20020818/gdb/config/pa/tm-hpux.h ---- gdb-5.2.cvs20020818.orig/gdb/config/pa/tm-hpux.h 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/config/pa/tm-hpux.h 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,41 @@ -+/* Definitions to target GDB to HPUX on HPPA. -+ Copyright 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001 -+ 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 PA_TM_HPUX_H -+#define PA_TM_HPUX_H -+ -+#include "pa/tm-pa.h" -+#include "pa/tm-pa32.h" -+#include "somsolib.h" -+ -+/* For HP-UX on PA-RISC we have an implementation -+ for the exception handling target op. */ -+#define CHILD_ENABLE_EXCEPTION_CALLBACK -+#define CHILD_GET_CURRENT_EXCEPTION_EVENT -+ -+#ifndef TYPE_PROCEDURE -+#define TYPE_PROCEDURE 3 -+#endif -+ -+struct gdbarch; -+void pa_hpux_initialize_tdep (struct gdbarch *, int); -+ -+#endif -diff -Npur gdb-5.2.cvs20020818.orig/gdb/config/pa/tm-hpux64.h gdb-5.2.cvs20020818/gdb/config/pa/tm-hpux64.h ---- gdb-5.2.cvs20020818.orig/gdb/config/pa/tm-hpux64.h 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/config/pa/tm-hpux64.h 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,40 @@ -+/* Definitions to target GDB to HPUX on HPPA. -+ Copyright 1999, 2000, 2001 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 PA_TM_HPUX64_H -+#define PA_TM_HPUX64_H -+ -+#include "pa/tm-pa.h" -+#include "pa/tm-pa64.h" -+#include "pa64solib.h" -+ -+/* For HP-UX on PA-RISC we have an implementation -+ for the exception handling target op. */ -+#define CHILD_ENABLE_EXCEPTION_CALLBACK -+#define CHILD_GET_CURRENT_EXCEPTION_EVENT -+ -+#ifndef TYPE_PROCEDURE -+#define TYPE_PROCEDURE 3 -+#endif -+ -+struct gdbarch; -+void pa_hpux_initialize_tdep (struct gdbarch *, int); -+ -+#endif -diff -Npur gdb-5.2.cvs20020818.orig/gdb/config/pa/tm-linux.h gdb-5.2.cvs20020818/gdb/config/pa/tm-linux.h ---- gdb-5.2.cvs20020818.orig/gdb/config/pa/tm-linux.h 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/config/pa/tm-linux.h 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,33 @@ -+/* Definitions to target GDB to GNU/Linux on HPPA Linux. -+ Copyright 2000, 2001 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 PA_TM_LINUX_H -+#define PA_TM_LINUX_H -+ -+#include "tm-linux.h" -+#include "pa/tm-pa.h" -+#include "pa/tm-pa32.h" -+ -+#define PA_LINUX_TARGET -+ -+struct gdbarch; -+void pa_linux_initialize_tdep (struct gdbarch *, int); -+ -+#endif -diff -Npur gdb-5.2.cvs20020818.orig/gdb/config/pa/tm-pa.h gdb-5.2.cvs20020818/gdb/config/pa/tm-pa.h ---- gdb-5.2.cvs20020818.orig/gdb/config/pa/tm-pa.h 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/config/pa/tm-pa.h 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,466 @@ -+/* Definitions to target GDB to any Hewlett-Packard PA-RISC machine. -+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, -+ 1998, 1999, 2000, 2001 Free Software Foundation, Inc. -+ -+ Contributed by the Center for Software Science at the -+ University of Utah (pa-gdb-bugs@cs.utah.edu). -+ -+ 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 PA_TM_PA_H -+#define PA_TM_PA_H -+ -+ -+#if !defined(GDBSERVER) -+ -+#define GDB_MULTI_ARCH 1 -+ -+#else /* Defines needed for GDBSERVER. */ -+ -+/* Target system byte order. */ -+ -+#define TARGET_BYTE_ORDER BIG_ENDIAN -+ -+/* Some pseudo register numbers. */ -+ -+#define PC_REGNUM PA_PCOQ_HEAD_REGNUM -+#define NPC_REGNUM PA_PCOQ_TAIL_REGNUM -+#define SP_REGNUM PA_GR31_REGNUM -+#define FP_REGNUM PA_GR3_REGNUM -+ -+#endif -+ -+/* Number of machine registers. Well, sort of. It really just -+ specifies the range of register numbers known to gdb. */ -+ -+#define NUM_REGS 128 -+ -+/* Register numbers of various registers, */ -+ -+/* General registers. */ -+#define PA_GR0_REGNUM 0 -+#define PA_GR1_REGNUM (PA_GR0_REGNUM+1) -+#define PA_GR2_REGNUM (PA_GR0_REGNUM+2) -+#define PA_GR3_REGNUM (PA_GR0_REGNUM+3) -+#define PA_GR4_REGNUM (PA_GR0_REGNUM+4) -+#define PA_GR5_REGNUM (PA_GR0_REGNUM+5) -+#define PA_GR6_REGNUM (PA_GR0_REGNUM+6) -+#define PA_GR7_REGNUM (PA_GR0_REGNUM+7) -+#define PA_GR8_REGNUM (PA_GR0_REGNUM+8) -+#define PA_GR9_REGNUM (PA_GR0_REGNUM+9) -+#define PA_GR10_REGNUM (PA_GR0_REGNUM+10) -+#define PA_GR11_REGNUM (PA_GR0_REGNUM+11) -+#define PA_GR12_REGNUM (PA_GR0_REGNUM+12) -+#define PA_GR13_REGNUM (PA_GR0_REGNUM+13) -+#define PA_GR14_REGNUM (PA_GR0_REGNUM+14) -+#define PA_GR15_REGNUM (PA_GR0_REGNUM+15) -+#define PA_GR16_REGNUM (PA_GR0_REGNUM+16) -+#define PA_GR17_REGNUM (PA_GR0_REGNUM+17) -+#define PA_GR18_REGNUM (PA_GR0_REGNUM+18) -+#define PA_GR19_REGNUM (PA_GR0_REGNUM+19) -+#define PA_GR20_REGNUM (PA_GR0_REGNUM+20) -+#define PA_GR21_REGNUM (PA_GR0_REGNUM+21) -+#define PA_GR22_REGNUM (PA_GR0_REGNUM+22) -+#define PA_GR23_REGNUM (PA_GR0_REGNUM+23) -+#define PA_GR24_REGNUM (PA_GR0_REGNUM+24) -+#define PA_GR25_REGNUM (PA_GR0_REGNUM+25) -+#define PA_GR26_REGNUM (PA_GR0_REGNUM+26) -+#define PA_GR27_REGNUM (PA_GR0_REGNUM+27) -+#define PA_GR28_REGNUM (PA_GR0_REGNUM+28) -+#define PA_GR29_REGNUM (PA_GR0_REGNUM+29) -+#define PA_GR30_REGNUM (PA_GR0_REGNUM+30) -+#define PA_GR31_REGNUM (PA_GR0_REGNUM+31) -+ -+/* Control registers. The peculiar layout is to match HPUX interrupt save -+ state. */ -+#define PA_CR11_REGNUM 32 -+#define PA_PCOQ_HEAD_REGNUM 33 /* CR18 */ -+#define PA_PCSQ_HEAD_REGNUM 34 /* CR17 */ -+#define PA_PCOQ_TAIL_REGNUM 35 /* CR18 */ -+#define PA_PCSQ_TAIL_REGNUM 36 /* CR17 */ -+#define PA_CR15_REGNUM 37 -+#define PA_CR19_REGNUM 38 -+#define PA_CR20_REGNUM 39 -+#define PA_CR21_REGNUM 40 -+#define PA_CR22_REGNUM 41 -+#define PA_CR31_REGNUM 42 -+ -+/* Space registers. */ -+#define PA_SR4_REGNUM 43 -+#define PA_SR0_REGNUM 44 -+#define PA_SR1_REGNUM 45 -+#define PA_SR2_REGNUM 46 -+#define PA_SR3_REGNUM 47 -+#define PA_SR5_REGNUM 48 -+#define PA_SR6_REGNUM 49 -+#define PA_SR7_REGNUM 50 -+ -+/* More control regs. */ -+#define PA_CR0_REGNUM 51 -+#define PA_CR8_REGNUM 52 -+#define PA_CR9_REGNUM 53 -+#define PA_CR10_REGNUM 54 -+#define PA_CR12_REGNUM 55 -+#define PA_CR13_REGNUM 56 -+#define PA_CR24_REGNUM 57 -+#define PA_CR25_REGNUM 58 -+#define PA_CR26_REGNUM 59 -+#define PA_CR27_REGNUM 60 -+#define PA_CR28_REGNUM 61 -+#define PA_CR29_REGNUM 62 -+#define PA_CR30_REGNUM 63 -+ -+/* Floating point registers. */ -+#define PA_FR0_REGNUM 64 -+#define PA_FR1_REGNUM (PA_FR0_REGNUM+2) -+#define PA_FR2_REGNUM (PA_FR0_REGNUM+4) -+#define PA_FR3_REGNUM (PA_FR0_REGNUM+6) -+#define PA_FR4_REGNUM (PA_FR0_REGNUM+8) -+#define PA_FR5_REGNUM (PA_FR0_REGNUM+10) -+#define PA_FR6_REGNUM (PA_FR0_REGNUM+12) -+#define PA_FR7_REGNUM (PA_FR0_REGNUM+14) -+#define PA_FR31_REGNUM (PA_FR0_REGNUM+62) -+ -+/* Some aliases. */ -+#define PA_FLAGS_REGNUM PA_GR0_REGNUM -+#define PA_SAR_REGNUM PA_CR11_REGNUM -+#define PA_IPSW_REGNUM PA_CR22_REGNUM -+ -+/* -+ * Processor Status Word Masks -+ */ -+ -+#define PSW_T 0x01000000 /* Taken Branch Trap Enable */ -+#define PSW_H 0x00800000 /* Higher-Privilege Transfer Trap Enable */ -+#define PSW_L 0x00400000 /* Lower-Privilege Transfer Trap Enable */ -+#define PSW_N 0x00200000 /* PC Queue Front Instruction Nullified */ -+#define PSW_X 0x00100000 /* Data Memory Break Disable */ -+#define PSW_B 0x00080000 /* Taken Branch in Previous Cycle */ -+#define PSW_C 0x00040000 /* Code Address Translation Enable */ -+#define PSW_V 0x00020000 /* Divide Step Correction */ -+#define PSW_M 0x00010000 /* High-Priority Machine Check Disable */ -+#define PSW_CB 0x0000ff00 /* Carry/Borrow Bits */ -+#define PSW_R 0x00000010 /* Recovery Counter Enable */ -+#define PSW_Q 0x00000008 /* Interruption State Collection Enable */ -+#define PSW_P 0x00000004 /* Protection ID Validation Enable */ -+#define PSW_D 0x00000002 /* Data Address Translation Enable */ -+#define PSW_I 0x00000001 /* External, Power Failure, Low-Priority */ -+ /* Machine Check Interruption Enable */ -+ -+/* By default assume we don't have to worry about software floating point. */ -+#ifndef SOFT_FLOAT -+#define SOFT_FLOAT 0 -+#endif -+ -+struct gdbarch_tdep -+ { -+ int os_ident; /* From the ELF header, one of the ELFOSABI_ -+ constants: ELFOSABI_LINUX, ELFOSABI_HPUX, -+ etc. */ -+ unsigned int is_elf:1; -+ unsigned int is_elf64:1; -+ int (*in_syscall) (const CORE_ADDR *); -+ int (*in_interrupt_handler) (CORE_ADDR); -+ int (*in_sigtramp) (CORE_ADDR, const char *); -+ CORE_ADDR (*frame_saved_pc_in_interrupt) (const struct frame_info *); -+ CORE_ADDR (*frame_base_before_interrupt) (const struct frame_info *); -+ void (*frame_find_saved_regs_in_interrupt) (struct frame_info *, -+ CORE_ADDR *); -+ CORE_ADDR (*frame_saved_pc_in_sigtramp) (const struct frame_info *); -+ CORE_ADDR (*frame_base_before_sigtramp) (struct frame_info *); -+ void (*frame_find_saved_regs_in_sigtramp) (struct frame_info *, -+ CORE_ADDR *); -+ }; -+ -+#define PA_IN_SYSCALL(flags) \ -+ (gdbarch_tdep (current_gdbarch)->in_syscall (flags)) -+#define PA_IN_INTERRUPT_HANDLER(pc) \ -+ (gdbarch_tdep (current_gdbarch)->in_interrupt_handler (pc)) -+#define IN_SIGTRAMP(pc, func_name) \ -+ (gdbarch_tdep (current_gdbarch)->in_sigtramp (pc, func_name)) -+ -+ -+/* -+ * Unwind table and descriptor. -+ */ -+ -+struct unwind_table_entry -+ { -+ CORE_ADDR region_start; -+ CORE_ADDR region_end; -+ -+ unsigned int Cannot_unwind:1; /* 0 */ -+ unsigned int Millicode:1; /* 1 */ -+ unsigned int Millicode_save_sr0:1; /* 2 */ -+ unsigned int Region_description:2; /* 3..4 */ -+ unsigned int reserved1:1; /* 5 */ -+ unsigned int Entry_SR:1; /* 6 */ -+ unsigned int Entry_FR:4; /* number saved *//* 7..10 */ -+ unsigned int Entry_GR:5; /* number saved *//* 11..15 */ -+ unsigned int Args_stored:1; /* 16 */ -+ unsigned int Variable_Frame:1; /* 17 */ -+ unsigned int Separate_Package_Body:1; /* 18 */ -+ unsigned int Frame_Extension_Millicode:1; /* 19 */ -+ unsigned int Stack_Overflow_Check:1; /* 20 */ -+ unsigned int Two_Instruction_SP_Increment:1; /* 21 */ -+ unsigned int Ada_Region:1; /* 22 */ -+ unsigned int cxx_info:1; /* 23 */ -+ unsigned int cxx_try_catch:1; /* 24 */ -+ unsigned int sched_entry_seq:1; /* 25 */ -+ unsigned int reserved2:1; /* 26 */ -+ unsigned int Save_SP:1; /* 27 */ -+ unsigned int Save_RP:1; /* 28 */ -+ unsigned int Save_MRP_in_frame:1; /* 29 */ -+ unsigned int extn_ptr_defined:1; /* 30 */ -+ unsigned int Cleanup_defined:1; /* 31 */ -+ -+ unsigned int MPE_XL_interrupt_marker:1; /* 0 */ -+ unsigned int HP_UX_interrupt_marker:1; /* 1 */ -+ unsigned int Large_frame:1; /* 2 */ -+ unsigned int Pseudo_SP_Set:1; /* 3 */ -+ unsigned int reserved4:1; /* 4 */ -+ unsigned int Total_frame_size:27; /* 5..31 */ -+ -+ /* This is *NOT* part of an actual unwind_descriptor in an object -+ file. It is *ONLY* part of the "internalized" descriptors that -+ we create from those in a file. -+ */ -+ struct -+ { -+ unsigned int stub_type:4; /* 0..3 */ -+ unsigned int padding:28; /* 4..31 */ -+ } -+ stub_unwind; -+ }; -+ -+/* HP linkers also generate unwinds for various linker-generated stubs. -+ GDB reads in the stubs from the $UNWIND_END$ subspace, then -+ "converts" them into normal unwind entries using some of the reserved -+ fields to store the stub type. */ -+ -+struct stub_unwind_entry -+ { -+ /* The offset within the executable for the associated stub. */ -+ unsigned stub_offset; -+ -+ /* The type of stub this unwind entry describes. */ -+ char type; -+ -+ /* Unknown. Not needed by GDB at this time. */ -+ char prs_info; -+ -+ /* Length (in instructions) of the associated stub. */ -+ short stub_length; -+ }; -+ -+/* Sizes (in bytes) of the native unwind entries. */ -+#define UNWIND_ENTRY_SIZE 16 -+#define STUB_UNWIND_ENTRY_SIZE 8 -+ -+/* The gaps represent linker stubs used in MPE and space for future -+ expansion. */ -+enum unwind_stub_types -+ { -+ LONG_BRANCH = 1, -+ PARAMETER_RELOCATION = 2, -+ EXPORT = 10, -+ IMPORT = 11, -+ IMPORT_SHLIB = 12, -+ }; -+ -+struct unwind_table_entry *find_unwind_entry (CORE_ADDR); -+ -+/* We use the objfile->obj_private pointer for two things: -+ -+ * 1. An unwind table; -+ * -+ * 2. A pointer to any associated shared library object. -+ * -+ * #defines are used to help refer to these objects. -+ */ -+ -+/* Info about the unwind table associated with an object file. -+ -+ * This is hung off of the "objfile->obj_private" pointer, and -+ * is allocated in the objfile's psymbol obstack. This allows -+ * us to have unique unwind info for each executable and shared -+ * library that we are debugging. -+ */ -+struct obj_unwind_info -+ { -+ struct unwind_table_entry *table; /* Pointer to unwind info */ -+ struct unwind_table_entry *cache; /* Pointer to last entry we found */ -+ int last; /* Index of last entry */ -+ }; -+ -+enum dyncall_enum -+ { -+ sr4export = 0, dyncall, dyncall_external, last_dyncall_enum -+ }; -+ -+typedef struct obj_private_struct -+ { -+ struct obj_unwind_info *unwind_info; -+ struct so_list *so_info; -+ CORE_ADDR dp; -+ CORE_ADDR dyn[last_dyncall_enum]; -+ } -+obj_private_data_t; -+ -+#define OBJ_PRIVATE_ALLOC pa_obj_private_alloc -+struct objfile; -+obj_private_data_t *pa_obj_private_alloc (struct objfile *); -+ -+ -+/* Used to match stub code sequences. */ -+struct stub_struc -+ { -+ unsigned int insn; -+ unsigned int mask; -+ int offset; -+ }; -+ -+enum stub_type { -+ pa_stub_none, -+ pa_stub_long_branch, -+ pa_stub_long_branch_shared, -+ pa_stub_import, -+ pa_stub_import_shared, -+ pa_stub_import_multi, -+ pa_stub_import_multi_shared, -+ pa_stub_lazy_link, -+ pa_stub_export, -+ pa64_stub_import -+}; -+ -+enum stub_type is_pa_stub (CORE_ADDR, const struct stub_struc *, CORE_ADDR *); -+ -+/* INIT_EXTRA_FRAME_INFO needs the PC. */ -+#define INIT_FRAME_PC(FROMLEAF, PREV) /* nothing */ -+#define INIT_FRAME_PC_FIRST(FROMLEAF, PREV) \ -+ (PREV)->pc = ((FROMLEAF) ? SAVED_PC_AFTER_CALL ((PREV)->next) \ -+ : (PREV)->next ? FRAME_SAVED_PC ((PREV)->next) \ -+ : PA_IN_SYSCALL (NULL) ? read_register (PA_GR31_REGNUM) & ~3 \ -+ : read_pc ()) -+ -+struct frame_extra_info -+ { -+ CORE_ADDR sp_adjust_insn; -+ CORE_ADDR fp_adjust_insn; -+ CORE_ADDR rp_save_insn; -+ }; -+ -+ -+/* If PC is in some function-call trampoline code, return the PC -+ where the function itself actually starts. If not, return NULL. */ -+ -+#undef SKIP_TRAMPOLINE_CODE -+#define SKIP_TRAMPOLINE_CODE(pc) pa_skip_trampoline_code (pc, NULL) -+extern CORE_ADDR pa_skip_trampoline_code (CORE_ADDR, char *); -+ -+/* Return non-zero if we are in an appropriate trampoline. */ -+#undef IN_SOLIB_CALL_TRAMPOLINE -+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \ -+ pa_in_solib_call_trampoline (pc, name) -+extern int pa_in_solib_call_trampoline (CORE_ADDR, char *); -+ -+#define IN_SOLIB_RETURN_TRAMPOLINE(pc, name) \ -+ pa_in_solib_return_trampoline (pc, name) -+extern int pa_in_solib_return_trampoline (CORE_ADDR, char *); -+ -+/* elz: Return a large value, which is stored on the stack at addr. -+ This is defined only for the hppa, at this moment. -+ EXTRACT_STRUCT_VALUE_ADDRESS is not called anymore, because it assumes -+ that on exit from a called function which returns a large structure on -+ the stack, the address of the ret structure is still in register 28. -+ Unfortunately this register is usually overwritten by the called -+ function itself, on hppa. This is specified in the calling convention -+ doc. As far as I know, the only way to get the return value is to have -+ the caller tell us where it told the callee to put it, rather than have -+ the callee tell us. */ -+#define VALUE_RETURNED_FROM_STACK(valtype,addr) \ -+ pa_value_returned_from_stack (valtype, addr) -+extern struct value *pa_value_returned_from_stack (struct type *, CORE_ADDR); -+ -+/* Sometimes we may pluck out a minimal symbol that has a negative -+ address. -+ -+ An example of this occurs when an a.out is linked against a foo.sl. -+ The foo.sl defines a global bar(), and the a.out declares a signature -+ for bar(). However, the a.out doesn't directly call bar(), but passes -+ its address in another call. -+ -+ If you have this scenario and attempt to "break bar" before running, -+ gdb will find a minimal symbol for bar() in the a.out. But that -+ symbol's address will be negative. What this appears to denote is -+ an index backwards from the base of the procedure linkage table (PLT) -+ into the data linkage table (DLT), the end of which is contiguous -+ with the start of the PLT. This is clearly not a valid address for -+ us to set a breakpoint on. -+ -+ Note that one must be careful in how one checks for a negative address. -+ 0xc0000000 is a legitimate address of something in a shared text -+ segment, for example. Since I don't know what the possible range -+ is of these "really, truly negative" addresses that come from the -+ minimal symbols, I'm resorting to the gross hack of checking the -+ top byte of the address for all 1's. Sigh. -+ */ -+#define PC_REQUIRES_RUN_BEFORE_USE(pc) \ -+ (! target_has_stack && (pc & 0xFF000000)) -+ -+/* When fetching register values from an inferior or a core file, -+ clean them up using this macro. BUF is a char pointer to -+ the raw value of the register in the registers[] array. */ -+ -+#define CLEAN_UP_REGISTER_VALUE(regno, buf) \ -+ do { \ -+ if ((regno) == PA_PCOQ_HEAD_REGNUM || (regno) == PA_PCOQ_TAIL_REGNUM) \ -+ (buf)[sizeof(CORE_ADDR) -1] &= ~0x3; \ -+ } while (0) -+ -+/* PA specific macro to see if the current instruction is nullified. */ -+#ifndef INSTRUCTION_NULLIFIED -+#define INSTRUCTION_NULLIFIED \ -+ (((int) read_register (PA_IPSW_REGNUM) & PSW_N) && ! PA_IN_SYSCALL (NULL)) -+#endif -+ -+/* The low two bits of the PC on the PA contain the privilege level. Some -+ genius implementing a (non-GCC) compiler apparently decided this means -+ that "addresses" in a text section therefore include a privilege level, -+ and thus symbol tables should contain these bits. This seems like a -+ bonehead thing to do--anyway, it seems to work for our purposes to just -+ ignore those bits. */ -+#define SMASH_TEXT_ADDRESS(addr) ((addr) &= ~0x3) -+ -+/* For a number of horrible reasons we may have to adjust the location -+ of variables on the stack. Ugh. */ -+#define HPREAD_ADJUST_STACK_ADDRESS(ADDR) hpread_adjust_stack_address(ADDR) -+ -+extern int hpread_adjust_stack_address (CORE_ADDR); -+ -+/* Here's how to step off a permanent breakpoint. */ -+#define SKIP_PERMANENT_BREAKPOINT pa_skip_permanent_breakpoint -+extern void pa_skip_permanent_breakpoint (void); -+ -+/* On HP-UX, certain system routines (millicode) have names beginning -+ with $ or $$, e.g. $$dyncall, which handles inter-space procedure -+ calls on PA-RISC. Tell the expression parser to check for those -+ when parsing tokens that begin with "$". */ -+#define SYMBOLS_CAN_START_WITH_DOLLAR 1 -+ -+#endif -diff -Npur gdb-5.2.cvs20020818.orig/gdb/config/pa/tm-pa32.h gdb-5.2.cvs20020818/gdb/config/pa/tm-pa32.h ---- gdb-5.2.cvs20020818.orig/gdb/config/pa/tm-pa32.h 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/config/pa/tm-pa32.h 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,49 @@ -+/* Definitions specific to 32 bit Hewlett-Packard PA-RISC machines. -+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, -+ 1998, 1999, 2000, 2001 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(GDBSERVER) -+ -+/* Say how long (ordinary) registers are. This is a piece of bogosity -+ used in push_word and a few other places; REGISTER_RAW_SIZE is the -+ real way to know how big a register is. */ -+ -+#define REGISTER_SIZE 4 -+ -+/* Total amount of space needed to store our copies of the machine's -+ register state, the array `registers'. */ -+#define REGISTER_BYTES (NUM_REGS * 4) -+ -+/* Number of bytes of storage in the actual machine representation -+ for register N. On the PA-RISC, all regs are 4 bytes, including -+ the FP registers (they're accessed as two 4 byte halves). */ -+ -+#define REGISTER_RAW_SIZE(N) 4 -+ -+/* Index within `registers' of the first byte of the space for -+ register N. */ -+ -+#define REGISTER_BYTE(N) (N) * 4 -+ -+/* Largest value REGISTER_RAW_SIZE can have. */ -+ -+#define MAX_REGISTER_RAW_SIZE 4 -+ -+#endif -diff -Npur gdb-5.2.cvs20020818.orig/gdb/config/pa/tm-pa64.h gdb-5.2.cvs20020818/gdb/config/pa/tm-pa64.h ---- gdb-5.2.cvs20020818.orig/gdb/config/pa/tm-pa64.h 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/config/pa/tm-pa64.h 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,52 @@ -+/* Definitions specific to 32 bit Hewlett-Packard PA-RISC machines. -+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, -+ 1998, 1999, 2000, 2001 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(GDBSERVER) -+ -+/* Say how long (ordinary) registers are. This is a piece of bogosity -+ used in push_word and a few other places; REGISTER_RAW_SIZE is the -+ real way to know how big a register is. */ -+ -+#define REGISTER_SIZE 8 -+ -+/* Total amount of space needed to store our copies of the machine's -+ register state, the array `registers'. */ -+#define REGISTER_BYTES (PA_FR0_REGNUM * 8 + (NUM_REGS - PA_FR0_REGNUM) * 4) -+ -+/* Number of bytes of storage in the actual machine representation -+ for register N. On a 64 bit PA-RISC, all regs are 8 bytes, including -+ the FP registers (but the FP regs are stored as two 4 byte halves). */ -+ -+#define REGISTER_RAW_SIZE(N) ((N) < PA_FR0_REGNUM ? 8 : 4) -+ -+/* Index within `registers' of the first byte of the space for -+ register N. */ -+ -+#define REGISTER_BYTE(N) \ -+ ((N) < PA_FR0_REGNUM \ -+ ? (N) * 8 \ -+ : ((N) - PA_FR0_REGNUM) * 4 + PA_FR0_REGNUM * 8) -+ -+/* Largest value REGISTER_RAW_SIZE can have. */ -+ -+#define MAX_REGISTER_RAW_SIZE 8 -+ -+#endif -diff -Npur gdb-5.2.cvs20020818.orig/gdb/config/pa/xm-linux.h gdb-5.2.cvs20020818/gdb/config/pa/xm-linux.h ---- gdb-5.2.cvs20020818.orig/gdb/config/pa/xm-linux.h 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/config/pa/xm-linux.h 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,37 @@ -+/* Native support for GNU/Linux, for GDB, the GNU debugger. -+ Copyright (C) 2000, 2001 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 PA_XM_LINUX_H -+#define PA_XM_LINUX_H -+ -+#define HOST_BYTE_ORDER BIG_ENDIAN -+ -+#define HAVE_TERMIOS -+ -+/* This is the amount to subtract from u.u_ar0 -+ to get the offset in the core file of the register values. */ -+#define KERNEL_U_ADDR 0x0 -+ -+#define NEED_POSIX_SETPGID -+ -+/* Need R_OK etc, but USG isn't defined. */ -+#include <unistd.h> -+ -+#endif -diff -Npur gdb-5.2.cvs20020818.orig/gdb/configure.host gdb-5.2.cvs20020818/gdb/configure.host ---- gdb-5.2.cvs20020818.orig/gdb/configure.host 2002-08-19 10:37:29.000000000 -0400 -+++ gdb-5.2.cvs20020818/gdb/configure.host 2002-08-19 10:39:17.000000000 -0400 -@@ -49,6 +49,8 @@ hppa*64*-*-hpux11*) gdb_host=hpux11w ;; - hppa*-*-hpux11*) gdb_host=hpux11 ;; - hppa*-*-hpux*) gdb_host=hppahpux ;; - hppa*-*-osf*) gdb_host=hppaosf ;; -+hppa*64*-*-linux* | parisc*64*-*-linux*) gdb_host=pa64-linux ;; -+hppa*-*-linux* | parisc*-*-linux*) gdb_host=pa-linux ;; - - i[3456]86-ncr-*) gdb_host=ncr3000 ;; - i[3456]86-sequent-bsd*) gdb_host=symmetry ;; # dynix -diff -Npur gdb-5.2.cvs20020818.orig/gdb/configure.tgt gdb-5.2.cvs20020818/gdb/configure.tgt ---- gdb-5.2.cvs20020818.orig/gdb/configure.tgt 2002-08-19 10:37:29.000000000 -0400 -+++ gdb-5.2.cvs20020818/gdb/configure.tgt 2002-08-19 10:39:17.000000000 -0400 -@@ -83,6 +83,8 @@ hppa*64*-*-hpux11*) gdb_target=hppa64 ;; - hppa*-*-hpux*) gdb_target=hppahpux ;; - hppa*-*-hiux*) gdb_target=hppahpux ;; - hppa*-*-osf*) gdb_target=hppaosf ;; -+hppa*64*-*-linux* | parisc*64*-*-linux*) gdb_target=pa64-linux ;; -+hppa*-*-linux* | parisc*-*-linux*) gdb_target=pa-linux ;; - hppa*-*-*) gdb_target=hppa ;; - - i[3456]86-sequent-bsd*) gdb_target=symmetry ;; -diff -Npur gdb-5.2.cvs20020818.orig/gdb/pa-linux-nat.c gdb-5.2.cvs20020818/gdb/pa-linux-nat.c ---- gdb-5.2.cvs20020818.orig/gdb/pa-linux-nat.c 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/pa-linux-nat.c 2002-08-19 10:39:17.000000000 -0400 -@@ -0,0 +1,354 @@ -+/* Functions specific to running gdb native on HPPA running Linux. -+ Copyright 2000, 2001 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 "inferior.h" -+#include "target.h" -+#include "gdbcore.h" -+#include "regcache.h" -+ -+#include <signal.h> -+#include <sys/ptrace.h> -+#include <sys/wait.h> -+#ifdef HAVE_SYS_REG_H -+#include <sys/reg.h> -+#endif -+#include <sys/user.h> -+ -+#include <asm/offset.h> -+#include <sys/procfs.h> -+ -+/* Prototypes for supply_gregset etc. */ -+#include "gregset.h" -+ -+/* These must match the order of the register names. -+ -+ Some sort of lookup table is needed because the offsets associated -+ with the registers are all over the board. */ -+ -+static const int u_offsets[NUM_REGS] = -+ { -+ /* general registers */ -+ -1, -+ PT_GR1, -+ PT_GR2, -+ PT_GR3, -+ PT_GR4, -+ PT_GR5, -+ PT_GR6, -+ PT_GR7, -+ PT_GR8, -+ PT_GR9, -+ PT_GR10, -+ PT_GR11, -+ PT_GR12, -+ PT_GR13, -+ PT_GR14, -+ PT_GR15, -+ PT_GR16, -+ PT_GR17, -+ PT_GR18, -+ PT_GR19, -+ PT_GR20, -+ PT_GR21, -+ PT_GR22, -+ PT_GR23, -+ PT_GR24, -+ PT_GR25, -+ PT_GR26, -+ PT_GR27, -+ PT_GR28, -+ PT_GR29, -+ PT_GR30, -+ PT_GR31, -+ -+ PT_SAR, -+ PT_IAOQ0, -+ PT_IASQ0, -+ PT_IAOQ1, -+ PT_IASQ1, -+ -1, /* eiem */ -+ PT_IIR, -+ PT_ISR, -+ PT_IOR, -+ PT_PSW, -+ -1, /* goto */ -+ -+ PT_SR4, -+ PT_SR0, -+ PT_SR1, -+ PT_SR2, -+ PT_SR3, -+ PT_SR5, -+ PT_SR6, -+ PT_SR7, -+ -+ -1, /* cr0 */ -+ -1, /* pid0 */ -+ -1, /* pid1 */ -+ -1, /* ccr */ -+ -1, /* pid2 */ -+ -1, /* pid3 */ -+ -1, /* cr24 */ -+ -1, /* cr25 */ -+ -1, /* cr26 */ -+ PT_CR27, -+ -1, /* cr28 */ -+ -1, /* cr29 */ -+ -1, /* cr30 */ -+ -+ /* Floating point regs. */ -+ PT_FR0, PT_FR0 + 4, -+ PT_FR1, PT_FR1 + 4, -+ PT_FR2, PT_FR2 + 4, -+ PT_FR3, PT_FR3 + 4, -+ PT_FR4, PT_FR4 + 4, -+ PT_FR5, PT_FR5 + 4, -+ PT_FR6, PT_FR6 + 4, -+ PT_FR7, PT_FR7 + 4, -+ PT_FR8, PT_FR8 + 4, -+ PT_FR9, PT_FR9 + 4, -+ PT_FR10, PT_FR10 + 4, -+ PT_FR11, PT_FR11 + 4, -+ PT_FR12, PT_FR12 + 4, -+ PT_FR13, PT_FR13 + 4, -+ PT_FR14, PT_FR14 + 4, -+ PT_FR15, PT_FR15 + 4, -+ PT_FR16, PT_FR16 + 4, -+ PT_FR17, PT_FR17 + 4, -+ PT_FR18, PT_FR18 + 4, -+ PT_FR19, PT_FR19 + 4, -+ PT_FR20, PT_FR20 + 4, -+ PT_FR21, PT_FR21 + 4, -+ PT_FR22, PT_FR22 + 4, -+ PT_FR23, PT_FR23 + 4, -+ PT_FR24, PT_FR24 + 4, -+ PT_FR25, PT_FR25 + 4, -+ PT_FR26, PT_FR26 + 4, -+ PT_FR27, PT_FR27 + 4, -+ PT_FR28, PT_FR28 + 4, -+ PT_FR29, PT_FR29 + 4, -+ PT_FR30, PT_FR30 + 4, -+ PT_FR31, PT_FR31 + 4, -+ }; -+ -+CORE_ADDR -+register_addr (int regno, CORE_ADDR blockend) -+{ -+ CORE_ADDR addr; -+ -+ if ((unsigned) regno >= NUM_REGS) -+ error ("Invalid register number %d.", regno); -+ -+ if (u_offsets[regno] == -1) -+ addr = 0; -+ else -+ { -+ addr = (CORE_ADDR) u_offsets[regno]; -+ /* If this is a 64 bit kernel, but we are debugging a 32 bit -+ task, then we want to pick up the low word of the register. */ -+ if (PT_GR2 - PT_GR1 == 8 && regno < PA_FR0_REGNUM) -+ addr += (PT_GR2 - PT_GR1) - REGISTER_RAW_SIZE (regno); -+ } -+ -+ return addr; -+} -+ -+int pa_cannot_fetch_register (regno) -+ int regno; -+{ -+ return (unsigned int) regno >= NUM_REGS || u_offsets[regno] == -1; -+} -+ -+int pa_cannot_store_register (regno) -+ int regno; -+{ -+ return ((unsigned int) regno >= NUM_REGS -+ || regno == PA_GR0_REGNUM -+ || regno == PA_PCSQ_HEAD_REGNUM -+ || (regno >= PA_PCSQ_TAIL_REGNUM && regno < PA_IPSW_REGNUM) -+ || (regno > PA_IPSW_REGNUM && regno < PA_FR4_REGNUM)); -+} -+ -+static const int greg_map[] = -+ { -+ PA_GR0_REGNUM, -+ PA_GR1_REGNUM, -+ PA_GR2_REGNUM, -+ PA_GR3_REGNUM, -+ PA_GR4_REGNUM, -+ PA_GR5_REGNUM, -+ PA_GR6_REGNUM, -+ PA_GR7_REGNUM, -+ PA_GR8_REGNUM, -+ PA_GR9_REGNUM, -+ PA_GR10_REGNUM, -+ PA_GR11_REGNUM, -+ PA_GR12_REGNUM, -+ PA_GR13_REGNUM, -+ PA_GR14_REGNUM, -+ PA_GR15_REGNUM, -+ PA_GR16_REGNUM, -+ PA_GR17_REGNUM, -+ PA_GR18_REGNUM, -+ PA_GR19_REGNUM, -+ PA_GR20_REGNUM, -+ PA_GR21_REGNUM, -+ PA_GR22_REGNUM, -+ PA_GR23_REGNUM, -+ PA_GR24_REGNUM, -+ PA_GR25_REGNUM, -+ PA_GR26_REGNUM, -+ PA_GR27_REGNUM, -+ PA_GR28_REGNUM, -+ PA_GR29_REGNUM, -+ PA_GR30_REGNUM, -+ PA_GR31_REGNUM, -+ PA_SR0_REGNUM, -+ PA_SR1_REGNUM, -+ PA_SR2_REGNUM, -+ PA_SR3_REGNUM, -+ PA_SR4_REGNUM, -+ PA_SR5_REGNUM, -+ PA_SR6_REGNUM, -+ PA_SR7_REGNUM, -+ PA_PCOQ_HEAD_REGNUM, -+ PA_PCOQ_TAIL_REGNUM, -+ PA_PCSQ_HEAD_REGNUM, -+ PA_PCSQ_TAIL_REGNUM, -+ PA_CR11_REGNUM, -+ PA_CR19_REGNUM, -+ PA_CR20_REGNUM, -+ PA_CR21_REGNUM, -+ PA_CR22_REGNUM, -+ PA_CR0_REGNUM, -+ PA_CR24_REGNUM, -+ PA_CR25_REGNUM, -+ PA_CR26_REGNUM, -+ PA_CR27_REGNUM, -+ PA_CR28_REGNUM, -+ PA_CR29_REGNUM, -+ PA_CR30_REGNUM, -+ PA_CR31_REGNUM, -+ PA_CR8_REGNUM, -+ PA_CR9_REGNUM, -+ PA_CR12_REGNUM, -+ PA_CR13_REGNUM, -+ PA_CR10_REGNUM, -+ PA_CR15_REGNUM -+ }; -+ -+void -+supply_gregset (gdb_gregset_t *gregsetp) -+{ -+ int i; -+ greg_t *regp = (greg_t *) gregsetp; -+ -+ for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++, regp++) -+ { -+ int regno = greg_map[i]; -+ /* When running a 64 bit kernel, a greg_t may be larger than the -+ actual register, so just pick off the LS bits of big-endian word. */ -+ supply_register (regno, -+ ((char *) (regp + 1)) - REGISTER_RAW_SIZE (regno)); -+ } -+} -+ -+void -+fill_gregset (gdb_gregset_t *gregsetp, int regno) -+{ -+ int i; -+ greg_t *regp = (greg_t *) gregsetp; -+ -+ memset (gregsetp, 0, sizeof (*gregsetp)); -+ for (i = 0; i < sizeof (greg_map) / sizeof (greg_map[0]); i++, regp++) -+ { -+ int regi = greg_map[i]; -+ -+ if (regno == -1 || regi == regno) -+ { -+ int rawsize = REGISTER_RAW_SIZE (regi); -+ memcpy (((char *) (regp + 1)) - rawsize, -+ registers + REGISTER_BYTE (regi), -+ rawsize); -+ } -+ } -+} -+ -+/* 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. */ -+ -+void -+supply_fpregset (gdb_fpregset_t *fpregsetp) -+{ -+ register int regi; -+ char *from; -+ -+ for (regi = 0; regi <= 31; regi++) -+ { -+ from = (char *) &((*fpregsetp)[regi]); -+ supply_register (2*regi + PA_FR0_REGNUM, from); -+ supply_register (2*regi + PA_FR0_REGNUM + 1, from + 4); -+ } -+} -+ -+/* Given a pointer to a floating point register set in /proc format -+ (fpregset_t *), update the register specified by REGNO from gdb's idea -+ of the current floating point register set. If REGNO is -1, update -+ them all. */ -+ -+void -+fill_fpregset (gdb_fpregset_t *fpregsetp, int regno) -+{ -+ if (regno == -1) -+ memcpy (fpregsetp, -+ ®isters[REGISTER_BYTE (PA_FR0_REGNUM)], -+ 32 * 2 * REGISTER_RAW_SIZE (PA_FR0_REGNUM)); -+ else -+ { -+ /* Gross. fpregset_t is double, registers[x] has single -+ precision reg. */ -+ char *from = (char *) ®isters[REGISTER_BYTE (regno)]; -+ char *to = (char *) &((*fpregsetp)[(regno - PA_FR0_REGNUM) / 2]); -+ if ((regno - PA_FR0_REGNUM) & 1) -+ to += 4; -+ memcpy (to, from, REGISTER_RAW_SIZE (regno)); -+ } -+} -+ -+int -+pa_linux_insert_watchpoint (int pid, CORE_ADDR addr, int len, int rw) -+{ -+ return -1; -+} -+ -+int -+pa_linux_remove_watchpoint (int pid, CORE_ADDR addr, int len) -+{ -+ return -1; -+} -+ -+CORE_ADDR -+pa_linux_stopped_by_watchpoint (int pid) -+{ -+ return 0; -+} -+ -diff -Npur gdb-5.2.cvs20020818.orig/gdb/pa-linux-tdep.c gdb-5.2.cvs20020818/gdb/pa-linux-tdep.c ---- gdb-5.2.cvs20020818.orig/gdb/pa-linux-tdep.c 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/pa-linux-tdep.c 2002-08-19 10:45:56.000000000 -0400 -@@ -0,0 +1,695 @@ -+/* Functions specific to gdb targetted to HPPA running Linux. -+ Copyright 2000, 2001 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 "value.h" -+#include "inferior.h" -+#include "gdbcore.h" -+#include "symfile.h" -+#include "objfiles.h" -+#include "arch-utils.h" -+#include "regcache.h" -+#include "tm.h" -+#include "elf/common.h" -+ -+static CORE_ADDR -+pa_read_pc (ptid_t ptid) -+{ -+ return (CORE_ADDR) read_register_pid (PA_PCOQ_HEAD_REGNUM, ptid) & ~3; -+} -+ -+static void -+pa_write_pc (CORE_ADDR pc, ptid_t ptid) -+{ -+ write_register_pid (PA_PCOQ_HEAD_REGNUM, pc, ptid); -+ write_register_pid (PA_PCOQ_TAIL_REGNUM, pc + 4, ptid); -+} -+ -+static CORE_ADDR -+pa_read_fp (void) -+{ -+ return read_register (PA_GR3_REGNUM); -+} -+ -+static CORE_ADDR -+pa_read_sp (void) -+{ -+ return read_register (PA_GR30_REGNUM); -+} -+ -+static void -+pa_write_sp (CORE_ADDR val) -+{ -+ write_register (PA_GR30_REGNUM, val); -+} -+ -+/* These functions deal with saving and restoring register state -+ around a function call in the inferior. They keep the stack -+ double-word aligned; eventually, on an hp700, the stack will have -+ to be aligned to a 64-byte boundary. */ -+ -+static void -+pa_push_dummy_frame (void) -+{ -+ CORE_ADDR sp, pc, pcspace; -+ register int regnum; -+ char reg_buffer[8]; -+ LONGEST int_buffer; -+ int reg_size = REGISTER_SIZE; -+ -+ pc = TARGET_READ_PC (inferior_ptid); -+ pcspace = read_register (PA_PCSQ_HEAD_REGNUM); -+ -+ /* Space for "arguments"; the RP goes in here. */ -+ sp = read_register (PA_GR30_REGNUM) + 48; -+ read_register_gen (PA_GR2_REGNUM, reg_buffer); -+ -+ /* The 32bit and 64bit ABIs save the return pointer into different -+ stack slots. */ -+ if (reg_size == 8) -+ write_memory (sp - 16, reg_buffer, 8); -+ else -+ write_memory (sp - 20, reg_buffer, 4); -+ -+ int_buffer = TARGET_READ_FP (); -+ write_register (PA_GR3_REGNUM, sp); -+ -+ sp = push_word (sp, int_buffer); -+ sp += reg_size; -+ -+ for (regnum = PA_GR1_REGNUM; regnum <= PA_GR31_REGNUM; regnum++) -+ if (regnum != PA_GR2_REGNUM && regnum != PA_GR3_REGNUM) -+ { -+ read_register_gen (regnum, reg_buffer); -+ sp = push_bytes (sp, reg_buffer, reg_size); -+ } -+ -+ /* This is not necessary for the 64bit ABI. In fact it is dangerous. */ -+ if (reg_size != 8) -+ sp += reg_size; -+ -+ for (regnum = PA_FR0_REGNUM; regnum < NUM_REGS; regnum++) -+ { -+ read_register_gen (regnum, reg_buffer); -+ sp = push_bytes (sp, reg_buffer, 4); -+ } -+ read_register_gen (PA_IPSW_REGNUM, reg_buffer); -+ sp = push_bytes (sp, reg_buffer, reg_size); -+ read_register_gen (PA_SAR_REGNUM, reg_buffer); -+ sp = push_bytes (sp, reg_buffer, reg_size); -+ sp = push_word (sp, pc); -+ sp = push_word (sp, pcspace); -+ sp = push_word (sp, pc + 4); -+ sp = push_word (sp, pcspace); -+ write_register (PA_GR30_REGNUM, sp); -+} -+ -+/* Called to determine if PC is in an interrupt handler of some -+ kind. */ -+static int -+pa_linux_in_interrupt_handler (CORE_ADDR pc) -+{ -+ /* gdb won't get control in a kernel ISR, so no need to worry here. */ -+ return 0; -+} -+ -+static CORE_ADDR -+pa_linux_frame_saved_pc_in_interrupt (const struct frame_info *frame) -+{ -+ return 0; -+} -+ -+static CORE_ADDR -+pa_hpux_frame_base_before_interrupt (const struct frame_info *frame) -+{ -+ /* return r30 from the interrupt save state. */ -+ return 0; -+} -+ -+static void -+pa_linux_frame_find_saved_regs_in_interrupt (struct frame_info *frame, -+ CORE_ADDR *saved_regs) -+{ -+} -+ -+#define LINUX_GATEWAY_ADDR 0x100 -+#define END_LINUX_GATEWAY_ADDR 0x1000 -+ -+/* Called to determine if the register state indicates we are in -+ a syscall. */ -+static int -+pa_linux_in_syscall (const CORE_ADDR *saved_regs) -+{ -+ int flags; -+ CORE_ADDR pc; -+ -+ if (saved_regs && saved_regs[PA_IPSW_REGNUM]) -+ flags = read_memory_integer (saved_regs[PA_IPSW_REGNUM], -+ REGISTER_SIZE); -+ else -+ flags = read_register (PA_IPSW_REGNUM); -+ -+ if ((flags & PSW_C) == 0) -+ return 1; -+ -+ if (saved_regs && saved_regs[PA_PCOQ_HEAD_REGNUM]) -+ pc = read_memory_integer (saved_regs[PA_PCOQ_HEAD_REGNUM], -+ REGISTER_SIZE); -+ else -+ pc = read_register (PA_PCOQ_HEAD_REGNUM); -+ pc &= ~3; -+ -+ if (pc >= LINUX_GATEWAY_ADDR && pc < END_LINUX_GATEWAY_ADDR) -+ return 1; -+ -+ return 0; -+} -+ -+static const struct stub_struc pa_linux_sigtramp[] = -+ { -+ { 0x34190000, 0xfffffffd, 0 }, /* ldi x,%r25 ; x=!!in_syscall */ -+ { 0x3414015a, 0xffffffff, 4 }, /* ldi __NR_rt_sigreturn,%r20 */ -+ { 0xe4008200, 0xffffffff, 8 }, /* be,l 0x100(%sr2,%r0),%sr0,%r31 */ -+ { 0x08000240, 0xffffffff, 12}, /* nop */ -+ -+ { (unsigned) -1, 0, -999 } /* sentinel */ -+ }; -+ -+int -+pa_linux_in_sigtramp (CORE_ADDR pc, const char *name) -+{ -+ if (is_pa_stub (pc, pa_linux_sigtramp, NULL)) -+ return 1; -+ -+ if (pc >= LINUX_GATEWAY_ADDR && pc < END_LINUX_GATEWAY_ADDR -+ && read_register (PA_GR20_REGNUM) == 0xad) /* __NR_rt_sigreturn */ -+ return 1; -+ -+ return 0; -+} -+ -+/* Where to find the start of the register save area in a signal frame. */ -+#define PA_LINUX_SIGCONTEXT(REGSIZE) \ -+ (((4 * 4 /* tramp */ \ -+ + 128 /* struct siginfo */ \ -+ + ((2 /* struct ucontext.uc_flags,uc_link */ \ -+ + 3) /* struct ucontext.uc_stack */ \ -+ * (REGSIZE))) + 7) & -8) -+ -+#define PA_LINUX_SIGCONTEXT_GR(REGSIZE) \ -+ (PA_LINUX_SIGCONTEXT (REGSIZE) + (REGSIZE)) -+ -+#define PA_LINUX_SIGCONTEXT_FR(REGSIZE) \ -+ ((PA_LINUX_SIGCONTEXT_GR (REGSIZE) + 32 * (REGSIZE) + 7) & -8) -+ -+#define PA_LINUX_SIGCONTEXT_PCSQ(REGSIZE) \ -+ (PA_LINUX_SIGCONTEXT_FR(REGSIZE) + 32 * 8) -+ -+#define PA_LINUX_SIGCONTEXT_PCOQ(REGSIZE) \ -+ (PA_LINUX_SIGCONTEXT_PCSQ(REGSIZE) + 2 * (REGSIZE)) -+ -+#define PA_LINUX_SIGCONTEXT_SAR(REGSIZE) \ -+ (PA_LINUX_SIGCONTEXT_PCOQ(REGSIZE) + 2 * (REGSIZE)) -+ -+static CORE_ADDR -+pa_linux_frame_saved_pc_in_sigtramp (const struct frame_info *frame) -+{ -+ int regsize = REGISTER_SIZE; -+ CORE_ADDR addr; -+ -+ /* read pcoqh in sigcontext structure */ -+ addr = frame->frame + PA_LINUX_SIGCONTEXT_PCOQ (regsize); -+ return read_memory_integer (addr, regsize) & ~3; -+} -+ -+static CORE_ADDR -+pa_linux_frame_base_before_sigtramp (struct frame_info *frame) -+{ -+ CORE_ADDR start_pc; -+ -+ if (is_pa_stub (frame->pc, pa_linux_sigtramp, &start_pc)) -+ { -+ /* Fudge alert: fix up frame->frame here as pa_frame_chain gets -+ it wrong. The problem being that linux doesn't set r3 on -+ entry to signal handlers, and find_proc_framesize returns -1 -+ for the signal handler trampoline as there is no unwind info. -+ It would be possible to make a special find_proc_framesize. -+ For now, this seems to work. */ -+ frame->frame = start_pc; -+ -+#if 0 -+ { -+ CORE_ADDR addr; -+ int regsize = REGISTER_SIZE; -+ -+ /* read r30 in sigcontext structure */ -+ addr = start_pc + PA_LINUX_SIGCONTEXT_GR (regsize) + 30 * regsize; -+ return read_memory_integer (addr, regsize); -+ } -+#else -+ /* We may as well just return the start pc, as it's the same as -+ our saved r30 anyway. */ -+ return start_pc; -+#endif -+ } -+ return 0; -+} -+ -+static void -+pa_linux_frame_find_saved_regs_in_sigtramp (struct frame_info *frame, -+ CORE_ADDR *saved_regs) -+{ -+ int i; -+ int regsize = REGISTER_SIZE; -+ CORE_ADDR addr; -+ -+ addr = frame->frame + PA_LINUX_SIGCONTEXT_GR (regsize); -+ -+ for (i = PA_GR0_REGNUM; i <= PA_GR31_REGNUM; i++) -+ { -+ if (i == PA_GR30_REGNUM) -+ saved_regs[i] = read_memory_integer (addr, regsize); -+ else -+ saved_regs[i] = addr; -+ addr += regsize; -+ } -+ addr = (addr + 7) & -8; -+ for (i = PA_FR0_REGNUM; i < NUM_REGS; i++) -+ { -+ saved_regs[i] = addr; -+ addr += 4; -+ } -+ saved_regs[PA_PCSQ_HEAD_REGNUM] = addr; addr += regsize; -+ saved_regs[PA_PCSQ_TAIL_REGNUM] = addr; addr += regsize; -+ saved_regs[PA_PCOQ_HEAD_REGNUM] = addr; addr += regsize; -+ saved_regs[PA_PCOQ_TAIL_REGNUM] = addr; addr += regsize; -+ saved_regs[PA_SAR_REGNUM] = addr; -+} -+ -+/* Attempt to find (and return) the global pointer for the given file. -+ -+ This code searchs for the .dynamic section in OBJFILE. Once it finds -+ the addresses at which the .dynamic section lives in the child process, -+ it scans the Elf64_Dyn or Elf32_Dyn entries for a DT_PLTGOT tag. If it -+ finds one of these, the corresponding d_un.d_ptr value is the global -+ pointer. */ -+ -+static CORE_ADDR -+generic_elf_find_global_pointer (struct objfile *objfile) -+{ -+ struct obj_section *osect; -+ -+ ALL_OBJFILE_OSECTIONS (objfile, osect) -+ if (strcmp (osect->the_bfd_section->name, ".dynamic") == 0) -+ { -+ CORE_ADDR addr; -+ int dtag_size = REGISTER_SIZE; -+ -+ addr = osect->addr; -+ while (addr < osect->endaddr) -+ { -+ int status; -+ LONGEST tag; -+ char buf[8]; -+ -+ status = target_read_memory (addr, buf, dtag_size); -+ if (status != 0) -+ break; -+ tag = extract_signed_integer (buf, dtag_size); -+ -+ if (tag == DT_PLTGOT) -+ { -+ CORE_ADDR global_pointer; -+ -+ status = target_read_memory (addr + dtag_size, buf, dtag_size); -+ if (status != 0) -+ break; -+ -+ global_pointer = extract_address (buf, dtag_size); -+ -+ /* The payoff... */ -+ return global_pointer; -+ } -+ -+ if (tag == DT_NULL) -+ break; -+ -+ addr += 2 * dtag_size; -+ } -+ break; -+ } -+ return 0; -+} -+ -+/* This the pa-linux64 call dummy -+ -+ Call stack frame has already been built by gdb. Since we could be -+ calling a varargs function, and we do not have the benefit of a stub to -+ put things in the right place, we load the first 8 word of arguments -+ into both the general and fp registers. -+ -+ fldd -64(0,%r29),%fr4 -+ fldd -56(0,%r29),%fr5 -+ fldd -48(0,%r29),%fr6 -+ fldd -40(0,%r29),%fr7 -+ fldd -32(0,%r29),%fr8 -+ fldd -24(0,%r29),%fr9 -+ fldd -16(0,%r29),%fr10 -+ fldd -8(0,%r29),%fr11 -+ ldd -64(%r29), %r26 -+ ldd -56(%r29), %r25 -+ ldd -48(%r29), %r24 -+ ldd -40(%r29), %r23 -+ ldd -32(%r29), %r22 -+ ldd -24(%r29), %r21 -+ ldd -16(%r29), %r20 -+ bve,l (%r1),%r2 -+ ldd -8(%r29), %r19 -+ mtsp %r21, %sr0 ; Code used when popping frame -+ ble 0(%sr0, %r22) -+ nop -+*/ -+ -+/* Call dummys are sized and written out in word sized hunks. So we have -+ to pack the instructions into words. */ -+ -+static const LONGEST pa_linux64_dummy[] = -+ { -+ 0x53a43f8353a53f93LL, 0x53a63fa353a73fb3LL, -+ 0x53a83fc353a93fd3LL, 0x2fa1100a2fb1100bLL, -+ 0x53ba3f8153b93f91LL, 0x53b83fa153b73fb1LL, -+ 0x53b63fc153b53fd1LL, 0x0fa110d4e820f000LL, -+ 0x0fb110d300151820LL, 0xe6c0000008000240LL -+ }; -+ -+/* Insert the specified number of args and function address -+ into a dummy call sequence, DUMMY, stored at PC. */ -+ -+static CORE_ADDR -+pa64_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, -+ struct value **args, struct type *type, int gcc_p) -+{ -+ CORE_ADDR pcoqh, pcoqt; -+ struct target_waitstatus w; -+ char buf[8]; -+ int status; -+ struct objfile *objfile; -+ static const char stub[8] = -+ { -+ 0xe8, 0x20, 0xd0, 0x00, /* BVE (r1) */ -+ 0x08, 0x00, 0x02, 0x40 /* NOP */ -+ }; -+ -+ /* We can not modify the instruction address queues directly, so we start -+ up the inferior and execute a couple of instructions to set them so -+ that they point to the call dummy in the stack. */ -+ pcoqh = read_register (PA_PCOQ_HEAD_REGNUM); -+ pcoqt = read_register (PA_PCOQ_TAIL_REGNUM); -+ -+ if (target_read_memory (pcoqh, buf, 4) != 0) -+ error ("Couldn't modify instruction address queue\n"); -+ -+ if (target_read_memory (pcoqt, buf + 4, 4) != 0) -+ error ("Couldn't modify instruction address queue\n"); -+ -+ if (target_write_memory (pcoqh, stub, 4) != 0) -+ error ("Couldn't modify instruction address queue\n"); -+ -+ if (target_write_memory (pcoqt, stub + 4, 4) != 0) -+ { -+ target_write_memory (pcoqh, buf, 4); -+ error ("Couldn't modify instruction address queue\n"); -+ } -+ -+ write_register (PA_GR1_REGNUM, pc); -+ -+ /* Single step twice, the BVE instruction will set the instruction -+ address queue such that it points to the PC value written immediately -+ above (ie the call dummy). */ -+ resume (1, 0); -+ target_wait (inferior_ptid, &w); -+ resume (1, 0); -+ target_wait (inferior_ptid, &w); -+ -+ /* Restore the two instructions at the old PC locations. */ -+ target_write_memory (pcoqh, buf, 4); -+ target_write_memory (pcoqt, buf + 4, 4); -+ -+ /* The call dummy wants the ultimate destination address in -+ register %r1. */ -+ write_register (PA_GR1_REGNUM, fun); -+ -+ /* We need to see if this objfile has a different DP value than our -+ own (it could be a shared library for example). */ -+ ALL_OBJFILES (objfile) -+ { -+ struct obj_section *s; -+ obj_private_data_t *obj_private; -+ -+ /* See if FUN is in any section within this shared library. */ -+ for (s = objfile->sections; s < objfile->sections_end; s++) -+ if (s->addr <= fun && fun < s->endaddr) -+ break; -+ -+ if (s >= objfile->sections_end) -+ continue; -+ -+ obj_private = (obj_private_data_t *) objfile->obj_private; -+ -+ /* The DP value may be different for each objfile. But within an -+ objfile each function uses the same dp value. Thus we do not need -+ to grope around the opd section looking for dp values. */ -+ -+ if (obj_private->dp == 0) -+ { -+ obj_private->dp = generic_elf_find_global_pointer (objfile); -+ if (obj_private->dp == 0) -+ obj_private->dp = -1; -+ } -+ if (obj_private->dp != -1) -+ write_register (PA_GR27_REGNUM, obj_private->dp); -+ break; -+ } -+ return pc; -+} -+ -+/* This is the pa-linux32 call dummy. The function address is in r22. -+ -+ Call stack frame has already been built by gdb. Since we could be -+ calling a varargs function, and we do not have the benefit of a stub to -+ put things in the right place, we load the first 4 word of arguments -+ into both the general and fp registers. -+ -+ ldo -36(%sp), %r1 -+ ldw -36(%sp), %arg0 -+ ldw -40(%sp), %arg1 -+ ldw -44(%sp), %arg2 -+ ldw -48(%sp), %arg3 -+ fldws 0(%r1), %fr4 -+ fldds -4(%r1), %fr5 -+ fldws -8(%r1), %fr6 -+ fldds -12(%r1), %fr7 -+ ble 0(%sr3, %r22) -+ copy %r31, %r2 -+ mtsp %r21, %sr0 ; Code used when popping a dummy frame. -+ ble,n 0(%sr0, %r22) -+ nop */ -+ -+static const LONGEST pa_linux32_dummy[] = -+ { -+ 0x37c13fb9, 0x4bda3fb9, 0x4bd93fb1, 0x4bd83fa9, -+ 0x4bd73fa1, 0x24201004, 0x2c391005, 0x24311006, -+ 0x2c291007, 0xe6c0c000, 0x081f0242, 0x00151820, -+ 0xe6c00002, 0x08000240 -+ }; -+ -+/* Insert the specified number of args and function address -+ into a dummy call sequence, DUMMY, stored at PC. */ -+ -+static CORE_ADDR -+pa_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, -+ struct value **args, struct type *type, int gcc_p) -+{ -+ CORE_ADDR pcoqh, pcoqt; -+ struct target_waitstatus w; -+ char buf[8]; -+ int status; -+ struct objfile *objfile; -+ static const char stub[8] = -+ { -+ 0xe4, 0x20, 0xc0, 0x00, /* ble 0(%sr3,%r1)) */ -+ 0x08, 0x00, 0x02, 0x40 /* nop */ -+ }; -+ -+ /* We can not modify the instruction address queues directly, so we start -+ up the inferior and execute a couple of instructions to set them so -+ that they point to the call dummy in the stack. */ -+ pcoqh = read_register (PA_PCOQ_HEAD_REGNUM); -+ pcoqt = read_register (PA_PCOQ_TAIL_REGNUM); -+ -+ if (target_read_memory (pcoqh, buf, 4) != 0) -+ error ("Couldn't modify instruction address queue\n"); -+ -+ if (target_read_memory (pcoqt, buf + 4, 4) != 0) -+ error ("Couldn't modify instruction address queue\n"); -+ -+ if (target_write_memory (pcoqh, stub, 4) != 0) -+ error ("Couldn't modify instruction address queue\n"); -+ -+ if (target_write_memory (pcoqt, stub + 4, 4) != 0) -+ { -+ target_write_memory (pcoqh, buf, 4); -+ error ("Couldn't modify instruction address queue\n"); -+ } -+ -+ write_register (PA_GR1_REGNUM, pc); -+ -+ /* Single step twice, the BLE instruction will set the instruction -+ address queue such that it points to the PC value written immediately -+ above (ie the call dummy). */ -+ resume (1, 0); -+ target_wait (inferior_ptid, &w); -+ resume (1, 0); -+ target_wait (inferior_ptid, &w); -+ -+ /* Restore the two instructions at the old PC locations. */ -+ target_write_memory (pcoqh, buf, 4); -+ target_write_memory (pcoqt, buf + 4, 4); -+ -+ /* The call dummy wants the ultimate destination address in -+ register %r22. */ -+ if (fun & 2) -+ { -+ /* It's a plabel. */ -+ int gp; -+ -+ fun &= ~3; -+ gp = read_memory_integer (fun + 4, 4); -+ write_register (PA_GR19_REGNUM, gp); -+ fun = read_memory_integer (fun, 4); -+ write_register (PA_GR22_REGNUM, fun); -+ } -+ else -+ { -+ write_register (PA_GR22_REGNUM, fun); -+ -+ /* We need to see if this objfile has a different DP value than our -+ own (it could be a shared library for example). */ -+ ALL_OBJFILES (objfile) -+ { -+ struct obj_section *s; -+ obj_private_data_t *obj_private; -+ -+ /* See if FUN is in any section within this shared library. */ -+ for (s = objfile->sections; s < objfile->sections_end; s++) -+ if (s->addr <= fun && fun < s->endaddr) -+ break; -+ -+ if (s >= objfile->sections_end) -+ continue; -+ -+ obj_private = (obj_private_data_t *) objfile->obj_private; -+ -+ /* The DP value may be different for each objfile. But within an -+ objfile each function uses the same dp value. */ -+ -+ if (obj_private->dp == 0) -+ { -+ obj_private->dp = generic_elf_find_global_pointer (objfile); -+ if (obj_private->dp == 0) -+ obj_private->dp = -1; -+ } -+ if (obj_private->dp != -1) -+ write_register (PA_GR19_REGNUM, obj_private->dp); -+ break; -+ } -+ } -+ return pc; -+} -+ -+#if defined (PA_XM_LINUX_H) && 0 -+/* For native compiles, check that our defines match the kernel. */ -+#include <asm/ucontext.h> -+#include <asm/rt_sigframe.h> -+#endif -+ -+void -+pa_linux_initialize_tdep (struct gdbarch *gdbarch, int is_elf64) -+{ -+#if defined (PA_XM_LINUX_H) && 0 -+#ifndef offsetof -+#define offsetof(TYPE, MEMBER) ((char *) &((TYPE *)0)->MEMBER - (char *)0) -+#endif -+ if (offsetof (struct rt_sigframe, uc.uc_mcontext) -+ != PA_LINUX_SIGCONTEXT (sizeof (unsigned long)) -+ || (offsetof (struct rt_sigframe, uc.uc_mcontext.sc_gr) -+ != PA_LINUX_SIGCONTEXT_GR (sizeof (unsigned long))) -+ || (offsetof (struct rt_sigframe, uc.uc_mcontext.sc_fr) -+ != PA_LINUX_SIGCONTEXT_FR (sizeof (unsigned long))) -+ || (offsetof (struct rt_sigframe, uc.uc_mcontext.sc_iasq) -+ != PA_LINUX_SIGCONTEXT_PCSQ (sizeof (unsigned long))) -+ || (offsetof (struct rt_sigframe, uc.uc_mcontext.sc_iaoq) -+ != PA_LINUX_SIGCONTEXT_PCOQ (sizeof (unsigned long))) -+ || (offsetof (struct rt_sigframe, uc.uc_mcontext.sc_sar) -+ != PA_LINUX_SIGCONTEXT_SAR (sizeof (unsigned long)))) -+ internal_error (__FILE__, __LINE__, -+ "kernel struct rt_sigframe has changed"); -+#endif -+ -+ set_gdbarch_read_pc (gdbarch, pa_read_pc); -+ set_gdbarch_write_pc (gdbarch, pa_write_pc); -+ set_gdbarch_read_fp (gdbarch, pa_read_fp); -+ set_gdbarch_read_sp (gdbarch, pa_read_sp); -+ set_gdbarch_write_sp (gdbarch, pa_write_sp); -+ set_gdbarch_push_dummy_frame (gdbarch, pa_push_dummy_frame); -+ -+ gdbarch_tdep (gdbarch)->in_interrupt_handler = pa_linux_in_interrupt_handler; -+ gdbarch_tdep (gdbarch)->frame_saved_pc_in_interrupt -+ = pa_linux_frame_saved_pc_in_interrupt; -+ gdbarch_tdep (gdbarch)->in_syscall = pa_linux_in_syscall; -+ gdbarch_tdep (gdbarch)->in_sigtramp = pa_linux_in_sigtramp; -+ gdbarch_tdep (gdbarch)->frame_saved_pc_in_sigtramp -+ = pa_linux_frame_saved_pc_in_sigtramp; -+ gdbarch_tdep (gdbarch)->frame_base_before_sigtramp -+ = pa_linux_frame_base_before_sigtramp; -+ gdbarch_tdep (gdbarch)->frame_find_saved_regs_in_sigtramp -+ = pa_linux_frame_find_saved_regs_in_sigtramp; -+ -+ set_gdbarch_call_dummy_location (gdbarch, ON_STACK); -+ /* call_dummy_address only needed for AT_ENTRY_POINT call dummies. */ -+ set_gdbarch_call_dummy_start_offset (gdbarch, 0); -+ set_gdbarch_call_dummy_breakpoint_offset (gdbarch, is_elf64 ? 0x44 : 0x2c); -+ set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1); -+ set_gdbarch_call_dummy_length (gdbarch, is_elf64 ? 0x50 : 0x38); -+ set_gdbarch_pc_in_call_dummy (gdbarch, pc_in_call_dummy_on_stack); -+ set_gdbarch_call_dummy_p (gdbarch, 1); -+ set_gdbarch_call_dummy_words (gdbarch, (is_elf64 -+ ? pa_linux64_dummy -+ : pa_linux32_dummy)); -+ set_gdbarch_sizeof_call_dummy_words (gdbarch, (is_elf64 -+ ? sizeof (pa_linux64_dummy) -+ : sizeof (pa_linux32_dummy))); -+ /* call_dummy_stack_adjust unused. */ -+ set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0); -+ set_gdbarch_fix_call_dummy (gdbarch, (is_elf64 -+ ? pa64_fix_call_dummy -+ : pa_fix_call_dummy)); -+} -+ -diff -Npur gdb-5.2.cvs20020818.orig/gdb/pa-tdep.c gdb-5.2.cvs20020818/gdb/pa-tdep.c ---- gdb-5.2.cvs20020818.orig/gdb/pa-tdep.c 1969-12-31 19:00:00.000000000 -0500 -+++ gdb-5.2.cvs20020818/gdb/pa-tdep.c 2002-08-19 10:45:28.000000000 -0400 -@@ -0,0 +1,3629 @@ -+/* Target-dependent code for the HP PA architecture, for GDB. -+ Copyright 1986, 1987, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, -+ 1998, 1999, 2000, 2001 Free Software Foundation, Inc. -+ -+ Contributed by the Center for Software Science at the -+ University of Utah (pa-gdb-bugs@cs.utah.edu). -+ -+ 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 "frame.h" -+#include "inferior.h" -+#include "value.h" -+ -+/* For argument passing to the inferior */ -+#include "symtab.h" -+ -+#include "gdb_stat.h" -+#include "gdb_wait.h" -+ -+#include "gdbcore.h" -+#include "gdbcmd.h" -+#include "target.h" -+#include "symfile.h" -+#include "objfiles.h" -+#include "arch-utils.h" -+#include "floatformat.h" -+#include "regcache.h" -+ -+#include "elf-bfd.h" -+#include "elf/common.h" -+#include "tm.h" -+ -+#if DEBUG -+static int framedebug = 0; -+static int grokdebug = 0; -+#ifndef DEBUG_PA_FRAME -+#define DEBUG_PA_FRAME framedebug -+#endif -+#ifndef DEBUG_PA_GROK -+#define DEBUG_PA_GROK grokdebug -+#endif -+#else -+#ifndef DEBUG_PA_FRAME -+#define DEBUG_PA_FRAME 0 -+#endif -+#ifndef DEBUG_PA_GROK -+#define DEBUG_PA_GROK 0 -+#endif -+#endif -+ -+/* To support detection of the pseudo-initial frame that threads have. */ -+#define THREAD_INITIAL_FRAME_SYMBOL "__pthread_exit" -+#define THREAD_INITIAL_FRAME_SYM_LEN sizeof(THREAD_INITIAL_FRAME_SYMBOL) -+ -+/* Array of register names. These should match register numbers -+ defined in tm-pa.h. The peculiar layout is to match HPUX, BSD and OSF -+ 32-bit interrupt frame register save state. */ -+static const char *pa_register_names[NUM_REGS] = -+ { -+ "flags", "r1", "rp", "r3", "r4", "r5", "r6", "r7", -+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", -+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", -+ "r24", "r25", "r26", "dp", "ret0", "ret1", "sp", "r31", -+ -+ "sar", "pcoqh", "pcsqh", "pcoqt", "pcsqt", "eiem", "iir", "isr", -+ /* cr11 cr18 cr17 cr18 cr17 cr15 cr19 cr20 */ -+ -+ "ior", "ipsw", "cr31", "sr4", "sr0", "sr1", "sr2", "sr3", -+ /* cr21 cr22 thandler? */ -+ -+ "sr5", "sr6", "sr7", "rcnt", "ptid1", "ptid2", "ccr", "ptid3", -+ /* cr0 cr8 cr9 cr10 cr12 */ -+ -+ "ptid4", "cr24", "cr25", "cr26", "cr27", "cr28", "cr29", "cr30", -+ /* cr13 mpsfu_high mpsfu_low mpsfu_ovflo */ -+ -+ "fpsr", "fpe1", "fpe2", "fpe3", "fpe4", "fpe5", "fpe6", "fpe7", -+ "fr4", "fr4R", "fr5", "fr5R", "fr6", "fr6R", "fr7", "fr7R", -+ "fr8", "fr8R", "fr9", "fr9R", "fr10", "fr10R", "fr11", "fr11R", -+ "fr12", "fr12R", "fr13", "fr13R", "fr14", "fr14R", "fr15", "fr15R", -+ "fr16", "fr16R", "fr17", "fr17R", "fr18", "fr18R", "fr19", "fr19R", -+ "fr20", "fr20R", "fr21", "fr21R", "fr22", "fr22R", "fr23", "fr23R", -+ "fr24", "fr24R", "fr25", "fr25R", "fr26", "fr26R", "fr27", "fr27R", -+ "fr28", "fr28R", "fr29", "fr29R", "fr30", "fr30R", "fr31", "fr31R", -+ }; -+ -+ -+static const char * -+pa_register_name (int reg) -+{ -+ return pa_register_names[reg]; -+} -+ -+int -+pa_register_byte (int reg) -+{ -+ return 4 * reg; -+} -+ -+int -+pa64_register_byte (int reg) -+{ -+ return reg < PA_FR0_REGNUM ? 8 * reg : 4 * PA_FR0_REGNUM + 4 * reg; -+} -+ -+int -+pa_register_raw_size (int reg) -+{ -+ return 4; -+} -+ -+int -+pa64_register_raw_size (int reg) -+{ -+ return reg < PA_FR0_REGNUM ? 8 : 4; -+} -+ -+struct type * -+pa_register_virtual_type (int reg) -+{ -+ if (reg >= PA_FR4_REGNUM) -+ return builtin_type_float; -+ else -+ return builtin_type_long; -+} -+ -+struct type * -+pa64_register_virtual_type (int reg) -+{ -+ if (reg < PA_FR0_REGNUM) -+ return builtin_type_unsigned_long_long; -+ else if (reg >= PA_FR4_REGNUM) -+ return builtin_type_float; -+ else -+ return builtin_type_long; -+} -+ -+ -+/* Routines to extract various sized constants out of hppa -+ instructions. */ -+ -+static inline int -+sign_extend (int x, int len) -+{ -+ int signbit = (1 << (len - 1)); -+ int mask = (signbit << 1) - 1; -+ return ((x & mask) ^ signbit) - signbit; -+} -+ -+/* For many immediate values the sign bit is the low bit! */ -+ -+static inline int -+low_sign_extend (int x, int len) -+{ -+ int mask = (1 << (len - 1)) - 1; -+ return ((x >> 1) & mask) - ((x & 1) << (len - 1)); -+} -+ -+/* This macro gets bit fields using HP's numbering (MSB = 0) */ -+#ifndef GET_FIELD -+#define GET_FIELD(X, FROM, TO) \ -+ ((X) >> (31 - (TO)) & ((1 << ((TO) - (FROM) + 1)) - 1)) -+#endif -+ -+/* extract a 21 bit constant */ -+ -+static int -+extract_21 (int word) -+{ -+ int val; -+ -+ val = GET_FIELD (word, 20 + 11, 20 + 11); -+ val <<= 11; -+ val |= GET_FIELD (word, 9 + 11, 19 + 11); -+ val <<= 2; -+ val |= GET_FIELD (word, 5 + 11, 6 + 11); -+ val <<= 5; -+ val |= GET_FIELD (word, 0 + 11, 4 + 11); -+ val <<= 2; -+ val |= GET_FIELD (word, 7 + 11, 8 + 11); -+ return sign_extend (val, 21) << 11; -+} -+ -+/* extract a 17 bit constant from branch instructions, returning the -+ 19 bit signed value. */ -+ -+static int -+extract_17 (unsigned word) -+{ -+ return sign_extend (GET_FIELD (word, 19, 28) | -+ GET_FIELD (word, 29, 29) << 10 | -+ GET_FIELD (word, 11, 15) << 11 | -+ (word & 0x1) << 16, 17) << 2; -+} -+ -+/* extract a 14 bit immediate field */ -+ -+static int -+extract_14 (unsigned word) -+{ -+ return low_sign_extend (word, 14); -+} -+ -+/* extract a 16 bit immediate field */ -+ -+static int -+extract_16a (unsigned word) -+{ -+ int low = low_sign_extend (word & 0x3ff9, 14); -+ return low ^ (word & 0xc000); -+} -+ -+/* Compare the start address for two unwind entries returning 1 if -+ the first address is larger than the second, -1 if the second is -+ larger than the first, and zero if they are equal. */ -+ -+static int -+compare_unwind_entries (const void *arg1, const void *arg2) -+{ -+ const struct unwind_table_entry *a = arg1; -+ const struct unwind_table_entry *b = arg2; -+ -+ if (a->region_start > b->region_start) -+ return 1; -+ else if (a->region_start < b->region_start) -+ return -1; -+ else -+ return 0; -+} -+ -+static void -+record_text_segment_lowaddr (bfd *abfd, asection *section, PTR info) -+{ -+ if ((section->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) -+ == (SEC_ALLOC | SEC_LOAD | SEC_READONLY)) -+ { -+ bfd_vma value = section->vma - section->filepos; -+ CORE_ADDR *low_text_segment_address = (CORE_ADDR *) info; -+ -+ if (value < *low_text_segment_address) -+ *low_text_segment_address = value; -+ } -+} -+ -+static void -+internalize_unwinds (struct objfile *objfile, struct unwind_table_entry *table, -+ asection *section, unsigned int entries, unsigned int size, -+ CORE_ADDR text_offset) -+{ -+ /* We will read the unwind entries into temporary memory, then -+ fill in the actual unwind table. */ -+ if (size > 0) -+ { -+ unsigned long tmp; -+ unsigned i; -+ char *buf = alloca (size); -+ -+ /* If ELF, then unwinds are supposed to be segment relative -+ offsets instead of absolute addresses. -+ -+ Note that when loading a shared library (text_offset != 0) the -+ unwinds are already relative to the text_offset that will be -+ passed in. */ -+ if (text_offset == 0 && gdbarch_tdep (current_gdbarch)->is_elf) -+ { -+ CORE_ADDR low_text_segment_address; -+ -+ low_text_segment_address = -1; -+ bfd_map_over_sections (objfile->obfd, -+ record_text_segment_lowaddr, -+ (PTR) &low_text_segment_address); -+ -+ text_offset += low_text_segment_address; -+ } -+ -+ bfd_get_section_contents (objfile->obfd, section, buf, 0, size); -+ -+ /* Now internalize the information being careful to handle host/target -+ endian issues. */ -+ for (i = 0; i < entries; i++) -+ { -+ table[i].region_start = bfd_get_32 (objfile->obfd, (bfd_byte *) buf); -+ table[i].region_start += text_offset; -+ buf += 4; -+ table[i].region_end = bfd_get_32 (objfile->obfd, (bfd_byte *) buf); -+ table[i].region_end += text_offset; -+ buf += 4; -+ tmp = bfd_get_32 (objfile->obfd, (bfd_byte *) buf); -+ buf += 4; -+ table[i].Cannot_unwind = (tmp >> 31) & 0x1; -+ table[i].Millicode = (tmp >> 30) & 0x1; -+ table[i].Millicode_save_sr0 = (tmp >> 29) & 0x1; -+ table[i].Region_description = (tmp >> 27) & 0x3; -+ table[i].reserved1 = (tmp >> 26) & 0x1; -+ table[i].Entry_SR = (tmp >> 25) & 0x1; -+ table[i].Entry_FR = (tmp >> 21) & 0xf; -+ table[i].Entry_GR = (tmp >> 16) & 0x1f; -+ table[i].Args_stored = (tmp >> 15) & 0x1; -+ table[i].Variable_Frame = (tmp >> 14) & 0x1; -+ table[i].Separate_Package_Body = (tmp >> 13) & 0x1; -+ table[i].Frame_Extension_Millicode = (tmp >> 12) & 0x1; -+ table[i].Stack_Overflow_Check = (tmp >> 11) & 0x1; -+ table[i].Two_Instruction_SP_Increment = (tmp >> 10) & 0x1; -+ table[i].Ada_Region = (tmp >> 9) & 0x1; -+ table[i].cxx_info = (tmp >> 8) & 0x1; -+ table[i].cxx_try_catch = (tmp >> 7) & 0x1; -+ table[i].sched_entry_seq = (tmp >> 6) & 0x1; -+ table[i].reserved2 = (tmp >> 5) & 0x1; -+ table[i].Save_SP = (tmp >> 4) & 0x1; -+ table[i].Save_RP = (tmp >> 3) & 0x1; -+ table[i].Save_MRP_in_frame = (tmp >> 2) & 0x1; -+ table[i].extn_ptr_defined = (tmp >> 1) & 0x1; -+ table[i].Cleanup_defined = tmp & 0x1; -+ tmp = bfd_get_32 (objfile->obfd, (bfd_byte *) buf); -+ buf += 4; -+ table[i].MPE_XL_interrupt_marker = (tmp >> 31) & 0x1; -+ table[i].HP_UX_interrupt_marker = (tmp >> 30) & 0x1; -+ table[i].Large_frame = (tmp >> 29) & 0x1; -+ table[i].Pseudo_SP_Set = (tmp >> 28) & 0x1; -+ table[i].reserved4 = (tmp >> 27) & 0x1; -+ table[i].Total_frame_size = tmp & 0x7ffffff; -+ -+ /* Stub unwinds are handled elsewhere. */ -+ table[i].stub_unwind.stub_type = 0; -+ table[i].stub_unwind.padding = 0; -+ } -+ } -+} -+ -+obj_private_data_t * -+pa_obj_private_alloc (struct objfile *objfile) -+{ -+ obj_private_data_t *obj_private; -+ obj_private = (obj_private_data_t *) -+ obstack_alloc (&objfile->psymbol_obstack, sizeof (obj_private_data_t)); -+ -+ memset (obj_private, 0, sizeof (obj_private)); -+ obj_private->unwind_info = NULL; -+ obj_private->so_info = NULL; -+ objfile->obj_private = (PTR) obj_private; -+ return obj_private; -+} -+ -+/* Read in the backtrace information stored in the unwind section of -+ the object file. This info is used mainly by find_unwind_entry to find -+ out the stack frame size and frame pointer used by procedures. We put -+ everything on the psymbol obstack in the objfile so that it automatically -+ gets freed when the objfile is destroyed. */ -+ -+static void -+read_unwind_info (struct objfile *objfile) -+{ -+ asection *unwind_sec, *stub_unwind_sec; -+ unsigned unwind_size, stub_unwind_size, total_size; -+ unsigned index, unwind_entries; -+ unsigned stub_entries, total_entries; -+ CORE_ADDR text_offset; -+ struct obj_unwind_info *ui; -+ obj_private_data_t *obj_private; -+ -+ text_offset = ANOFFSET (objfile->section_offsets, 0); -+ ui = (struct obj_unwind_info *) obstack_alloc (&objfile->psymbol_obstack, -+ sizeof (struct obj_unwind_info)); -+ -+ ui->table = NULL; -+ ui->cache = NULL; -+ ui->last = -1; -+ -+ /* For reasons unknown the HP PA64 tools generate multiple unwinder -+ sections in a single executable. So we just iterate over every -+ section in the BFD looking for unwinder sections intead of trying -+ to do a lookup with bfd_get_section_by_name. -+ -+ First determine the total size of the unwind tables so that we -+ can allocate memory in a nice big hunk. */ -+ total_entries = 0; -+ for (unwind_sec = objfile->obfd->sections; -+ unwind_sec; -+ unwind_sec = unwind_sec->next) -+ { -+ if (strcmp (unwind_sec->name, "$UNWIND_START$") == 0 -+ || strcmp (unwind_sec->name, ".PARISC.unwind") == 0) -+ { -+ unwind_size = bfd_section_size (objfile->obfd, unwind_sec); -+ unwind_entries = unwind_size / UNWIND_ENTRY_SIZE; -+ -+ total_entries += unwind_entries; -+ } -+ } -+ -+ /* Now compute the size of the stub unwinds. Note the ELF tools do not -+ use stub unwinds at the current time. */ -+ stub_unwind_size = 0; -+ stub_entries = 0; -+ stub_unwind_sec = bfd_get_section_by_name (objfile->obfd, "$UNWIND_END$"); -+ -+ if (stub_unwind_sec) -+ { -+ stub_unwind_size = bfd_section_size (objfile->obfd, stub_unwind_sec); -+ stub_entries = stub_unwind_size / STUB_UNWIND_ENTRY_SIZE; -+ } -+ -+ /* Compute total number of unwind entries and their total size. */ -+ total_entries += stub_entries; -+ total_size = total_entries * sizeof (struct unwind_table_entry); -+ -+ /* Allocate memory for the unwind table. */ -+ ui->table = (struct unwind_table_entry *) -+ obstack_alloc (&objfile->psymbol_obstack, total_size); -+ ui->last = total_entries - 1; -+ -+ /* Now read in each unwind section and internalize the standard unwind -+ entries. */ -+ index = 0; -+ for (unwind_sec = objfile->obfd->sections; -+ unwind_sec; -+ unwind_sec = unwind_sec->next) -+ { -+ if (strcmp (unwind_sec->name, "$UNWIND_START$") == 0 -+ || strcmp (unwind_sec->name, ".PARISC.unwind") == 0) -+ { -+ unwind_size = bfd_section_size (objfile->obfd, unwind_sec); -+ unwind_entries = unwind_size / UNWIND_ENTRY_SIZE; -+ -+ internalize_unwinds (objfile, &ui->table[index], unwind_sec, -+ unwind_entries, unwind_size, text_offset); -+ index += unwind_entries; -+ } -+ } -+ -+ /* Now read in and internalize the stub unwind entries. */ -+ if (stub_unwind_size > 0) -+ { -+ unsigned int i; -+ char *buf = alloca (stub_unwind_size); -+ -+ /* Read in the stub unwind entries. */ -+ bfd_get_section_contents (objfile->obfd, stub_unwind_sec, buf, -+ 0, stub_unwind_size); -+ -+ /* Now convert them into regular unwind entries. */ -+ for (i = 0; i < stub_entries; i++, index++) -+ { -+ /* Clear out the next unwind entry. */ -+ memset (&ui->table[index], 0, sizeof (struct unwind_table_entry)); -+ -+ /* Convert offset & size into region_start and region_end. -+ Stuff away the stub type into "reserved" fields. */ -+ ui->table[index].region_start = bfd_get_32 (objfile->obfd, -+ (bfd_byte *) buf); -+ ui->table[index].region_start += text_offset; -+ buf += 4; -+ ui->table[index].stub_unwind.stub_type = bfd_get_8 (objfile->obfd, -+ (bfd_byte *) buf); -+ buf += 2; -+ ui->table[index].region_end -+ = ui->table[index].region_start + 4 * -+ (bfd_get_16 (objfile->obfd, (bfd_byte *) buf) - 1); -+ buf += 2; -+ } -+ -+ } -+ -+ /* Unwind table needs to be kept sorted. */ -+ qsort (ui->table, total_entries, sizeof (struct unwind_table_entry), -+ compare_unwind_entries); -+ -+ /* Keep a pointer to the unwind information. */ -+ obj_private = (obj_private_data_t *) objfile->obj_private; -+ if (obj_private == NULL) -+ obj_private = (PTR) pa_obj_private_alloc (objfile); -+ -+ obj_private->unwind_info = ui; -+} -+ -+/* Lookup the unwind (stack backtrace) info for the given PC. We search all -+ of the objfiles seeking the unwind table entry for this PC. Each objfile -+ contains a sorted list of struct unwind_table_entry. Since we do a binary -+ search of the unwind tables, we depend upon them to be sorted. */ -+ -+struct unwind_table_entry * -+find_unwind_entry (CORE_ADDR pc) -+{ -+ int first, middle, last; -+ struct objfile *objfile; -+ -+ /* A function at address 0? Not in HP-UX! Or linux, for that matter. */ -+ if (pc == (CORE_ADDR) 0) -+ return NULL; -+ -+ ALL_OBJFILES (objfile) -+ { -+ struct obj_unwind_info *ui; -+ ui = NULL; -+ if (objfile->obj_private) -+ ui = ((obj_private_data_t *) (objfile->obj_private))->unwind_info; -+ -+ if (!ui) -+ { -+ read_unwind_info (objfile); -+ if (objfile->obj_private == NULL) -+ error ("Internal error reading unwind information."); -+ ui = ((obj_private_data_t *) (objfile->obj_private))->unwind_info; -+ } -+ -+ /* First, check the cache */ -+ -+ if (ui->cache -+ && pc >= ui->cache->region_start -+ && pc <= ui->cache->region_end) -+ return ui->cache; -+ -+ /* Not in the cache, do a binary search */ -+ -+ first = 0; -+ last = ui->last; -+ -+ while (first <= last) -+ { -+ middle = (first + last) / 2; -+ if (pc >= ui->table[middle].region_start -+ && pc <= ui->table[middle].region_end) -+ { -+ ui->cache = &ui->table[middle]; -+ return &ui->table[middle]; -+ } -+ -+ if (pc < ui->table[middle].region_start) -+ last = middle - 1; -+ else -+ first = middle + 1; -+ } -+ } /* ALL_OBJFILES() */ -+ return NULL; -+} -+ -+static const struct stub_struc pa32_stubs[] = -+ { -+ /* Long branch stub. */ -+ { 0x20200000, 0xffe00000, 0 }, /* ldil LR'XXX,%r1 */ -+ { 0xe0202002, 0xffe0e002, 4 }, /* be,n RR'XXX(%sr4,%r1) */ -+ -+ /* PIC long branch stub. */ -+ { 0xe8200000, 0xffffffff, /* b,l .+8,%r1 */ -+ -pa_stub_long_branch }, /* type of previous stub */ -+ { 0x28200000, 0xffe00000, 4 }, /* addil LR'XXX,%r1,%r1 */ -+ { 0xe0202002, 0xffe0e002, 8 }, /* be,n RR'XXX(%sr4,%r1) */ -+ -+ /* Import stub. */ -+ { 0x2b600000, 0xffe00000, /* addil LR'XXX,%dp,%r1 */ -+ -pa_stub_long_branch_shared }, -+ { 0x48350000, 0xffffc000, 4 }, /* ldw RR'XXX(%sr0,%r1),%r21 */ -+ { 0xeaa0c000, 0xffffffff, 8 }, /* bv %r0(%r21) */ -+ { 0x48330000, 0xffffc000, 12 }, /* ldw RR'XXX+4(%sr0,%r1),%r19 */ -+ -+ /* Import stub for shared lib. */ -+ { 0x2a600000, 0xffe00000, /* addil LR'XXX,%r19,%r1 */ -+ -pa_stub_import }, -+ { 0x48350000, 0xffffc000, 4 }, /* ldw RR'XXX(%sr0,%r1),%r21 */ -+ { 0xeaa0c000, 0xffffffff, 8 }, /* bv %r0(%r21) */ -+ { 0x48330000, 0xffffc000, 12 }, /* ldw RR'XXX+4(%sr0,%r1),%r19 */ -+ -+ /* Multiple sub-space import stub. */ -+ { 0x2b600000, 0xffe00000, /* addil LR'XXX,%dp */ -+ -pa_stub_import_shared }, -+ { 0x48350000, 0xffffc000, 4 }, /* ldw RR'XXX(%r1),%r21 */ -+ { 0x48330000, 0xffffc000, 8 }, /* ldw RR'XXX+4(%r1),%r19 */ -+ { 0x02a010a1, 0xffffffff, 12 }, /* ldsid (%r21),%r1 */ -+ { 0x00011820, 0xffffffff, 16 }, /* mtsp %r1,%sr0 */ -+ { 0xe2a00000, 0xffffffff, 20 }, /* be 0(%sr0,%r21) */ -+ { 0x6bc23fd1, 0xffffffff, 24 }, /* stw %rp,-24(%sp) */ -+ -+ /* Multiple sub-space import stub for shared lib. */ -+ { 0x2a600000, 0xffe00000, /* addil LR'XXX,%r19 */ -+ -pa_stub_import_multi }, -+ { 0x48350000, 0xffffc000, 4 }, /* ldw RR'XXX(%r1),%r21 */ -+ { 0x48330000, 0xffffc000, 8 }, /* ldw RR'XXX+4(%r1),%r19 */ -+ { 0x02a010a1, 0xffffffff, 12 }, /* ldsid (%r21),%r1 */ -+ { 0x00011820, 0xffffffff, 16 }, /* mtsp %r1,%sr0 */ -+ { 0xe2a00000, 0xffffffff, 20 }, /* be 0(%sr0,%r21) */ -+ { 0x6bc23fd1, 0xffffffff, 24 }, /* stw %rp,-24(%sp) */ -+ -+ /* ELF32 .plt lazy linking stub. */ -+ { 0x0e801096, 0xffffffff, /* 1: ldw 0(%r20),%r22 */ -+ -pa_stub_import_multi_shared }, -+ { 0xeac0c000, 0xffffffff, 4 }, /* bv %r0(%r22) */ -+ { 0x0e881095, 0xffffffff, 8 }, /* ldw 4(%r20),%r21 */ -+ { 0xea9f1fdd, 0xffffffff, 12 }, /* b,l 1b,%r20 */ -+ { 0xd6801c1e, 0xffffffff, 16 }, /* depi 0,31,2,%r20 */ -+ -+#define EXPORT_STUB_ENT 32 -+ /* Export stub. */ -+ { 0xe8400002, 0xffe0e002, /* bl,n X,%rp */ -+ -pa_stub_lazy_link }, -+ { 0x08000240, 0xffffffff, 4 }, /* nop */ -+ { 0x4bc23fd1, 0xffffffff, 8 }, /* ldw -24(%sp),%rp */ -+ { 0x004010a1, 0xffffffff, 12 }, /* ldsid (%rp),%r1 */ -+ { 0x00011820, 0xffffffff, 16 }, /* mtsp %r1,%sr0 */ -+ { 0xe0400002, 0xffffffff, 20 }, /* be,n 0(%sr0,%rp) */ -+ -+ { (unsigned) -1, 0, /* sentinel */ -+ -pa_stub_export } -+ }; -+ -+static const struct stub_struc pa64_stubs[] = -+ { -+ { 0x53610000, 0xffffc00e, 0 }, /* ldd pltoff(%r27),%r1 */ -+ { 0xe820d000, 0xffffffff, 4 }, /* bve (%r1) */ -+ { 0x537b0000, 0xffffc00e, 8 }, /* ldd pltoff+8(%r27),%r27 */ -+ -+ { (unsigned) -1, 0, /* sentinel */ -+ -pa64_stub_import } -+ }; -+ -+enum stub_type -+is_pa_stub (CORE_ADDR pc, const struct stub_struc *srch, CORE_ADDR *start) -+{ -+ unsigned int insn; -+ -+ insn = read_memory_integer (pc, 4); -+ if (DEBUG_PA_GROK) -+ printf ("is_pa_stub (%#lx, %p), insn=%#x = ", (long) pc, srch, insn); -+ -+ for (; srch->mask != 0; srch++) -+ { -+ if ((insn & srch->mask) == srch->insn) -+ { -+ /* Possible match, check the whole stub. */ -+ int i; -+ CORE_ADDR addr; -+ const struct stub_struc *stub; -+ -+ i = srch->offset; -+ if (i < 0) -+ i = 0; -+ stub = ((const struct stub_struc *) -+ ((const char *) srch - i * (sizeof (pa32_stubs[0]) / 4))); -+ addr = pc - i; -+ if (start) -+ *start = addr; -+ do -+ { -+ unsigned int x = read_memory_integer (addr, 4); -+ if ((x & stub->mask) != stub->insn) -+ goto no_match; -+ stub++; -+ addr += 4; -+ } -+ while (stub->offset > 0); -+ if (DEBUG_PA_GROK) -+ printf ("matches %d\n", -stub->offset); -+ return -stub->offset; -+ } -+ no_match: ; -+ } -+ if (DEBUG_PA_GROK) -+ printf ("no\n"); -+ return pa_stub_none; -+} -+ -+/* Called when no unwind descriptor was found for PC. Returns 1 if it -+ appears that PC is in a linker stub. */ -+ -+static enum stub_type -+pc_in_linker_stub (CORE_ADDR pc, CORE_ADDR *start) -+{ -+ const struct stub_struc *srch = pa32_stubs; -+ -+ if (gdbarch_tdep (current_gdbarch)->is_elf64) -+ srch = pa64_stubs; -+ -+ return is_pa_stub (pc, srch, start); -+} -+ -+/* Called when no unwind descriptor was found for PC. Returns 1 if it -+ appears that PC is in a linker export stub. */ -+ -+static int -+pc_in_linker_call_stub (CORE_ADDR pc) -+{ -+ if (gdbarch_tdep (current_gdbarch)->is_elf) -+ return 0; -+ return is_pa_stub (pc, pa32_stubs + EXPORT_STUB_ENT, NULL) != pa_stub_none; -+} -+ -+static int -+find_return_regnum (CORE_ADDR pc) -+{ -+ struct unwind_table_entry *u; -+ -+ u = find_unwind_entry (pc); -+ -+ if (u && u->Millicode) -+ return PA_GR31_REGNUM; -+ -+ return PA_GR2_REGNUM; -+} -+ -+/* Return size of frame, or -1 if we should use a frame pointer. */ -+static int -+find_proc_framesize (CORE_ADDR pc) -+{ -+ struct unwind_table_entry *u; -+ int ret = -1; -+ -+ if (DEBUG_PA_FRAME) -+ printf ("find_proc_framesize (%#lx)\n", (long) pc); -+ -+ /* This may indicate a bug in our callers... */ -+ if (pc == (CORE_ADDR) 0) -+ return ret; -+ -+ u = find_unwind_entry (pc); -+ if (!u) -+ { -+ /* Linker stubs have a zero size frame. */ -+ if (pc_in_linker_stub (pc, NULL) != pa_stub_none) -+ ret = 0; -+ } -+ /* If Save_SP is set, and we're not in an interrupt or signal caller, -+ then we have a frame pointer. Use it. Otherwise find the size -+ from unwind info. */ -+ else if (!u->Save_SP -+ || PA_IN_INTERRUPT_HANDLER (pc) -+ || IN_SIGTRAMP (pc, SYMBOL_NAME (lookup_minimal_symbol_by_pc (pc)))) -+ { -+ ret = u->Total_frame_size << 3; -+ } -+ if (DEBUG_PA_FRAME) -+ printf (" unwind = %p, returning %#x\n", u, ret); -+ -+ return ret; -+} -+ -+/* Return offset from sp at which rp is saved, or 0 if not saved. */ -+static int -+rp_saved (CORE_ADDR pc) -+{ -+ struct unwind_table_entry *u; -+ -+ /* A function at, and thus a return PC from, address 0? Not in HP-UX! */ -+ if (pc == (CORE_ADDR) 0) -+ return 0; -+ -+ u = find_unwind_entry (pc); -+ -+ if (!u) -+ { -+ if (pc_in_linker_call_stub (pc)) -+ /* This is the so-called RP'. */ -+ return -24; -+ else -+ return 0; -+ } -+ -+ if (u->Save_RP) -+ return (REGISTER_SIZE == 8 ? -16 : -20); -+ -+ switch (u->stub_unwind.stub_type) -+ { -+ case EXPORT: -+ case IMPORT: -+ return -24; -+ case PARAMETER_RELOCATION: -+ return -8; -+ } -+ return 0; -+} -+ -+/* Returns non-zero if the function invocation represented by FI does not -+ have a frame on the stack associated with it. */ -+static int pa_frameless_function_invocation (struct frame_info *fi) -+{ -+ int ret; -+ -+ if (pc_in_linker_stub (fi->pc, NULL) != pa_stub_none) -+ ret = 1; -+ else -+ { -+ struct unwind_table_entry *u; -+ -+ u = find_unwind_entry (fi->pc); -+ ret = (u != 0 && u->Total_frame_size == 0 -+ && u->stub_unwind.stub_type == 0); -+ } -+ -+ if (DEBUG_PA_FRAME) -+ printf ("frameless_func (%p) = %#x\n", fi, ret); -+ return ret; -+} -+ -+static CORE_ADDR -+pa_saved_pc_after_call (struct frame_info *frame) -+{ -+ int ret_regnum; -+ CORE_ADDR pc; -+ struct unwind_table_entry *u; -+ -+ if (DEBUG_PA_FRAME) -+ printf ("saved_pc_after_call (%p)\n", frame); -+ -+ ret_regnum = find_return_regnum (frame->pc); -+ pc = read_register (ret_regnum) & ~3; -+ -+ /* If PC is in a linker stub, then we need to dig the address -+ the stub will return to out of the stack. */ -+ u = find_unwind_entry (pc); -+ if (u && u->stub_unwind.stub_type != 0) -+ pc = FRAME_SAVED_PC (frame); -+ -+ return pc; -+} -+ -+static CORE_ADDR -+pa_frame_saved_pc (struct frame_info *frame) -+{ -+ CORE_ADDR pc = frame->pc; -+ struct unwind_table_entry *u; -+ CORE_ADDR old_pc = 0; -+ int spun_around_loop = 0; -+ int rp_offset = 0; -+ -+ if (DEBUG_PA_FRAME) -+ { -+ printf ("frame_saved_pc (%p)\n", frame); -+ printf (" frame->prev = %p, frame->next = %p\n", -+ frame->prev, frame->next); -+ printf (" frame->frame = %#lx, frame->pc = %#lx, frame->extra = %p\n", -+ (long) frame->frame, (long) frame->pc, frame->extra_info); -+ } -+ -+ if (PA_IN_INTERRUPT_HANDLER (pc)) -+ { -+ CORE_ADDR rp; -+ rp = gdbarch_tdep (current_gdbarch)->frame_saved_pc_in_interrupt (frame); -+ if (DEBUG_PA_FRAME) -+ printf (" in interrupt, returning %#lx\n", (long) rp & ~3); -+ return rp & ~3; -+ } -+ -+ /* Deal with signal handler caller frames too. */ -+ if (frame->signal_handler_caller -+ && gdbarch_tdep (current_gdbarch)->frame_saved_pc_in_sigtramp) -+ { -+ CORE_ADDR rp; -+ rp = gdbarch_tdep (current_gdbarch)->frame_saved_pc_in_sigtramp (frame); -+ if (DEBUG_PA_FRAME) -+ printf (" in signal handler, returning %#lx\n", (long) rp & ~3); -+ return rp & ~3; -+ } -+ -+ /* Are we in a call dummy? */ -+ if (frame->pc >= frame->frame -+ && frame->pc < (frame->frame -+ + CALL_DUMMY_LENGTH -+ /* Account for register saves. See -+ find_dummy_frame_regs and push_dummy_frame. */ -+ + ((32 + 6) * REGISTER_SIZE) -+ + (NUM_REGS - PA_FR0_REGNUM) * 4)) -+ { -+ CORE_ADDR rp; -+ rp = read_memory_integer (frame->frame - (REGISTER_SIZE == 8 ? 16 : 20), -+ REGISTER_SIZE); -+ if (DEBUG_PA_FRAME) -+ printf (" in dummy, returning %#lx\n", (long) rp & ~3); -+ return rp & ~3; -+ } -+ -+ if (FRAMELESS_FUNCTION_INVOCATION (frame)) -+ { -+ int ret_regnum; -+ -+ ret_regnum = find_return_regnum (pc); -+ -+ if (DEBUG_PA_FRAME > 1) -+ printf (" frameless, ret reg = %#x\n", ret_regnum); -+ -+ /* If the next frame is an interrupt frame or a signal -+ handler caller, then we need to look in the saved -+ register area to get the return pointer (the values -+ in the registers may not correspond to anything useful). */ -+ if (frame->next -+ && (frame->next->signal_handler_caller -+ || PA_IN_INTERRUPT_HANDLER (frame->next->pc))) -+ { -+ if (!frame->next->saved_regs) -+ FRAME_INIT_SAVED_REGS (frame->next); -+ if (PA_IN_SYSCALL (frame->next->saved_regs)) -+ { -+ pc = read_memory_integer (frame->next->saved_regs[PA_GR31_REGNUM], -+ REGISTER_SIZE) & ~3; -+ -+ /* Syscalls are really two frames. The syscall stub itself -+ with a return pointer in %rp and the kernel call with -+ a return pointer in %r31. We return the %rp variant -+ if %r31 is the same as frame->pc. */ -+ if (pc == frame->pc) -+ pc = read_memory_integer (frame->next->saved_regs[PA_GR2_REGNUM], -+ REGISTER_SIZE) & ~3; -+ } -+ else -+ pc = read_memory_integer (frame->next->saved_regs[PA_GR2_REGNUM], -+ REGISTER_SIZE) & ~3; -+ } -+ else -+ pc = read_register (ret_regnum) & ~3; -+ } -+ else -+ { -+ spun_around_loop = 0; -+ old_pc = pc; -+ -+ rp_offset = 0; -+ if (frame->next -+ || !frame->extra_info -+ || pc > frame->extra_info->rp_save_insn) -+ { -+ restart: -+ rp_offset = rp_saved (pc); -+ } -+ -+ if (DEBUG_PA_FRAME > 1) -+ printf (" framed, rp_offset = %#x\n", rp_offset); -+ -+ /* Similar to code in frameless function case. If the next -+ frame is a signal or interrupt handler, then dig the right -+ information out of the saved register info. */ -+ if (rp_offset == 0 -+ && frame->next -+ && (frame->next->signal_handler_caller -+ || PA_IN_INTERRUPT_HANDLER (frame->next->pc))) -+ { -+ if (!frame->next->saved_regs) -+ FRAME_INIT_SAVED_REGS (frame->next); -+ if (PA_IN_SYSCALL (frame->next->saved_regs)) -+ { -+ pc = read_memory_integer (frame->next->saved_regs[PA_GR31_REGNUM], -+ REGISTER_SIZE) & ~3; -+ -+ /* Syscalls are really two frames. The syscall stub -+ itself with a return pointer in %rp and the kernel call -+ with a return pointer in %r31. We return the %rp -+ variant if %r31 is the same as frame->pc. */ -+ if (pc == frame->pc) -+ pc = read_memory_integer (frame->next->saved_regs[PA_GR2_REGNUM], -+ REGISTER_SIZE) & ~3; -+ } -+ else -+ pc = read_memory_integer (frame->next->saved_regs[PA_GR2_REGNUM], -+ REGISTER_SIZE) & ~3; -+ } -+ else if (rp_offset == 0 && frame->next) -+ { -+ /* Can't find pc save position, but frame->next set implies -+ r2 has been trashed. I suppose we could dig r2 out of -+ saved regs, but this point here is typically reached on -+ _start, so it's reasonable to say we don't have a saved -+ pc. */ -+ pc = 0; -+ } -+ else if (rp_offset == 0) -+ { -+ old_pc = pc; -+ pc = read_register (PA_GR2_REGNUM) & ~3; -+ } -+ else -+ { -+ old_pc = pc; -+ pc = read_memory_integer (frame->frame + rp_offset, -+ REGISTER_SIZE) & ~3; -+ } -+ } -+ -+ /* If PC is inside a linker stub, then dig out the address the stub -+ will return to. -+ -+ Don't do this for long branch stubs. Why? For some unknown reason -+ _start is marked as a long branch stub in hpux10. */ -+ if (pc) -+ { -+ u = find_unwind_entry (pc); -+ if (u && u->stub_unwind.stub_type != 0 -+ && u->stub_unwind.stub_type != LONG_BRANCH) -+ { -+ unsigned int insn; -+ -+ /* If this is a dynamic executable, and we're in a signal -+ handler, then the call chain will eventually point us -+ into the stub for _sigreturn. Unlike most cases, we'll -+ be pointed to the branch to the real sigreturn rather -+ than the code after the real branch!. Else, try to dig -+ the address the stub will return to in the normal -+ fashion. */ -+ insn = read_memory_integer (pc, 4); -+ if (DEBUG_PA_FRAME > 1) -+ printf (" stub, insn = %#x\n", insn); -+ -+ if ((insn & 0xfc00e000) == 0xe8000000) -+ return (pc + extract_17 (insn) + 8) & ~3; -+ else -+ { -+ if (old_pc == pc) -+ spun_around_loop++; -+ -+ if (spun_around_loop > 1) -+ { -+ /* We're just about to go around the loop again with -+ no more hope of success. Die. */ -+ error ("Unable to find return pc for this frame"); -+ } -+ else -+ goto restart; -+ } -+ } -+ } -+ -+ if (DEBUG_PA_FRAME) -+ printf (" returning %#lx\n", (long) pc); -+ -+ return pc; -+} -+ -+/* For the given instruction (INST), return any adjustment it makes -+ to the stack pointer or zero for no adjustment. -+ -+ This only handles instructions commonly found in prologues. */ -+ -+static int -+prologue_inst_adjust_sp (unsigned int inst, unsigned int high21) -+{ -+ /* The most common way to perform a stack adjustment ldo X(sp),sp */ -+ if ((inst & 0xffffc000) == 0x37de0000) -+ return extract_14 (inst); -+ -+ /* stwm X,D(sp) */ -+ if ((inst & 0xffe00000) == 0x6fc00000) -+ return extract_14 (inst); -+ -+ /* std,ma X,D(sp) */ -+ if ((inst & 0xffe00008) == 0x73c00008) -+ return ((inst & 0x1ff8) >> 1) - ((inst & 1) << 13); -+ -+ /* Second insn of "addil high21,%r30; ldo low11,(%r1),%r30" pair. */ -+ if ((inst & 0xffff0000) == 0x343e0000) -+ return high21 + extract_14 (inst); -+ -+ /* fstws as used by the HP compilers. */ -+ if ((inst & 0xffffffe0) == 0x2fd01220) -+ return low_sign_extend (inst >> 16, 5); -+ -+ /* No adjustment. */ -+ return 0; -+} -+ -+/* Return nonzero if INST is a branch of some kind, else return zero. */ -+ -+static inline int -+is_branch (unsigned int inst) -+{ -+ /* Return true on opcodes -+ 0x20,0x21,0x22,0x23, 0x28,0x29,0x2a,0x2b -+ 0x30,0x31,0x32,0x33, 0x38,0x39,0x3a,0x3b. */ -+ return ((inst & (0x24 << 26)) == (0x20 << 26) -+ /* Or on opcodes 0x27, 0x2f. */ -+ || (inst & (0x37 << 26)) == (0x27 << 26)); -+} -+ -+/* Return the register number for a GR which is saved by INST or -+ zero if INST does not save a GR. */ -+ -+static int -+inst_saves_gr (unsigned int inst) -+{ -+ if ( -+ /* Does it look like a non-indexed stb, sth, stw, stwm? -+ ie. opcodes 0x18, 0x19, 0x1a, 0x1b. */ -+ (inst & (0x3c << 26)) == (0x18 << 26) -+ -+ /* How about a non-indexed std? */ -+ || (inst & ((0x3f << 26) | 2)) == ((0x1c << 26) | 0) -+ -+ /* or a pa2 stwm? */ -+ || (inst & ((0x3f << 26) | 6)) == ((0x1f << 26) | 4) -+ -+ /* Or possibly an indexed stb, stw, sth or std? */ -+ || ((inst & ((0x3f << 26) | (1 << 12) | (3 << 8))) -+ == ((0x03 << 26) | (1 << 12) | (2 << 8))) -+ ) -+ return (inst >> 16) & 0x1f; -+ -+ return 0; -+} -+ -+/* Return the register number for a FR which is saved by INST or -+ zero if INST does not save a FR. We don't distinguish between left -+ and right float reg saves here. */ -+ -+static int -+inst_saves_fr (unsigned int inst) -+{ -+ if ( -+ /* Is this a long displacement fstd? */ -+ (inst & ((0x3f << 26) | 2)) == ((0x1c << 26) | 2) -+ -+ /* or a long displacement fstw? */ -+ || (inst & ((0x3f << 26) | 4)) == ((0x1f << 26) | 0) -+ || (inst & (0x3f << 26)) == (0x1e << 26) -+ ) -+ return (inst >> 16) & 0x1f; -+ -+ /* How about a short or indexed fstd or fstw? */ -+ if ((inst & ((0x3d << 26) | (1 << 9))) == ((0x09 << 26) | (1 << 9))) -+ return inst & 0x1f; -+ -+ return 0; -+} -+ -+/* Run through the prologue instructions for the function given by PC, -+ storing information about register saves in FRAME_INFO. Return the pc -+ at the end of the prologue. */ -+CORE_ADDR -+pa_grok_prologue (CORE_ADDR pc, struct frame_info *frame_info) -+{ -+ char buf[4]; -+ CORE_ADDR orig_pc = pc; -+ CORE_ADDR *fsr = 0; -+ unsigned long inst, stack_remaining, save_gr, save_fr, save_rp, save_sp; -+ unsigned long args_stored, status, i, restart_gr, restart_fr; -+ struct unwind_table_entry *u; -+ unsigned int r1_val, r1_base; -+ int final_iteration; -+ -+ if (frame_info) -+ fsr = frame_info->saved_regs; -+ -+ if (DEBUG_PA_GROK) -+ printf ("grok_prologue (%#lx, %p), fsr = %p, pc = %#lx\n", -+ (long) pc, frame_info, fsr, -+ (long) (frame_info ? frame_info->pc : 0)); -+ -+ u = find_unwind_entry (pc); -+ if (!u) -+ { -+ if (DEBUG_PA_GROK) -+ printf (" no unwind, returning %#lx\n", (long) pc); -+ return pc; -+ } -+ -+ /* If we are not at the beginning of a function, then return now. */ -+ if ((pc & ~3) != u->region_start) -+ { -+ if (DEBUG_PA_GROK) -+ printf (" not at region_start, returning %#lx\n", (long) pc); -+ return pc; -+ } -+ -+ restart_gr = 0; -+ restart_fr = 0; -+ -+restart: -+ r1_val = 0; -+ r1_base = 0; -+ -+ /* This is how much of a frame adjustment we need to account for. */ -+ stack_remaining = u->Total_frame_size << 3; -+ -+ /* Magic register saves we want to know about. */ -+ save_rp = u->Save_RP; -+ save_sp = u->Save_SP; -+ -+ /* An indication that args may be stored into the stack. Unfortunately -+ the HPUX compilers tend to set this in cases where no args were -+ stored too!. Heh, and gcc tends to *not* set it when args *are* -+ stored. So for the case where we care about arg store, ie. when -+ looking for the end of the prologue, assume there are args -+ stored. */ -+ args_stored = u->Args_stored || frame_info == 0; -+ -+ /* Turn the Entry_GR field into a bitmask. */ -+ save_gr = 1 << (u->Entry_GR + 3); -+ if (u->Save_SP) -+ { -+ /* Frame pointer (GR3) gets saved into a special location. */ -+ save_gr -= 1 << 4; -+ if (u->Entry_GR == 0) -+ save_gr = 0; -+ } -+ else -+ { -+ save_gr -= 1 << 3; -+ } -+ save_gr &= ~restart_gr; -+ -+ /* Turn the Entry_FR field into a bitmask too. */ -+ save_fr = (1 << (u->Entry_FR + 12)) - (1 << 12); -+ save_fr &= ~restart_fr; -+ -+ /* The frame always represents the value of %sp at entry to the -+ current function (and is thus equivalent to the "saved" stack -+ pointer. */ -+ if (fsr) -+ fsr[PA_GR30_REGNUM] = frame_info->frame; -+ -+ if (DEBUG_PA_GROK > 1) -+ printf (" save_gr=%#lx, save_fr=%#lx, save_rp=%#lx, save_sp=%#lx, stack=%#lx, args=%#lx\n", -+ save_gr, save_fr, save_rp, save_sp, stack_remaining, args_stored); -+ -+ /* Loop until we find everything of interest or hit a branch. -+ -+ For unoptimized GCC code and for any HP CC code this will never ever -+ examine any user instructions. -+ -+ For optimized GCC code we're faced with problems. GCC will schedule -+ its prologue and make prologue instructions available for delay slot -+ filling. The end result is user code gets mixed in with the prologue -+ and a prologue instruction may be in the delay slot of the first branch -+ or call. -+ -+ Some unexpected things are expected with debugging optimized code, so -+ we allow this routine to walk past user instructions in optimized -+ GCC code. */ -+ -+ for (final_iteration = 0; -+ ((!fsr || pc <= frame_info->pc + 4) -+ && ((save_gr || save_fr || save_rp || save_sp -+ || stack_remaining > 0 || args_stored))); -+ pc += 4) -+ { -+ unsigned int gr_num, fr_num; -+ unsigned long old_stack_remaining, old_save_gr, old_save_fr; -+ unsigned long old_save_rp, old_save_sp, next_inst; -+ -+ /* Save copies of all the triggers so we can compare them later -+ (only for HPC). */ -+ old_save_gr = save_gr; -+ old_save_fr = save_fr; -+ old_save_rp = save_rp; -+ old_save_sp = save_sp; -+ old_stack_remaining = stack_remaining; -+ -+ status = target_read_memory (pc, buf, 4); -+ -+ /* Yow! */ -+ if (status != 0) -+ return pc; -+ -+ inst = extract_unsigned_integer (buf, 4); -+ -+ /* Note the interesting effects of this instruction. */ -+ /* Save r1 value from addil high21,%r30 or addil high21,%r3. */ -+ if ((inst & 0xffe00000) == ((0x0a << 26) | (30 << 21)) -+ || (inst & 0xffe00000) == ((0x0a << 26) | (3 << 21))) -+ { -+ r1_val = extract_21 (inst); -+ r1_base = (inst >> 21) & 0x1f; -+ continue; -+ } -+ /* ldo offset(%r30),%r1 or ldo offset(%r3),%r1 */ -+ else if ((inst & 0xffff0000) == ((0x0d << 26) | (30 << 21) | (1 << 16)) -+ || (inst & 0xffff0000) == ((0x0d << 26) | (3 << 21) | (1 << 16))) -+ { -+ r1_val = extract_14 (inst); -+ r1_base = (inst >> 21) & 0x1f; -+ continue; -+ } -+ /* ldo offset(%r1),%r1 */ -+ else if ((inst & 0xffff0000) == ((0x0d << 26) | (1 << 21) | (1 << 16))) -+ { -+ r1_val += extract_14 (inst); -+ continue; -+ } -+ else -+ { -+ int stack_adj = prologue_inst_adjust_sp (inst, r1_val); -+ -+ stack_remaining -= stack_adj; -+ if (stack_adj && frame_info && frame_info->extra_info) -+ { -+ frame_info->extra_info->sp_adjust_insn = pc; -+ if (DEBUG_PA_GROK > 1) -+ printf (" found sp_adjust_insn = %#lx\n", (long) pc); -+ } -+ /* copy %sp,%r3 */ -+ if (inst == 0x081e0243 && frame_info && frame_info->extra_info) -+ { -+ frame_info->extra_info->fp_adjust_insn = pc; -+ if (DEBUG_PA_GROK > 1) -+ printf (" found fp_adjust_insn = %#lx\n", (long) pc); -+ } -+ } -+ -+ /* There are limited ways to store the return pointer into the -+ stack. */ -+ if (inst == 0x6bc23fd9) /* stw rp,-0x14(sr0,sp) */ -+ { -+ save_rp = 0; -+ if (fsr) -+ fsr[PA_GR2_REGNUM] = frame_info->frame - 20; -+ if (frame_info && frame_info->extra_info) -+ frame_info->extra_info->rp_save_insn = pc; -+ if (DEBUG_PA_GROK > 1) -+ printf (" found rp_save_insn = %#lx\n", (long) pc); -+ continue; -+ } -+ else if (inst == 0x0fc212c1) /* std rp,-0x10(sr0,sp) */ -+ { -+ save_rp = 0; -+ if (fsr) -+ fsr[PA_GR2_REGNUM] = frame_info->frame - 16; -+ if (frame_info && frame_info->extra_info) -+ frame_info->extra_info->rp_save_insn = pc; -+ if (DEBUG_PA_GROK > 1) -+ printf (" found rp_save_insn = %#lx\n", (long) pc); -+ continue; -+ } -+ -+ /* Note if we saved SP into the stack. This also happens to indicate -+ the location of the saved frame pointer. At this time the HP -+ compilers never bother to save SP into the stack. */ -+ if ((inst & 0xffffc000) == 0x6fc10000 /* stw,ma r1,N(sr0,sp) */ -+ || (inst & 0xffffc00c) == 0x73c10008) /* std,ma r1,N(sr0,sp) */ -+ { -+ if (fsr) -+ fsr[PA_GR3_REGNUM] = frame_info->frame; -+ save_sp = 0; -+ continue; -+ } -+ -+ /* Are we loading some register with an offset from the argument -+ pointer? */ -+ if ((inst & 0xffe00000) == 0x37a00000 /* ldo offs(ret1),rn */ -+ || (inst & 0xffffffe0) == 0x081d0240 /* copy ret1,rn */) -+ continue; -+ -+ /* Account for general and floating-point register saves. */ -+ gr_num = inst_saves_gr (inst); -+ save_gr &= ~(1 << gr_num); -+ if (fsr -+ && (gr_num > 3 || (gr_num == 3 && !u->Save_SP)) -+ && gr_num < u->Entry_GR + 3) -+ { -+ /* stwm with a positive displacement is a post modify. */ -+ if ((inst & ((0x3f << 26) | 1)) == ((0x1b << 26) | 0)) -+ fsr[gr_num] = frame_info->frame; -+ /* A std has explicit post_modify forms. */ -+ else if ((inst & 0xfc0000c0) == ((0x1c << 26) | 8)) -+ fsr[gr_num] = frame_info->frame; -+ else -+ { -+ CORE_ADDR offset; -+ int base_reg; -+ -+ if ((inst & (0x3f << 26)) == 0x1c << 26) -+ offset = ((inst >> 1) & 0x1ff8) - ((inst & 1) << 13); -+ else if ((inst & (0x3f << 26)) == 0x03 << 26) -+ offset = low_sign_extend (inst, 5); -+ else -+ offset = extract_14 (inst); -+ -+ base_reg = (inst >> 21) & 0x1f; -+ -+ /* Handle code with and without frame pointers. */ -+ if (base_reg == 1) -+ offset += r1_val; -+ if ((base_reg == 1 && r1_base == 30) -+ || base_reg == 30) -+ offset += u->Total_frame_size << 3; -+ -+ fsr[gr_num] = frame_info->frame + offset; -+ } -+ } -+ -+ fr_num = inst_saves_fr (inst); -+ save_fr &= ~(1 << fr_num); -+ -+ /* GCC handles callee saved FP regs a little differently. -+ -+ It emits an instruction to put the value of the start of -+ the FP store area into %r1. It then uses fstds,ma with -+ a basereg of %r1 for the stores. -+ -+ HP CC emits them at the current stack pointer modifying -+ the stack pointer as it stores each register. */ -+ -+ if (fsr -+ && fr_num >= 12 && fr_num <= 21) -+ { -+ int base_reg = (inst >> 21) & 0x1f; -+ -+ if (base_reg == 30) -+ { -+ /* HP CC FP register store. */ -+ fsr[2 * fr_num + PA_FR0_REGNUM] -+ = (frame_info->frame -+ + (u->Total_frame_size << 3) - old_stack_remaining); -+ } -+ else if (base_reg == 1) -+ { -+ int offset = r1_val; -+ -+ if (r1_base == 30) -+ offset += u->Total_frame_size << 3; -+ -+ fsr[2 * fr_num + PA_FR0_REGNUM] -+ = frame_info->frame + offset; -+ -+ /* I suppose we should really check the offset in the -+ instruction, but it will always be eight. */ -+ r1_val += 8; -+ } -+ } -+ -+ /* Quit if we hit any kind of branch the previous iteration. */ -+ if (final_iteration) -+ { -+ pc -= 4; -+ break; -+ } -+ -+ /* We want to look precisely one instruction beyond the branch -+ if we have not found everything yet. */ -+ if (is_branch (inst)) -+ { -+ /* If the branch delay slot is nullified, don't look at it. */ -+ if ((inst & 2) != 0 -+ && inst >= (0x38 << 26) && inst < (0x3b << 26)) -+ break; -+ final_iteration = 1; -+ } -+ -+ /* Ugh. Also account for argument stores into the stack. -+ Unfortunately args_stored only tells us that some arguments -+ where stored into the stack. Not how many or what kind! -+ -+ This is a kludge as on the HP compiler sets this bit and it -+ never does prologue scheduling. So once we see one, skip past -+ all of them. */ -+ if (args_stored -+ && ((gr_num >= (REGISTER_SIZE == 8 ? 19 : 23) && gr_num <= 26) -+ || (fr_num >= 4 && fr_num <= (REGISTER_SIZE == 8 ? 11 : 7)))) -+ { -+ do -+ { -+ pc += 4; -+ status = target_read_memory (pc, buf, 4); -+ if (status != 0) -+ return pc; -+ inst = extract_unsigned_integer (buf, 4); -+ gr_num = inst_saves_gr (inst); -+ fr_num = inst_saves_fr (inst); -+ } -+ while ((gr_num >= (REGISTER_SIZE == 8 ? 19 : 23) && gr_num <= 26) -+ || (fr_num >= 4 && fr_num <= (REGISTER_SIZE == 8 ? 11 : 7)) -+ || (inst & 0xfc000000) == (0x0d << 26) /* ldo */); -+ -+ args_stored = 0; -+ pc -= 4; -+ continue; -+ } -+ -+ /* What a crock. The HP compilers set args_stored even if no -+ arguments were stored into the stack (boo hiss). This could -+ cause this code to then skip a bunch of user insns (up to the -+ first branch). -+ -+ To combat this we try to identify when args_stored was bogusly -+ set and clear it. We only do this when args_stored is nonzero, -+ all other resources are accounted for, and nothing changed on -+ this pass. */ -+ if (args_stored -+ && !(save_gr || save_fr || save_rp || save_sp || stack_remaining > 0) -+ && old_save_gr == save_gr && old_save_fr == save_fr -+ && old_save_rp == save_rp && old_save_sp == save_sp -+ && old_stack_remaining == stack_remaining) -+ { -+ if (DEBUG_PA_GROK > 1) -+ printf (" toodleoo"); -+ break; -+ } -+ } -+ -+ if (DEBUG_PA_GROK > 2 && fsr) -+ { -+ int i; -+ for (i = PA_GR0_REGNUM; i <= PA_GR31_REGNUM; i++) -+ printf (" [r%d]=%#lx", i - PA_GR0_REGNUM, fsr[i]); -+ for (i = PA_FR0_REGNUM; i <= PA_FR31_REGNUM; i += 2) -+ printf (" [fr%d]=%#lx,%#lx", (i-PA_FR0_REGNUM) / 2, fsr[i], fsr[i+1]); -+ printf ("\n"); -+ } -+ if (DEBUG_PA_GROK) -+ printf (" pc=%#lx\n", (long) pc); -+ -+ /* We've got a tenative location for the end of the prologue. However -+ because of limitations in the unwind descriptor mechanism we may -+ have gone too far into user code looking for the save of a register -+ that does not exist. So, if there were registers we expected to be -+ saved but they never were, mask them out and restart. -+ -+ This should only happen in optimized code, and should be very rare. */ -+ if (frame_info == NULL -+ && (save_gr || save_fr) && !(restart_fr || restart_gr)) -+ { -+ pc = orig_pc; -+ restart_gr = save_gr; -+ restart_fr = save_fr; -+ goto restart; -+ } -+ -+ return pc; -+} -+ -+static void -+pa_init_extra_frame_info (int fromleaf, struct frame_info *frame) -+{ -+ int framesize; -+ -+ if (DEBUG_PA_FRAME) -+ { -+ printf ("init_extra_frame_info (%d, %p)\n", fromleaf, frame); -+ printf (" frame->prev = %p, frame->next = %p\n", -+ frame->prev, frame->next); -+ printf (" frame->frame = %#lx, frame->pc = %#lx\n", -+ (long) frame->frame, (long) frame->pc); -+ } -+ -+ frame->extra_info = frame_obstack_alloc (sizeof (*frame->extra_info)); -+ memset (frame->extra_info, 0, sizeof (*frame->extra_info)); -+ -+ /* If the next frame represents a frameless function invocation -+ then we have to do some adjustments that are normally done by -+ FRAME_CHAIN. (FRAME_CHAIN is not called in this case.) -+ -+ One might think frameless innermost frames should have -+ a frame->frame that is the same as the parent's frame->frame. -+ That is wrong; frame->frame in that case should be the *high* -+ address of the parent's frame. It's complicated as hell to -+ explain, but the parent *always* creates some stack space for -+ the child. So the child actually does have a frame of some -+ sorts, and its base is the high address in its parent's frame. */ -+ if (fromleaf) -+ { -+ framesize = find_proc_framesize (FRAME_SAVED_PC (frame->next)); -+ -+ /* Now adjust our base frame accordingly. If we have a frame pointer -+ use it, else subtract the size of this frame from the current -+ frame. (we always want frame->frame to point at the lowest address -+ in the frame). */ -+ if (framesize == -1) -+ frame->frame = TARGET_READ_FP (); -+ else -+ frame->frame -= framesize; -+ -+ if (DEBUG_PA_FRAME) -+ printf (" framesize = %#x, frame->frame = %#lx\n", -+ framesize, (long) frame->frame); -+ return; -+ } -+ -+ /* Adjustments for innermost frames. */ -+ if (!frame->next) -+ { -+ if (pc_in_linker_stub (frame->pc, NULL)) -+ { -+ /* stubs always have frame->frame == sp. */ -+ framesize = 0; -+ } -+ else -+ { -+ CORE_ADDR start_pc; -+ -+ /* gcc schedules the function prologue when optimizing, -+ which can lead to code from the function body moving -+ before the stack adjustment. That means we may have a -+ breakpoint set before the stack has been adjusted. In -+ any case, we can stepi anywhere. Thus, for innermost -+ frames we need to rummage through the prologue to see -+ exactly where we are. For other frames in the call -+ chain, we don't need to worry as no function will be -+ called before the prologue has fully executed. */ -+ start_pc = get_pc_function_start (frame->pc); -+ pa_grok_prologue (start_pc, frame); -+ framesize = find_proc_framesize (frame->pc); -+ } -+ -+ if (DEBUG_PA_FRAME> 1) -+ printf (" sp_adjust_insn = %#lx, fp_adjust_insn = %#lx, rp_save_insn = %#lx\n", -+ (long) frame->extra_info->sp_adjust_insn, -+ (long) frame->extra_info->fp_adjust_insn, -+ (long) frame->extra_info->rp_save_insn); -+ -+ if (framesize == -1) -+ { -+ if (frame->pc > frame->extra_info->fp_adjust_insn) -+ frame->frame = TARGET_READ_FP (); -+ else -+ frame->frame = read_register (PA_GR30_REGNUM); -+ } -+ else -+ { -+ frame->frame = read_register (PA_GR30_REGNUM); -+ if (frame->pc > frame->extra_info->sp_adjust_insn) -+ frame->frame -= framesize; -+ } -+ -+ if (DEBUG_PA_FRAME) -+ printf (" framesize = %#x, frame->frame = %#lx\n", -+ framesize, -+ (long) frame->frame); -+ } -+} -+ -+/* We always have some sort of frame. See above. */ -+static int -+pa_prologue_frameless_p (CORE_ADDR ip) -+{ -+ return 0; -+} -+ -+/* Given a GDB frame, determine the address of the calling function's -+ frame. This will be used to create a new GDB frame struct, and -+ then INIT_FRAME_PC_FIRST and INIT_EXTRA_FRAME_INFO will be called -+ for the new frame. -+ -+ This may involve searching through prologues for several functions -+ at boundaries where GCC calls HP C code, or where code which has -+ a frame pointer calls code without a frame pointer. -+ -+ In the case of the PA-RISC, the frame's nominal address is the address -+ of a 4-byte word containing the calling frame's address (previous FP). */ -+ -+static CORE_ADDR -+pa_frame_chain (struct frame_info *frame) -+{ -+ int my_framesize, caller_framesize; -+ struct unwind_table_entry *u; -+ CORE_ADDR frame_base; -+ struct frame_info *tmp_frame; -+ CORE_ADDR caller_pc; -+ struct minimal_symbol *min_frame_symbol; -+ struct symbol *frame_symbol; -+ char *frame_symbol_name; -+ CORE_ADDR ret; -+ -+ if (DEBUG_PA_FRAME) -+ { -+ printf ("frame_chain (%p)\n", frame); -+ printf (" frame->frame = %#lx, frame->pc = %#lx\n", -+ (long) frame->frame, (long) frame->pc); -+ } -+ -+ /* If this is a threaded application, and we see the -+ routine "__pthread_exit", treat it as the stack root -+ for this thread. */ -+ min_frame_symbol = lookup_minimal_symbol_by_pc (frame->pc); -+ frame_symbol = find_pc_function (frame->pc); -+ -+ if ((min_frame_symbol != 0) /* && (frame_symbol == 0) */ ) -+ { -+ /* The test above for "no user function name" would defend -+ against the slim likelihood that a user might define a -+ routine named "__pthread_exit" and then try to debug it. -+ -+ If it weren't commented out, and you tried to debug the -+ pthread library itself, you'd get errors. -+ -+ So for today, we don't make that check. */ -+ frame_symbol_name = SYMBOL_NAME (min_frame_symbol); -+ if (frame_symbol_name != 0) -+ { -+ if (0 == strncmp (frame_symbol_name, -+ THREAD_INITIAL_FRAME_SYMBOL, -+ THREAD_INITIAL_FRAME_SYM_LEN)) -+ { -+ /* Pretend we've reached the bottom of the stack. */ -+ return (CORE_ADDR) 0; -+ } -+ } -+ } /* End of hacky code for threads. */ -+ -+ if (PA_IN_INTERRUPT_HANDLER (frame->pc)) -+ frame_base = gdbarch_tdep (current_gdbarch)->frame_base_before_interrupt (frame); -+ else if (frame->signal_handler_caller -+ && gdbarch_tdep (current_gdbarch)->frame_base_before_sigtramp) -+ frame_base = gdbarch_tdep (current_gdbarch)->frame_base_before_sigtramp (frame); -+ else -+ frame_base = frame->frame; -+ -+ /* Get frame sizes for the current frame and the frame of the -+ caller. */ -+ my_framesize = find_proc_framesize (frame->pc); -+ caller_pc = FRAME_SAVED_PC (frame); -+ -+ if (DEBUG_PA_FRAME > 1) -+ printf (" frame_base = %#lx, my_framesize = %#x, caller_pc = %#lx\n", -+ (long) frame_base, my_framesize, (long) caller_pc); -+ -+ /* If we can't determine the caller's PC, then it's not likely we can -+ really determine anything meaningful about its frame. We'll consider -+ this to be stack bottom. */ -+ if (caller_pc == (CORE_ADDR) 0) -+ return (CORE_ADDR) 0; -+ -+ caller_framesize = find_proc_framesize (caller_pc); -+ -+ if (DEBUG_PA_FRAME > 1) -+ printf (" caller_framesize = %#x\n", caller_framesize); -+ -+ /* If caller does not have a frame pointer, then its frame -+ can be found at current_frame - caller_framesize. */ -+ if (caller_framesize != -1) -+ { -+ ret = frame_base - caller_framesize; -+ if (DEBUG_PA_FRAME) -+ printf (" returning %#lx\n", (long) ret); -+ return ret; -+ } -+ -+ /* Both caller and callee have frame pointers. -+ The previous frame pointer is found at the top of the current frame. */ -+ if (caller_framesize == -1 && my_framesize == -1) -+ { -+ ret = read_memory_integer (frame_base, REGISTER_SIZE); -+ if (DEBUG_PA_FRAME) -+ printf (" returning %#lx\n", (long) ret); -+ return ret; -+ } -+ -+ /* Caller has a frame pointer, but callee does not. This is a little -+ more difficult as GCC and HP C lay out locals and callee register save -+ areas very differently. -+ -+ The previous frame pointer could be in a register, or in one of -+ several areas on the stack. -+ -+ Walk from the current frame to the innermost frame examining -+ unwind descriptors to determine if %r3 ever gets saved into the -+ stack. If so return whatever value got saved into the stack. -+ If it was never saved in the stack, then the value in %r3 is still -+ valid, so use it. -+ -+ We use information from unwind descriptors to determine if %r3 -+ is saved into the stack (Entry_GR field has this information). */ -+ -+ for (tmp_frame = frame; tmp_frame; tmp_frame = tmp_frame->next) -+ { -+ u = find_unwind_entry (tmp_frame->pc); -+ -+ if (!u) -+ { -+ /* We could find this information by examining prologues. I don't -+ think anyone has actually written any tools (not even "strip") -+ which leave them out of an executable, so maybe this is a moot -+ point. */ -+ /* ??rehrauer: Actually, it's quite possible to stepi your way into -+ code that doesn't have unwind entries. For example, stepping into -+ the dynamic linker will give you a PC that has none. Thus, I've -+ disabled this warning. */ -+#if 0 -+ warning ("Unable to find unwind for PC 0x%x -- Help!", tmp_frame->pc); -+#endif -+ ret = 0; -+ if (DEBUG_PA_FRAME) -+ printf (" returning %#lx\n", (long) ret); -+ return ret; -+ } -+ -+ if (u->Save_SP -+ || tmp_frame->signal_handler_caller -+ || PA_IN_INTERRUPT_HANDLER (tmp_frame->pc)) -+ break; -+ -+ /* Entry_GR specifies the number of callee-saved general registers -+ saved in the stack. It starts at %r3, so %r3 would be 1. */ -+ if (u->Entry_GR >= 1) -+ { -+ /* The unwind entry claims that r3 is saved here. However, -+ in optimized code, GCC often doesn't actually save r3. -+ We'll discover this if we look at the prologue. */ -+ if (!tmp_frame->saved_regs) -+ FRAME_INIT_SAVED_REGS (tmp_frame); -+ if (tmp_frame->saved_regs[PA_GR3_REGNUM]) -+ break; -+ } -+ } -+ -+ if (tmp_frame) -+ { -+ /* We may have walked down the chain into a function with a frame -+ pointer. */ -+ if (DEBUG_PA_FRAME > 1) -+ printf (" reading fp from frame %p", tmp_frame); -+ if (u->Save_SP -+ && !tmp_frame->signal_handler_caller -+ && !PA_IN_INTERRUPT_HANDLER (tmp_frame->pc)) -+ { -+ if (DEBUG_PA_FRAME > 1) -+ printf ("->frame\n"); -+ ret = read_memory_integer (tmp_frame->frame, REGISTER_SIZE); -+ } -+ /* %r3 was saved somewhere in the stack. Dig it out. */ -+ else -+ { -+ /* Sick. -+ -+ For optimization purposes many kernels don't save the -+ callee saved registers into the save_state structure upon -+ entry into the kernel for a syscall; the optimization -+ is usually turned off if the process is being traced so -+ that the debugger can get full register state for the -+ process. -+ -+ This scheme works well except for two cases: -+ -+ * Attaching to a process when the process is in the -+ kernel performing a system call (debugger can't get -+ full register state for the inferior process since -+ the process wasn't being traced when it entered the -+ system call). -+ -+ * Register state is not complete if the system call -+ causes the process to core dump. -+ -+ The following heinous code is an attempt to deal with -+ the lack of register state in a core dump. It will -+ fail miserably if the function which performs the -+ system call has a variable sized stack frame. */ -+ -+ /* Abominable hack. */ -+ if (current_target.to_has_execution == 0 -+ && PA_IN_SYSCALL (tmp_frame->saved_regs) -+ && (u = find_unwind_entry (FRAME_SAVED_PC (frame))) != NULL) -+ { -+ ret = frame_base - (u->Total_frame_size << 3); -+ } -+ else -+ { -+ if (DEBUG_PA_FRAME > 1) -+ printf ("->saved_regs\n"); -+ ret = read_memory_integer (tmp_frame->saved_regs[PA_GR3_REGNUM], -+ REGISTER_SIZE); -+ } -+ } -+ } -+ else -+ { -+ /* Get the innermost frame. */ -+ tmp_frame = frame; -+ while (tmp_frame->next != NULL) -+ tmp_frame = tmp_frame->next; -+ -+ /* Abominable hack. See above. */ -+ if (current_target.to_has_execution == 0 -+ && PA_IN_SYSCALL (tmp_frame->saved_regs)) -+ { -+ u = find_unwind_entry (FRAME_SAVED_PC (frame)); -+ if (u) -+ ret = frame_base - (u->Total_frame_size << 3); -+ else if (tmp_frame->saved_regs[PA_GR3_REGNUM]) -+ ret = read_memory_integer (tmp_frame->saved_regs[PA_GR3_REGNUM], -+ REGISTER_SIZE); -+ else -+ ret = TARGET_READ_FP (); -+ } -+ else -+ { -+ /* The value in %r3 was never saved into the stack (thus %r3 -+ still holds the value of the previous frame pointer). */ -+ if (DEBUG_PA_FRAME > 1) -+ printf (" reading fp reg\n"); -+ ret = TARGET_READ_FP (); -+ } -+ } -+ if (DEBUG_PA_FRAME) -+ printf (" returning %#lx\n", (long) ret); -+ return ret; -+} -+ -+/* Return the base address used when calculating arg symbol offsets. This -+ doesn't have anything to do with the actual start of the args. */ -+static CORE_ADDR -+pa_frame_args_address (struct frame_info *fi) -+{ -+ return fi->frame; -+} -+ -+/* As for above, but for local vars. */ -+static CORE_ADDR -+pa_frame_locals_address (struct frame_info *fi) -+{ -+ return fi->frame; -+} -+ -+/* Stack grows upward. */ -+static int -+pa_inner_than (CORE_ADDR lhs, CORE_ADDR rhs) -+{ -+ return lhs > rhs; -+} -+ -+/* On hppa the stack must always be kept 64-bit aligned. */ -+static CORE_ADDR -+pa_stack_align (CORE_ADDR sp) -+{ -+ return (sp+7) & -8; -+} -+ -+/* On hppa64 the stack must always be kept 128-bit aligned. */ -+static CORE_ADDR -+pa64_stack_align (CORE_ADDR sp) -+{ -+ return (sp+15) & -16; -+} -+ -+/* On the PA, any pass-by-value structure > 8 bytes is actually -+ passed via a pointer regardless of its type or the compiler -+ used. */ -+static int -+pa_reg_struct_has_addr (int gcc_p, struct type *type) -+{ -+ return TYPE_LENGTH (type) > 8; -+} -+ -+static CORE_ADDR -+pa_read_sp (void) -+{ -+ return read_register (PA_GR30_REGNUM); -+} -+ -+static void -+pa_write_sp (CORE_ADDR val) -+{ -+ write_register (PA_GR30_REGNUM, val); -+} -+ -+void -+pa_extract_return_value (struct type *type, struct regcache *regcache, char *valbuf) -+{ -+ /* Extract from an array REGBUF containing the (raw) register state -+ a function return value of type TYPE, and copy that, in virtual -+ format, into VALBUF. */ -+ -+ if (TYPE_CODE (type) == TYPE_CODE_FLT && !SOFT_FLOAT) -+ regcache_cooked_read_using_offset_hack (regcache, -+ REGISTER_BYTE (PA_FR4_REGNUM), -+ TYPE_LENGTH (type), valbuf); -+ else -+ regcache_cooked_read_using_offset_hack (regcache, -+ REGISTER_BYTE (PA_GR28_REGNUM) -+ + 3 - ((TYPE_LENGTH (type) - 1) & 3), -+ TYPE_LENGTH (type), valbuf); -+} -+ -+void -+pa64_extract_return_value (struct type *type, struct regcache *regcache, char *valbuf) -+{ -+ /* Floats are returned in FR4R, doubles in FR4 -+ integral values are in r28, padded on the left -+ aggregates less that 65 bits are in r28, right padded -+ aggregates up to 128 bits are in r28 and r29, right padded. */ -+ if (TYPE_CODE (type) == TYPE_CODE_FLT && !SOFT_FLOAT) -+ regcache_cooked_read_using_offset_hack (regcache, -+ REGISTER_BYTE (PA_FR4_REGNUM) + 8 - TYPE_LENGTH (type), -+ TYPE_LENGTH (type), valbuf); -+ else if (is_integral_type (type) || SOFT_FLOAT) -+ regcache_cooked_read_using_offset_hack (regcache, -+ REGISTER_BYTE (PA_GR28_REGNUM) + 8 - TYPE_LENGTH (type), -+ TYPE_LENGTH (type), valbuf); -+ else if (TYPE_LENGTH (type) <= 16) -+ regcache_cooked_read_using_offset_hack (regcache, -+ REGISTER_BYTE (PA_GR28_REGNUM), -+ TYPE_LENGTH (type), valbuf); -+} -+ -+static void -+find_dummy_frame_regs (struct frame_info *frame, CORE_ADDR *frame_saved_regs) -+{ -+ CORE_ADDR fp = frame->frame; -+ int i; -+ int reg_size = REGISTER_SIZE; -+ -+ /* The 32bit and 64bit ABIs save RP into different locations. */ -+ if (reg_size == 8) -+ frame_saved_regs[PA_GR2_REGNUM] = fp - 16; -+ else -+ frame_saved_regs[PA_GR2_REGNUM] = fp - 20; -+ -+ frame_saved_regs[PA_GR3_REGNUM] = fp; -+ -+ fp += 2 * reg_size; -+ -+ for (i = PA_GR1_REGNUM; i <= PA_GR31_REGNUM; i++) -+ if (i != PA_GR2_REGNUM && i != PA_GR3_REGNUM) -+ { -+ frame_saved_regs[i] = fp; -+ fp += reg_size; -+ } -+ -+ /* This is not necessary or desirable for the 64bit ABI. */ -+ if (reg_size != 8) -+ fp += reg_size; -+ -+ for (i = PA_FR0_REGNUM; i < NUM_REGS; i++, fp += 4) -+ frame_saved_regs[i] = fp; -+ -+ frame_saved_regs[PA_IPSW_REGNUM] = fp; fp += reg_size; -+ frame_saved_regs[PA_SAR_REGNUM] = fp; fp += reg_size; -+ frame_saved_regs[PA_PCOQ_HEAD_REGNUM] = fp; fp += reg_size; -+ frame_saved_regs[PA_PCSQ_HEAD_REGNUM] = fp; fp += reg_size; -+ frame_saved_regs[PA_PCOQ_TAIL_REGNUM] = fp; fp += reg_size; -+ frame_saved_regs[PA_PCSQ_TAIL_REGNUM] = fp; -+} -+ -+/* After returning to a dummy on the stack, restore the instruction -+ queue space registers. */ -+ -+static int -+restore_pc_queue (CORE_ADDR *fsr) -+{ -+ CORE_ADDR pc = read_pc (); -+ CORE_ADDR new_pc = read_memory_integer (fsr[PA_PCOQ_HEAD_REGNUM], -+ REGISTER_SIZE); -+ struct target_waitstatus w; -+ int insn_count; -+ -+ /* HPUX doesn't let us set the space registers or the space -+ registers of the PC queue through ptrace. Boo, hiss. -+ -+ But the call dummy has this sequence of instructions at the break: -+ mtsp r21, sr0 -+ ble,n 0(sr0, r22) -+ nop -+ -+ So, load up the registers and single step until we are in the -+ right place. */ -+ -+ write_register (PA_GR21_REGNUM, -+ read_memory_integer (fsr[PA_PCSQ_HEAD_REGNUM], -+ REGISTER_SIZE)); -+ write_register (PA_GR22_REGNUM, new_pc); -+ -+ for (insn_count = 0; insn_count < 3; insn_count++) -+ { -+ /* FIXME: What if the inferior gets a signal right now? Want to -+ merge this into wait_for_inferior (as a special kind of -+ watchpoint? By setting a breakpoint at the end? Is there -+ any other choice? Is there *any* way to do this stuff with -+ ptrace() or some equivalent?). */ -+ resume (1, 0); -+ target_wait (inferior_ptid, &w); -+ -+ if (w.kind == TARGET_WAITKIND_SIGNALLED) -+ { -+ stop_signal = w.value.sig; -+ terminal_ours_for_output (); -+ printf_unfiltered ("\nProgram terminated with signal %s, %s.\n", -+ target_signal_to_name (stop_signal), -+ target_signal_to_string (stop_signal)); -+ gdb_flush (gdb_stdout); -+ return 0; -+ } -+ } -+ target_terminal_ours (); -+ target_fetch_registers (-1); -+ return 1; -+} -+ -+void -+pa_pop_frame (void) -+{ -+ struct frame_info *frame = get_current_frame (); -+ CORE_ADDR fp, npc, target_pc; -+ int regnum; -+ CORE_ADDR *fsr; -+ char reg_buffer[8]; -+ int reg_size = REGISTER_SIZE; -+ -+ fp = FRAME_FP (frame); -+ fsr = frame->saved_regs; -+ -+#ifndef NO_PC_SPACE_QUEUE_RESTORE -+ if (fsr[PA_IPSW_REGNUM]) /* Restoring a call dummy frame */ -+ restore_pc_queue (fsr); -+#endif -+ -+ for (regnum = PA_GR31_REGNUM; regnum > PA_GR0_REGNUM; regnum--) -+ if (fsr[regnum]) -+ { -+ read_memory (fsr[regnum], reg_buffer, reg_size); -+ write_register_gen (regnum, reg_buffer); -+ } -+ -+ for (regnum = NUM_REGS - 1; regnum >= PA_FR0_REGNUM; regnum--) -+ if (fsr[regnum]) -+ { -+ read_memory (fsr[regnum], reg_buffer, 4); -+ write_register_gen (regnum, reg_buffer); -+ } -+ -+ if (fsr[PA_IPSW_REGNUM]) -+ { -+ read_memory (fsr[PA_IPSW_REGNUM], reg_buffer, reg_size); -+ write_register_gen (PA_IPSW_REGNUM, reg_buffer); -+ } -+ -+ if (fsr[PA_SAR_REGNUM]) -+ { -+ read_memory (fsr[PA_SAR_REGNUM], reg_buffer, reg_size); -+ write_register_gen (PA_SAR_REGNUM, reg_buffer); -+ } -+ -+ /* If the PC was explicitly saved, then just restore it. */ -+ if (fsr[PA_PCOQ_TAIL_REGNUM]) -+ { -+ npc = read_memory_integer (fsr[PA_PCOQ_TAIL_REGNUM], reg_size); -+ write_register (PA_PCOQ_TAIL_REGNUM, npc); -+ npc = read_memory_integer (fsr[PA_PCOQ_HEAD_REGNUM], reg_size); -+ write_register (PA_PCOQ_HEAD_REGNUM, npc); -+ } -+ /* Else use the value in %rp to set the new PC. */ -+ else -+ { -+ npc = read_register (PA_GR2_REGNUM); -+ write_pc (npc); -+ } -+ -+ read_memory (fp, reg_buffer, reg_size); -+ write_register_gen (PA_GR3_REGNUM, reg_buffer); -+ -+ if (fsr[PA_IPSW_REGNUM]) /* call dummy */ -+ write_register (PA_GR30_REGNUM, fp - 48); -+ else -+ write_register (PA_GR30_REGNUM, fp); -+ -+ /* The PC we just restored may be inside a return trampoline. If so -+ we want to restart the inferior and run it through the trampoline. -+ -+ Do this by setting a momentary breakpoint at the location the -+ trampoline returns to. -+ -+ Don't skip through the trampoline if we're popping a dummy frame. */ -+ target_pc = SKIP_TRAMPOLINE_CODE (npc & ~3) & ~3; -+ if (target_pc && !fsr[PA_IPSW_REGNUM]) -+ { -+ struct symtab_and_line sal; -+ struct breakpoint *breakpoint; -+ struct cleanup *old_chain; -+ -+ /* Set up our breakpoint. Set it to be silent as the MI code -+ for "return_command" will print the frame we returned to. */ -+ sal = find_pc_line (target_pc, 0); -+ sal.pc = target_pc; -+ breakpoint = set_momentary_breakpoint (sal, NULL, bp_finish); -+ breakpoint->silent = 1; -+ -+ /* So we can clean things up. */ -+ old_chain = make_cleanup_delete_breakpoint (breakpoint); -+ -+ /* Start up the inferior. */ -+ clear_proceed_status (); -+ proceed_to_finish = 1; -+ proceed ((CORE_ADDR) -1, TARGET_SIGNAL_DEFAULT, 0); -+ -+ /* Perform our cleanups. */ -+ do_cleanups (old_chain); -+ } -+ flush_cached_frames (); -+} -+ -+/* This function pushes a stack frame with arguments as part of the -+ inferior function calling mechanism. -+ -+ This is the version for the PA64, in which later arguments appear -+ at higher addresses. (The stack always grows towards higher -+ addresses.) -+ -+ We simply allocate the appropriate amount of stack space and put -+ arguments into their proper slots. The call dummy code will copy -+ arguments into registers as needed by the ABI. -+ -+ This ABI also requires that the caller provide an argument pointer -+ to the callee, so we do that too. */ -+ -+#define PA64_REGISTER_SIZE 8 -+#define REG_PARM_STACK_SPACE64 (8 * 8) -+ -+CORE_ADDR -+pa64_push_arguments (int nargs, struct value **args, CORE_ADDR sp, int -+ struct_return, CORE_ADDR struct_addr) -+{ -+ /* array of arguments' offsets */ -+ int *offset = (int *) alloca (nargs * sizeof (int)); -+ -+ /* array of arguments' lengths: real lengths in bytes, not aligned to -+ word size */ -+ int *lengths = (int *) alloca (nargs * sizeof (int)); -+ -+ /* The value of SP as it was passed into this function after -+ aligning. */ -+ CORE_ADDR orig_sp = STACK_ALIGN (sp); -+ -+ /* The number of stack bytes occupied by the current argument. */ -+ int bytes_reserved; -+ -+ /* The total number of bytes reserved for the arguments. */ -+ int cum_bytes_reserved = 0; -+ -+ /* Similarly, but aligned. */ -+ int cum_bytes_aligned = 0; -+ int i; -+ -+ /* Iterate over each argument provided by the user. */ -+ for (i = 0; i < nargs; i++) -+ { -+ struct type *arg_type = VALUE_TYPE (args[i]); -+ -+ /* Integral scalar values smaller than a register are padded on -+ the left. We do this by promoting them to full-width, -+ although the ABI says to pad them with garbage. */ -+ if (is_integral_type (arg_type) -+ && TYPE_LENGTH (arg_type) < PA64_REGISTER_SIZE) -+ { -+ args[i] = value_cast ((TYPE_UNSIGNED (arg_type) -+ ? builtin_type_unsigned_long -+ : builtin_type_long), -+ args[i]); -+ arg_type = VALUE_TYPE (args[i]); -+ } -+ -+ lengths[i] = TYPE_LENGTH (arg_type); -+ -+ /* Align the size of the argument to the word size for this -+ target. */ -+ bytes_reserved = ((lengths[i] + PA64_REGISTER_SIZE - 1) -+ & -PA64_REGISTER_SIZE); -+ -+ offset[i] = cum_bytes_reserved; -+ -+ /* Aggregates larger than eight bytes (the only types larger -+ than eight bytes we have) are aligned on a 16-byte boundary, -+ possibly padded on the right with garbage. This may leave an -+ empty word on the stack, and thus an unused register, as per -+ the ABI. */ -+ if (bytes_reserved > 8) -+ { -+ /* Round up the offset to a multiple of two slots. */ -+ int new_offset = ((offset[i] + 2*PA64_REGISTER_SIZE-1) -+ & -(2*PA64_REGISTER_SIZE)); -+ -+ /* Note the space we've wasted, if any. */ -+ bytes_reserved += new_offset - offset[i]; -+ offset[i] = new_offset; -+ } -+ -+ cum_bytes_reserved += bytes_reserved; -+ } -+ -+ /* CUM_BYTES_RESERVED already accounts for all the arguments -+ passed by the user. However, the ABIs mandate minimum stack space -+ allocations for outgoing arguments. -+ -+ The ABIs also mandate minimum stack alignments which we must -+ preserve. */ -+ cum_bytes_aligned = STACK_ALIGN (cum_bytes_reserved); -+ sp += max (cum_bytes_aligned, REG_PARM_STACK_SPACE64); -+ -+ /* Now write each of the args at the proper offset down the stack. */ -+ for (i = 0; i < nargs; i++) -+ write_memory (orig_sp + offset[i], VALUE_CONTENTS (args[i]), lengths[i]); -+ -+ /* For the PA64 we must pass a pointer to the outgoing argument list. -+ The ABI mandates that the pointer should point to the first byte of -+ storage beyond the register flushback area. */ -+ write_register (PA_GR29_REGNUM, orig_sp + REG_PARM_STACK_SPACE64); -+ -+ /* The stack will have 64 bytes of additional space for a frame marker. */ -+ return sp + 64; -+} -+ -+/* This function pushes a stack frame with arguments as part of the -+ inferior function calling mechanism. -+ -+ This is the version of the function for the 32-bit PA machines, in -+ which later arguments appear at lower addresses. (The stack always -+ grows towards higher addresses.) -+ -+ We simply allocate the appropriate amount of stack space and put -+ arguments into their proper slots. The call dummy code will copy -+ arguments into registers as needed by the ABI. */ -+ -+#define PA32_REGISTER_SIZE 4 -+#define REG_PARM_STACK_SPACE32 (4 * 4) -+ -+CORE_ADDR -+pa_push_arguments (int nargs, struct value **args, CORE_ADDR sp, int -+ struct_return, CORE_ADDR struct_addr) -+{ -+ /* array of arguments' offsets */ -+ int *offset = (int *) alloca (nargs * sizeof (int)); -+ -+ /* array of arguments' lengths: real lengths in bytes, not aligned to -+ word size */ -+ int *lengths = (int *) alloca (nargs * sizeof (int)); -+ -+ /* The number of stack bytes occupied by the current argument. */ -+ int bytes_reserved; -+ -+ /* The total number of bytes reserved for the arguments. */ -+ int cum_bytes_reserved = 0; -+ -+ /* Similarly, but aligned. */ -+ int cum_bytes_aligned = 0; -+ int i; -+ -+ /* Iterate over each argument provided by the user. */ -+ for (i = 0; i < nargs; i++) -+ { -+ lengths[i] = TYPE_LENGTH (VALUE_TYPE (args[i])); -+ -+ /* Align the size of the argument to the word size for this -+ target. */ -+ bytes_reserved = ((lengths[i] + PA32_REGISTER_SIZE - 1) -+ & -PA32_REGISTER_SIZE); -+ -+ offset[i] = cum_bytes_reserved + lengths[i]; -+ -+ /* If the argument is a double word argument, then it needs to be -+ double word aligned. */ -+ if ((bytes_reserved == 2 * PA32_REGISTER_SIZE) -+ && (offset[i] % 2 * PA32_REGISTER_SIZE)) -+ { -+ int new_offset = 0; -+ /* BYTES_RESERVED is already aligned to the word, so we put -+ the argument at one word more down the stack. -+ -+ This will leave one empty word on the stack, and one unused -+ register as mandated by the ABI. */ -+ new_offset = ((offset[i] + 2 * PA32_REGISTER_SIZE - 1) -+ & -(2 * PA32_REGISTER_SIZE)); -+ -+ if ((new_offset - offset[i]) >= 2 * PA32_REGISTER_SIZE) -+ { -+ bytes_reserved += PA32_REGISTER_SIZE; -+ offset[i] += PA32_REGISTER_SIZE; -+ } -+ } -+ -+ cum_bytes_reserved += bytes_reserved; -+ } -+ -+ /* CUM_BYTES_RESERVED already accounts for all the arguments passed -+ by the user. However, the ABI mandates minimum stack space -+ allocations for outgoing arguments. -+ -+ The ABI also mandates minimum stack alignments which we must -+ preserve. */ -+ cum_bytes_aligned = STACK_ALIGN (cum_bytes_reserved); -+ sp += max (cum_bytes_aligned, REG_PARM_STACK_SPACE32); -+ -+ /* Now write each of the args at the proper offset down the stack. -+ ?!? We need to promote values to a full register instead of skipping -+ words in the stack. */ -+ for (i = 0; i < nargs; i++) -+ write_memory (sp - offset[i], VALUE_CONTENTS (args[i]), lengths[i]); -+ -+ /* The stack will have 32 bytes of additional space for a frame marker. */ -+ return sp + 32; -+} -+ -+/* We don't need to push the return address as we use a call dummy. */ -+CORE_ADDR -+pa_push_return_address (CORE_ADDR pc, CORE_ADDR sp) -+{ -+ return sp; -+} -+ -+/* elz: This function returns a value which is built looking at the given -+ address. It is called from call_function_by_hand, in case we need to -+ return a value which is larger than 64 bits, and it is stored in the -+ stack rather than in the registers r28 and r29 or fr4. This function -+ does the same stuff as value_being_returned in values.c, but gets the -+ value from the stack rather than from the buffer where all the registers -+ were saved when the function called completed. */ -+struct value * -+pa_value_returned_from_stack (struct type *valtype, CORE_ADDR addr) -+{ -+ struct value *val; -+ -+ val = allocate_value (valtype); -+ CHECK_TYPEDEF (valtype); -+ target_read_memory (addr, VALUE_CONTENTS_RAW (val), TYPE_LENGTH (valtype)); -+ -+ return val; -+} -+ -+/* Store the address of the place in which to copy the structure the -+ subroutine will return. This is called from call_function. */ -+ -+static void -+pa_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) -+{ -+ write_register (PA_GR28_REGNUM, addr); -+} -+ -+/* Write into appropriate registers a function return value -+ of type TYPE, given in virtual format. -+ -+ For software floating point the return value goes into the integer -+ registers. But we don't have any flag to key this on, so we always -+ store the value into the integer registers, and if it's a float value, -+ then we put it in the float registers too. */ -+ -+static void -+pa_store_return_value (struct type *type, char *valbuf) -+{ -+ write_register_bytes (REGISTER_BYTE (PA_GR28_REGNUM), -+ valbuf, TYPE_LENGTH (type)); -+ if (!SOFT_FLOAT) -+ write_register_bytes ((TYPE_CODE (type) == TYPE_CODE_FLT -+ ? REGISTER_BYTE (PA_FR4_REGNUM) -+ : REGISTER_BYTE (PA_GR28_REGNUM)), -+ valbuf, TYPE_LENGTH (type)); -+} -+ -+/* Extract from an array REGBUF containing the (raw) register state -+ the address in which a function should return its structure value, -+ as a CORE_ADDR. */ -+ -+static CORE_ADDR -+pa_extract_struct_value_address (char *regbuf) -+{ -+ return extract_unsigned_integer (regbuf + REGISTER_BYTE (PA_GR28_REGNUM), -+ REGISTER_RAW_SIZE (PA_GR28_REGNUM)); -+} -+ -+ /* Decide whether the function returning a value of type VALUE_TYPE -+ will put it on the stack or in the registers. */ -+static int -+pa_use_struct_convention (int gcc_p, struct type *value_type) -+{ -+ return TYPE_LENGTH (value_type) > 2 * REGISTER_SIZE; -+} -+ -+/* Determines the address of all registers in the current stack frame -+ storing each in frame->saved_regs. This includes special registers -+ such as pc and fp saved in special ways in the stack frame. sp is -+ even more special: the address we return for it IS the sp for the -+ next frame. */ -+ -+static void -+pa_frame_init_saved_regs (struct frame_info *frame_info) -+{ -+ CORE_ADDR pc; -+ struct unwind_table_entry *u; -+ unsigned long inst, stack_remaining, save_gr, save_fr, save_rp, save_sp; -+ int status, i, reg; -+ char buf[4]; -+ int fp_loc = -1; -+ int final_iteration; -+ -+ if (DEBUG_PA_FRAME) -+ printf ("frame_init_saved_regs (%p), pc = %#lx : ", -+ frame_info, frame_info->pc); -+ -+ if (frame_info->saved_regs) -+ { -+ if (DEBUG_PA_FRAME) -+ printf ("already done\n"); -+ return; -+ } -+ -+ frame_saved_regs_zalloc (frame_info); -+ -+ /* Interrupt handlers are special. */ -+ if (PA_IN_INTERRUPT_HANDLER (frame_info->pc)) -+ { -+ if (DEBUG_PA_FRAME) -+ printf ("in interrupt\n"); -+ gdbarch_tdep (current_gdbarch)->frame_find_saved_regs_in_interrupt -+ (frame_info, frame_info->saved_regs); -+ return; -+ } -+ -+ /* So are signal handler callers. */ -+ if (frame_info->signal_handler_caller -+ && gdbarch_tdep (current_gdbarch)->frame_find_saved_regs_in_sigtramp) -+ { -+ if (DEBUG_PA_FRAME) -+ printf ("in sigtramp\n"); -+ gdbarch_tdep (current_gdbarch)->frame_find_saved_regs_in_sigtramp -+ (frame_info, frame_info->saved_regs); -+ return; -+ } -+ -+ /* Call dummy frames always look the same, so there's no need to -+ examine the dummy code to determine locations of saved registers; -+ instead, let find_dummy_frame_regs fill in the correct offsets -+ for the saved registers. */ -+ if (frame_info->pc >= frame_info->frame -+ && frame_info->pc <= (frame_info->frame -+ + CALL_DUMMY_LENGTH -+ /* Account for register saves. */ -+ + ((32 + 6) * REGISTER_SIZE) -+ + (NUM_REGS - PA_FR0_REGNUM) * 4)) -+ { -+ if (DEBUG_PA_FRAME) -+ printf ("in dummy\n"); -+ find_dummy_frame_regs (frame_info, frame_info->saved_regs); -+ return; -+ } -+ -+ if (DEBUG_PA_FRAME) -+ printf ("grok prologue\n"); -+ -+ /* Get the starting address of the function referred to by the PC -+ saved in frame. */ -+ pc = get_pc_function_start (frame_info->pc); -+ -+ /* Now rummage through the function machine instructions to find out -+ where registers are saved. */ -+ pa_grok_prologue (pc, frame_info); -+} -+ -+static void -+pa_print_fp_reg (int i) -+{ -+ char buf[8]; -+ -+ /* Get 32bits of data. */ -+ frame_register_read (selected_frame, i, buf); -+ -+ printf_filtered ("%-8s(single precision) ", REGISTER_NAME (i)); -+ val_print (REGISTER_VIRTUAL_TYPE (i), buf, 0, 0, gdb_stdout, 0, -+ 1, 0, Val_pretty_default); -+ printf_filtered ("\n"); -+ -+ /* If "i" is even, then this register can also be a double-precision -+ FP register. Dump it out as such. */ -+ if ((i % 2) == 0) -+ { -+ /* Get the data in raw format for the 2nd half. */ -+ frame_register_read (selected_frame, i + 1, buf + 4); -+ -+ /* Dump it as a double. */ -+ printf_filtered ("%-8s(double precision) ", REGISTER_NAME (i)); -+ val_print (builtin_type_double, buf, 0, 0, gdb_stdout, 0, -+ 1, 0, Val_pretty_default); -+ printf_filtered ("\n"); -+ } -+} -+ -+/* "Info all-reg" command */ -+ -+static void -+pa_print_registers (int fpregs) -+{ -+ int i, j; -+ int columns = 2; -+ int rows = PA_FR4_REGNUM / columns; -+ -+ for (i = 0; i < rows; i++) -+ { -+ for (j = 0; j < columns; j++) -+ { -+ /* We display registers in column-major order. */ -+ int regnum = i + j * rows; -+ char buf[8]; -+ ULONGEST reg_val; -+ -+ frame_register_read (selected_frame, regnum, buf); -+ reg_val = extract_unsigned_integer (buf, -+ REGISTER_RAW_SIZE (regnum)); -+ -+ /* Even fancier % formats to prevent leading zeros -+ and still maintain the output in columns. */ -+ -+ printf_unfiltered ("%10s: %-19s", REGISTER_NAME (regnum), -+ phex_nz (reg_val, sizeof (ULONGEST))); -+ } -+ printf_unfiltered ("\n"); -+ } -+ -+ if (fpregs) -+ for (i = PA_FR4_REGNUM; i < NUM_REGS; i++) -+ pa_print_fp_reg (i); -+} -+ -+/* Print the register regnum, or all registers if regnum is -1 */ -+ -+static void -+pa_do_registers_info (int regnum, int fpregs) -+{ -+ if (regnum == -1) -+ pa_print_registers (fpregs); -+ else if (regnum < PA_FR4_REGNUM) -+ { -+ char buf[sizeof (ULONGEST)]; -+ ULONGEST reg_val; -+ -+ frame_register_read (selected_frame, regnum, buf); -+ reg_val = extract_unsigned_integer (buf, -+ REGISTER_RAW_SIZE (regnum)); -+ -+ printf_unfiltered ("%s %s\n", REGISTER_NAME (regnum), -+ phex_nz (reg_val, sizeof (ULONGEST))); -+ } -+ else -+ /* Note that real floating point values only start at -+ PA_FR4_REGNUM. FP0 and up are just status and error -+ registers, which have integral (bit) values. */ -+ pa_print_fp_reg (regnum); -+} -+ -+/* Finds the addresses of the dynamic call routines for this object -+ file. If PC isn't in any of the object files, return NULL. */ -+ -+static obj_private_data_t * -+pa_find_dyn (CORE_ADDR pc) -+{ -+ struct obj_section *pc_sec; -+ struct objfile *pc_obj; -+ obj_private_data_t *obj_private; -+ CORE_ADDR *addr; -+ static const char *syms[] = { -+ "_sr4export", "$$dyncall", "$$dyncall_external" -+ }; -+ const char **sym; -+ -+ pc_sec = find_pc_section (pc); -+ if (!pc_sec) -+ return NULL; -+ -+ pc_obj = pc_sec->objfile; -+ obj_private = (obj_private_data_t *) pc_obj->obj_private; -+ if (obj_private == NULL) -+ obj_private = pa_obj_private_alloc (pc_obj); -+ -+ for (addr = obj_private->dyn, sym = syms; -+ sym < syms + sizeof (syms) / sizeof (syms[0]); -+ addr++, sym++) -+ { -+ if (*addr == 0) -+ { -+ struct minimal_symbol *minsym; -+ CORE_ADDR val; -+ -+ /* First look in this object file, but if we didn't find it, -+ look globally. */ -+ minsym = lookup_minimal_symbol (*sym, NULL, pc_obj); -+ if (!minsym) -+ minsym = lookup_minimal_symbol (*sym, NULL, NULL); -+ if (minsym) -+ val = SYMBOL_VALUE_ADDRESS (minsym); -+ else -+ val = -1; -+ *addr = val; -+ } -+ } -+ return obj_private; -+} -+ -+/* Return one if PC is in the call path of a trampoline, else return zero. -+ -+ Note we return one for *any* call trampoline (long-call, arg-reloc), not -+ just shared library trampolines (import, export). */ -+ -+int -+pa_in_solib_call_trampoline (CORE_ADDR pc, char *name) -+{ -+ obj_private_data_t *obj_private; -+ struct minimal_symbol *minsym; -+ struct unwind_table_entry *u; -+ -+ if (DEBUG_PA_GROK) -+ printf ("in_solib_call_tramp (%#lx, %s)\n", pc, name); -+ -+ if (gdbarch_tdep (current_gdbarch)->is_elf) -+ { -+ /* PA64 has a completely different stub/trampoline scheme. Is -+ it better? Maybe. It's certainly harder to determine with -+ any certainty that we are in a stub because we can not refer -+ to the unwinders to help. -+ -+ The heuristic is simple. Try to lookup the current PC value -+ in the minimal symbol table. If that fails, then assume we -+ are not in a stub and return. -+ -+ Then see if the PC value falls within the section bounds for -+ the section containing the minimal symbol we found in the -+ first step. If it does, then assume we are not in a stub and -+ return. -+ -+ Finally peek at the instructions to see if they look like a -+ stub. */ -+#if 0 -+ /* I think this is bogus. Stub sections get merged into the -+ .text section, so the sec->vma test will not differentiate -+ between stub/non-stub code. ADM */ -+ asection *sec; -+ -+ minsym = lookup_minimal_symbol_by_pc (pc); -+ if (! minsym) -+ return 0; -+ -+ sec = SYMBOL_BFD_SECTION (minsym); -+ -+ if (sec->vma <= pc -+ && sec->vma + sec->_cooked_size < pc) -+ return 0; -+#endif -+ -+ /* Are we in the plt stub that supports lazy dynamic linking? */ -+ if (in_plt_section (pc, name)) -+ { -+ if (DEBUG_PA_GROK) -+ printf (" was in plt\n"); -+ return 1; -+ } -+ -+ /* We might be in a stub. */ -+ if (pc_in_linker_stub (pc, NULL) != pa_stub_none) -+ { -+ if (DEBUG_PA_GROK) -+ printf (" was in stub\n"); -+ return 1; -+ } -+ } -+ -+ obj_private = pa_find_dyn (pc); -+ -+ if (obj_private != NULL -+ && (pc == obj_private->dyn[dyncall] -+ || pc == obj_private->dyn[sr4export])) -+ { -+ if (DEBUG_PA_GROK) -+ printf (" was dyn_call\n"); -+ return 1; -+ } -+ -+ minsym = lookup_minimal_symbol_by_pc (pc); -+ if (minsym) -+ { -+ CORE_ADDR addr = SYMBOL_VALUE_ADDRESS (minsym); -+ if (obj_private != NULL -+ && (addr == obj_private->dyn[dyncall] -+ || addr == obj_private->dyn[sr4export])) -+ { -+ if (DEBUG_PA_GROK) -+ printf (" was in dyn_call\n"); -+ return 1; -+ } -+ -+ if (strcmp (SYMBOL_NAME (minsym), ".stub") == 0) -+ { -+ if (DEBUG_PA_GROK) -+ printf (" was stub sym\n"); -+ return 1; -+ } -+ } -+ -+ if (gdbarch_tdep (current_gdbarch)->is_elf) -+ { -+ if (DEBUG_PA_GROK) -+ printf (" nup\n"); -+ return 0; -+ } -+ -+ /* Get the unwind descriptor corresponding to PC, return zero -+ if no unwind was found. */ -+ u = find_unwind_entry (pc); -+ if (!u) -+ return 0; -+ -+ /* If this isn't a linker stub, then return now. */ -+ if (u->stub_unwind.stub_type == 0) -+ return 0; -+ -+ /* By definition a long-branch stub is a call stub. */ -+ if (u->stub_unwind.stub_type == LONG_BRANCH) -+ return 1; -+ -+ /* The call and return path execute the same instructions within -+ an IMPORT stub! So an IMPORT stub is both a call and return -+ trampoline. */ -+ if (u->stub_unwind.stub_type == IMPORT) -+ return 1; -+ -+ /* Parameter relocation stubs always have a call path and may have a -+ return path. */ -+ if (u->stub_unwind.stub_type == PARAMETER_RELOCATION -+ || u->stub_unwind.stub_type == EXPORT) -+ { -+ CORE_ADDR addr; -+ -+ /* Search forward from the current PC until we hit a branch -+ or the end of the stub. */ -+ for (addr = pc; addr <= u->region_end; addr += 4) -+ { -+ unsigned long insn; -+ -+ insn = read_memory_integer (addr, 4); -+ -+ /* Does it look like a bl? If so then it's the call path, if -+ we find a bv or be first, then we're on the return path. */ -+ if ((insn & 0xfc00e000) == 0xe8000000) -+ return 1; -+ else if ((insn & 0xfc00e001) == 0xe800c000 -+ || (insn & 0xfc000000) == 0xe0000000) -+ return 0; -+ } -+ -+ /* Should never happen. */ -+ warning ("Unable to find branch in parameter relocation stub.\n"); -+ return 0; -+ } -+ -+ /* Unknown stub type. For now, just return zero. */ -+ return 0; -+} -+ -+/* Return one if PC is in the return path of a trampoline, else return zero. -+ -+ Note we return one for *any* call trampoline (long-call, arg-reloc), not -+ just shared library trampolines (import, export). */ -+ -+int -+pa_in_solib_return_trampoline (CORE_ADDR pc, char *name) -+{ -+ struct unwind_table_entry *u; -+ -+ /* Get the unwind descriptor corresponding to PC, return zero -+ if no unwind was found. */ -+ u = find_unwind_entry (pc); -+ if (!u) -+ { -+ return 0; -+ } -+ -+ /* If this isn't a linker stub or it's just a long branch stub, then -+ return zero. */ -+ if (u->stub_unwind.stub_type == 0 || u->stub_unwind.stub_type == LONG_BRANCH) -+ return 0; -+ -+ /* The call and return path execute the same instructions within -+ an IMPORT stub! So an IMPORT stub is both a call and return -+ trampoline. */ -+ if (u->stub_unwind.stub_type == IMPORT) -+ return 1; -+ -+ /* Parameter relocation stubs always have a call path and may have a -+ return path. */ -+ if (u->stub_unwind.stub_type == PARAMETER_RELOCATION -+ || u->stub_unwind.stub_type == EXPORT) -+ { -+ CORE_ADDR addr; -+ -+ /* Search forward from the current PC until we hit a branch -+ or the end of the stub. */ -+ for (addr = pc; addr <= u->region_end; addr += 4) -+ { -+ unsigned long insn; -+ -+ insn = read_memory_integer (addr, 4); -+ -+ /* Does it look like a bl? If so then it's the call path, if -+ we find a bv or be first, then we're on the return path. */ -+ if ((insn & 0xfc00e000) == 0xe8000000) -+ return 0; -+ else if ((insn & 0xfc00e001) == 0xe800c000 -+ || (insn & 0xfc000000) == 0xe0000000) -+ return 1; -+ } -+ -+ /* Should never happen. */ -+ warning ("Unable to find branch in parameter relocation stub.\n"); -+ return 0; -+ } -+ -+ /* Unknown stub type. For now, just return zero. */ -+ return 0; -+} -+ -+/* Figure out if PC is in a trampoline, and if so find out where -+ the trampoline will jump to. If not in a trampoline, return zero. -+ -+ Simple code examination probably is not a good idea since the code -+ sequences in trampolines can also appear in user code. -+ -+ We use unwinds and information from the minimal symbol table to -+ determine when we're in a trampoline. This won't work for ELF -+ (yet) since it doesn't create stub unwind entries. Whether or -+ not ELF will create stub unwinds or normal unwinds for linker -+ stubs is still being debated. -+ -+ This should handle simple calls through dyncall or sr4export, -+ long calls, argument relocation stubs, and dyncall/sr4export -+ calling an argument relocation stub. It even handles some stubs -+ used in dynamic executables. */ -+ -+CORE_ADDR -+pa_skip_trampoline_code (CORE_ADDR pc, char *name) -+{ -+ obj_private_data_t *obj_private; -+ CORE_ADDR orig_pc = pc; -+ int prev_inst, curr_inst; -+ CORE_ADDR loc; -+ struct minimal_symbol *msym; -+ struct unwind_table_entry *u; -+ -+ if (DEBUG_PA_GROK) -+ printf ("skip_trampoline (%#lx, %s)\n", pc, name); -+ -+ obj_private = pa_find_dyn (pc); -+ -+ /* Addresses passed to dyncall may *NOT* be the actual address -+ of the function. So we may have to do something special. */ -+ if (obj_private != NULL) -+ { -+ if (pc == obj_private->dyn[dyncall]) -+ { -+ pc = (CORE_ADDR) read_register (PA_GR22_REGNUM); -+ -+ /* If bit 30 (counting from the left) is on, then pc is the -+ address of the PLT entry for this function, not the -+ address of the function itself. Bit 31 has meaning too, -+ but only for MPE. */ -+ if (pc & 0x2) -+ pc = (CORE_ADDR) read_memory_integer (pc & ~3, REGISTER_SIZE); -+ } -+ else if (pc == obj_private->dyn[dyncall_external]) -+ { -+ pc = (CORE_ADDR) read_register (PA_GR22_REGNUM); -+ pc = (CORE_ADDR) read_memory_integer (pc & ~3, REGISTER_SIZE); -+ } -+ else if (pc == obj_private->dyn[sr4export]) -+ { -+ pc = (CORE_ADDR) (read_register (PA_GR22_REGNUM)); -+ } -+ } -+ -+ /* Get the unwind descriptor corresponding to PC, return zero -+ if no unwind was found. */ -+ u = find_unwind_entry (pc); -+ if (!u) -+ { -+ CORE_ADDR stub_start, addr = 0; -+ enum stub_type stubt = pc_in_linker_stub (pc, &stub_start); -+ -+ switch (stubt) -+ { -+ default: -+ break; -+ -+ case pa_stub_long_branch_shared: -+ addr = stub_start + 8; -+ stub_start += 4; -+ /* Fall thru */ -+ -+ case pa_stub_long_branch: -+ addr += extract_21 (read_memory_integer (stub_start, 4)); -+ addr += extract_17 (read_memory_integer (stub_start + 4, 4)); -+ break; -+ -+ case pa_stub_import: -+ case pa_stub_import_multi: -+ addr = read_register (PA_GR27_REGNUM); -+ goto handle_stub_import; -+ -+ case pa_stub_import_shared: -+ case pa_stub_import_multi_shared: -+ addr = read_register (PA_GR19_REGNUM); -+ handle_stub_import: -+ addr += extract_21 (read_memory_integer (stub_start, 4)); -+ addr += extract_14 (read_memory_integer (stub_start + 4, 4)); -+ addr = read_memory_integer (addr, 4); -+ if (pc_in_linker_stub (addr, &stub_start) != pa_stub_lazy_link) -+ break; -+ /* Fall thru */ -+ -+ case pa_stub_lazy_link: -+ addr = read_memory_integer (stub_start + 20, 4); -+ break; -+ -+ case pa_stub_export: -+ addr = stub_start + 8; -+ if (pc < addr) -+ addr += extract_17 (read_memory_integer (stub_start, 4)); -+ else -+ addr = read_memory_integer (read_register (PA_GR30_REGNUM) - 24, 4); -+ break; -+ -+ case pa64_stub_import: -+ addr = read_register (PA_GR27_REGNUM); -+ addr += extract_16a (read_memory_integer (stub_start, 4)); -+ addr = read_memory_integer (addr, 8); -+ break; -+ } -+ -+ if (DEBUG_PA_GROK) -+ printf (" type = %d, returning %#lx\n", stubt, addr & ~3); -+ -+ return addr & ~3; -+ } -+ -+ /* If this isn't a linker stub, then return now. */ -+ /* elz: attention here! (FIXME) because of a compiler/linker -+ error, some stubs which should have a non zero stub_unwind.stub_type -+ have unfortunately a value of zero. So this function would return here -+ as if we were not in a trampoline. To fix this, we go look at the partial -+ symbol information, which reports this guy as a stub. -+ (FIXME): Unfortunately, we are not that lucky: it turns out that the -+ partial symbol information is also wrong sometimes. This is because -+ when it is entered (somread.c::som_symtab_read()) it can happen that -+ if the type of the symbol (from the som) is Entry, and the symbol is -+ in a shared library, then it can also be a trampoline. This would -+ be OK, except that I believe the way they decide if we are ina shared library -+ does not work. SOOOO..., even if we have a regular function w/o trampolines -+ its minimal symbol can be assigned type mst_solib_trampoline. -+ Also, if we find that the symbol is a real stub, then we fix the unwind -+ descriptor, and define the stub type to be EXPORT. -+ Hopefully this is correct most of the times. */ -+ if (u->stub_unwind.stub_type == 0) -+ { -+ -+/* elz: NOTE (FIXME!) once the problem with the unwind information is fixed -+ we can delete all the code which appears between the lines */ -+/*--------------------------------------------------------------------------*/ -+ msym = lookup_minimal_symbol_by_pc (pc); -+ -+ if (msym == NULL || MSYMBOL_TYPE (msym) != mst_solib_trampoline) -+ return orig_pc == pc ? 0 : pc & ~3; -+ -+ else if (msym != NULL && MSYMBOL_TYPE (msym) == mst_solib_trampoline) -+ { -+ struct objfile *objfile; -+ struct minimal_symbol *msymbol; -+ int function_found = 0; -+ -+ /* go look if there is another minimal symbol with the same name as -+ this one, but with type mst_text. This would happen if the msym -+ is an actual trampoline, in which case there would be another -+ symbol with the same name corresponding to the real function */ -+ -+ ALL_MSYMBOLS (objfile, msymbol) -+ { -+ if (MSYMBOL_TYPE (msymbol) == mst_text -+ && STREQ (SYMBOL_NAME (msymbol), SYMBOL_NAME (msym))) -+ { -+ function_found = 1; -+ break; -+ } -+ } -+ -+ if (function_found) -+ /* the type of msym is correct (mst_solib_trampoline), but -+ the unwind info is wrong, so set it to the correct value */ -+ u->stub_unwind.stub_type = EXPORT; -+ else -+ /* the stub type info in the unwind is correct (this is not a -+ trampoline), but the msym type information is wrong, it -+ should be mst_text. So we need to fix the msym, and also -+ get out of this function */ -+ { -+ MSYMBOL_TYPE (msym) = mst_text; -+ return orig_pc == pc ? 0 : pc & ~3; -+ } -+ } -+ -+/*--------------------------------------------------------------------------*/ -+ } -+ -+ /* It's a stub. Search for a branch and figure out where it goes. -+ Note we have to handle multi insn branch sequences like ldil;ble. -+ Most (all?) other branches can be determined by examining the contents -+ of certain registers and the stack. */ -+ -+ loc = pc; -+ curr_inst = 0; -+ prev_inst = 0; -+ while (1) -+ { -+ /* Make sure we haven't walked outside the range of this stub. */ -+ if (u != find_unwind_entry (loc)) -+ { -+ warning ("Unable to find branch in linker stub"); -+ return orig_pc == pc ? 0 : pc & ~3; -+ } -+ -+ prev_inst = curr_inst; -+ curr_inst = read_memory_integer (loc, 4); -+ -+ /* Does it look like a branch external using %r1? Then it's the -+ branch from the stub to the actual function. */ -+ if ((curr_inst & 0xffe0e000) == 0xe0202000) -+ { -+ /* Yup. See if the previous instruction loaded -+ a value into %r1. If so compute and return the jump address. */ -+ if ((prev_inst & 0xffe00000) == 0x20200000) -+ return (extract_21 (prev_inst) + extract_17 (curr_inst)) & ~3; -+ else -+ { -+ warning ("Unable to find ldil X,%%r1 before ble Y(%%sr4,%%r1)."); -+ return orig_pc == pc ? 0 : pc & ~3; -+ } -+ } -+ -+ /* Does it look like a be 0(sr0,%r21)? OR -+ Does it look like a be, n 0(sr0,%r21)? OR -+ Does it look like a bve (r21)? (this is on PA2.0) -+ Does it look like a bve, n(r21)? (this is also on PA2.0) -+ That's the branch from an -+ import stub to an export stub. -+ -+ It is impossible to determine the target of the branch via -+ simple examination of instructions and/or data (consider -+ that the address in the plabel may be the address of the -+ bind-on-reference routine in the dynamic loader). -+ -+ So we have try an alternative approach. -+ -+ Get the name of the symbol at our current location; it should -+ be a stub symbol with the same name as the symbol in the -+ shared library. -+ -+ Then lookup a minimal symbol with the same name; we should -+ get the minimal symbol for the target routine in the shared -+ library as those take precedence of import/export stubs. */ -+ if ((curr_inst == 0xe2a00000) || -+ (curr_inst == 0xe2a00002) || -+ (curr_inst == 0xeaa0d000) || -+ (curr_inst == 0xeaa0d002)) -+ { -+ struct minimal_symbol *stubsym, *libsym; -+ -+ stubsym = lookup_minimal_symbol_by_pc (loc); -+ if (stubsym == NULL) -+ { -+ warning ("Unable to find symbol for 0x%lx", (long) loc); -+ return orig_pc == pc ? 0 : pc & ~3; -+ } -+ -+ libsym = lookup_minimal_symbol (SYMBOL_NAME (stubsym), NULL, NULL); -+ if (libsym == NULL) -+ { -+ warning ("Unable to find library symbol for %s\n", -+ SYMBOL_NAME (stubsym)); -+ return orig_pc == pc ? 0 : pc & ~3; -+ } -+ -+ return SYMBOL_VALUE (libsym); -+ } -+ -+ /* Does it look like bl X,%rp or bl X,%r0? Another way to do a -+ branch from the stub to the actual function. */ -+ /*elz */ -+ else if ((curr_inst & 0xffe0e000) == 0xe8400000 -+ || (curr_inst & 0xffe0e000) == 0xe8000000 -+ || (curr_inst & 0xffe0e000) == 0xe800A000) -+ return (loc + extract_17 (curr_inst) + 8) & ~3; -+ -+ /* Does it look like bv (rp)? Note this depends on the -+ current stack pointer being the same as the stack -+ pointer in the stub itself! This is a branch on from the -+ stub back to the original caller. */ -+ /*else if ((curr_inst & 0xffe0e000) == 0xe840c000) */ -+ else if ((curr_inst & 0xffe0f000) == 0xe840c000) -+ { -+ /* Yup. See if the previous instruction loaded -+ rp from sp - 8. */ -+ if (prev_inst == 0x4bc23ff1) -+ return (read_memory_integer -+ (read_register (PA_GR30_REGNUM) - 8, 4)) & ~3; -+ else -+ { -+ warning ("Unable to find restore of %%rp before bv (%%rp)."); -+ return orig_pc == pc ? 0 : pc & ~3; -+ } -+ } -+ -+ /* elz: added this case to capture the new instruction -+ at the end of the return part of an export stub used by -+ the PA2.0: BVE, n (rp) */ -+ else if ((curr_inst & 0xffe0f000) == 0xe840d000) -+ { -+ return (read_memory_integer -+ (read_register (PA_GR30_REGNUM) - 24, REGISTER_SIZE)) & ~3; -+ } -+ -+ /* What about be,n 0(sr0,%rp)? It's just another way we return to -+ the original caller from the stub. Used in dynamic executables. */ -+ else if (curr_inst == 0xe0400002) -+ { -+ /* The value we jump to is sitting in sp - 24. But that's -+ loaded several instructions before the be instruction. -+ I guess we could check for the previous instruction being -+ mtsp %r1,%sr0 if we want to do sanity checking. */ -+ return (read_memory_integer -+ (read_register (PA_GR30_REGNUM) - 24, REGISTER_SIZE)) & ~3; -+ } -+ -+ /* Haven't found the branch yet, but we're still in the stub. -+ Keep looking. */ -+ loc += 4; -+ } -+} -+ -+/* Return the address of the PC after the last prologue instruction if -+ we can determine it from the debug symbols. Else return zero. */ -+ -+static CORE_ADDR -+after_prologue (CORE_ADDR pc) -+{ -+ struct symtab_and_line sal; -+ CORE_ADDR func_addr, func_end; -+ struct symbol *f; -+ asection *sect; -+ -+ if (DEBUG_PA_GROK) -+ printf ("after_prologue (%#lx)\n", pc); -+ -+ sect = find_pc_overlay (pc); -+ -+ /* If we can not find the symbol in the partial symbol table, then -+ there is no hope we can determine the function's start address -+ with this code. */ -+ if (!find_pc_sect_partial_function (pc, sect, NULL, &func_addr, &func_end)) -+ return 0; -+ -+ if (DEBUG_PA_GROK) -+ printf (" func_addr = %#lx, func_end = %#lx\n", func_addr, func_end); -+ -+ /* Get the line associated with FUNC_ADDR. */ -+ sal = find_pc_sect_line (func_addr, sect, 0); -+ -+ /* There are only two cases to consider. First, the end of the source line -+ is within the function bounds. In that case we return the end of the -+ source line. Second is the end of the source line extends beyond the -+ bounds of the current function. We need to use the slow code to -+ examine instructions in that case. -+ -+ Anything else is simply a bug elsewhere. Fixing it here is absolutely -+ the wrong thing to do. In fact, it should be entirely possible for this -+ function to always return zero since the slow instruction scanning code -+ is supposed to *always* work. If it does not, then it is a bug. */ -+ if (sal.end > func_addr && sal.end < func_end) -+ return sal.end; -+ return 0; -+} -+ -+/* Advance PC across any function entry prologue instructions -+ to reach some "real" code. -+ Returns either PC itself if the code at PC does not look like a -+ function prologue; otherwise returns an address that (if we're -+ lucky) follows the prologue. */ -+ -+static CORE_ADDR -+pa_skip_prologue (CORE_ADDR pc) -+{ -+ CORE_ADDR post_prologue_pc; -+ -+ if (DEBUG_PA_GROK) -+ printf ("skip_prologue (%#lx)\n", pc); -+ -+ /* See if we can determine the end of the prologue via the symbol table. -+ If so, then return either PC, or the PC after the prologue, whichever -+ is greater. */ -+ -+ post_prologue_pc = after_prologue (pc); -+ -+ if (DEBUG_PA_GROK > 1) -+ printf (" post_prologue_pc = %#lx\n", post_prologue_pc); -+ -+ /* If after_prologue returned a useful address, then use it. Else -+ fall back on the instruction skipping code. -+ -+ Some folks have claimed this causes problems because the breakpoint -+ may be the first instruction of the prologue. If that happens, then -+ the instruction skipping code has a bug that needs to be fixed. */ -+ if (post_prologue_pc != 0) -+ return pc >= post_prologue_pc ? pc : post_prologue_pc; -+ -+ return pa_grok_prologue (pc, NULL); -+} -+ -+/* Sequence of bytes for breakpoint instruction. */ -+static const unsigned char * -+pa_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr) -+{ -+ static const unsigned char breakpoint[4] = {0x00, 0x01, 0x00, 0x04}; -+ *lenptr = sizeof (breakpoint); -+ return breakpoint; -+} -+ -+static void -+pa_remote_translate_xfer_address (CORE_ADDR memaddr, int nr_bytes, -+ CORE_ADDR *targ_addr, int *targ_len) -+{ -+ *targ_addr = memaddr; -+ *targ_len = nr_bytes; -+} -+ -+void -+pa_skip_permanent_breakpoint (void) -+{ -+ /* To step over a breakpoint instruction on the PA takes some -+ fiddling with the instruction address queue. -+ -+ When we stop at a breakpoint, the IA queue front (the instruction -+ we're executing now) points at the breakpoint instruction, and -+ the IA queue back (the next instruction to execute) points to -+ whatever instruction we would execute after the breakpoint, if it -+ were an ordinary instruction. This is the case even if the -+ breakpoint is in the delay slot of a branch instruction. -+ -+ Clearly, to step past the breakpoint, we need to set the queue -+ front to the back. But what do we put in the back? What -+ instruction comes after that one? Because of the branch delay -+ slot, the next insn is always at the back + 4. */ -+ int tail; -+ -+ tail = read_register (PA_PCOQ_TAIL_REGNUM); -+ write_register (PA_PCOQ_HEAD_REGNUM, tail); -+ write_register (PA_PCSQ_HEAD_REGNUM, read_register (PA_PCSQ_TAIL_REGNUM)); -+ -+ write_register (PA_PCOQ_TAIL_REGNUM, tail + 4); -+ /* We can leave the tail's space the same, since there's no jump. */ -+} -+ -+static void -+unwind_command (char *exp, int from_tty) -+{ -+ CORE_ADDR address; -+ struct unwind_table_entry *u; -+ -+ /* If we have an expression, evaluate it and use it as the address. */ -+ -+ if (exp != 0 && *exp != 0) -+ address = parse_and_eval_address (exp); -+ else -+ return; -+ -+ u = find_unwind_entry (address); -+ -+ if (!u) -+ { -+ printf_unfiltered ("Can't find unwind table entry for %s\n", exp); -+ return; -+ } -+ -+ printf_unfiltered ("unwind_table_entry (%p):\n", u); -+ -+ printf_unfiltered ("\tregion_start = "); -+ print_address (u->region_start, gdb_stdout); -+ -+ printf_unfiltered ("\n\tregion_end = "); -+ print_address (u->region_end, gdb_stdout); -+ -+#ifdef __STDC__ -+#define pif(FLD) if (u->FLD) printf_unfiltered (" "#FLD); -+#else -+#define pif(FLD) if (u->FLD) printf_unfiltered (" FLD"); -+#endif -+ -+ printf_unfiltered ("\n\tflags ="); -+ pif (Cannot_unwind); -+ pif (Millicode); -+ pif (Millicode_save_sr0); -+ pif (Entry_SR); -+ pif (Args_stored); -+ pif (Variable_Frame); -+ pif (Separate_Package_Body); -+ pif (Frame_Extension_Millicode); -+ pif (Stack_Overflow_Check); -+ pif (Two_Instruction_SP_Increment); -+ pif (Ada_Region); -+ pif (Save_SP); -+ pif (Save_RP); -+ pif (Save_MRP_in_frame); -+ pif (extn_ptr_defined); -+ pif (Cleanup_defined); -+ pif (MPE_XL_interrupt_marker); -+ pif (HP_UX_interrupt_marker); -+ pif (Large_frame); -+ -+ putchar_unfiltered ('\n'); -+ -+#ifdef __STDC__ -+#define pin(FLD) printf_unfiltered ("\t"#FLD" = 0x%x\n", u->FLD); -+#else -+#define pin(FLD) printf_unfiltered ("\tFLD = 0x%x\n", u->FLD); -+#endif -+ -+ pin (Region_description); -+ pin (Entry_FR); -+ pin (Entry_GR); -+ pin (Total_frame_size); -+} -+ -+void pa_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) -+{ -+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); -+ -+ fprintf_unfiltered (file, -+ "gdbarch_dump_tdep: OS_IDENT = %#x\n", -+ tdep->os_ident); -+ fprintf_unfiltered (file, -+ "gdbarch_dump_tdep: IS_ELF = %d\n", -+ tdep->is_elf); -+ fprintf_unfiltered (file, -+ "gdbarch_dump_tdep: IS_ELF64 = %d\n", -+ tdep->is_elf64); -+ fprintf_unfiltered (file, -+ "gdbarch_dump_tdep: IN_SYSCALL = %p\n", -+ tdep->in_syscall); -+ fprintf_unfiltered (file, -+ "gdbarch_dump_tdep: IN_INTERRUPT_HANDLER = %p\n", -+ tdep->in_interrupt_handler); -+ fprintf_unfiltered (file, -+ "gdbarch_dump_tdep: IN_SIGTRAMP = %p\n", -+ tdep->in_sigtramp); -+ fprintf_unfiltered (file, -+ "gdbarch_dump_tdep: FRAME_SAVED_PC_IN_INTERRUPT = %p\n", -+ tdep->frame_saved_pc_in_interrupt); -+ fprintf_unfiltered (file, -+ "gdbarch_dump_tdep: FRAME_BASE_BEFORE_INTERRUPT = %p\n", -+ tdep->frame_base_before_interrupt); -+ fprintf_unfiltered (file, -+ "gdbarch_dump_tdep: FRAME_FIND_SAVED_REGS_IN_INTERRUPT = %p\n", -+ tdep->frame_find_saved_regs_in_interrupt); -+ fprintf_unfiltered (file, -+ "gdbarch_dump_tdep: FRAME_SAVED_PC_IN_SIGTRAMP = %p\n", -+ tdep->frame_saved_pc_in_sigtramp); -+ fprintf_unfiltered (file, -+ "gdbarch_dump_tdep: FRAME_BASE_BEFORE_SIGTRAMP = %p\n", -+ tdep->frame_base_before_sigtramp); -+ fprintf_unfiltered (file, -+ "gdbarch_dump_tdep: FRAME_FIND_SAVED_REGS_IN_SIGTRAMP = %p\n", -+ tdep->frame_find_saved_regs_in_sigtramp); -+} -+ -+static struct gdbarch * -+pa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) -+{ -+ struct gdbarch *gdbarch; -+ struct gdbarch_tdep *tdep; -+ int os_ident = -1; -+ unsigned int is_elf = 0; -+ unsigned int is_elf64 = 0; -+ -+ if (info.abfd != NULL -+ && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour) -+ { -+ is_elf = 1; -+ is_elf64 = elf_elfheader (info.abfd)->e_ident[EI_CLASS] == ELFCLASS64; -+ os_ident = elf_elfheader (info.abfd)->e_ident[EI_OSABI]; -+ } -+ -+ for (arches = gdbarch_list_lookup_by_info (arches, &info); -+ arches != NULL; -+ arches = gdbarch_list_lookup_by_info (arches->next, &info)) -+ { -+ if (gdbarch_tdep (arches->gdbarch)->os_ident == os_ident) -+ return arches->gdbarch; -+ } -+ -+ tdep = xmalloc (sizeof (struct gdbarch_tdep)); -+ gdbarch = gdbarch_alloc (&info, tdep); -+ tdep->os_ident = os_ident; -+ tdep->is_elf = is_elf; -+ tdep->is_elf64 = is_elf64; -+ -+ set_gdbarch_short_bit (gdbarch, 16); -+ set_gdbarch_int_bit (gdbarch, 32); -+ set_gdbarch_long_bit (gdbarch, is_elf64 ? 64: 32); -+ set_gdbarch_long_long_bit (gdbarch, 64); -+ set_gdbarch_float_bit (gdbarch, 32); -+ set_gdbarch_double_bit (gdbarch, 64); -+ set_gdbarch_long_double_bit (gdbarch, 64); -+ set_gdbarch_ptr_bit (gdbarch, is_elf64 ? 64 : 32); -+ /* default addr_bit, bfd_vma_bit. */ -+ /* set_gdbarch_ieee_float (gdbarch, 1); */ -+ -+ set_gdbarch_num_regs (gdbarch, NUM_REGS); -+ /* default num_pseudo_regs. */ -+ set_gdbarch_sp_regnum (gdbarch, PA_GR31_REGNUM); -+ set_gdbarch_fp_regnum (gdbarch, PA_GR3_REGNUM); -+ set_gdbarch_pc_regnum (gdbarch, PA_PCOQ_HEAD_REGNUM); -+ set_gdbarch_npc_regnum (gdbarch, PA_PCOQ_TAIL_REGNUM); -+ set_gdbarch_fp0_regnum (gdbarch, PA_FR0_REGNUM); -+ -+ set_gdbarch_register_name (gdbarch, pa_register_name); -+ set_gdbarch_register_size (gdbarch, is_elf64 ? 8 : 4); -+ set_gdbarch_register_bytes (gdbarch, (is_elf64 -+ ? (NUM_REGS * 8 -+ - (NUM_REGS - PA_FR0_REGNUM) * 4) -+ : NUM_REGS * 4)); -+ set_gdbarch_register_byte (gdbarch, (is_elf64 -+ ? pa64_register_byte -+ : pa_register_byte)); -+ set_gdbarch_register_raw_size (gdbarch, (is_elf64 -+ ? pa64_register_raw_size -+ : pa_register_raw_size)); -+ set_gdbarch_max_register_raw_size (gdbarch, is_elf64 ? 8 : 4); -+ set_gdbarch_register_virtual_size (gdbarch, (is_elf64 -+ ? pa64_register_raw_size -+ : pa_register_raw_size)); -+ set_gdbarch_max_register_virtual_size (gdbarch, is_elf64 ? 8 : 4); -+ set_gdbarch_register_virtual_type (gdbarch, (is_elf64 -+ ? pa64_register_virtual_type -+ : pa_register_virtual_type)); -+ set_gdbarch_do_registers_info (gdbarch, pa_do_registers_info); -+ -+ /* default register_sim_regno. */ -+ set_gdbarch_use_generic_dummy_frames (gdbarch, 0); -+ -+ set_gdbarch_believe_pcc_promotion (gdbarch, 1); -+ /* default believe_pcc_promotion_type. */ -+ -+ set_gdbarch_coerce_float_to_double (gdbarch, standard_coerce_float_to_double); -+ set_gdbarch_get_saved_register (gdbarch, generic_get_saved_register); -+ /* default register_convertible. */ -+ /* default register_convert_to_virtual. */ -+ /* default register_convert_to_raw. */ -+ /* default fetch_pseudo_register. */ -+ /* default store_pseudo_register. */ -+ /* default pointer_to_address. */ -+ /* default address_to_pointer. */ -+ /* default return_value_on_stack. */ -+ set_gdbarch_extract_return_value (gdbarch, (is_elf64 -+ ? pa64_extract_return_value -+ : pa_extract_return_value)); -+ set_gdbarch_push_arguments (gdbarch, (is_elf64 -+ ? pa64_push_arguments -+ : pa_push_arguments)); -+ set_gdbarch_push_return_address (gdbarch, pa_push_return_address); -+ set_gdbarch_pop_frame (gdbarch, pa_pop_frame); -+ set_gdbarch_store_struct_return (gdbarch, pa_store_struct_return); -+ set_gdbarch_deprecated_store_return_value (gdbarch, pa_store_return_value); -+ set_gdbarch_deprecated_extract_struct_value_address (gdbarch, -+ pa_extract_struct_value_address); -+ set_gdbarch_use_struct_convention (gdbarch, pa_use_struct_convention); -+ set_gdbarch_frame_init_saved_regs (gdbarch, pa_frame_init_saved_regs); -+ set_gdbarch_init_extra_frame_info (gdbarch, pa_init_extra_frame_info); -+ set_gdbarch_skip_prologue (gdbarch, pa_skip_prologue); -+ set_gdbarch_prologue_frameless_p (gdbarch, pa_prologue_frameless_p); -+ set_gdbarch_inner_than (gdbarch, pa_inner_than); -+ set_gdbarch_breakpoint_from_pc (gdbarch, pa_breakpoint_from_pc); -+ /* default memory_insert_breakpoint. */ -+ /* default memory_remove_breakpoint. */ -+ set_gdbarch_decr_pc_after_break (gdbarch, 0); -+ set_gdbarch_function_start_offset (gdbarch, 0); -+ set_gdbarch_remote_translate_xfer_address (gdbarch, -+ pa_remote_translate_xfer_address); -+ set_gdbarch_frame_args_skip (gdbarch, 0); -+ set_gdbarch_frameless_function_invocation (gdbarch, -+ pa_frameless_function_invocation); -+ set_gdbarch_frame_chain (gdbarch, pa_frame_chain); -+ set_gdbarch_frame_chain_valid (gdbarch, generic_func_frame_chain_valid); -+ set_gdbarch_frame_saved_pc (gdbarch, pa_frame_saved_pc); -+ set_gdbarch_frame_args_address (gdbarch, pa_frame_args_address); -+ set_gdbarch_frame_locals_address (gdbarch, pa_frame_locals_address); -+ set_gdbarch_saved_pc_after_call (gdbarch, pa_saved_pc_after_call); -+ set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown); -+ set_gdbarch_stack_align (gdbarch, (is_elf64 -+ ? pa64_stack_align -+ : pa_stack_align)); -+ /* Default extra_stack_alignment_needed. */ -+ set_gdbarch_reg_struct_has_addr (gdbarch, pa_reg_struct_has_addr); -+ /* Default save_dummy_frame_tos */ -+ set_gdbarch_float_format (gdbarch, &floatformat_ieee_single_big); -+ set_gdbarch_double_format (gdbarch, &floatformat_ieee_double_big); -+ set_gdbarch_long_double_format (gdbarch, &floatformat_ieee_double_big); -+ /* Default convert_from_func_ptr_addr. */ -+ -+#if 0 -+ if (os_ident == ELFOSABI_LINUX) -+#endif -+ pa_linux_initialize_tdep (gdbarch, is_elf64); -+#if 0 -+ /* Disable hpux support as som stuff only compiles native. Sheesh. */ -+ else -+ pa_hpux_initialize_tdep (gdbarch, is_elf64); -+#endif -+ -+ return gdbarch; -+} -+ -+void -+_initialize_pa_tdep (void) -+{ -+ gdbarch_register (bfd_arch_hppa, pa_gdbarch_init, pa_dump_tdep); -+ -+ tm_print_insn = print_insn_hppa; -+ tm_print_insn_info.bytes_per_line = 4; -+ -+ add_cmd ("unwind", class_maintenance, unwind_command, -+ "Print unwind table entry at given address.", -+ &maintenanceprintlist); -+#if DEBUG -+ add_show_from_set (add_set_cmd ("frame", class_maintenance, var_zinteger, -+ (char *) &framedebug, -+ "Set frame debugging.\n\ -+When non-zero, frame debugging is enabled.", -+ &setdebuglist), -+ &showdebuglist); -+ add_show_from_set (add_set_cmd ("grok", class_maintenance, var_zinteger, -+ (char *) &grokdebug, -+ "Set prologue debugging.\n\ -+When non-zero, prologue debugging is enabled.", -+ &setdebuglist), -+ &showdebuglist); -+#endif -+} diff --git a/sys-devel/gdb/files/gdb-5.3-hppa-02.patch b/sys-devel/gdb/files/gdb-5.3-hppa-02.patch deleted file mode 100644 index aced5e630a7f..000000000000 --- a/sys-devel/gdb/files/gdb-5.3-hppa-02.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- gdb-5.2.cvs20020401/bfd/elf64-hppa.c~ Sun Mar 31 19:09:41 2002 -+++ gdb-5.2.cvs20020401/bfd/elf64-hppa.c Sat Apr 20 09:35:54 2002 -@@ -372,7 +372,8 @@ - i_ehdrp = elf_elfheader (abfd); - if (strcmp (bfd_get_target (abfd), "elf64-hppa-linux") == 0) - { -- if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX) -+ if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX && -+ i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) - return false; - } - else ---- gdb-5.2.cvs20020401/bfd/elf32-hppa.c~ Sun Mar 31 19:09:41 2002 -+++ gdb-5.2.cvs20020401/bfd/elf32-hppa.c Sat Apr 20 09:35:54 2002 -@@ -1038,7 +1038,8 @@ - i_ehdrp = elf_elfheader (abfd); - if (strcmp (bfd_get_target (abfd), "elf32-hppa-linux") == 0) - { -- if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX) -+ if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX && -+ i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) - return false; - } - else diff --git a/sys-devel/gdb/files/gdb-5.3-hppa-03.patch b/sys-devel/gdb/files/gdb-5.3-hppa-03.patch deleted file mode 100644 index 788fd183a77e..000000000000 --- a/sys-devel/gdb/files/gdb-5.3-hppa-03.patch +++ /dev/null @@ -1,67 +0,0 @@ -package: gdb -version: 5.2.cvs20020401-6 - -The attached patch fixes gdb on hppa so that it will print function -returns (e.g. "print foo(6)"), where previously it would crash the -inferior with protection faults. - -There are still some problems, for example, print strlen("foo") will -fail. To evaluate that, gdb has first got to get the inferior to call -malloc so there is somewhere to store the string. For a dynamically -linked program, gdb is finding a symbol 'malloc' in ld-2.2.5.so and -trying to call that, with a bogus dp value. If you link the program -statically, gdb finds the right 'malloc' to call and it works. - -Richard - - - -diff -ur gdb-5.2.cvs20020401.ori/gdb/pa-linux-tdep.c gdb-5.2.cvs20020401/gdb/pa-linux-tdep.c ---- gdb-5.2.cvs20020401.ori/gdb/pa-linux-tdep.c Fri May 31 17:57:21 2002 -+++ gdb-5.2.cvs20020401/gdb/pa-linux-tdep.c Fri May 31 18:25:22 2002 -@@ -38,8 +38,8 @@ - static void - pa_write_pc (CORE_ADDR pc, ptid_t ptid) - { -- write_register_pid (PA_PCOQ_HEAD_REGNUM, pc, ptid); -- write_register_pid (PA_PCOQ_TAIL_REGNUM, pc + 4, ptid); -+ write_register_pid (PA_PCOQ_HEAD_REGNUM, pc | 3, ptid); -+ write_register_pid (PA_PCOQ_TAIL_REGNUM, (pc + 4) | 3, ptid); - } - - static CORE_ADDR -@@ -426,8 +426,8 @@ - /* We can not modify the instruction address queues directly, so we start - up the inferior and execute a couple of instructions to set them so - that they point to the call dummy in the stack. */ -- pcoqh = read_register (PA_PCOQ_HEAD_REGNUM); -- pcoqt = read_register (PA_PCOQ_TAIL_REGNUM); -+ pcoqh = read_register (PA_PCOQ_HEAD_REGNUM) & ~3; -+ pcoqt = read_register (PA_PCOQ_TAIL_REGNUM) & ~3; - - if (target_read_memory (pcoqh, buf, 4) != 0) - error ("Couldn't modify instruction address queue\n"); -@@ -547,8 +547,8 @@ - /* We can not modify the instruction address queues directly, so we start - up the inferior and execute a couple of instructions to set them so - that they point to the call dummy in the stack. */ -- pcoqh = read_register (PA_PCOQ_HEAD_REGNUM); -- pcoqt = read_register (PA_PCOQ_TAIL_REGNUM); -+ pcoqh = read_register (PA_PCOQ_HEAD_REGNUM) & ~3; -+ pcoqt = read_register (PA_PCOQ_TAIL_REGNUM) & ~3; - - if (target_read_memory (pcoqh, buf, 4) != 0) - error ("Couldn't modify instruction address queue\n"); -diff -ur gdb-5.2.cvs20020401.ori/gdb/pa-tdep.c gdb-5.2.cvs20020401/gdb/pa-tdep.c ---- gdb-5.2.cvs20020401.ori/gdb/pa-tdep.c Fri May 31 17:57:21 2002 -+++ gdb-5.2.cvs20020401/gdb/pa-tdep.c Fri May 31 01:01:42 2002 -@@ -2098,6 +2098,7 @@ - int reg_size = REGISTER_SIZE; - - fp = FRAME_FP (frame); -+ FRAME_INIT_SAVED_REGS(frame); - fsr = frame->saved_regs; - - #ifndef NO_PC_SPACE_QUEUE_RESTORE - - diff --git a/sys-devel/gdb/gdb-5.3-r1.ebuild b/sys-devel/gdb/gdb-5.3-r1.ebuild index 7c2c9a5f5151..4f66d51e4cfb 100644 --- a/sys-devel/gdb/gdb-5.3-r1.ebuild +++ b/sys-devel/gdb/gdb-5.3-r1.ebuild @@ -1,12 +1,13 @@ # Copyright 1999-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-devel/gdb/gdb-5.3-r1.ebuild,v 1.6 2004/06/24 22:46:27 agriffis Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-devel/gdb/gdb-5.3-r1.ebuild,v 1.7 2004/08/03 04:31:00 vapier Exp $ inherit flag-o-matic ccc eutils DESCRIPTION="GNU debugger" HOMEPAGE="http://sources.redhat.com/gdb/" SRC_URI="http://mirrors.rcn.net/pub/sourceware/gdb/releases/${P}.tar.bz2 + hppa? ( mirror://gentoo/${P}-hppa-patches.tar.bz2 ) objc? ( ftp://ftp.gnustep.org/pub/gnustep/patches/gdb-5_3-objc-patch.tgz ) mirror://gentoo/${P}-s390-june2003.tar.gz" @@ -23,10 +24,9 @@ src_unpack() { unpack ${P}-s390-june2003.tar.gz if [ "${ARCH}" = "hppa" ]; then + unpack ${P}-hppa-patches.tar.bz2 cd ${S} - epatch ${FILESDIR}/gdb-5.3-hppa-01.patch - epatch ${FILESDIR}/gdb-5.3-hppa-02.patch - epatch ${FILESDIR}/gdb-5.3-hppa-03.patch + EPATCH_SUFFIX="patch" epatch ${WORKDIR}/hppa fi #s390 Specific fixes to close Bug #47903 diff --git a/sys-devel/gdb/gdb-5.3.90.ebuild b/sys-devel/gdb/gdb-5.3.90.ebuild index 334e1361140d..ea4108d22e55 100644 --- a/sys-devel/gdb/gdb-5.3.90.ebuild +++ b/sys-devel/gdb/gdb-5.3.90.ebuild @@ -1,8 +1,8 @@ # Copyright 1999-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-devel/gdb/gdb-5.3.90.ebuild,v 1.11 2004/07/15 03:25:41 agriffis Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-devel/gdb/gdb-5.3.90.ebuild,v 1.12 2004/08/03 04:31:00 vapier Exp $ -IUSE="nls objc" +inherit flag-o-matic ccc eutils SNAPSHOT="20030710" PATCH_VER="1.0" @@ -26,16 +26,13 @@ fi LICENSE="GPL-2 LGPL-2" SLOT="0" -KEYWORDS="~x86 ~ppc ~sparc ~alpha -hppa amd64 ~mips" +KEYWORDS="~x86 ~ppc ~sparc ~alpha amd64 ~mips" +IUSE="nls objc" DEPEND=">=sys-libs/ncurses-5.2-r2 nls? ( sys-devel/gettext )" -inherit flag-o-matic ccc eutils -replace-flags -O? -O2 - src_unpack() { - if [ -n "${SNAPSHOT}" ] then unpack ${P}-${SNAPSHOT}.tar.bz2 \ @@ -84,15 +81,13 @@ src_unpack() { } src_compile() { + replace-flags -O? -O2 - local myconf= - - use nls && myconf="--enable-nls" || myconf="--disable-nls" - - econf --enable-threads \ + econf \ + --enable-threads \ --with-separate-debug-dir=/usr/lib/debug \ - ${myconf} || die - + `use_enable nls` \ + || die make || die } diff --git a/sys-devel/gdb/gdb-5.3.ebuild b/sys-devel/gdb/gdb-5.3.ebuild index c5b68a923888..a361933c00c3 100644 --- a/sys-devel/gdb/gdb-5.3.ebuild +++ b/sys-devel/gdb/gdb-5.3.ebuild @@ -1,37 +1,34 @@ # Copyright 1999-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-devel/gdb/gdb-5.3.ebuild,v 1.18 2004/07/15 03:25:41 agriffis Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-devel/gdb/gdb-5.3.ebuild,v 1.19 2004/08/03 04:31:00 vapier Exp $ -IUSE="nls objc" +inherit flag-o-matic ccc eutils DESCRIPTION="GNU debugger" HOMEPAGE="http://sources.redhat.com/gdb/" SRC_URI="http://mirrors.rcn.net/pub/sourceware/gdb/releases/${P}.tar.bz2 + mirror://gentoo/${P}-hppa-patches.tar.bz2 ) objc? ( ftp://ftp.gnustep.org/pub/gnustep/patches/gdb-5_3-objc-patch.tgz )" LICENSE="GPL-2 LGPL-2" SLOT="0" KEYWORDS="x86 ppc ~sparc alpha hppa amd64 ia64" +IUSE="nls objc" DEPEND=">=sys-libs/ncurses-5.2-r2 nls? ( sys-devel/gettext )" -inherit flag-o-matic ccc eutils -replace-flags -O? -O2 - src_unpack() { unpack gdb-${PV}.tar.bz2 - if [ "${ARCH}" = "hppa" ]; then + if [ "${ARCH}" == "hppa" ] ; then + unpack ${P}-hppa-patches.tar.bz2 cd ${S} - patch -p1 < ${FILESDIR}/gdb-5.3-hppa-01.patch - patch -p1 < ${FILESDIR}/gdb-5.3-hppa-02.patch - patch -p1 < ${FILESDIR}/gdb-5.3-hppa-03.patch + EPATCH_SUFFIX="patch" epatch ${WORKDIR}/hppa fi - # Fix Compile bug on sparc - if [ "${ARCH}" = "sparc" ]; then + if [ "${ARCH}" == "sparc" ] ; then cd ${S} epatch ${FILESDIR}/${P}-sparc-nat-asm.patch fi @@ -41,7 +38,7 @@ src_unpack() { unpack gdb-5_3-objc-patch.tgz cd ${S} - patch -p1 < ${WORKDIR}/gdb-5_3-objc-patch/gdb-5.3-objc-patch.diff || die + epatch ${WORKDIR}/gdb-5_3-objc-patch/gdb-5.3-objc-patch.diff || die cp ${WORKDIR}/gdb-5_3-objc-patch/objc-exp.y gdb/ cp ${WORKDIR}/gdb-5_3-objc-patch/objc-lang.c gdb/ @@ -55,18 +52,13 @@ src_unpack() { } src_compile() { + replace-flags -O? -O2 - local myconf - - use nls && myconf="--enable-nls" || myconf="--disable-nls" - - econf ${myconf} || die - + econf `use_enable nls` || die make || die } src_install() { - make \ prefix=${D}/usr \ mandir=${D}/usr/share/man \ |