This commit is contained in:
gdb-2.8 1988-09-03 08:00:00 +01:00 committed by Pedro Alves
parent 7c75bab3d3
commit 3bf57d2108
87 changed files with 16659 additions and 10555 deletions

146
gdb/COPYING Normal file
View File

@ -0,0 +1,146 @@
GDB GENERAL PUBLIC LICENSE
(Clarified 11 Feb 1988)
Copyright (C) 1988 Richard M. Stallman
Everyone is permitted to copy and distribute verbatim copies
of this license, but changing it is not allowed. You can also
use this wording to make the terms for other programs.
The license agreements of most software companies keep you at the
mercy of those companies. By contrast, our general public license is
intended to give everyone the right to share GDB. To make sure that
you get the rights we want you to have, we need to make restrictions
that forbid anyone to deny you these rights or to ask you to surrender
the rights. Hence this license agreement.
Specifically, we want to make sure that you have the right to give
away copies of GDB, that you receive source code or else can get it
if you want it, that you can change GDB or use pieces of it in new
free programs, and that you know you can do these things.
To make sure that everyone has such rights, we have to forbid you to
deprive anyone else of these rights. For example, if you distribute
copies of GDB, you must give the recipients all the rights that you
have. You must make sure that they, too, receive or can get the
source code. And you must tell them their rights.
Also, for our own protection, we must make certain that everyone
finds out that there is no warranty for GDB. If GDB is modified by
someone else and passed on, we want its recipients to know that what
they have is not what we distributed, so that any problems introduced
by others will not reflect on our reputation.
Therefore we (Richard Stallman and the Free Software Foundation,
Inc.) make the following terms which say what you must do to be
allowed to distribute or change GDB.
COPYING POLICIES
1. You may copy and distribute verbatim copies of GDB source code as
you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy a valid copyright notice "Copyright
(C) 1988 Free Software Foundation, Inc." (or with whatever year is
appropriate); keep intact the notices on all files that refer to this
License Agreement and to the absence of any warranty; and give any
other recipients of the GDB program a copy of this License Agreement
along with the program. You may charge a distribution fee for the
physical act of transferring a copy.
2. You may modify your copy or copies of GDB or any portion of it,
and copy and distribute such modifications under the terms of
Paragraph 1 above, provided that you also do the following:
a) cause the modified files to carry prominent notices stating
that you changed the files and the date of any change; and
b) cause the whole of any work that you distribute or publish,
that in whole or in part contains or is a derivative of GDB or any
part thereof, to be licensed at no charge to all third parties on
terms identical to those contained in this License Agreement
(except that you may choose to grant more extensive warranty
protection to third parties, at your option).
c) if the modified program serves as a debugger, cause it when
started running in the simplest and usual way, to print an
announcement including a valid copyright notice "Copyright (C)
1988 Free Software Foundation, Inc." (or with the year that is
appropriate), saying that there is no warranty (or else, saying
that you provide a warranty) and that users may redistribute the
program under these conditions, and telling the user how to view a
copy of this License Agreement.
d) You may charge a distribution fee for the physical act of
transferring a copy, and you may at your option offer warranty
protection in exchange for a fee.
Mere aggregation of another unrelated program with this program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other program under the scope of these terms.
3. You may copy and distribute GDB (or a portion or derivative of it,
under Paragraph 2) in object code or executable form under the terms of
Paragraphs 1 and 2 above provided that you also do one of the following:
a) accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
Paragraphs 1 and 2 above; or,
b) accompany it with a written offer, valid for at least three
years, to give any third party free (except for a nominal
shipping charge) a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of
Paragraphs 1 and 2 above; or,
c) accompany it with the information you received as to where the
corresponding source code may be obtained. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form alone.)
For an executable file, complete source code means all the source code for
all modules it contains; but, as a special exception, it need not include
source code for modules which are standard libraries that accompany the
operating system on which the executable file runs.
4. You may not copy, sublicense, distribute or transfer GDB
except as expressly provided under this License Agreement. Any attempt
otherwise to copy, sublicense, distribute or transfer GDB is void and
your rights to use the program under this License agreement shall be
automatically terminated. However, parties who have received computer
software programs from you with this License Agreement will not have
their licenses terminated so long as such parties remain in full compliance.
5. If you wish to incorporate parts of GDB into other free programs
whose distribution conditions are different, write to the Free
Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not
yet worked out a simple rule that can be stated here, but we will
often permit this. We will be guided by the two goals of preserving
the free status of all derivatives of our free software and of
promoting the sharing and reuse of software.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
NO WARRANTY
BECAUSE GDB IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY NO
WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE GDB "AS IS" WITHOUT
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
PERFORMANCE OF GDB IS WITH YOU. SHOULD GDB PROVE DEFECTIVE, YOU
ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
WHO MAY MODIFY AND REDISTRIBUTE GDB AS PERMITTED ABOVE, BE LIABLE TO
YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER
SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GDB, EVEN
IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR
ANY CLAIM BY ANY OTHER PARTY.

1609
gdb/ChangeLog Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,31 @@
# Makefile for GDB
# Copyright (C) 1986, 1988 Free Software Foundation, Inc.
#
#GDB is distributed in the hope that it will be useful, but WITHOUT ANY
#WARRANTY. No author or distributor accepts responsibility to anyone
#for the consequences of using it or for whether it serves any
#particular purpose or works at all, unless he says so in writing.
#Refer to the GDB General Public License for full details.
#
#Everyone is granted permission to copy, modify and redistribute GDB,
#but only under the conditions described in the GDB General Public
#License. A copy of this license is supposed to have been given to you
#along with GDB so you can know your rights and responsibilities. It
#should be in a file named COPYING. Among other things, the copyright
#notice and this notice must be preserved on all copies.
#
#In other words, go ahead and share GDB, but don't try to stop
#anyone else from sharing it farther. Help stamp out software hoarding!
# On HPUX, you need to add -Ihpux to CFLAGS.
# The headers in the subdir hpux override system headers
# and tell GDB to use BSD executable file format.
# You also need to add -lGNU to CLIBS, and perhaps CC = gcc.
# -I. for "#include <obstack.h>"
CFLAGS = -g -I.
# NOTE!!! -O may FAIL TO WORK! See initialize.h for some weird hacks.
CC = cc
BISON = bison
# define this to be "obstack.o" if you don't have the obstack library installed
# you must at the same time define OBSTACK1 as "obstack.o"
@ -10,6 +33,8 @@ BISON = bison
OBSTACK = obstack.o
OBSTACK1 = obstack.o
CLIBS = $(OBSTACK)
STARTOBS = main.o firstfile.o
OBS = blockframe.o breakpoint.o findvar.o stack.o source.o \
@ -27,15 +52,15 @@ TSSTART = /lib/crt0.o
NTSSTART = kdb-start.o
gdb+: $(STARTOBS) $(OBS) $(TSOBS) $(ENDOBS) $(OBSTACK1)
$(CC) -o gdb+ $(STARTOBS) $(OBS) $(TSOBS) $(ENDOBS) -lc -lg $(OBSTACK)
gdb : $(STARTOBS) $(OBS) $(TSOBS) $(ENDOBS) $(OBSTACK1)
$(CC) $(LDFLAGS) -o gdb $(STARTOBS) $(OBS) $(TSOBS) $(ENDOBS) $(CLIBS)
xgdb+ : $(STARTOBS) $(OBS) xgdb.o $(TSOBS) $(ENDOBS) $(OBSTACK1)
$(CC) -o xgdb+ $(STARTOBS) $(OBS) xgdb.o $(TSOBS) $(ENDOBS) \
-lXtk11 -lXrm -lX11 -lg $(OBSTACK)
xgdb : $(STARTOBS) $(OBS) $(TSOBS) xgdb.o $(ENDOBS) $(OBSTACK1)
$(CC) $(LDFLAGS) -o xgdb $(STARTOBS) $(OBS) $(TSOBS) xgdb.o $(ENDOBS) \
-lXaw -lXt -lX11 $(CLIBS)
kdb : $(NTSSTART) $(STARTOBS) $(OBS) $(NTSOBS) $(ENDOBS) $(OBSTACK1)
ld -o kdb $(NTSSTART) $(STARTOBS) $(OBS) $(NTSOBS) $(ENDOBS) -lc -lg $(OBSTACK)
ld -o kdb $(NTSSTART) $(STARTOBS) $(OBS) $(NTSOBS) $(ENDOBS) -lc $(CLIBS)
blockframe.o : blockframe.c defs.h initialize.h param.h symtab.h frame.h
breakpoint.o : breakpoint.c defs.h initialize.h param.h symtab.h frame.h
@ -46,8 +71,9 @@ dbxread.o : dbxread.c defs.h initialize.h param.h symtab.h
environ.o : environ.c environ.h
expprint.o : expprint.c defs.h symtab.h expression.h
expread.tab.c : expread.y
@echo 'Expect 101 shift/reduce conflicts and 1 reduce/reduce conflict.'
$(BISON) -v expread.y
@echo 'Expect 96 shift/reduce conflicts.'
yacc expread.y
mv y.tab.c expread.tab.c
expread.o : expread.tab.c defs.h param.h symtab.h frame.h expression.h
$(CC) -c ${CFLAGS} expread.tab.c
mv expread.tab.o expread.o
@ -74,7 +100,7 @@ symtab.o : symtab.c defs.h initialize.h param.h symtab.h
utils.o : utils.c defs.h
valarith.o : valarith.c defs.h initialize.h param.h symtab.h value.h expression.h
valops.o : valops.c defs.h initialize.h param.h symtab.h value.h
valprint.o : valprint.c defs.h initialize.h symtab.h value.h
valprint.o : valprint.c defs.h initialize.h param.h symtab.h value.h
values.o : values.c defs.h initialize.h param.h symtab.h value.h
version.o : version.c
xgdb.o : xgdb.c defs.h initialize.h param.h symtab.h frame.h

16
gdb/ORIGIN Normal file
View File

@ -0,0 +1,16 @@
Host akbar.cac.washington.edu (128.95.112.1)
Last updated 17:04 11 Nov 1990
Location: local/emacs.pmax/info
FILE rw-rw-r-- 2515 Feb 12 1988 gdb
Location: local/emacs.pmax.old
DIRECTORY rwxr-xr-x 2048 Sep 11 01:16 gdb
Location: local/emacs.pmax.old/info
FILE rw-rw-r-- 2515 Feb 12 1988 gdb
Location: local/emacs.pmax4.0
DIRECTORY rwxr-xr-x 2048 Aug 11 01:16 gdb
Location: local/emacs.pmax4.0/info
FILE rw-r--r-- 2515 Feb 12 1988 gdb
Location: local/emacs.sun386
DIRECTORY rwxr-xr-x 2048 May 23 01:17 gdb
Location: local/emacs.sun386/info
FILE rw-rw-r-- 2515 Feb 12 1988 gdb

95
gdb/ORIGIN.ls.lag Normal file
View File

@ -0,0 +1,95 @@
total 1304
drwxr-xr-x 2 bin system 2048 May 23 1990 .
drwxr-xr-x 11 bin system 512 May 23 1990 ..
-rw-rw-r-- 2 5057 staff 7517 Feb 11 1988 COPYING
-rw-rw-r-- 2 5057 staff 58620 Sep 3 1988 ChangeLog
-rw-rw-r-- 2 5057 staff 4698 Sep 3 1988 Makefile
-rw-rw-r-- 2 5057 staff 1168 Jul 8 1988 README
-rw-rw-r-- 2 5057 staff 30273 May 6 1988 TAGS
-rw-rw-r-- 2 5057 staff 8285 Mar 24 1988 blockframe.c
-rw-rw-r-- 2 5057 staff 28258 Jun 9 1988 breakpoint.c
-rw-r--r-- 2 5057 staff 12288 Dec 20 1988 coffread.c
-rw-rw-r-- 2 5057 staff 14515 Mar 25 1988 command.c
-rw-rw-r-- 2 5057 staff 7397 Feb 11 1988 command.h
-rwxrwxr-x 2 5057 staff 2273 Sep 1 1988 config.gdb
-rw-rw-r-- 2 5057 staff 19678 May 3 1988 core.c
-rw-rw-r-- 2 5057 staff 69156 Jul 6 1988 dbxread.c
-rw-rw-r-- 2 5057 staff 2499 May 22 1988 defs.h
-rw-rw-r-- 2 5057 staff 8436 Feb 11 1988 environ.c
-rw-rw-r-- 2 5057 staff 615 Jul 15 1986 environ.h
-rw-rw-r-- 2 5057 staff 16501 Feb 3 1988 eval.c
-rw-rw-r-- 2 5057 staff 9484 May 30 1988 expprint.c
-rw-rw-r-- 2 5057 staff 27745 Apr 30 1988 expread.y
-rw-rw-r-- 2 5057 staff 6455 Nov 22 1986 expression.h
-rw-rw-r-- 2 5057 staff 10805 Jun 27 1988 findvar.c
-rw-rw-r-- 2 5057 staff 7052 Feb 11 1988 firstfile.c
-rw-rw-r-- 2 5057 staff 2287 Sep 30 1986 frame.h
-rw-rw-r-- 2 5057 staff 4006 Apr 13 1987 gdb.1
-rw-rw-r-- 2 5057 staff 41892 Sep 2 1988 gdb.ideas
-rw-rw-r-- 2 5057 staff 6759 Jun 21 1988 gld-pinsn.c
-rw-rw-r-- 2 5057 staff 23615 Jun 27 1988 infcmd.c
-rw-rw-r-- 2 5057 staff 2820 Feb 3 1988 inferior.h
-rw-rw-r-- 2 5057 staff 23111 Sep 3 1988 inflow.c
-rw-rw-r-- 2 5057 staff 29393 Jun 25 1988 infrun.c
-rw-rw-r-- 2 5057 staff 6545 Jun 21 1988 initialize.h
-rw-rw-r-- 2 5057 staff 409 Jul 15 1986 kdb-start.c
-rw-rw-r-- 2 5057 staff 172 Jul 15 1986 lastfile.c
-rw-rw-r-- 2 5057 staff 20054 Apr 11 1988 m-hp9k320.h
-rw-rw-r-- 2 5057 staff 19325 Sep 1 1988 m-hp9k320bsd.h
-rw-rw-r-- 4 5057 staff 141 Feb 6 1988 m-init.h
-rw-rw-r-- 2 5057 staff 20411 Apr 6 1988 m-isi.h
-rw-rw-r-- 2 5057 staff 348 Mar 20 1988 m-isiinit.h
-rw-rw-r-- 2 5057 staff 15011 Mar 24 1988 m-merlin.h
-rw-rw-r-- 2 5057 staff 19335 Aug 30 1988 m-news.h
-rw-rw-r-- 2 5057 staff 146 Jan 15 1988 m-newsinit.h
-rw-rw-r-- 2 5057 staff 18267 Jun 17 1988 m-npl.h
-rw-rw-r-- 2 5057 staff 189 Jun 16 1988 m-nplinit.h
-rw-rw-r-- 2 5057 staff 17503 Jun 17 1988 m-pn.h
-rw-rw-r-- 2 5057 staff 191 Jun 16 1988 m-pninit.h
-rw-rw-r-- 2 5057 staff 15507 Apr 6 1988 m-sun2.h
-rw-rw-r-- 2 5057 staff 130 Jul 15 1986 m-sun2init.h
-rw-rw-r-- 4 5057 staff 18051 Apr 6 1988 m-sun3.h
-rw-rw-r-- 4 5057 staff 141 Feb 6 1988 m-sun3init.h
-rw-rw-r-- 2 5057 staff 14711 Jun 17 1988 m-umax.h
-rw-rw-r-- 2 5057 staff 147 Apr 9 1988 m-umaxinit.h
-rw-rw-r-- 2 5057 staff 13590 Mar 24 1988 m-vax.h
-rw-rw-r-- 2 5057 staff 141 Sep 24 1986 m-vaxinit.h
-rw-rw-r-- 4 5057 staff 68314 Apr 8 1988 m68k-opcode.h
-rw-rw-r-- 4 5057 staff 17695 Jun 21 1988 m68k-pinsn.c
-rw-rw-r-- 2 5057 staff 34227 Jul 20 1988 main.c
-rw-rw-r-- 2 5057 staff 18362 Jun 16 1988 npl-opcode.h
-rw-rw-r-- 2 5057 staff 10621 Nov 25 1987 ns32k-opcode.h
-rw-rw-r-- 2 5057 staff 10662 Jun 21 1988 ns32k-pinsn.c
-rw-rw-r-- 2 5057 staff 12230 Jun 17 1988 obstack.c
-rw-rw-r-- 2 5057 staff 18478 Jul 24 1988 obstack.h
-rw-rw-r-- 4 5057 staff 68314 Apr 8 1988 opcode.h
-rw-rw-r-- 4 5057 staff 18051 Apr 6 1988 param.h
-rw-rw-r-- 4 5057 staff 17695 Jun 21 1988 pinsn.c
-rw-rw-r-- 2 5057 staff 12573 Jun 16 1988 pn-opcode.h
-rw-rw-r-- 2 5057 staff 31150 Jul 22 1988 printcmd.c
-rw-rw-r-- 2 5057 staff 13024 Apr 7 1988 remote.c
-rw-rw-r-- 2 5057 staff 22485 May 23 1988 source.c
-rw-rw-r-- 2 5057 staff 16743 May 23 1988 stack.c
-rw-rw-r-- 2 5057 staff 12067 May 3 1988 standalone.c
-rw-rw-r-- 2 5057 staff 5366 Sep 30 1986 stuff.c
-rw-rw-r-- 2 5057 staff 15537 Jul 26 1988 symmisc.c
-rw-rw-r-- 2 5057 staff 13976 Feb 17 1988 symseg.h
-rw-rw-r-- 2 5057 staff 30879 Apr 8 1988 symtab.c
-rw-rw-r-- 2 5057 staff 8030 Apr 8 1988 symtab.h
-rw-rw-r-- 2 5057 staff 303 Jul 15 1986 test2.c
-rw-rw-r-- 2 5057 staff 602 Apr 9 1988 testbpt.c
-rw-rw-r-- 2 5057 staff 205 Jan 2 1988 testfun.c
-rw-rw-r-- 2 5057 staff 79 Jul 15 1986 testrec.c
-rw-rw-r-- 2 5057 staff 365 Jul 15 1986 testreg.c
-rw-rw-r-- 2 5057 staff 387 Dec 3 1987 testregs.c
-rw-rw-r-- 2 5057 staff 9872 May 30 1988 utils.c
-rw-rw-r-- 2 5057 staff 8374 Dec 17 1987 valarith.c
-rw-rw-r-- 2 5057 staff 16436 Jan 7 1988 valops.c
-rw-rw-r-- 2 5057 staff 17003 Sep 3 1988 valprint.c
-rw-rw-r-- 2 5057 staff 3799 Feb 6 1988 value.h
-rw-rw-r-- 2 5057 staff 19062 May 20 1988 values.c
-rw-rw-r-- 2 5057 staff 12750 Jul 15 1986 vax-opcode.h
-rw-rw-r-- 2 5057 staff 5681 Jun 21 1988 vax-pinsn.c
-rw-rw-r-- 2 5057 staff 73 Sep 8 1988 version.c
-rw-rw-r-- 2 5057 staff 961 May 1 1988 wait.h
-rw-rw-r-- 2 5057 staff 19446 Jul 20 1988 xgdb.c

95
gdb/ORIGIN.ls.pmax Normal file
View File

@ -0,0 +1,95 @@
total 1338
drwxr-xr-x 2 bin system 2048 Aug 11 01:16 .
drwxr-xr-x 11 bin system 512 Sep 5 01:14 ..
-rw-r--r-- 2 5057 staff 7517 Feb 11 1988 COPYING
-rw-r--r-- 2 5057 staff 58620 Sep 3 1988 ChangeLog
-rw-r--r-- 2 5057 staff 4698 Sep 3 1988 Makefile
-rw-r--r-- 2 5057 staff 1168 Jul 8 1988 README
-rw-r--r-- 2 5057 staff 30273 May 6 1988 TAGS
-rw-r--r-- 2 5057 staff 8285 Mar 24 1988 blockframe.c
-rw-r--r-- 2 5057 staff 28258 Jun 9 1988 breakpoint.c
-rw-r--r-- 2 5057 staff 46897 Jul 12 1988 coffread.c
-rw-r--r-- 2 5057 staff 14515 Mar 25 1988 command.c
-rw-r--r-- 2 5057 staff 7397 Feb 11 1988 command.h
-rwxr-xr-x 2 5057 staff 2273 Sep 1 1988 config.gdb
-rw-r--r-- 2 5057 staff 19678 May 3 1988 core.c
-rw-r--r-- 2 5057 staff 69156 Jul 6 1988 dbxread.c
-rw-r--r-- 2 5057 staff 2499 May 22 1988 defs.h
-rw-r--r-- 2 5057 staff 8436 Feb 11 1988 environ.c
-rw-r--r-- 2 5057 staff 615 Jul 15 1986 environ.h
-rw-r--r-- 2 5057 staff 16501 Feb 3 1988 eval.c
-rw-r--r-- 2 5057 staff 9484 May 30 1988 expprint.c
-rw-r--r-- 2 5057 staff 27745 Apr 30 1988 expread.y
-rw-r--r-- 2 5057 staff 6455 Nov 22 1986 expression.h
-rw-r--r-- 2 5057 staff 10805 Jun 27 1988 findvar.c
-rw-r--r-- 2 5057 staff 7052 Feb 11 1988 firstfile.c
-rw-r--r-- 2 5057 staff 2287 Sep 30 1986 frame.h
-rw-r--r-- 2 5057 staff 4006 Apr 13 1987 gdb.1
-rw-r--r-- 2 5057 staff 41892 Sep 2 1988 gdb.ideas
-rw-r--r-- 2 5057 staff 6759 Jun 21 1988 gld-pinsn.c
-rw-r--r-- 2 5057 staff 23615 Jun 27 1988 infcmd.c
-rw-r--r-- 2 5057 staff 2820 Feb 3 1988 inferior.h
-rw-r--r-- 2 5057 staff 23111 Sep 3 1988 inflow.c
-rw-r--r-- 2 5057 staff 29393 Jun 25 1988 infrun.c
-rw-r--r-- 2 5057 staff 6545 Jun 21 1988 initialize.h
-rw-r--r-- 2 5057 staff 409 Jul 15 1986 kdb-start.c
-rw-r--r-- 2 5057 staff 172 Jul 15 1986 lastfile.c
-rw-r--r-- 2 5057 staff 20054 Apr 11 1988 m-hp9k320.h
-rw-r--r-- 2 5057 staff 19325 Sep 1 1988 m-hp9k320bsd.h
-rw-r--r-- 4 5057 staff 141 Feb 6 1988 m-init.h
-rw-r--r-- 2 5057 staff 20411 Apr 6 1988 m-isi.h
-rw-r--r-- 2 5057 staff 348 Mar 20 1988 m-isiinit.h
-rw-r--r-- 2 5057 staff 15011 Mar 24 1988 m-merlin.h
-rw-r--r-- 2 5057 staff 19335 Aug 30 1988 m-news.h
-rw-r--r-- 2 5057 staff 146 Jan 15 1988 m-newsinit.h
-rw-r--r-- 2 5057 staff 18267 Jun 17 1988 m-npl.h
-rw-r--r-- 2 5057 staff 189 Jun 16 1988 m-nplinit.h
-rw-r--r-- 2 5057 staff 17503 Jun 17 1988 m-pn.h
-rw-r--r-- 2 5057 staff 191 Jun 16 1988 m-pninit.h
-rw-r--r-- 2 5057 staff 15507 Apr 6 1988 m-sun2.h
-rw-r--r-- 2 5057 staff 130 Jul 15 1986 m-sun2init.h
-rw-r--r-- 4 5057 staff 18051 Apr 6 1988 m-sun3.h
-rw-r--r-- 4 5057 staff 141 Feb 6 1988 m-sun3init.h
-rw-r--r-- 2 5057 staff 14711 Jun 17 1988 m-umax.h
-rw-r--r-- 2 5057 staff 147 Apr 9 1988 m-umaxinit.h
-rw-r--r-- 2 5057 staff 13590 Mar 24 1988 m-vax.h
-rw-r--r-- 2 5057 staff 141 Sep 24 1986 m-vaxinit.h
-rw-r--r-- 4 5057 staff 68314 Apr 8 1988 m68k-opcode.h
-rw-r--r-- 4 5057 staff 17695 Jun 21 1988 m68k-pinsn.c
-rw-r--r-- 2 5057 staff 34227 Jul 20 1988 main.c
-rw-r--r-- 2 5057 staff 18362 Jun 16 1988 npl-opcode.h
-rw-r--r-- 2 5057 staff 10621 Nov 25 1987 ns32k-opcode.h
-rw-r--r-- 2 5057 staff 10662 Jun 21 1988 ns32k-pinsn.c
-rw-r--r-- 2 5057 staff 12230 Jun 17 1988 obstack.c
-rw-r--r-- 2 5057 staff 18478 Jul 24 1988 obstack.h
-rw-r--r-- 4 5057 staff 68314 Apr 8 1988 opcode.h
-rw-r--r-- 4 5057 staff 18051 Apr 6 1988 param.h
-rw-r--r-- 4 5057 staff 17695 Jun 21 1988 pinsn.c
-rw-r--r-- 2 5057 staff 12573 Jun 16 1988 pn-opcode.h
-rw-r--r-- 2 5057 staff 31150 Jul 22 1988 printcmd.c
-rw-r--r-- 2 5057 staff 13024 Apr 7 1988 remote.c
-rw-r--r-- 2 5057 staff 22485 May 23 1988 source.c
-rw-r--r-- 2 5057 staff 16743 May 23 1988 stack.c
-rw-r--r-- 2 5057 staff 12067 May 3 1988 standalone.c
-rw-r--r-- 2 5057 staff 5366 Sep 30 1986 stuff.c
-rw-r--r-- 2 5057 staff 15537 Jul 26 1988 symmisc.c
-rw-r--r-- 2 5057 staff 13976 Feb 17 1988 symseg.h
-rw-r--r-- 2 5057 staff 30879 Apr 8 1988 symtab.c
-rw-r--r-- 2 5057 staff 8030 Apr 8 1988 symtab.h
-rw-r--r-- 2 5057 staff 303 Jul 15 1986 test2.c
-rw-r--r-- 2 5057 staff 602 Apr 9 1988 testbpt.c
-rw-r--r-- 2 5057 staff 205 Jan 2 1988 testfun.c
-rw-r--r-- 2 5057 staff 79 Jul 15 1986 testrec.c
-rw-r--r-- 2 5057 staff 365 Jul 15 1986 testreg.c
-rw-r--r-- 2 5057 staff 387 Dec 3 1987 testregs.c
-rw-r--r-- 2 5057 staff 9872 May 30 1988 utils.c
-rw-r--r-- 2 5057 staff 8374 Dec 17 1987 valarith.c
-rw-r--r-- 2 5057 staff 16436 Jan 7 1988 valops.c
-rw-r--r-- 2 5057 staff 17003 Sep 3 1988 valprint.c
-rw-r--r-- 2 5057 staff 3799 Feb 6 1988 value.h
-rw-r--r-- 2 5057 staff 19062 May 20 1988 values.c
-rw-r--r-- 2 5057 staff 12750 Jul 15 1986 vax-opcode.h
-rw-r--r-- 2 5057 staff 5681 Jun 21 1988 vax-pinsn.c
-rw-r--r-- 2 5057 staff 73 Sep 8 1988 version.c
-rw-r--r-- 2 5057 staff 961 May 1 1988 wait.h
-rw-r--r-- 2 5057 staff 19446 Jul 20 1988 xgdb.c

32
gdb/README Normal file
View File

@ -0,0 +1,32 @@
This is GDB, a source-level debugger intended for GNU,
presently running under un*x.
Before compiling GDB, you must set up links to four files according to
the kind of machine you are running on. To do this, type `config.gdb
machine', where machine is something like `vax' or `sun2'. This
creates links named `param.h', `m-init.h', `opcode.h', and `pinsn.c'.
(Note: we lack information on certain machines.)
Also, `Makefile' must be changed to say `OBSTACK = obstack.o' instead
of `OBSTACK=-lobstack' (unless you want to install obstack.o as
/lib/libobstack.a).
Once these files are set up, just `make' will do everything,
producing an executable `gdb' in this directory.
About the machine-dependent files...
m-<machine>.h
This file contains macro definitions that express information
about the machine's registers, stack frame format and instructions.
m-<machine>init.h
This file defines one macro, which says how to round up from the
address of the end of the text of one .o file to the beginning of
the text of the next .o file.
<machine>-opcode.h, <machine>-pinsn.c
These files contain the information necessary to print instructions
for your cpu type.

1191
gdb/TAGS Normal file

File diff suppressed because it is too large Load Diff

View File

@ -297,6 +297,10 @@ find_pc_misc_function (pc)
/* Note that the last thing in the vector is always _etext. */
/* Above statement is not *always* true - fix for case where there are */
/* no misc functions at all (ie no symbol table has been read). */
if (hi < 0) return -1; /* no misc functions recorded */
/* trivial reject range test */
if (pc < misc_function_vector[0].address ||
pc > misc_function_vector[hi].address)

View File

@ -185,8 +185,11 @@ commands_command (arg)
if (b->number == bnum)
{
if (input_from_terminal_p ())
printf ("Type commands for when breakpoint %d is hit, one per line.\n\
{
printf ("Type commands for when breakpoint %d is hit, one per line.\n\
End with a line saying just \"end\".\n", bnum);
fflush (stdout);
}
l = read_command_lines ();
free_command_lines (&b->commands);
b->commands = l;
@ -316,6 +319,16 @@ breakpoint_here_p (pc)
return 0;
}
/* Evaluate the expression EXP and return 1 if value is zero.
This is used inside a catch_errors to evaluate the breakpoint condition. */
int
breakpoint_cond_eval (exp)
struct expression *exp;
{
return value_zerop (evaluate_expression (exp));
}
/* Return 0 if PC is not the address just after a breakpoint,
or -1 if breakpoint says do not stop now,
or -2 if breakpoint says it has deleted itself and don't stop,
@ -344,7 +357,9 @@ breakpoint_stop_status (pc, frame)
int value_zero;
if (b->cond)
{
value_zero = value_zerop (evaluate_expression (b->cond));
value_zero
= catch_errors (breakpoint_cond_eval, b->cond,
"Error occurred in testing breakpoint condition.");
free_all_values ();
}
if (b->cond && value_zero)
@ -607,96 +622,63 @@ set_breakpoint (s, line, tempflag)
}
/* Set a breakpoint according to ARG (function, linenum or *address)
and make it temporary if TEMPFLAG is nonzero.
LINE_NUM is for C++. */
and make it temporary if TEMPFLAG is nonzero. */
static void
break_command_1 (arg, tempflag, from_tty, line_num)
break_command_1 (arg, tempflag, from_tty)
char *arg;
int tempflag, from_tty, line_num;
int tempflag, from_tty;
{
struct symtabs_and_lines sals;
struct symtab_and_line sal;
register struct expression *cond = 0;
register struct breakpoint *b;
char *save_arg;
int i;
sals.sals = NULL;
sals.nelts = 0;
sal.line = sal.pc = sal.end = 0;
sal.symtab = 0;
sal.pc = 0;
if (arg)
{
CORE_ADDR pc;
sals = decode_line_1 (&arg, 1, 0, 0);
sal = decode_line_1 (&arg, 1, 0, 0);
if (! sals.nelts) return;
save_arg = arg;
for (i = 0; i < sals.nelts; i++)
if (sal.pc == 0 && sal.symtab != 0)
{
sal = sals.sals[i];
if (sal.pc == 0 && sal.symtab != 0)
{
pc = find_line_pc (sal.symtab, sal.line);
if (pc == 0)
error ("No line %d in file \"%s\".",
sal.line, sal.symtab->filename);
}
else pc = sal.pc;
sal.pc = find_line_pc (sal.symtab, sal.line);
if (sal.pc == 0)
error ("No line %d in file \"%s\".",
sal.line, sal.symtab->filename);
}
while (*arg)
{
if (arg[0] == 'i' && arg[1] == 'f'
&& (arg[2] == ' ' || arg[2] == '\t'))
cond = (struct expression *) parse_c_1 ((arg += 2, &arg),
block_for_pc (pc), 0);
else
error ("Junk at end of arguments.");
}
arg = save_arg;
sals.sals[i].pc = pc;
while (*arg)
{
if (arg[0] == 'i' && arg[1] == 'f'
&& (arg[2] == ' ' || arg[2] == '\t'))
cond = (struct expression *) parse_c_1 ((arg += 2, &arg),
block_for_pc (sal.pc), 0);
else
error ("Junk at end of arguments.");
}
}
else if (default_breakpoint_valid)
{
sals.sals = (struct symtab_and_line *) malloc (sizeof (struct symtab_and_line));
sal.pc = default_breakpoint_address;
sal.line = default_breakpoint_line;
sal.symtab = default_breakpoint_symtab;
sals.sals[0] = sal;
sals.nelts = 1;
}
else
error ("No default breakpoint address now.");
for (i = 0; i < sals.nelts; i++)
{
sal = sals.sals[i];
sal.line += line_num; /** C++ **/
if (line_num != 0)
{ /* get the pc for a particular line */
sal.pc = find_line_pc (sal.symtab, sal.line);
}
if (from_tty)
describe_other_breakpoints (sal.pc);
if (from_tty)
describe_other_breakpoints (sal.pc);
b = set_raw_breakpoint (sal);
b->number = ++breakpoint_count;
b->cond = cond;
if (tempflag)
b->enable = temporary;
b = set_raw_breakpoint (sal);
b->number = ++breakpoint_count;
b->cond = cond;
if (tempflag)
b->enable = temporary;
printf ("Breakpoint %d at 0x%x", b->number, b->address);
if (b->symtab)
printf (": file %s, line %d.", b->symtab->filename, b->line_number);
printf ("\n");
}
free (sals.sals);
printf ("Breakpoint %d at 0x%x", b->number, b->address);
if (b->symtab)
printf (": file %s, line %d.", b->symtab->filename, b->line_number);
printf ("\n");
}
static void
@ -704,7 +686,7 @@ break_command (arg, from_tty)
char *arg;
int from_tty;
{
break_command_1 (arg, 0, from_tty, 0);
break_command_1 (arg, 0, from_tty);
}
static void
@ -712,7 +694,7 @@ tbreak_command (arg, from_tty)
char *arg;
int from_tty;
{
break_command_1 (arg, 1, from_tty, 0);
break_command_1 (arg, 1, from_tty);
}
static void
@ -721,72 +703,60 @@ clear_command (arg, from_tty)
int from_tty;
{
register struct breakpoint *b, *b1;
struct symtabs_and_lines sals;
struct symtab_and_line sal;
register struct breakpoint *found;
int i;
if (arg)
{
sals = decode_line_spec (arg, 1);
}
sal = decode_line_spec (arg, 1);
else
{
sals.sals = (struct symtab_and_line *) malloc (sizeof (struct symtab_and_line));
sal.line = default_breakpoint_line;
sal.symtab = default_breakpoint_symtab;
sal.pc = 0;
if (sal.symtab == 0)
error ("No source file specified.");
sals.sals[0] = sal;
sals.nelts = 1;
}
for (i = 0; i < sals.nelts; i++)
/* If exact pc given, clear bpts at that pc.
But if sal.pc is zero, clear all bpts on specified line. */
found = (struct breakpoint *) 0;
while (breakpoint_chain
&& (sal.pc ? breakpoint_chain->address == sal.pc
: (breakpoint_chain->symtab == sal.symtab
&& breakpoint_chain->line_number == sal.line)))
{
/* If exact pc given, clear bpts at that pc.
But if sal.pc is zero, clear all bpts on specified line. */
sal = sals.sals[i];
found = (struct breakpoint *) 0;
while (breakpoint_chain
&& (sal.pc ? breakpoint_chain->address == sal.pc
: (breakpoint_chain->symtab == sal.symtab
&& breakpoint_chain->line_number == sal.line)))
{
b1 = breakpoint_chain;
breakpoint_chain = b1->next;
b1->next = found;
found = b1;
}
ALL_BREAKPOINTS (b)
while (b->next
&& (sal.pc ? b->next->address == sal.pc
: (b->next->symtab == sal.symtab
&& b->next->line_number == sal.line)))
{
b1 = b->next;
b->next = b1->next;
b1->next = found;
found = b1;
}
if (found == 0)
error ("No breakpoint at %s.", arg);
if (found->next) from_tty = 1; /* Always report if deleted more than one */
if (from_tty) printf ("Deleted breakpoint%s ", found->next ? "s" : "");
while (found)
{
if (from_tty) printf ("%d ", found->number);
b1 = found->next;
delete_breakpoint (found);
found = b1;
}
if (from_tty) putchar ('\n');
b1 = breakpoint_chain;
breakpoint_chain = b1->next;
b1->next = found;
found = b1;
}
free (sals.sals);
ALL_BREAKPOINTS (b)
while (b->next
&& (sal.pc ? b->next->address == sal.pc
: (b->next->symtab == sal.symtab
&& b->next->line_number == sal.line)))
{
b1 = b->next;
b->next = b1->next;
b1->next = found;
found = b1;
}
if (found == 0)
error ("No breakpoint at %s.", arg);
if (found->next) from_tty = 1; /* Alwats report if deleted more than one */
if (from_tty) printf ("Deleted breakpoint%s ", found->next ? "s" : "");
while (found)
{
if (from_tty) printf ("%d ", found->number);
b1 = found->next;
delete_breakpoint (found);
found = b1;
}
if (from_tty) putchar ('\n');
}
/* Delete breakpoint number BNUM if it is a `delete' breakpoint.
@ -909,13 +879,12 @@ ignore_command (args, from_tty)
char *args;
int from_tty;
{
register char *p;
register char *p = args;
register int num;
if (p == 0)
error_no_arg ("a breakpoint number");
p = args;
while (*p >= '0' && *p <= '9') p++;
if (*p && *p != ' ' && *p != '\t')
error ("First argument must be a breakpoint number.");

File diff suppressed because it is too large Load Diff

12
gdb/coffread.c.README Normal file
View File

@ -0,0 +1,12 @@
coffread.c is truncated.
It ends on a 4096-byte boundary, which makes me think it got chopped
in a disk operation, so the modification date probably doesn't reflect
the date of the damage.
We checked the backups of Sep 8, 1992 and June 3, 1991, and in both
cases it was truncated. So we would appear to be out of luck.
Someone found gdb-assorted on a dump of /s3 from cygint on November
19, 1990, but no gdb-2.8. The guess is that gdb-2.8 moved there after
/s3 moved to /work (which was apparently a new 1gig disk at the time).

1851
gdb/coffread.c.pmax Normal file

File diff suppressed because it is too large Load Diff

View File

@ -370,7 +370,7 @@ lookup_cmd (line, list, cmdtype, allow_unknown)
while (*p == '-'
|| (*p >= 'a' && *p <= 'z')
|| (*p >= 'A' && *p <= 'Z')
|| (*p >= '1' && *p <= '9'))
|| (*p >= '0' && *p <= '9'))
{
if (*p >= 'A' && *p <= 'Z')
*p += 'a' - 'A';

119
gdb/config.gdb Normal file
View File

@ -0,0 +1,119 @@
#!/bin/sh
#
# Shell script to create proper links to machine-dependent files in
# preparation for compiling gdb.
#
# Usage: config.gdb machine
#
# If config.gdb succeeds, it leaves its status in config.status.
# If config.gdb fails after disturbing the status quo,
# config.status is removed.
#
progname=$0
case $# in
1)
machine=$1
paramfile=m-${machine}.h
initfile=m-${machine}init.h
pinsnfile=${machine}-pinsn.c
opcodefile=${machine}-opcode.h
case $machine in
hp9k320)
initfile=m-sun3init.h
pinsnfile=m68k-pinsn.c
opcodefile=m68k-opcode.h
;;
hp9k320bsd)
initfile=m-sun3init.h
pinsnfile=m68k-pinsn.c
opcodefile=m68k-opcode.h
;;
isi)
# some version of m68k-pinsn.c should work here
pinsnfile=m68k-pinsn.c
opcodefile=m68k-opcode.h
;;
merlin)
# m-umaxinit.h?
initfile=unknown-or-unavailable
pinsnfile=ns32k-pinsn.c
opcodefile=ns32k-opcode.h
;;
news)
pinsnfile=m68k-pinsn.c
opcodefile=m68k-opcode.h
;;
npl)
pinsnfile=gld-pinsn.c
;;
pn)
pinsnfile=gld-pinsn.c
;;
sun2)
pinsnfile=m68k-pinsn.c
opcodefile=m68k-opcode.h
;;
sun3)
pinsnfile=m68k-pinsn.c
opcodefile=m68k-opcode.h
;;
umax)
pinsnfile=ns32k-pinsn.c
opcodefile=ns32k-opcode.h
;;
test)
paramfile=one
initfile=two
pinsnfile=three
opcodefile=four
;;
esac
files="$paramfile $initfile $pinsnfile $opcodefile"
links="param.h m-init.h pinsn.c opcode.h"
while [ -n "$files" ]
do
# set file to car of files, files to cdr of files
set $files; file=$1; shift; files=$*
set $links; link=$1; shift; links=$*
if [ ! -r $file ]
then
echo "$progname: cannot create a link \`$link',"
echo "since the file \`$file' does not exist."
exit 1
fi
rm -f $link config.status
# Make a symlink if possible, otherwise try a hard link
ln -s $file $link 2>/dev/null || ln $file $link
if [ ! -r $link ]
then
echo "$progname: unable to link \`$link' to \`$file'."
exit 1
fi
echo "Linked \`$link' to \`$file'."
done
echo "Links are now set up for use with a $machine." \
| tee config.status
exit 0
;;
*)
echo "Usage: $progname machine"
echo -n "Where \`machine' is something like "
echo "\`vax', \`sun3', \`umax', etc."
if [ -r config.status ]
then
cat config.status
fi
exit 1
;;
esac

View File

@ -42,8 +42,16 @@ anyone else from sharing it farther. Help stamp out software hoarding!
#include <sys/ptrace.h>
#else /* not UMAX_CORE */
#include <sys/user.h>
#endif
#endif /* NEW_SUN_CORE */
#ifdef HP9K320
#include <sys/reg.h>
#include <sys/trap.h>
#ifdef HPUX_VERSION_5
#define e_PS e_regs[PS]
#define e_PC e_regs[PC]
#endif /* HPUX_VERSION_5 */
#endif /* HP9K320 */
#endif /* not UMAX_CORE */
#endif /* not NEW_SUN_CORE */
#ifndef N_TXTADDR
#define N_TXTADDR(hdr) 0
@ -258,6 +266,39 @@ core_file_command (filename, from_tty)
/* Read the register values out of the core file and store
them where `read_register' will find them. */
#ifdef HP9K320
{
register int regno;
struct exception_stack es;
int val;
val = lseek (corechan, (REGISTER_ADDR (reg_offset, 0)), 0);
if (val < 0)
perror_with_name (filename);
val = myread (corechan, es,
((char *) &es.e_regs[R0] - (char *) &es.e_offset));
if (val < 0)
perror_with_name (filename);
for (regno = 0; (regno < PS_REGNUM); regno++)
supply_register (regno, &es.e_regs[regno + R0]);
val = es.e_PS;
supply_register (regno++, &val);
supply_register (regno++, &es.e_PC);
for (; (regno < NUM_REGS); regno++)
{
char buf[MAX_REGISTER_RAW_SIZE];
val = lseek (corechan, (FP_REGISTER_ADDR (u, regno)), 0);
if (val < 0)
perror_with_name (filename);
val = myread (corechan, buf, sizeof buf);
if (val < 0)
perror_with_name (filename);
supply_register (regno, buf);
}
}
#else /* not HP9K320 */
{
register int regno;
@ -275,6 +316,7 @@ core_file_command (filename, from_tty)
supply_register (regno, buf);
}
}
#endif /* not HP9K320 */
}
#endif /* not NEW_SUN_CORE */
if (filename[0] == '/')
@ -357,17 +399,30 @@ exec_file_command (filename, from_tty)
{
struct stat st_exec;
#ifdef gould
FILHDR exec_coffhdr;
val = myread (execchan, &exec_coffhdr, sizeof exec_coffhdr);
if (val < 0)
perror_with_name (filename);
#endif
val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
if (val < 0)
perror_with_name (filename);
text_start = N_TXTADDR (exec_aouthdr);
text_end = text_start + exec_aouthdr.a_text;
text_start = N_TXTADDR (exec_aouthdr);
exec_data_start = N_DATADDR (exec_aouthdr);
#ifdef gould
text_offset = N_TXTOFF (exec_coffhdr, exec_aouthdr);
exec_data_offset = N_TXTOFF (exec_coffhdr, exec_aouthdr)
+ exec_aouthdr.a_text;
#else
text_offset = N_TXTOFF (exec_aouthdr);
exec_data_start = N_DATADDR (exec_aouthdr);
exec_data_end = exec_data_start + exec_aouthdr.a_data;
exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
#endif
text_end = text_start + exec_aouthdr.a_text;
exec_data_end = exec_data_start + exec_aouthdr.a_data;
data_start = exec_data_start;
data_end += exec_data_start;
@ -383,8 +438,7 @@ exec_file_command (filename, from_tty)
/* Tell display code (if any) about the changed file name. */
if (exec_file_display_hook)
(*exec_file_display_hook)
(filename ? filename : "No executable specified.\n");
(*exec_file_display_hook) (filename);
}
/* Call this to specify the hook for exec_file_command to call back.
@ -439,10 +493,15 @@ validate_files ()
}
}
/* Return the name of the executable file as a string.
ERR nonzero means get error if there is none specified;
otherwise return 0 in that case. */
char *
get_exec_file ()
get_exec_file (err)
int err;
{
if (execfile == 0)
if (err && execfile == 0)
error ("No executable file specified.\n\
Use the \"exec-file\" and \"symbol-file\" commands.");
return execfile;
@ -648,9 +707,10 @@ myread (desc, addr, len)
len -= val;
addr += val;
}
return orglen;
}
#ifndef NEW_SUN_CORE
#ifdef REGISTER_U_ADDR
/* Return the address in the core dump or inferior of register REGNO.
BLOCKEND is the address of the end of the user structure. */
@ -670,7 +730,7 @@ register_addr (regno, blockend)
return addr;
}
#endif /* not NEW_SUN_CORE */
#endif /* REGISTER_U_ADDR */
static
initialize ()

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@ anyone else from sharing it farther. Help stamp out software hoarding!
extern char *savestring ();
extern char *concat ();
extern char *xmalloc (), *xrealloc ();
extern char *alloca ();
extern int parse_escape ();
extern char *reg_names[];

View File

@ -136,8 +136,8 @@ evaluate_subexp (exp, pos, noside)
{
enum exp_opcode op;
int tem;
register int pc, pc2, *oldpos;
register value arg1, arg2, arg3;
register int pc;
register value arg1, arg2;
int nargs;
value *argvec;
@ -146,12 +146,6 @@ evaluate_subexp (exp, pos, noside)
switch (op)
{
case OP_SCOPE:
tem = strlen (&exp->elts[pc + 2].string);
(*pos) += 3 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
return value_static_field (exp->elts[pc + 1].type,
&exp->elts[pc + 2].string, -1);
case OP_LONG:
(*pos) += 3;
return value_from_long (exp->elts[pc + 1].type,
@ -180,6 +174,21 @@ evaluate_subexp (exp, pos, noside)
(*pos) += 2;
return value_of_internalvar (exp->elts[pc + 1].internalvar);
case OP_FUNCALL:
(*pos) += 2;
nargs = exp->elts[pc + 1].longconst;
argvec = (value *) alloca (sizeof (value) * (nargs + 1));
for (tem = 0; tem <= nargs; tem++)
/* Ensure that array expressions are coerced into pointer objects. */
argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0])));
return call_function (argvec[0], nargs, argvec + 1);
case OP_STRING:
tem = strlen (&exp->elts[pc + 1].string);
(*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
@ -202,146 +211,13 @@ evaluate_subexp (exp, pos, noside)
return arg2;
}
case OP_FUNCALL:
(*pos) += 2;
op = exp->elts[*pos].opcode;
if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
{
int fnptr;
int tem2;
nargs = exp->elts[pc + 1].longconst + 1;
/* First, evaluate the structure into arg2 */
pc2 = (*pos)++;
if (noside == EVAL_SKIP)
goto nosideret;
if (op == STRUCTOP_MEMBER)
{
arg2 = evaluate_subexp_for_address (exp, pos, noside);
}
else
{
arg2 = evaluate_subexp (exp, pos, noside);
}
/* If the function is a virtual function, then the
aggregate value (providing the structure) plays
its part by providing the vtable. Otherwise,
it is just along for the ride: call the function
directly. */
arg1 = evaluate_subexp (exp, pos, noside);
fnptr = value_as_long (arg1);
if (fnptr < 128)
{
struct type *basetype;
int i, j;
basetype = TYPE_TARGET_TYPE (VALUE_TYPE (arg2));
basetype = TYPE_VPTR_BASETYPE (basetype);
for (i = TYPE_NFN_FIELDS (basetype) - 1; i >= 0; i--)
{
struct fn_field *f = TYPE_FN_FIELDLIST1 (basetype, i);
/* If one is virtual, then all are virtual. */
if (TYPE_FN_FIELD_VIRTUAL_P (f, 0))
for (j = TYPE_FN_FIELDLIST_LENGTH (basetype, i) - 1; j >= 0; --j)
if (TYPE_FN_FIELD_VOFFSET (f, j) == fnptr)
{
value vtbl;
value base = value_ind (arg2);
struct type *fntype = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
if (TYPE_VPTR_FIELDNO (basetype) < 0)
TYPE_VPTR_FIELDNO (basetype)
= fill_in_vptr_fieldno (basetype);
VALUE_TYPE (base) = basetype;
vtbl = value_field (base, TYPE_VPTR_FIELDNO (basetype));
VALUE_TYPE (vtbl) = lookup_pointer_type (fntype);
VALUE_TYPE (arg1) = builtin_type_int;
arg1 = value_subscript (vtbl, arg1);
VALUE_TYPE (arg1) = fntype;
goto got_it;
}
}
if (i < 0)
error ("virtual function at index %d not found", fnptr);
}
else
{
VALUE_TYPE (arg1) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)));
}
got_it:
/* Now, say which argument to start evaluating from */
tem = 2;
}
else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
{
/* Hair for method invocations */
int tem2;
nargs = exp->elts[pc + 1].longconst + 1;
/* First, evaluate the structure into arg2 */
pc2 = (*pos)++;
tem2 = strlen (&exp->elts[pc2 + 1].string);
*pos += 2 + (tem2 + sizeof (union exp_element)) / sizeof (union exp_element);
if (noside == EVAL_SKIP)
goto nosideret;
if (op == STRUCTOP_STRUCT)
{
arg2 = evaluate_subexp_for_address (exp, pos, noside);
}
else
{
arg2 = evaluate_subexp (exp, pos, noside);
}
/* Now, say which argument to start evaluating from */
tem = 2;
}
else
{
nargs = exp->elts[pc + 1].longconst;
tem = 0;
}
argvec = (value *) alloca (sizeof (value) * (nargs + 2));
for (; tem <= nargs; tem++)
/* Ensure that array expressions are coerced into pointer objects. */
argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside);
/* signal end of arglist */
argvec[tem] = 0;
if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
{
argvec[1] = arg2;
argvec[0] =
value_struct_elt (arg2, argvec+1, &exp->elts[pc2 + 1].string,
op == STRUCTOP_STRUCT
? "structure" : "structure pointer");
}
else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
{
argvec[1] = arg2;
argvec[0] = arg1;
}
if (noside == EVAL_SKIP)
goto nosideret;
if (noside == EVAL_AVOID_SIDE_EFFECTS)
return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0])));
return call_function (argvec[0], nargs, argvec + 1);
case STRUCTOP_STRUCT:
tem = strlen (&exp->elts[pc + 1].string);
(*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
arg1 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
return value_struct_elt (arg1, 0, &exp->elts[pc + 1].string,
return value_struct_elt (arg1, &exp->elts[pc + 1].string,
"structure");
case STRUCTOP_PTR:
@ -350,46 +226,15 @@ evaluate_subexp (exp, pos, noside)
arg1 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
return value_struct_elt (arg1, 0, &exp->elts[pc + 1].string,
return value_struct_elt (arg1, &exp->elts[pc + 1].string,
"structure pointer");
case STRUCTOP_MEMBER:
arg1 = evaluate_subexp_for_address (exp, pos, noside);
arg2 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
/* Now, convert these values to an address.
@@ We do not know what type we are looking for,
@@ so we must assume that the value requested is a
@@ member address (as opposed to a member function address). */
arg3 = value_from_long (builtin_type_long,
value_as_long (arg1) + value_as_long (arg2));
VALUE_TYPE (arg3) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)));
return value_ind (arg3);
case STRUCTOP_MPTR:
arg1 = evaluate_subexp (exp, pos, noside);
arg2 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
/* Now, convert these values to an address.
@@ We do not know what type we are looking for,
@@ so we must assume that the value requested is a
@@ member address (as opposed to a member function address). */
arg3 = value_from_long (builtin_type_long,
value_as_long (arg1) + value_as_long (arg2));
VALUE_TYPE (arg3) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg2)));
return value_ind (arg3);
case BINOP_ASSIGN:
arg1 = evaluate_subexp (exp, pos, noside);
arg2 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
if (binop_must_be_user_defined (arg1, arg2))
return value_x_binop (arg1, arg2, op, 0);
else
return value_assign (arg1, arg2);
return value_assign (arg1, arg2);
case BINOP_ASSIGN_MODIFY:
(*pos) += 2;
@ -398,9 +243,7 @@ evaluate_subexp (exp, pos, noside)
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
op = exp->elts[pc + 1].opcode;
if (binop_must_be_user_defined (arg1, arg2))
return value_x_binop (arg1, arg2, BINOP_ASSIGN_MODIFY, op);
else if (op == BINOP_ADD)
if (op == BINOP_ADD)
arg2 = value_add (arg1, arg2);
else if (op == BINOP_SUB)
arg2 = value_sub (arg1, arg2);
@ -413,20 +256,14 @@ evaluate_subexp (exp, pos, noside)
arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_must_be_user_defined (arg1, arg2))
return value_x_binop (arg1, arg2, op, 0);
else
return value_add (arg1, arg2);
return value_add (arg1, arg2);
case BINOP_SUB:
arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_must_be_user_defined (arg1, arg2))
return value_x_binop (arg1, arg2, op, 0);
else
return value_sub (arg1, arg2);
return value_sub (arg1, arg2);
case BINOP_MUL:
case BINOP_DIV:
@ -440,142 +277,78 @@ evaluate_subexp (exp, pos, noside)
arg2 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_must_be_user_defined (arg1, arg2))
return value_x_binop (arg1, arg2, op, 0);
else
return value_binop (arg1, arg2, op);
return value_binop (arg1, arg2, op);
case BINOP_SUBSCRIPT:
arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_must_be_user_defined (arg1, arg2))
return value_x_binop (arg1, arg2, op, 0);
else
return value_subscript (arg1, arg2, op);
return value_subscript (arg1, arg2, op);
case BINOP_AND:
arg1 = evaluate_subexp (exp, pos, noside);
if (binop_must_be_user_defined (arg1, arg2))
{
arg2 = evaluate_subexp (exp, pos, noside);
return value_x_binop (arg1, arg2, op, 0);
}
else
{
tem = value_zerop (arg1);
arg2 = evaluate_subexp (exp, pos,
(tem ? EVAL_SKIP : noside));
return value_from_long (builtin_type_int,
!tem && !value_zerop (arg2));
}
tem = value_zerop (arg1);
arg2 = evaluate_subexp (exp, pos,
(tem ? EVAL_SKIP : noside));
return value_from_long (builtin_type_int,
!tem && !value_zerop (arg2));
case BINOP_OR:
arg1 = evaluate_subexp (exp, pos, noside);
if (binop_must_be_user_defined (arg1, arg2))
{
arg2 = evaluate_subexp (exp, pos, noside);
return value_x_binop (arg1, arg2, op, 0);
}
else
{
tem = value_zerop (arg1);
arg2 = evaluate_subexp (exp, pos,
(!tem ? EVAL_SKIP : noside));
return value_from_long (builtin_type_int,
!tem || !value_zerop (arg2));
}
tem = value_zerop (arg1);
arg2 = evaluate_subexp (exp, pos,
(!tem ? EVAL_SKIP : noside));
return value_from_long (builtin_type_int,
!tem || !value_zerop (arg2));
case BINOP_EQUAL:
arg1 = evaluate_subexp (exp, pos, noside);
arg2 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_must_be_user_defined (arg1, arg2))
{
return value_x_binop (arg1, arg2, op, 0);
}
else
{
tem = value_equal (arg1, arg2);
return value_from_long (builtin_type_int, tem);
}
tem = value_equal (arg1, arg2);
return value_from_long (builtin_type_int, tem);
case BINOP_NOTEQUAL:
arg1 = evaluate_subexp (exp, pos, noside);
arg2 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_must_be_user_defined (arg1, arg2))
{
return value_x_binop (arg1, arg2, op, 0);
}
else
{
tem = value_equal (arg1, arg2);
return value_from_long (builtin_type_int, ! tem);
}
tem = value_equal (arg1, arg2);
return value_from_long (builtin_type_int, ! tem);
case BINOP_LESS:
arg1 = evaluate_subexp (exp, pos, noside);
arg2 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_must_be_user_defined (arg1, arg2))
{
return value_x_binop (arg1, arg2, op, 0);
}
else
{
tem = value_less (arg1, arg2);
return value_from_long (builtin_type_int, tem);
}
tem = value_less (arg1, arg2);
return value_from_long (builtin_type_int, tem);
case BINOP_GTR:
arg1 = evaluate_subexp (exp, pos, noside);
arg2 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_must_be_user_defined (arg1, arg2))
{
return value_x_binop (arg1, arg2, op, 0);
}
else
{
tem = value_less (arg2, arg1);
return value_from_long (builtin_type_int, tem);
}
tem = value_less (arg2, arg1);
return value_from_long (builtin_type_int, tem);
case BINOP_GEQ:
arg1 = evaluate_subexp (exp, pos, noside);
arg2 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_must_be_user_defined (arg1, arg2))
{
return value_x_binop (arg1, arg2, op, 0);
}
else
{
tem = value_less (arg1, arg2);
return value_from_long (builtin_type_int, ! tem);
}
tem = value_less (arg1, arg2);
return value_from_long (builtin_type_int, ! tem);
case BINOP_LEQ:
arg1 = evaluate_subexp (exp, pos, noside);
arg2 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (binop_must_be_user_defined (arg1, arg2))
{
return value_x_binop (arg1, arg2, op, 0);
}
else
{
tem = value_less (arg2, arg1);
return value_from_long (builtin_type_int, ! tem);
}
tem = value_less (arg2, arg1);
return value_from_long (builtin_type_int, ! tem);
case BINOP_REPEAT:
arg1 = evaluate_subexp (exp, pos, noside);
@ -592,28 +365,19 @@ evaluate_subexp (exp, pos, noside)
arg1 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (unop_must_be_user_defined (arg1))
return value_x_unop (arg1, op, 0);
else
return value_neg (arg1);
return value_neg (arg1);
case UNOP_LOGNOT:
arg1 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (unop_must_be_user_defined (arg1))
return value_x_unop (arg1, op, 0);
else
return value_lognot (arg1);
return value_lognot (arg1);
case UNOP_ZEROP:
arg1 = evaluate_subexp (exp, pos, noside);
if (noside == EVAL_SKIP)
goto nosideret;
if (unop_must_be_user_defined (arg1))
return value_x_unop (arg1, op, 0);
else
return value_from_long (builtin_type_int, value_zerop (arg1));
return value_from_long (builtin_type_int, value_zerop (arg1));
case UNOP_IND:
arg1 = evaluate_subexp (exp, pos, noside);
@ -627,22 +391,7 @@ evaluate_subexp (exp, pos, noside)
evaluate_subexp (exp, pos, EVAL_SKIP);
goto nosideret;
}
/* C++: check for and handle pointer to members. */
op = exp->elts[*pos].opcode;
if (op == OP_SCOPE)
{
char *name = &exp->elts[pc+3].string;
int tem = strlen (name);
struct type *domain = exp->elts[pc+2].type;
(*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element);
arg1 = value_struct_elt_for_address (domain, 0, name);
if (arg1)
return arg1;
error ("no field `%s' in structure", name);
}
else
return evaluate_subexp_for_address (exp, pos, noside);
return evaluate_subexp_for_address (exp, pos, noside);
case UNOP_SIZEOF:
if (noside == EVAL_SKIP)
@ -668,68 +417,33 @@ evaluate_subexp (exp, pos, noside)
case UNOP_PREINCREMENT:
arg1 = evaluate_subexp (exp, pos, noside);
arg2 = value_add (arg1, value_from_long (builtin_type_char, 1));
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
else if (unop_must_be_user_defined (arg1))
{
return value_x_unop (arg1, op, 0);
}
else
{
arg2 = value_add (arg1, value_from_long (builtin_type_char, 1));
return value_assign (arg1, arg2);
}
return value_assign (arg1, arg2);
case UNOP_PREDECREMENT:
arg1 = evaluate_subexp (exp, pos, noside);
arg2 = value_sub (arg1, value_from_long (builtin_type_char, 1));
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
else if (unop_must_be_user_defined (arg1))
{
return value_x_unop (arg1, op, 0);
}
else
{
arg2 = value_sub (arg1, value_from_long (builtin_type_char, 1));
return value_assign (arg1, arg2);
}
return value_assign (arg1, arg2);
case UNOP_POSTINCREMENT:
arg1 = evaluate_subexp (exp, pos, noside);
arg2 = value_add (arg1, value_from_long (builtin_type_char, 1));
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
else if (unop_must_be_user_defined (arg1))
{
return value_x_unop (arg1, op, 0);
}
else
{
arg2 = value_add (arg1, value_from_long (builtin_type_char, 1));
value_assign (arg1, arg2);
return arg1;
}
value_assign (arg1, arg2);
return arg1;
case UNOP_POSTDECREMENT:
arg1 = evaluate_subexp (exp, pos, noside);
arg2 = value_sub (arg1, value_from_long (builtin_type_char, 1));
if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
return arg1;
else if (unop_must_be_user_defined (arg1))
{
return value_x_unop (arg1, op, 0);
}
else
{
arg2 = value_sub (arg1, value_from_long (builtin_type_char, 1));
value_assign (arg1, arg2);
return arg1;
}
case OP_THIS:
(*pos) += 1;
return value_of_this (1);
default:
error ("internal error: I dont know how to evaluation what you gave me");
value_assign (arg1, arg2);
return arg1;
}
nosideret:

View File

@ -79,9 +79,7 @@ static struct op_print op_print_tab[] =
{"&", UNOP_ADDR, PREC_PREFIX, 0},
{"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
{"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
{"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
/* C++ */
{"::", BINOP_SCOPE, PREC_PREFIX, 0},
{"--", UNOP_PREDECREMENT, PREC_PREFIX, 0}
};
static void print_subexp ();
@ -121,30 +119,18 @@ print_subexp (exp, pos, stream, prec)
opcode = exp->elts[pc].opcode;
switch (opcode)
{
case OP_SCOPE:
myprec = PREC_PREFIX;
assoc = 0;
(*pos) += 2;
print_subexp (exp, pos, stream, (int) myprec + assoc);
fprintf (stream, " :: ");
nargs = strlen (&exp->elts[pc + 2].string);
(*pos) += 1 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
fprintf (stream, &exp->elts[pc + 2].string);
return;
case OP_LONG:
(*pos) += 3;
value_print (value_from_long (exp->elts[pc + 1].type,
exp->elts[pc + 2].longconst),
stream);
stream, 0);
return;
case OP_DOUBLE:
(*pos) += 3;
value_print (value_from_double (exp->elts[pc + 1].type,
exp->elts[pc + 2].doubleconst),
stream);
stream, 0);
return;
case OP_VAR_VALUE:
@ -187,7 +173,7 @@ print_subexp (exp, pos, stream, prec)
(*pos) += 2 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element);
fprintf (stream, "\"");
for (tem = 0; tem < nargs; tem++)
printchar ((&exp->elts[pc + 1].string)[tem], stream);
printchar ((&exp->elts[pc + 1].string)[tem], stream, '"');
fprintf (stream, "\"");
return;

File diff suppressed because it is too large Load Diff

View File

@ -93,14 +93,10 @@ struct stoken
struct block *bval;
enum exp_opcode opcode;
struct internalvar *ivar;
struct type **tvec;
int *ivec;
}
%type <voidval> exp exp1 start variable
%type <tval> type typebase
%type <tvec> nonempty_typelist
%type <bval> block
%token <lval> INT CHAR
@ -126,9 +122,6 @@ struct stoken
%token <opcode> ASSIGN_MODIFY
/* C++ */
%token THIS
%left ','
%left ABOVE_COMMA
%right '=' ASSIGN_MODIFY
@ -203,20 +196,12 @@ exp : exp ARROW name
write_exp_elt (STRUCTOP_PTR); }
;
exp : exp ARROW '*' exp
{ write_exp_elt (STRUCTOP_MPTR); }
;
exp : exp '.' name
{ write_exp_elt (STRUCTOP_STRUCT);
write_exp_string ($3);
write_exp_elt (STRUCTOP_STRUCT); }
;
exp : exp '.' '*' exp
{ write_exp_elt (STRUCTOP_MEMBER); }
;
exp : exp '[' exp1 ']'
{ write_exp_elt (BINOP_SUBSCRIPT); }
;
@ -405,17 +390,8 @@ exp : STRING
write_exp_elt (OP_STRING); }
;
/* C++. */
exp : THIS
{ write_exp_elt (OP_THIS);
write_exp_elt (OP_THIS); }
;
/* end of C++. */
block : name
{
struct symtab *tem = lookup_symtab (copy_name ($1));
{ struct symtab *tem = lookup_symtab (copy_name ($1));
struct symbol *sym;
if (tem)
@ -430,88 +406,34 @@ block : name
else
error ("No file or function \"%s\".",
copy_name ($1));
}
}
}}
;
block : block COLONCOLON name
{
struct symbol *tem
{ struct symbol *tem
= lookup_symbol (copy_name ($3), $1, VAR_NAMESPACE);
if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK)
error ("No function \"%s\" in specified context.",
copy_name ($1));
$$ = SYMBOL_BLOCK_VALUE (tem);
}
copy_name ($3));
$$ = SYMBOL_BLOCK_VALUE (tem); }
;
variable: block COLONCOLON name
{
struct symbol *sym;
{ struct symbol *sym;
sym = lookup_symbol (copy_name ($3), $1, VAR_NAMESPACE);
if (sym == 0)
error ("No symbol \"%s\" in specified context.",
copy_name ($3));
write_exp_elt (OP_VAR_VALUE);
write_exp_elt (sym);
write_exp_elt (OP_VAR_VALUE);
}
;
variable: typebase COLONCOLON name
{
struct type *type = $1;
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
&& TYPE_CODE (type) != TYPE_CODE_UNION)
error ("`%s' is not defined as an aggregate type.",
TYPE_NAME (type));
write_exp_elt (OP_SCOPE);
write_exp_elt (type);
write_exp_string ($3);
write_exp_elt (OP_SCOPE);
}
| COLONCOLON name
{
char *name = copy_name ($2);
struct symbol *sym;
int i;
sym = lookup_symbol_2 (name, 0, VAR_NAMESPACE);
if (sym)
{
write_exp_elt (OP_VAR_VALUE);
write_exp_elt (sym);
write_exp_elt (OP_VAR_VALUE);
break;
}
for (i = 0; i < misc_function_count; i++)
if (!strcmp (misc_function_vector[i].name, name))
break;
if (i < misc_function_count)
{
write_exp_elt (OP_LONG);
write_exp_elt (builtin_type_int);
write_exp_elt (misc_function_vector[i].address);
write_exp_elt (OP_LONG);
write_exp_elt (UNOP_MEMVAL);
write_exp_elt (builtin_type_char);
write_exp_elt (UNOP_MEMVAL);
}
else
if (symtab_list == 0)
error ("No symbol table is loaded. Use the \"symbol-file\" command.");
else
error ("No symbol \"%s\" in current context.", name);
}
write_exp_elt (OP_VAR_VALUE); }
;
variable: NAME
{ struct symbol *sym;
sym = lookup_symbol_1 (copy_name ($1),
expression_context_block,
VAR_NAMESPACE);
sym = lookup_symbol (copy_name ($1),
expression_context_block,
VAR_NAMESPACE);
if (sym)
{
write_exp_elt (OP_VAR_VALUE);
@ -522,32 +444,6 @@ variable: NAME
{
register char *arg = copy_name ($1);
register int i;
int v, val;
/* C++: see if it hangs off of `this'. Must
not inadvertently convert from a method call
to data ref. */
v = (int)value_of_this (0);
if (v)
{
val = check_field (v, arg);
if (val)
{
write_exp_elt (OP_THIS);
write_exp_elt (OP_THIS);
write_exp_elt (STRUCTOP_PTR);
write_exp_string ($1);
write_exp_elt (STRUCTOP_PTR);
break;
}
}
sym = lookup_symbol_2 (arg, 0, VAR_NAMESPACE);
if (sym)
{
write_exp_elt (OP_VAR_VALUE);
write_exp_elt (sym);
write_exp_elt (OP_VAR_VALUE);
break; /* YACC-dependent */
}
for (i = 0; i < misc_function_count; i++)
if (!strcmp (misc_function_vector[i].name, arg))
break;
@ -575,17 +471,6 @@ variable: NAME
type : typebase
| type '*'
{ $$ = lookup_pointer_type ($1); }
| type '&'
{ $$ = lookup_reference_type ($1); }
| typebase COLONCOLON '*'
{ $$ = lookup_member_type (builtin_type_int, $1); }
| type '(' typebase COLONCOLON '*' ')'
{ $$ = lookup_member_type ($1, $3); }
| type '(' typebase COLONCOLON '*' ')' '(' ')'
{ $$ = lookup_member_type (lookup_function_type ($1, 0), $3); }
| type '(' typebase COLONCOLON '*' ')' '(' nonempty_typelist ')'
{ $$ = lookup_member_type (lookup_function_type ($1, $8), $3);
free ($8); }
;
typebase
@ -605,19 +490,6 @@ typebase
{ $$ = lookup_unsigned_typename (copy_name ($2)); }
;
nonempty_typelist
: type
{ $$ = (struct type **)xmalloc (sizeof (struct type *) * 2);
$$[0] = (struct type *)0;
$$[1] = $1;
}
| nonempty_typelist ',' type
{ int len = sizeof (struct type *) * ++($<ivec>1[0]);
$$ = (struct type **)xrealloc ($1, len);
$$[$<ivec>$[0]] = $3;
}
;
name : NAME
| TYPENAME
;
@ -1032,23 +904,13 @@ yylex ()
{
return STRUCT;
}
if (namelen == 5)
if (namelen == 5 && !strncmp (tokstart, "union", 5))
{
if (!strncmp (tokstart, "union", 5))
{
return UNION;
}
return UNION;
}
if (namelen == 4)
if (namelen == 4 && !strncmp (tokstart, "enum", 4))
{
if (!strncmp (tokstart, "enum", 4))
{
return ENUM;
}
if (!strncmp (tokstart, "this", 4))
{
return THIS;
}
return ENUM;
}
if (namelen == 6 && !strncmp (tokstart, "sizeof", 6))
{
@ -1129,20 +991,10 @@ length_of_subexp (expr, endpos)
register int args = 0;
register int i;
if (endpos < 0)
error ("?error in length_of_subexp");
i = (int) expr->elts[endpos - 1].opcode;
switch (i)
{
/* C++ */
case OP_SCOPE:
oplen = 4 + ((expr->elts[endpos - 2].longconst
+ sizeof (union exp_element))
/ sizeof (union exp_element));
break;
case OP_LONG:
case OP_DOUBLE:
oplen = 4;
@ -1173,6 +1025,7 @@ length_of_subexp (expr, endpos)
oplen = 3 + ((expr->elts[endpos - 2].longconst
+ sizeof (union exp_element))
/ sizeof (union exp_element));
break;
case TERNOP_COND:
@ -1184,11 +1037,6 @@ length_of_subexp (expr, endpos)
args = 2;
break;
/* C++ */
case OP_THIS:
oplen = 2;
break;
default:
args = 1 + (i < (int) BINOP_END);
}
@ -1226,13 +1074,6 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
opcode = inexpr->elts[inend - 1].opcode;
switch (opcode)
{
/* C++ */
case OP_SCOPE:
oplen = 4 + ((inexpr->elts[inend - 2].longconst
+ sizeof (union exp_element))
/ sizeof (union exp_element));
break;
case OP_LONG:
case OP_DOUBLE:
oplen = 4;
@ -1275,11 +1116,6 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg)
args = 2;
break;
/* C++ */
case OP_THIS:
oplen = 2;
break;
default:
args = 1 + ((int) opcode < (int) BINOP_END);
}

View File

@ -60,20 +60,6 @@ enum exp_opcode
BINOP_COMMA, /* , */
BINOP_SUBSCRIPT, /* x[y] */
BINOP_EXP, /* Exponentiation */
/* C++. */
BINOP_MIN, /* <? */
BINOP_MAX, /* >? */
BINOP_SCOPE, /* :: */
/* STRUCTOP_MEMBER is used for pointer-to-member constructs.
X . * Y translates into X STRUCTOP_MEMBER Y. */
STRUCTOP_MEMBER,
/* STRUCTOP_MPTR is used for pointer-to-member constructs
when X is a pointer instead of an aggregate. */
STRUCTOP_MPTR,
/* end of C++. */
BINOP_END,
BINOP_ASSIGN_MODIFY, /* +=, -=, *=, and so on.
@ -158,17 +144,6 @@ enum exp_opcode
(after the string), followed by another STRUCTOP_... code. */
STRUCTOP_STRUCT,
STRUCTOP_PTR,
/* C++ */
/* OP_THIS is just a placeholder for the class instance variable.
It just comes in a tight (OP_THIS, OP_THIS) pair. */
OP_THIS,
/* OP_SCOPE surrounds a type name and a field name. The type
name is encoded as one element, but the field name stays as
a string, which, of course, is variable length. */
OP_SCOPE,
};
union exp_element

View File

@ -212,9 +212,6 @@ read_var_value (var, frame)
int val = SYMBOL_VALUE (var);
register int len;
if (SYMBOL_CLASS (var) == LOC_BLOCK)
type = lookup_function_type (type, 0);
v = allocate_value (type);
VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */
len = TYPE_LENGTH (type);
@ -347,6 +344,7 @@ locate_var_value (var, frame)
register CORE_ADDR addr = 0;
int val = SYMBOL_VALUE (var);
struct frame_info fi;
struct type *type = SYMBOL_TYPE (var);
if (frame == 0) frame = selected_frame;
@ -362,7 +360,7 @@ locate_var_value (var, frame)
if (addr != 0)
{
union { int i; char c; } test;
int len = TYPE_LENGTH (SYMBOL_TYPE (var));
int len = TYPE_LENGTH (type);
/* If var is less than the full size of register, we need to
test for a big-endian or little-endian machine. */
test.i = 1;
@ -398,7 +396,7 @@ locate_var_value (var, frame)
break;
}
return value_cast (lookup_pointer_type (SYMBOL_TYPE (var)),
return value_cast (lookup_pointer_type (type),
value_from_long (builtin_type_long, addr));
}

File diff suppressed because it is too large Load Diff

91
gdb/gdb.1 Normal file
View File

@ -0,0 +1,91 @@
.TH GDB 1 "13 April 1987"
.UC 4
.SH NAME
gdb \- Project GNU's DeBugger
.SH SYNOPSIS
\fBgdb\fP [ \fBoptions\fP ] See documentation mentioned below.
.SH DESCRIPTION
\fIgdb\fP is a source level symbolic debugger for C programs, created by
Richard M. Stallman (rms) for the GNU Project, and distributed by the
Free Software Foundation. Eventually GNU (Gnu's Not Unix) will be a
complete replacement for Berkeley Unix, all of which everyone will be
able to use freely. See the \fIGNU Emacs\fP man page for pointers to more
information.
.PP
\fIgdb\fP has something of the flavor of \fIdbx\fP,
but has more features and power. It can also be used to debug o/s
kernels, but needs to be configured differently for that task.
.PP
Project GNU isn't using Unix man pages. Its style of complete
documentation can be found by:
.PP
The help and info commands inside \fIgdb\fP.
.PP
In the Info system in \fIGNU Emacs\fP. Type C-h i, and follow the
directions. This is equivalent to the reference manual for
\fIgdb\fP, and has about 55 pages of text.
.PP
\fIgdb\fP could be extended to work with other languages (e.g. Pascal) and
machines (e.g. encores). If you like, copy the sources and give it a
try. When you have it working send \fIdiff -c\fP's of the changed files to
bug-gdb@prep.ai.mit.edu (fuller details below), so they can benefit everyone.
.SH DISTRIBUTION
\fIgdb\fP is free; anyone may redistribute copies of
\fIgdb\fP to anyone under the terms stated in the
\fIgdb\fP General Public License, a copy of which accompanies each copy of
\fIgdb\fP, is readable with the info command inside \fIgdb\fP,
and which also appears in the \fIgdb\fP reference manual.
.PP
Copies of \fIgdb\fP may sometimes be received packaged with
distributions of Unix systems, but it is never included in the scope
of any license covering those systems. Such inclusion would violate
the terms on which distribution is permitted. In fact, the primary
purpose of the General Public License is to prohibit anyone from
attaching any other restrictions to redistribution of \fIgdb\fP.
.PP
You can order printed copies of the \fIgdb\fP reference manual for $10.00/copy
postpaid from the Free Software Foundation, which develops GNU software
(contact them for quantity prices on the manual). Their address is:
.nf
Free Software Foundation
1000 Mass Ave.
Cambridge, MA 02138
.fi
As with all software and publications from FSF, everyone is permitted to
make and distribute copies of the \fIgdb\fP reference manual.
The TeX source to the \fIgdb\fP reference
manual is also included in the \fIGNU Emacs\fP source distribution.
.PP
.SH OPTIONS
See documentation.
.SH EXAMPLES
See documentation.
.SH "SEE ALSO"
adb(1), sdb(1), dbx(1)
.SH BUGS
There is a mailing list, bug-gdb@prep.ai.mit.edu on the internet
(ucbvax!prep.ai.mit.edu!bug-gdb on UUCPnet), for reporting \fIgdb\fP
bugs and fixes. But before reporting something as a bug, please try
to be sure that it really is a bug, not a misunderstanding or a
deliberate feature. We ask you to read the section ``Reporting Emacs
Bugs'' near the end of the \fIGNU Emacs\fP reference manual
(or Info system) for hints
on how and when to report bugs. Also, include the version number of
the \fIgdb\fP you are running in \fIevery\fR bug report that you send in.
.PP
Do not expect a personal answer to a bug report. The purpose of reporting
bugs is to get them fixed for everyone in the next release, if possible.
For personal assistance, look in the SERVICE file
(see the \fIGNU Emacs\fP man page) for
a list of people who offer it.
.PP
Please do not send anything but bug reports to this mailing list.
Send other stuff to gnu@prep.ai.mit.edu (or the
corresponding UUCP address). For more information about GNU mailing
lists, see the file MAILINGLISTS (see the \fIGNU Emacs\fP man page). Bugs tend
actually to be fixed if they can be isolated, so it is in your
interest to report them in such a way that they can be easily
reproduced.
.PP
No bugs are known at this time.

1277
gdb/gdb.ideas Normal file

File diff suppressed because it is too large Load Diff

284
gdb/gld-pinsn.c Normal file
View File

@ -0,0 +1,284 @@
/* Print GOULD RISC instructions for GDB, the GNU debugger.
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
#include <stdio.h>
#include <a.out.h>
#include "defs.h"
#include "param.h"
#include "symtab.h"
#include "frame.h"
#include "opcode.h"
/* GOULD RISC instructions are never longer than this many bytes. */
#define MAXLEN 4
/* Number of elements in the opcode table. */
#define NOPCODES (sizeof gld_opcodes / sizeof gld_opcodes[0])
/* Print the GOULD instruction at address MEMADDR in debugged memory,
on STREAM. Returns length of the instruction, in bytes. */
int
print_insn (memaddr, stream)
CORE_ADDR memaddr;
FILE *stream;
{
unsigned char buffer[MAXLEN];
register int i;
register char *d;
register int bestmask;
unsigned best;
int temp, index, bestlen;
read_memory (memaddr, buffer, MAXLEN);
bestmask = 0;
index = -1;
best = 0xffffffff;
for (i = 0; i < NOPCODES; i++)
{
register unsigned int opcode = gld_opcodes[i].opcode;
register unsigned int mask = gld_opcodes[i].mask;
register unsigned int len = gld_opcodes[i].length;
register unsigned int test;
/* Get possible opcode bytes into integer */
test = buffer[0] << 24;
test |= buffer[1] << 16;
test |= buffer[2] << 8;
test |= buffer[3];
/* Mask with opcode and see if match */
if ((opcode & mask) == (test & mask))
{
/* See if second or third match */
if (index >= 0)
{
/* Take new one if it looks good */
if (bestlen == MAXLEN && len == MAXLEN)
{
/* See if lower bits matched */
if (((bestmask & 3) == 0) &&
((mask & 3) != 0))
{
bestmask = mask;
bestlen = len;
best = test;
index = i;
}
}
}
else
{
/* First match, save it */
bestmask = mask;
bestlen = len;
best = test;
index = i;
}
}
}
/* Handle undefined instructions. */
if (index < 0)
{
fprintf (stream, "undefined 0%o",(buffer[0]<<8)+buffer[1]);
return 2;
}
/* Print instruction name */
fprintf (stream, "%-12s", gld_opcodes[index].name);
/* Adjust if short instruction */
if (gld_opcodes[index].length < 4)
{
best >>= 16;
i = 0;
}
else
{
i = 16;
}
/* Dump out instruction arguments */
for (d = gld_opcodes[index].args; *d; ++d)
{
switch (*d)
{
case 'f':
fprintf (stream, "%d", (best >> (7 + i)) & 7);
break;
case 'r':
fprintf (stream, "r%d", (best >> (7 + i)) & 7);
break;
case 'R':
fprintf (stream, "r%d", (best >> (4 + i)) & 7);
break;
case 'b':
fprintf (stream, "b%d", (best >> (7 + i)) & 7);
break;
case 'B':
fprintf (stream, "b%d", (best >> (4 + i)) & 7);
break;
case 'v':
fprintf (stream, "b%d", (best >> (7 + i)) & 7);
break;
case 'V':
fprintf (stream, "b%d", (best >> (4 + i)) & 7);
break;
case 'X':
temp = (best >> 20) & 7;
if (temp)
fprintf (stream, "r%d", temp);
else
putc ('0', stream);
break;
case 'A':
temp = (best >> 16) & 7;
if (temp)
fprintf (stream, "(b%d)", temp);
break;
case 'S':
fprintf (stream, "#%d", best & 0x1f);
break;
case 'I':
fprintf (stream, "#%x", best & 0xffff);
break;
case 'O':
fprintf (stream, "%x", best & 0xffff);
break;
case 'h':
fprintf (stream, "%d", best & 0xfffe);
break;
case 'd':
fprintf (stream, "%d", best & 0xfffc);
break;
case 'T':
fprintf (stream, "%d", (best >> 8) & 0xff);
break;
case 'N':
fprintf (stream, "%d", best & 0xff);
break;
default:
putc (*d, stream);
break;
}
}
/* Return length of instruction */
return (gld_opcodes[index].length);
}
/*
* Find the number of arguments to a function.
*/
findarg(frame)
struct frame_info frame;
{
register struct symbol *func;
register unsigned pc;
#ifdef notdef
/* find starting address of frame function */
pc = get_pc_function_start (frame.pc);
/* find function symbol info */
func = find_pc_function (pc);
/* call blockframe code to look for match */
if (func != NULL)
return (func->value.block->nsyms / sizeof(int));
#endif
return (-1);
}
/*
* In the case of the NPL, the frame's norminal address is Br2 and the
* previous routines frame is up the stack X bytes. Finding out what
* 'X' is can be tricky.
*
* 1.) stored in the code function header xA(Br1).
* 2.) must be careful of recurssion.
*/
findframe(thisframe)
FRAME thisframe;
{
register FRAME pointer;
struct frame_info frame;
/* Setup toplevel frame structure */
frame.pc = read_pc();
frame.next_frame = 0;
frame.frame = read_register (SP_REGNUM); /* Br2 */
/* Search for this frame (start at current Br2) */
do
{
pointer = framechain(frame);
frame.next_frame = frame.frame;
frame.frame = pointer;
frame.pc = FRAME_SAVED_PC(frame.next_frame);
}
while (frame.next_frame != thisframe);
/* stop gap for now, end at __base3 */
if (frame.pc == 0)
return 0;
return pointer;
}
/*
* Gdb front-end and internal framechain routine.
* Go back up stack one level. Tricky...
*/
framechain(frame)
register struct frame_info frame;
{
register CORE_ADDR func, prevsp;
register unsigned value;
/* Get real function start address from internal frame address */
func = get_pc_function_start(frame.pc);
/* If no stack given, read register Br1 "(sp)" */
if (!frame.frame)
prevsp = read_register (SP_REGNUM);
else
prevsp = frame.frame;
/* Check function header, case #2 */
value = read_memory_integer (func, 4);
if (value)
{
/* 32bit call push value stored in function header */
prevsp += value;
}
else
{
/* read half-word from suabr at start of function */
prevsp += read_memory_integer (func + 10, 2);
}
return (prevsp);
}

View File

@ -172,7 +172,7 @@ Start it from the beginning? "))
if (args)
set_args_command (args);
exec_file = (char *) get_exec_file ();
exec_file = (char *) get_exec_file (1);
if (from_tty)
{
printf ("Starting program: %s%s\n",
@ -299,7 +299,6 @@ jump_command (arg, from_tty)
int from_tty;
{
register CORE_ADDR addr;
struct symtabs_and_lines sals;
struct symtab_and_line sal;
ERROR_NO_INFERIOR;
@ -307,14 +306,7 @@ jump_command (arg, from_tty)
if (!arg)
error_no_arg ("starting address");
sals = decode_line_spec (arg, 1);
if (sals.nelts != 1)
{
error ("Unreasonable jump request");
}
sal = sals.sals[0];
free (sals.sals);
sal = decode_line_spec (arg, 1);
if (sal.symtab == 0 && sal.pc == 0)
error ("No source file has been specified.");
@ -326,7 +318,7 @@ jump_command (arg, from_tty)
struct symbol *fn = get_frame_function (get_current_frame ());
struct symbol *sfn = find_pc_function (sal.pc);
if (fn != 0 && sfn != fn
&& ! query ("That is not in function %s. Continue there? ",
&& ! query ("Line %d is not in `%s'. Jump anyway? ",
sal.line, SYMBOL_NAME (fn)))
error ("Not confirmed.");
}
@ -482,14 +474,13 @@ finish_command (arg, from_tty)
struct type *value_type;
register value val;
if (TYPE_CODE (SYMBOL_TYPE (function)) != TYPE_CODE_VOID)
value_type = SYMBOL_TYPE (function);
else
value_type = TYPE_TARGET_TYPE (SYMBOL_TYPE (function));
if (TYPE_CODE (value_type) == TYPE_CODE_VOID)
return;
val = value_being_returned (value_type, stop_registers);
printf ("Value returned is $%d = ", record_latest_value (val));
value_print (val, stdout);
value_print (val, stdout, 0);
putchar ('\n');
}
}
@ -679,7 +670,7 @@ registers_info (addr_exp)
/* If virtual format is floating, print it that way. */
if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT
&& ! INVALID_FLOAT (virtual_buffer, REGISTER_VIRTUAL_SIZE (i)))
val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, stdout);
val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, stdout, 0);
/* Else if virtual format is too long for printf,
print in hex a byte at a time. */
else if (REGISTER_VIRTUAL_SIZE (i) > sizeof (long))
@ -743,7 +734,7 @@ attach_command (args, from_tty)
{
char *exec_file;
int pid;
int remote;
int remote = 0;
dont_repeat();
@ -765,7 +756,7 @@ attach_command (args, from_tty)
error ("Inferior not killed.");
}
exec_file = (char *) get_exec_file ();
exec_file = (char *) get_exec_file (1);
if (from_tty)
{
@ -802,13 +793,15 @@ detach_command (args, from_tty)
char *args;
int from_tty;
{
char *exec_file = (char *)get_exec_file ();
int signal = 0;
if (!inferior_pid)
error ("Not currently tracing a program\n");
if (from_tty)
{
char *exec_file = (char *)get_exec_file (0);
if (exec_file == 0)
exec_file = "";
printf ("Detaching program: %s pid %d\n",
exec_file, inferior_pid);
fflush (stdout);

View File

@ -27,14 +27,18 @@ anyone else from sharing it farther. Help stamp out software hoarding!
#include <stdio.h>
#include <sys/param.h>
#include <sys/dir.h>
#ifndef UMAX_PTRACE
#include <sys/user.h>
#endif
#include <signal.h>
#include <sys/ioctl.h>
#include <sgtty.h>
#include <fcntl.h>
#ifdef UMAX_PTRACE
#include <a.out.h>
#include <sys/ptrace.h>
#define PTRACE_ATTACH PT_ATTACH
#define PTRACE_DETACH PT_FREEPROC
#endif
#ifdef NEW_SUN_PTRACE
@ -42,6 +46,26 @@ anyone else from sharing it farther. Help stamp out software hoarding!
#include <machine/reg.h>
#endif
#ifdef HP9K320
#include <sys/ptrace.h>
#include <sys/reg.h>
#include <sys/trap.h>
#endif
#ifdef HAVE_TERMIO
#include <termio.h>
#undef TIOCGETP
#define TIOCGETP TCGETA
#undef TIOCSETN
#define TIOCSETN TCSETA
#undef TIOCSETP
#define TIOCSETP TCSETAF
#define TERMINAL struct termio
#else
#include <sgtty.h>
#define TERMINAL struct sgttyb
#endif
extern int errno;
/* Nonzero if we are debugging an attached outside process
@ -53,19 +77,27 @@ START_FILE
/* Record terminal status separately for debugger and inferior. */
static struct sgttyb sg_inferior;
static struct tchars tc_inferior;
static struct ltchars ltc_inferior;
static int lmode_inferior;
static TERMINAL sg_inferior;
static TERMINAL sg_ours;
static int tflags_inferior;
static int pgrp_inferior;
static struct sgttyb sg_ours;
static struct tchars tc_ours;
static struct ltchars ltc_ours;
static int lmode_ours;
static int tflags_ours;
#ifdef TIOCGLTC
static struct tchars tc_inferior;
static struct tchars tc_ours;
static struct ltchars ltc_inferior;
static struct ltchars ltc_ours;
static int lmode_inferior;
static int lmode_ours;
#endif /* TIOCGLTC */
#ifdef TIOCGPGRP
static int pgrp_inferior;
static int pgrp_ours;
#else
static int (*sigint_ours) ();
static int (*sigquit_ours) ();
#endif /* TIOCGPGRP */
/* Copy of inferior_io_terminal when inferior was last started. */
static char *inferior_thisrun_terminal;
@ -86,11 +118,17 @@ terminal_init_inferior ()
return;
sg_inferior = sg_ours;
tflags_inferior = tflags_ours;
#ifdef TIOCGLTC
tc_inferior = tc_ours;
ltc_inferior = ltc_ours;
lmode_inferior = lmode_ours;
tflags_inferior = tflags_ours;
#endif /* TIOCGLTC */
#ifdef TIOCGPGRP
pgrp_inferior = inferior_pid;
#endif /* TIOCGPGRP */
terminal_is_ours = 1;
}
@ -109,10 +147,19 @@ terminal_inferior ()
fcntl (0, F_SETFL, tflags_inferior);
fcntl (0, F_SETFL, tflags_inferior);
ioctl (0, TIOCSETN, &sg_inferior);
#ifdef TIOCGLTC
ioctl (0, TIOCSETC, &tc_inferior);
ioctl (0, TIOCSLTC, &ltc_inferior);
ioctl (0, TIOCLSET, &lmode_inferior);
#endif /* TIOCGLTC */
#ifdef TIOCGPGRP
ioctl (0, TIOCSPGRP, &pgrp_inferior);
#else
sigint_ours = (signal (SIGINT, SIG_IGN));
sigquit_ours = (signal (SIGQUIT, SIG_IGN));
#endif /* TIOCGPGRP */
}
terminal_is_ours = 0;
}
@ -151,38 +198,63 @@ static void
terminal_ours_1 (output_only)
int output_only;
{
#ifdef TIOCGPGRP
/* Ignore this signal since it will happen when we try to set the pgrp. */
int (*osigttou) ();
#endif /* TIOCGPGRP */
if (!terminal_is_ours) /* && inferior_thisrun_terminal == 0) */
{
terminal_is_ours = 1;
#ifdef TIOCGPGRP
osigttou = signal (SIGTTOU, SIG_IGN);
ioctl (0, TIOCGPGRP, &pgrp_inferior);
ioctl (0, TIOCSPGRP, &pgrp_ours);
signal (SIGTTOU, osigttou);
#else
signal (SIGINT, sigint_ours);
signal (SIGQUIT, sigquit_ours);
#endif /* TIOCGPGRP */
tflags_inferior = fcntl (0, F_GETFL, 0);
ioctl (0, TIOCGETP, &sg_inferior);
#ifdef TIOCGLTC
ioctl (0, TIOCGETC, &tc_inferior);
ioctl (0, TIOCGLTC, &ltc_inferior);
ioctl (0, TIOCLGET, &lmode_inferior);
#endif /* TIOCGLTC */
}
#ifdef HAVE_TERMIO
sg_ours.c_lflag |= ICANON;
if (output_only && !(sg_inferior.c_lflag & ICANON))
sg_ours.c_lflag &= ~ICANON;
#else /* not HAVE_TERMIO */
sg_ours.sg_flags &= ~RAW & ~CBREAK;
if (output_only)
sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags;
#endif /* not HAVE_TERMIO */
fcntl (0, F_SETFL, tflags_ours);
fcntl (0, F_SETFL, tflags_ours);
ioctl (0, TIOCSETN, &sg_ours);
#ifdef TIOCGLTC
ioctl (0, TIOCSETC, &tc_ours);
ioctl (0, TIOCSLTC, &ltc_ours);
ioctl (0, TIOCLSET, &lmode_ours);
#endif /* TIOCGLTC */
#ifdef HAVE_TERMIO
sg_ours.c_lflag |= ICANON;
#else /* not HAVE_TERMIO */
sg_ours.sg_flags &= ~RAW & ~CBREAK;
#endif /* not HAVE_TERMIO */
}
static void
@ -197,6 +269,20 @@ term_status_command ()
}
printf ("Inferior's terminal status (currently saved by GDB):\n");
#ifdef HAVE_TERMIO
printf ("fcntl flags = 0x%x, c_iflag = 0x%x, c_oflag = 0x%x,\n",
tflags_inferior, sg_inferior.c_iflag, sg_inferior.c_oflag);
printf ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
sg_inferior.c_cflag, sg_inferior.c_lflag, sg_inferior.c_line);
printf ("c_cc: ");
for (i = 0; (i < NCC); i += 1)
printf ("0x%x ", sg_inferior.c_cc[i]);
printf ("\n");
#else /* not HAVE_TERMIO */
printf ("fcntl flags = 0x%x, lmode = 0x%x,\nsgttyb.sg_flags = 0x%x, owner pid = %d.\n",
tflags_inferior, lmode_inferior,
sg_inferior.sg_flags, pgrp_inferior);
@ -207,7 +293,8 @@ term_status_command ()
printf ("ltchars: ");
for (i = 0; i < sizeof (struct ltchars); i++)
printf ("0x%x ", ((char *)&ltc_inferior)[i]);
printf ("\n");
#endif /* not HAVE_TERMIO */
}
static void
@ -243,19 +330,34 @@ new_tty (ttyname)
}
/* Start an inferior process and returns its pid.
ALLARGS is a vector of program-name and args.
ALLARGS is a string containing shell command to run the program.
ENV is the environment vector to pass. */
#ifndef SHELL_FILE
#define SHELL_FILE "/bin/sh"
#endif
int
create_inferior (allargs, env)
char **allargs;
char *allargs;
char **env;
{
int pid;
char *shell_command;
extern int sys_nerr;
extern char *sys_errlist[];
extern int errno;
/* If desired, concat something onto the front of ALLARGS.
SHELL_COMMAND is the result. */
#ifdef SHELL_COMMAND_CONCAT
shell_command = (char *) alloca (strlen (SHELL_COMMAND_CONCAT) + strlen (allargs) + 1);
strcpy (shell_command, SHELL_COMMAND_CONCAT);
strcat (shell_command, allargs);
#else
shell_command = allargs;
#endif
/* exec is said to fail if the executable is open. */
close_exec_file ();
@ -265,8 +367,12 @@ create_inferior (allargs, env)
if (pid == 0)
{
char *args[4];
#ifdef TIOCGPGRP
/* Run inferior in a separate process group. */
setpgrp (getpid (), getpid ());
#endif /* TIOCGPGRP */
inferior_thisrun_terminal = inferior_io_terminal;
if (inferior_io_terminal != 0)
@ -278,9 +384,15 @@ create_inferior (allargs, env)
signal (SIGINT, SIG_DFL); */
ptrace (0);
execle ("/bin/sh", "sh", "-c", allargs, 0, env);
fprintf (stderr, "Cannot exec /bin/sh: %s.\n",
args[0] = "sh";
args[1] = "-c";
args[2] = shell_command;
args[3] = 0;
execve (SHELL_FILE, args, env);
fprintf (stderr, "Cannot exec %s: %s.\n", SHELL_FILE,
errno < sys_nerr ? sys_errlist[errno] : "unknown error");
fflush (stderr);
_exit (0177);
@ -313,6 +425,18 @@ kill_inferior ()
inferior_died ();
}
/* This is used when GDB is exiting. It gives less chance of error.*/
kill_inferior_fast ()
{
if (remote_debugging)
return;
if (inferior_pid == 0)
return;
ptrace (8, inferior_pid, 0, 0);
wait (0);
}
inferior_died ()
{
inferior_pid = 0;
@ -343,7 +467,7 @@ resume (step, signal)
}
}
#ifdef NEW_SUN_PTRACE
#ifdef ATTACH_DETACH
/* Start debugging the process whose number is PID. */
@ -372,7 +496,7 @@ detach (signal)
perror_with_name ("ptrace");
attach_flag = 0;
}
#endif
#endif /* ATTACH_DETACH */
#ifdef NEW_SUN_PTRACE
@ -431,6 +555,146 @@ store_inferior_registers (regno)
}
#else
#ifdef HP9K320
#define FP_REGISTER_ADDR_DIFF(u, regno) \
(((char *) (FP_REGISTER_ADDR (u, regno))) - ((char *) &(u)))
#define INFERIOR_AR0(u) \
((ptrace \
(PT_RUAREA, inferior_pid, ((char *) &u.u_ar0 - (char *) &u), 0)) \
- KERNEL_U_ADDR)
static void
fetch_inferior_register (regno, regaddr)
register int regno;
register unsigned int regaddr;
{
#ifndef HPUX_VERSION_5
if (regno == PS_REGNUM)
{
union { int i; short s[2]; } ps_val;
int regval;
ps_val.i = (ptrace (PT_RUAREA, inferior_pid, regaddr, 0));
regval = ps_val.s[0];
supply_register (regno, &regval);
}
else
#endif /* not HPUX_VERSION_5 */
{
char buf[MAX_REGISTER_RAW_SIZE];
register int i;
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
{
*(int *) &buf[i] = ptrace (PT_RUAREA, inferior_pid, regaddr, 0);
regaddr += sizeof (int);
}
supply_register (regno, buf);
}
return;
}
static void
store_inferior_register_1 (regno, regaddr, value)
int regno;
unsigned int regaddr;
int value;
{
errno = 0;
ptrace (PT_WUAREA, inferior_pid, regaddr, value);
#if 0
/* HP-UX randomly sets errno to non-zero for regno == 25.
However, the value is correctly written, so ignore errno. */
if (errno != 0)
{
char string_buf[64];
sprintf (string_buf, "writing register number %d", regno);
perror_with_name (string_buf);
}
#endif
return;
}
static void
store_inferior_register (regno, regaddr)
register int regno;
register unsigned int regaddr;
{
#ifndef HPUX_VERSION_5
if (regno == PS_REGNUM)
{
union { int i; short s[2]; } ps_val;
ps_val.i = (ptrace (PT_RUAREA, inferior_pid, regaddr, 0));
ps_val.s[0] = (read_register (regno));
store_inferior_register_1 (regno, regaddr, ps_val.i);
}
else
#endif /* not HPUX_VERSION_5 */
{
char buf[MAX_REGISTER_RAW_SIZE];
register int i;
extern char registers[];
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
{
store_inferior_register_1
(regno, regaddr,
(*(int *) &registers[(REGISTER_BYTE (regno)) + i]));
regaddr += sizeof (int);
}
}
return;
}
void
fetch_inferior_registers ()
{
struct user u;
register int regno;
register unsigned int ar0_offset;
ar0_offset = (INFERIOR_AR0 (u));
for (regno = 0; (regno < FP0_REGNUM); regno++)
fetch_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
for (; (regno < NUM_REGS); regno++)
fetch_inferior_register (regno, (FP_REGISTER_ADDR_DIFF (u, regno)));
}
/* Store our register values back into the inferior.
If REGNO is -1, do this for all registers.
Otherwise, REGNO specifies which register (so we can save time). */
store_inferior_registers (regno)
register int regno;
{
struct user u;
register unsigned int ar0_offset;
if (regno >= FP0_REGNUM)
{
store_inferior_register (regno, (FP_REGISTER_ADDR_DIFF (u, regno)));
return;
}
ar0_offset = (INFERIOR_AR0 (u));
if (regno >= 0)
{
store_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
return;
}
for (regno = 0; (regno < FP0_REGNUM); regno++)
store_inferior_register (regno, (REGISTER_ADDR (ar0_offset, regno)));
for (; (regno < NUM_REGS); regno++)
store_inferior_register (regno, (FP_REGISTER_ADDR_DIFF (u, regno)));
return;
}
#else /* not HP9K320 */
void
fetch_inferior_registers ()
@ -469,6 +733,8 @@ store_inferior_registers (regno)
{
register unsigned int regaddr;
char buf[80];
extern char registers[];
int i;
#ifdef UMAX_PTRACE
unsigned int offset = 0;
@ -481,27 +747,38 @@ store_inferior_registers (regno)
if (regno >= 0)
{
regaddr = register_addr (regno, offset);
errno = 0;
ptrace (6, inferior_pid, regaddr, read_register (regno));
if (errno != 0)
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
{
sprintf (buf, "writing register number %d", regno);
perror_with_name (buf);
errno = 0;
ptrace (6, inferior_pid, regaddr,
*(int *) &registers[REGISTER_BYTE (regno) + i]);
if (errno != 0)
{
sprintf (buf, "writing register number %d(%d)", regno, i);
perror_with_name (buf);
}
regaddr += sizeof(int);
}
}
else for (regno = 0; regno < NUM_REGS; regno++)
{
regaddr = register_addr (regno, offset);
errno = 0;
ptrace (6, inferior_pid, regaddr, read_register (regno));
if (errno != 0)
for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof(int))
{
sprintf (buf, "writing register number %d", regno);
perror_with_name (buf);
errno = 0;
ptrace (6, inferior_pid, regaddr,
*(int *) &registers[REGISTER_BYTE (regno) + i]);
if (errno != 0)
{
sprintf (buf, "writing register number %d(%d)", regno, i);
perror_with_name (buf);
}
regaddr += sizeof(int);
}
}
}
#endif /* not HP9K320 */
#endif /* not NEW_SUN_PTRACE */
/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
@ -641,11 +918,17 @@ Report which ones can be written.");
inferior_pid = 0;
ioctl (0, TIOCGETP, &sg_ours);
fcntl (0, F_GETFL, tflags_ours);
#ifdef TIOCGLTC
ioctl (0, TIOCGETC, &tc_ours);
ioctl (0, TIOCGLTC, &ltc_ours);
ioctl (0, TIOCLGET, &lmode_ours);
fcntl (0, F_GETFL, tflags_ours);
#endif /* TIOCGLTC */
#ifdef TIOCGPGRP
ioctl (0, TIOCGPGRP, &pgrp_ours);
#endif /* TIOCGPGRP */
terminal_is_ours = 1;
}

View File

@ -29,6 +29,7 @@ anyone else from sharing it farther. Help stamp out software hoarding!
#include <stdio.h>
#include <signal.h>
#include <a.out.h>
#include <sys/file.h>
#ifdef UMAX_PTRACE
#include <sys/param.h>
@ -76,6 +77,12 @@ static int step_resume_break_duplicate;
static int trap_expected;
/* Nonzero if the next time we try to continue the inferior, it will
step one instruction and generate a spurious trace trap.
This is used to compensate for a bug in HP-UX. */
static int trap_expected_after_continue;
/* Nonzero means expecting a trace trap
and should stop the inferior and return silently when it happens. */
@ -168,17 +175,26 @@ proceed (addr, signal, step)
so that we do not stop right away. */
if (!pc_changed && breakpoint_here_p (read_pc ()))
{
oneproc = 1;
/* We will get a trace trap after one instruction.
Continue it automatically and insert breakpoints then. */
trap_expected = 1;
}
oneproc = 1;
}
else
write_register (PC_REGNUM, addr);
if (!oneproc)
if (trap_expected_after_continue)
{
/* If (step == 0), a trap will be automatically generated after
the first instruction is executed. Force step one
instruction to clear this condition. This should not occur
if step is nonzero, but it is harmless in that case. */
oneproc = 1;
trap_expected_after_continue = 0;
}
if (oneproc)
/* We will get a trace trap after one instruction.
Continue it automatically and insert breakpoints then. */
trap_expected = 1;
else
{
int temp = insert_breakpoints ();
if (temp)
@ -232,6 +248,7 @@ start_inferior ()
it will get another trace trap. Then insert breakpoints and continue. */
trap_expected = 2;
running_in_shell = 0; /* Set to 1 at first SIGTRAP, 0 at second. */
trap_expected_after_continue = 0;
breakpoints_inserted = 0;
mark_breakpoints_out ();
@ -321,10 +338,10 @@ wait_for_inferior ()
struct symtab_and_line sal;
int prev_pc;
prev_pc = read_pc ();
while (1)
{
prev_pc = read_pc ();
if (remote_debugging)
remote_wait (&w);
else
@ -545,6 +562,9 @@ wait_for_inferior ()
{
stop_print_frame = 0;
stop_stack_dummy = 1;
#ifdef HP9K320
trap_expected_after_continue = 1;
#endif
break;
}
@ -611,20 +631,27 @@ wait_for_inferior ()
continue to the end of that source line.
Otherwise, just go to end of prologue. */
if (sal.end && sal.pc != newfun_pc)
step_resume_break_address = sal.end;
else
step_resume_break_address = newfun_pc;
newfun_pc = sal.end;
step_resume_break_duplicate
= breakpoint_here_p (step_resume_break_address);
if (breakpoints_inserted)
insert_step_breakpoint ();
/* Do not specify what the fp should be when we stop
since on some machines the prologue
is where the new fp value is established. */
step_frame = 0;
/* And make sure stepping stops right away then. */
step_range_end = step_range_start;
if (newfun_pc == stop_pc)
/* We are already there: stop now. */
stop_step = 1;
else
/* Put the step-breakpoint there and go until there. */
{
step_resume_break_address = newfun_pc;
step_resume_break_duplicate
= breakpoint_here_p (step_resume_break_address);
if (breakpoints_inserted)
insert_step_breakpoint ();
/* Do not specify what the fp should be when we stop
since on some machines the prologue
is where the new fp value is established. */
step_frame = 0;
/* And make sure stepping stops right away then. */
step_range_end = step_range_start;
}
}
/* No subroutince call; stop now. */
else
@ -635,6 +662,9 @@ wait_for_inferior ()
}
}
/* Save the pc before execution, to compare with pc after stop. */
prev_pc = read_pc ();
/* If we did not do break;, it means we should keep
running the inferior and not return to debugger. */
@ -723,6 +753,11 @@ Further execution is probably impossible.\n");
breakpoint_auto_delete (stop_breakpoint);
/* If an auto-display called a function and that got a signal,
delete that auto-display to avoid an infinite recursion. */
delete_current_display ();
if (step_multi && stop_step)
return;
@ -731,7 +766,13 @@ Further execution is probably impossible.\n");
if (running_in_shell)
{
if (stop_signal == SIGSEGV)
printf ("\
{
char *exec_file = (char *) get_exec_file (1);
if (access (exec_file, X_OK) != 0)
printf ("The file \"%s\" is not executable.\n", exec_file);
else
printf ("\
You have just encountered a bug in \"sh\". GDB starts your program\n\
by running \"sh\" with a command to exec your program.\n\
This is so that \"sh\" will process wildcards and I/O redirection.\n\
@ -743,6 +784,7 @@ some variables whose values are large; then do \"run\" again.\n\
\n\
If that works, you might want to put those \"unset-env\" commands\n\
into a \".gdbinit\" file in this directory so they will happen every time.\n");
}
/* Don't confuse user with his program's symbols on sh's data. */
stop_print_frame = 0;
}

View File

@ -111,7 +111,7 @@ what you give them. Help stamp out software-hoarding! */
of the end of one object file's text to the start of the next
object file's text. */
#include "m-suninit.h"
#include "m-init.h"
/* This is used to make a file's initialization function.
It calls another function named `initialize', which must

542
gdb/m-hp9k320.h Normal file
View File

@ -0,0 +1,542 @@
/* Parameters for execution on an HP 9000 model 320, for GDB, the GNU debugger.
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
#ifndef HP9K320
#define HP9K320
#endif
/* Set flag to indicate whether HP's assembler is in use. */
#ifdef __GNU__
#ifdef __HPUX_ASM__
#define HPUX_ASM
#endif
#else
#define HPUX_ASM
#endif
/* Define this for versions of hp-ux older than 6.0 */
/* #define HPUX_VERSION_5 */
#define HAVE_TERMIO
/* Get rid of any system-imposed stack limit if possible. */
/* #define SET_STACK_LIMIT_HUGE */
/* Define this if the C compiler puts an underscore at the front
of external names before giving them to the linker. */
#define NAMES_HAVE_UNDERSCORE
/* Debugger information will be in DBX format. */
#define READ_DBX_FORMAT
/* Offset from address of function to start of its code.
Zero on most machines. */
#define FUNCTION_START_OFFSET 0
/* Advance PC across any function entry prologue instructions
to reach some "real" code. */
#define SKIP_PROLOGUE(pc) \
{ register int op = read_memory_integer (pc, 2); \
if (op == 0047126) \
pc += 4; /* Skip link #word */ \
else if (op == 0044016) \
pc += 6; /* Skip link #long */ \
}
/* Immediately after a function call, return the saved pc.
Can't go through the frames for this because on some machines
the new frame is not set up until the new function executes
some instructions. */
#define SAVED_PC_AFTER_CALL(frame) \
read_memory_integer (read_register (SP_REGNUM), 4)
/* This is the amount to subtract from u.u_ar0
to get the offset in the core file of the register values. */
#ifdef HPUX_VERSION_5
#define KERNEL_U_ADDR 0x00979000
#else
#define KERNEL_U_ADDR 0x00C01000
#endif
/* Address of end of stack space. */
#define STACK_END_ADDR 0xFFF00000
/* Stack grows downward. */
#define INNER_THAN <
/* Sequence of bytes for breakpoint instruction. */
#define BREAKPOINT {0x4e, 0x41}
/* Amount PC must be decremented by after a breakpoint.
This is often the number of bytes in BREAKPOINT
but not always. */
#define DECR_PC_AFTER_BREAK 2
/* Nonzero if instruction at PC is a return instruction. */
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e75)
/* Return 1 if P points to an invalid floating point value. */
#define INVALID_FLOAT(p, len) 0 /* Just a first guess; not checked */
/* Say how long (ordinary) registers are. */
#define REGISTER_TYPE long
/* Number of machine registers */
#define NUM_REGS 29
/* Initializer for an array of names of registers.
There should be NUM_REGS strings in this initializer. */
#define REGISTER_NAMES \
{"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
"a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \
"ps", "pc", \
"fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \
"fpcontrol", "fpstatus", "fpiaddr" }
/* Register numbers of various important registers.
Note that some of these values are "real" register numbers,
and correspond to the general registers of the machine,
and some are "phony" register numbers which are too large
to be actual register numbers as far as the user is concerned
but do serve to get the desired values when passed to read_register. */
#define FP_REGNUM 14 /* Contains address of executing stack frame */
#define SP_REGNUM 15 /* Contains address of top of stack */
#define PS_REGNUM 16 /* Contains processor status */
#define PC_REGNUM 17 /* Contains program counter */
#define FP0_REGNUM 18 /* Floating point register 0 */
#define FPC_REGNUM 26 /* 68881 control register */
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'. */
#define REGISTER_BYTES (16*4+8*12+8+12)
/* Index within `registers' of the first byte of the space for
register N. */
#define REGISTER_BYTE(N) \
((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \
: (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \
: (N) * 4)
/* Number of bytes of storage in the actual machine representation
for register N. On the 68000, all regs are 4 bytes
except the floating point regs which are 12 bytes. */
#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4)
/* Number of bytes of storage in the program's representation
for register N. On the 68000, all regs are 4 bytes
except the floating point regs which are 8-byte doubles. */
#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4)
/* Largest value REGISTER_RAW_SIZE can have. */
#define MAX_REGISTER_RAW_SIZE 12
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
#define MAX_REGISTER_VIRTUAL_SIZE 8
/* Nonzero if register N requires conversion
from raw format to virtual format. */
#define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8)
/* Convert data from raw format for register REGNUM
to virtual format for register REGNUM. */
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
convert_from_68881 ((FROM), (TO)); \
else \
bcopy ((FROM), (TO), 4); }
/* Convert data from virtual format for register REGNUM
to raw format for register REGNUM. */
#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
convert_to_68881 ((FROM), (TO)); \
else \
bcopy ((FROM), (TO), 4); }
/* Return the GDB type object for the "standard" data type
of data in register N. */
#define REGISTER_VIRTUAL_TYPE(N) \
(((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double : builtin_type_int)
/* 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. */
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
/* Write into appropriate registers a function return value
of type TYPE, given in virtual format. */
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
write_register_bytes (0, 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 (or an expression that can be used as one). */
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
#define REGISTER_ADDR(u_ar0, regno) \
(((regno) < PS_REGNUM) \
? (&((struct exception_stack *) (u_ar0))->e_regs[(regno + R0)]) \
: (((regno) == PS_REGNUM) \
? ((int *) (&((struct exception_stack *) (u_ar0))->e_PS)) \
: (&((struct exception_stack *) (u_ar0))->e_PC)))
#define FP_REGISTER_ADDR(u, regno) \
(((regno) < FPC_REGNUM) \
? (&u.u_pcb.pcb_mc68881[FMC68881_R0 + (((regno) - FP0_REGNUM) * 3)]) \
: (&u.u_pcb.pcb_mc68881[FMC68881_C + ((regno) - FPC_REGNUM)]))
/* It is safe to look for symsegs on a Sun, because Sun's ld
does not screw up with random garbage at end of file. */
#define READ_GDB_SYMSEGS
/* Describe the pointer in each stack frame to the previous stack frame
(its caller). */
/* FRAME_CHAIN takes a frame's nominal address
and produces the frame's chain-pointer.
FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
and produces the nominal address of the caller frame.
However, if FRAME_CHAIN_VALID returns zero,
it means the given frame is the outermost one and has no caller.
In that case, FRAME_CHAIN_COMBINE is not used. */
/* In the case of the Sun, the frame's nominal address
is the address of a 4-byte word containing the calling frame's address. */
#define FRAME_CHAIN(thisframe) (read_memory_integer (thisframe, 4))
#define FRAME_CHAIN_VALID(chain, thisframe) \
(chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
/* Define other aspects of the stack frame. */
#define FRAME_SAVED_PC(frame) (read_memory_integer (frame + 4, 4))
#define FRAME_ARGS_ADDRESS(fi) (fi.frame)
#define FRAME_LOCALS_ADDRESS(fi) (fi.frame)
/* Set VAL to the number of args passed to frame described by FI.
Can set VAL to -1, meaning no way to tell. */
/* We can't tell how many args there are
now that the C compiler delays popping them. */
#define FRAME_NUM_ARGS(val,fi) (val = -1)
#if 0
#define FRAME_NUM_ARGS(val, fi) \
{ register CORE_ADDR pc = FRAME_SAVED_PC (fi.frame); \
register int insn = 0177777 & read_memory_integer (pc, 2); \
val = 0; \
if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ \
val = read_memory_integer (pc + 2, 2); \
else if ((insn & 0170777) == 0050217 /* addql #N, sp */ \
|| (insn & 0170777) == 0050117) /* addqw */ \
{ val = (insn >> 9) & 7; if (val == 0) val = 8; } \
else if (insn == 0157774) /* addal #WW, sp */ \
val = read_memory_integer (pc + 2, 4); \
val >>= 2; }
#endif
/* Return number of bytes at start of arglist that are not really args. */
#define FRAME_ARGS_SKIP 8
/* Put here the code to store, into a struct frame_saved_regs,
the addresses of the saved registers of frame described by FRAME_INFO.
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. */
#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
{ register int regnum; \
register int regmask; \
register CORE_ADDR next_addr; \
register CORE_ADDR pc; \
int nextinsn; \
bzero (&frame_saved_regs, sizeof frame_saved_regs); \
if ((frame_info).pc >= (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
&& (frame_info).pc <= (frame_info).frame) \
{ next_addr = (frame_info).frame; \
pc = (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\
else \
{ pc = get_pc_function_start ((frame_info).pc); \
/* Verify we have a link a6 instruction next; \
if not we lose. If we win, find the address above the saved \
regs using the amount of storage from the link instruction. */\
if (044016 == read_memory_integer (pc, 2)) \
next_addr = (frame_info).frame + read_memory_integer (pc += 2, 4), pc+=4; \
else if (047126 == read_memory_integer (pc, 2)) \
next_addr = (frame_info).frame + read_memory_integer (pc += 2, 2), pc+=2; \
else goto lose; \
/* If have an addal #-n, sp next, adjust next_addr. */ \
if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \
next_addr += read_memory_integer (pc += 2, 4), pc += 4; \
} \
/* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \
regmask = read_memory_integer (pc + 2, 2); \
/* But before that can come an fmovem. Check for it. */ \
nextinsn = 0xffff & read_memory_integer (pc, 2); \
if (0xf227 == nextinsn \
&& (regmask & 0xff00) == 0xe000) \
{ pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr -= 12); \
regmask = read_memory_integer (pc + 2, 2); } \
if (0044327 == read_memory_integer (pc, 2)) \
{ pc += 4; /* Regmask's low bit is for register 0, the first written */ \
for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; } \
else if (0044347 == read_memory_integer (pc, 2)) \
{ pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \
for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
else if (0x2f00 == 0xfff0 & read_memory_integer (pc, 2)) \
{ regnum = 0xf & read_memory_integer (pc, 2); pc += 2; \
(frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
/* fmovemx to index of sp may follow. */ \
regmask = read_memory_integer (pc + 2, 2); \
nextinsn = 0xffff & read_memory_integer (pc, 2); \
if (0xf236 == nextinsn \
&& (regmask & 0xff00) == 0xf000) \
{ pc += 10; /* Regmask's low bit is for register fp0, the first written */ \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr += 12) - 12; \
regmask = read_memory_integer (pc + 2, 2); } \
/* clrw -(sp); movw ccr,-(sp) may follow. */ \
if (0x426742e7 == read_memory_integer (pc, 4)) \
(frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \
lose: ; \
(frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 8; \
(frame_saved_regs).regs[FP_REGNUM] = (frame_info).frame; \
(frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \
}
/* Things needed for making the inferior call functions. */
/* Push an empty stack frame, to record the current PC, etc. */
#define PUSH_DUMMY_FRAME \
{ register CORE_ADDR sp = read_register (SP_REGNUM); \
register int regnum; \
char raw_buffer[12]; \
sp = push_word (sp, read_register (PC_REGNUM)); \
sp = push_word (sp, read_register (FP_REGNUM)); \
write_register (FP_REGNUM, sp); \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
{ read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); \
sp = push_bytes (sp, raw_buffer, 12); } \
for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
sp = push_word (sp, read_register (regnum)); \
sp = push_word (sp, read_register (PS_REGNUM)); \
write_register (SP_REGNUM, sp); }
/* Discard from the stack the innermost frame,
restoring all saved registers. */
#define POP_FRAME \
{ register CORE_ADDR fp = read_register (FP_REGNUM); \
register int regnum; \
struct frame_saved_regs fsr; \
struct frame_info fi; \
char raw_buffer[12]; \
fi = get_frame_info (fp); \
get_frame_saved_regs (&fi, &fsr); \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
if (fsr.regs[regnum]) \
{ read_memory (fsr.regs[regnum], raw_buffer, 12); \
write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
if (fsr.regs[regnum]) \
write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
if (fsr.regs[PS_REGNUM]) \
write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
write_register (SP_REGNUM, fp + 8); \
set_current_frame (read_register (FP_REGNUM)); }
/* This sequence of words is the instructions
fmovem 0xff,-(sp)
moveml 0xfffc,-(sp)
clrw -(sp)
movew ccr,-(sp)
/..* The arguments are pushed at this point by GDB;
no code is needed in the dummy for this.
The CALL_DUMMY_START_OFFSET gives the position of
the following jsr instruction. *../
jsr @#32323232
addl #69696969,sp
bpt
nop
Note this is 28 bytes.
We actually start executing at the jsr, since the pushing of the
registers is done by PUSH_DUMMY_FRAME. If this were real code,
the arguments for the function called by the jsr would be pushed
between the moveml and the jsr, and we could allow it to execute through.
But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
and we cannot allow the moveml to push the registers again lest they be
taken for the arguments. */
#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e414e71}
#define CALL_DUMMY_LENGTH 28
#define CALL_DUMMY_START_OFFSET 12
/* Insert the specified number of args and function address
into a call sequence of the above form stored at DUMMYNAME. */
#define FIX_CALL_DUMMY(dummyname, fun, nargs) \
{ *(int *)((char *) dummyname + 20) = nargs * 4; \
*(int *)((char *) dummyname + 14) = fun; }
/* Interface definitions for kernel debugger KDB. */
/* Map machine fault codes into signal numbers.
First subtract 0, divide by 4, then index in a table.
Faults for which the entry in this table is 0
are not handled by KDB; the program's own trap handler
gets to handle then. */
#define FAULT_CODE_ORIGIN 0
#define FAULT_CODE_UNITS 4
#define FAULT_TABLE \
{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
0, 0, 0, 0, 0, 0, 0, 0, \
SIGILL }
#ifndef HPUX_ASM
/* Start running with a stack stretching from BEG to END.
BEG and END should be symbols meaningful to the assembler.
This is used only for kdb. */
#define INIT_STACK(beg, end) \
{ asm (".globl end"); \
asm ("movel $ end, sp"); \
asm ("clrl fp"); }
/* Push the frame pointer register on the stack. */
#define PUSH_FRAME_PTR \
asm ("movel fp, -(sp)");
/* Copy the top-of-stack to the frame pointer register. */
#define POP_FRAME_PTR \
asm ("movl (sp), fp");
/* After KDB is entered by a fault, push all registers
that GDB thinks about (all NUM_REGS of them),
so that they appear in order of ascending GDB register number.
The fault code will be on the stack beyond the last register. */
#define PUSH_REGISTERS \
{ asm ("clrw -(sp)"); \
asm ("pea 10(sp)"); \
asm ("movem $ 0xfffe,-(sp)"); }
/* Assuming the registers (including processor status) have been
pushed on the stack in order of ascending GDB register number,
restore them and return to the address in the saved PC register. */
#define POP_REGISTERS \
{ asm ("subil $8,28(sp)"); \
asm ("movem (sp),$ 0xffff"); \
asm ("rte"); }
#else /* HPUX_ASM */
/* Start running with a stack stretching from BEG to END.
BEG and END should be symbols meaningful to the assembler.
This is used only for kdb. */
#define INIT_STACK(beg, end) \
{ asm ("global end"); \
asm ("mov.l &end,%sp"); \
asm ("clr.l %a6"); }
/* Push the frame pointer register on the stack. */
#define PUSH_FRAME_PTR \
asm ("mov.l %fp,-(%sp)");
/* Copy the top-of-stack to the frame pointer register. */
#define POP_FRAME_PTR \
asm ("mov.l (%sp),%fp");
/* After KDB is entered by a fault, push all registers
that GDB thinks about (all NUM_REGS of them),
so that they appear in order of ascending GDB register number.
The fault code will be on the stack beyond the last register. */
#define PUSH_REGISTERS \
{ asm ("clr.w -(%sp)"); \
asm ("pea 10(%sp)"); \
asm ("movm.l &0xfffe,-(%sp)"); }
/* Assuming the registers (including processor status) have been
pushed on the stack in order of ascending GDB register number,
restore them and return to the address in the saved PC register. */
#define POP_REGISTERS \
{ asm ("subi.l &8,28(%sp)"); \
asm ("mov.m (%sp),&0xffff"); \
asm ("rte"); }
#endif /* HPUX_ASM */

508
gdb/m-hp9k320bsd.h Normal file
View File

@ -0,0 +1,508 @@
/* Parameters for execution on a Sun, for GDB, the GNU debugger.
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
/*
* Configuration file for HP9000/300 series machine running
* University of Utah's 4.3bsd port. This is NOT for HP-UX.
* Problems to hpbsd-bugs@cs.utah.edu
*/
#ifndef hp300
#define hp300
#endif
/* Watch out for NaNs */
#define IEEE_FLOAT
/* Get rid of any system-imposed stack limit if possible. */
#define SET_STACK_LIMIT_HUGE
/* Define this if the C compiler puts an underscore at the front
of external names before giving them to the linker. */
#define NAMES_HAVE_UNDERSCORE
/* Debugger information will be in DBX format. */
#define READ_DBX_FORMAT
/* Offset from address of function to start of its code.
Zero on most machines. */
#define FUNCTION_START_OFFSET 0
/* Advance PC across any function entry prologue instructions
to reach some "real" code. */
#define SKIP_PROLOGUE(pc) \
{ register int op = read_memory_integer (pc, 2); \
if (op == 0047126) \
pc += 4; /* Skip link #word */ \
else if (op == 0044016) \
pc += 6; /* Skip link #long */ \
}
/* Immediately after a function call, return the saved pc.
Can't go through the frames for this because on some machines
the new frame is not set up until the new function executes
some instructions. */
#define SAVED_PC_AFTER_CALL(frame) \
read_memory_integer (read_register (SP_REGNUM), 4)
/* 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 0x00917000
/* Address of end of stack space. */
#define STACK_END_ADDR 0xFFF00000
/* Stack grows downward. */
#define INNER_THAN <
/* Sequence of bytes for breakpoint instruction. */
#define BREAKPOINT {0x4e, 0x42}
/* Amount PC must be decremented by after a breakpoint.
This is often the number of bytes in BREAKPOINT
but not always. */
#define DECR_PC_AFTER_BREAK 2
/* Nonzero if instruction at PC is a return instruction. */
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e75)
/* Return 1 if P points to an invalid floating point value. */
#define INVALID_FLOAT(p, len) 0 /* Just a first guess; not checked */
/* Say how long (ordinary) registers are. */
#define REGISTER_TYPE long
/* Number of machine registers */
#define NUM_REGS 29
/* Initializer for an array of names of registers.
There should be NUM_REGS strings in this initializer. */
#define REGISTER_NAMES \
{"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
"a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \
"ps", "pc", \
"fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \
"fpcontrol", "fpstatus", "fpiaddr" }
/* Register numbers of various important registers.
Note that some of these values are "real" register numbers,
and correspond to the general registers of the machine,
and some are "phony" register numbers which are too large
to be actual register numbers as far as the user is concerned
but do serve to get the desired values when passed to read_register. */
#define FP_REGNUM 14 /* Contains address of executing stack frame */
#define SP_REGNUM 15 /* Contains address of top of stack */
#define PS_REGNUM 16 /* Contains processor status */
#define PC_REGNUM 17 /* Contains program counter */
#define FP0_REGNUM 18 /* Floating point register 0 */
#define FPC_REGNUM 26 /* 68881 control register */
#define FPS_REGNUM 27 /* 68881 status register */
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'. */
#define REGISTER_BYTES (16*4+8*12+8+12)
/* Index within `registers' of the first byte of the space for
register N. */
#define REGISTER_BYTE(N) \
((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \
: (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \
: (N) * 4)
/* Number of bytes of storage in the actual machine representation
for register N. On the 68000, all regs are 4 bytes
except the floating point regs which are 12 bytes. */
#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4)
/* Number of bytes of storage in the program's representation
for register N. On the 68000, all regs are 4 bytes
except the floating point regs which are 8-byte doubles. */
#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4)
/* Largest value REGISTER_RAW_SIZE can have. */
#define MAX_REGISTER_RAW_SIZE 12
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
#define MAX_REGISTER_VIRTUAL_SIZE 8
/* Nonzero if register N requires conversion
from raw format to virtual format. */
#define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8)
/* Convert data from raw format for register REGNUM
to virtual format for register REGNUM. */
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
convert_from_68881 ((FROM), (TO)); \
else \
bcopy ((FROM), (TO), 4); }
/* Convert data from virtual format for register REGNUM
to raw format for register REGNUM. */
#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
convert_to_68881 ((FROM), (TO)); \
else \
bcopy ((FROM), (TO), 4); }
/* Return the GDB type object for the "standard" data type
of data in register N. */
#define REGISTER_VIRTUAL_TYPE(N) \
(((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double : builtin_type_int)
/* 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. */
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
/* Write into appropriate registers a function return value
of type TYPE, given in virtual format. */
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
write_register_bytes (0, 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 (or an expression that can be used as one). */
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
/* Compensate for lack of `vprintf' function. */
#define vprintf(format, ap) _doprnt (format, ap, stdout)
/* This is a piece of magic that is given a register number REGNO
and as BLOCKEND the address in the system of the end of the user structure
and stores in ADDR the address in the kernel or core dump
of that register. */
#define REGISTER_U_ADDR(addr, blockend, regno) \
{ \
if (regno < PS_REGNUM) \
addr = (int) &((struct frame *)(blockend))->f_regs[regno]; \
else if (regno == PS_REGNUM) \
addr = (int) &((struct frame *)(blockend))->f_stackadj; \
else if (regno == PC_REGNUM) \
addr = (int) &((struct frame *)(blockend))->f_pc; \
else if (regno < FPC_REGNUM) \
addr = (int) \
&((struct user *)0)->u_pcb.pcb_fpregs.fpf_regs[((regno)-FP0_REGNUM)*3];\
else if (regno == FPC_REGNUM) \
addr = (int) &((struct user *)0)->u_pcb.pcb_fpregs.fpf_fpcr; \
else if (regno == FPS_REGNUM) \
addr = (int) &((struct user *)0)->u_pcb.pcb_fpregs.fpf_fpsr; \
else \
addr = (int) &((struct user *)0)->u_pcb.pcb_fpregs.fpf_fpiar; \
}
/* It is safe to look for symsegs on a Sun, because Sun's ld
does not screw up with random garbage at end of file. */
#define READ_GDB_SYMSEGS
/* Describe the pointer in each stack frame to the previous stack frame
(its caller). */
/* FRAME_CHAIN takes a frame's nominal address
and produces the frame's chain-pointer.
FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
and produces the nominal address of the caller frame.
However, if FRAME_CHAIN_VALID returns zero,
it means the given frame is the outermost one and has no caller.
In that case, FRAME_CHAIN_COMBINE is not used. */
/* In the case of the Sun, the frame's nominal address
is the address of a 4-byte word containing the calling frame's address. */
#define FRAME_CHAIN(thisframe) (read_memory_integer (thisframe, 4))
#define FRAME_CHAIN_VALID(chain, thisframe) \
(chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
/* Define other aspects of the stack frame. */
#define FRAME_SAVED_PC(frame) (read_memory_integer (frame + 4, 4))
#define FRAME_ARGS_ADDRESS(fi) (fi.frame)
#define FRAME_LOCALS_ADDRESS(fi) (fi.frame)
/* Set VAL to the number of args passed to frame described by FI.
Can set VAL to -1, meaning no way to tell. */
/* We can't tell how many args there are
now that the C compiler delays popping them. */
#define FRAME_NUM_ARGS(val,fi) (val = -1)
#if 0
#define FRAME_NUM_ARGS(val, fi) \
{ register CORE_ADDR pc = FRAME_SAVED_PC (fi.frame); \
register int insn = 0177777 & read_memory_integer (pc, 2); \
val = 0; \
if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ \
val = read_memory_integer (pc + 2, 2); \
else if ((insn & 0170777) == 0050217 /* addql #N, sp */ \
|| (insn & 0170777) == 0050117) /* addqw */ \
{ val = (insn >> 9) & 7; if (val == 0) val = 8; } \
else if (insn == 0157774) /* addal #WW, sp */ \
val = read_memory_integer (pc + 2, 4); \
val >>= 2; }
#endif
/* Return number of bytes at start of arglist that are not really args. */
#define FRAME_ARGS_SKIP 8
/* Put here the code to store, into a struct frame_saved_regs,
the addresses of the saved registers of frame described by FRAME_INFO.
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. */
#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
{ register int regnum; \
register int regmask; \
register CORE_ADDR next_addr; \
register CORE_ADDR pc; \
int nextinsn; \
bzero (&frame_saved_regs, sizeof frame_saved_regs); \
if ((frame_info).pc >= (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
&& (frame_info).pc <= (frame_info).frame) \
{ next_addr = (frame_info).frame; \
pc = (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\
else \
{ pc = get_pc_function_start ((frame_info).pc); \
/* Verify we have a link a6 instruction next; \
if not we lose. If we win, find the address above the saved \
regs using the amount of storage from the link instruction. */\
if (044016 == read_memory_integer (pc, 2)) \
next_addr = (frame_info).frame + read_memory_integer (pc += 2, 4), pc+=4; \
else if (047126 == read_memory_integer (pc, 2)) \
next_addr = (frame_info).frame + read_memory_integer (pc += 2, 2), pc+=2; \
else goto lose; \
/* If have an addal #-n, sp next, adjust next_addr. */ \
if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \
next_addr += read_memory_integer (pc += 2, 4), pc += 4; \
} \
/* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \
regmask = read_memory_integer (pc + 2, 2); \
/* But before that can come an fmovem. Check for it. */ \
nextinsn = 0xffff & read_memory_integer (pc, 2); \
if (0xf227 == nextinsn \
&& (regmask & 0xff00) == 0xe000) \
{ pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr -= 12); \
regmask = read_memory_integer (pc + 2, 2); } \
if (0044327 == read_memory_integer (pc, 2)) \
{ pc += 4; /* Regmask's low bit is for register 0, the first written */ \
for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; } \
else if (0044347 == read_memory_integer (pc, 2)) \
{ pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \
for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
else if (0x2f00 == 0xfff0 & read_memory_integer (pc, 2)) \
{ regnum = 0xf & read_memory_integer (pc, 2); pc += 2; \
(frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
/* fmovemx to index of sp may follow. */ \
regmask = read_memory_integer (pc + 2, 2); \
nextinsn = 0xffff & read_memory_integer (pc, 2); \
if (0xf236 == nextinsn \
&& (regmask & 0xff00) == 0xf000) \
{ pc += 10; /* Regmask's low bit is for register fp0, the first written */ \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr += 12) - 12; \
regmask = read_memory_integer (pc + 2, 2); } \
/* clrw -(sp); movw ccr,-(sp) may follow. */ \
if (0x426742e7 == read_memory_integer (pc, 4)) \
(frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \
lose: ; \
(frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 8; \
(frame_saved_regs).regs[FP_REGNUM] = (frame_info).frame; \
(frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \
}
/* Things needed for making the inferior call functions. */
/* Push an empty stack frame, to record the current PC, etc. */
#define PUSH_DUMMY_FRAME \
{ register CORE_ADDR sp = read_register (SP_REGNUM); \
register int regnum; \
char raw_buffer[12]; \
sp = push_word (sp, read_register (PC_REGNUM)); \
sp = push_word (sp, read_register (FP_REGNUM)); \
write_register (FP_REGNUM, sp); \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
{ read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); \
sp = push_bytes (sp, raw_buffer, 12); } \
for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
sp = push_word (sp, read_register (regnum)); \
sp = push_word (sp, read_register (PS_REGNUM)); \
write_register (SP_REGNUM, sp); }
/* Discard from the stack the innermost frame,
restoring all saved registers. */
#define POP_FRAME \
{ register CORE_ADDR fp = read_register (FP_REGNUM); \
register int regnum; \
struct frame_saved_regs fsr; \
struct frame_info fi; \
char raw_buffer[12]; \
fi = get_frame_info (fp); \
get_frame_saved_regs (&fi, &fsr); \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
if (fsr.regs[regnum]) \
{ read_memory (fsr.regs[regnum], raw_buffer, 12); \
write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
if (fsr.regs[regnum]) \
write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
if (fsr.regs[PS_REGNUM]) \
write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
write_register (SP_REGNUM, fp + 8); \
set_current_frame (read_register (FP_REGNUM)); }
/* This sequence of words is the instructions
fmovem 0xff,-(sp)
moveml 0xfffc,-(sp)
clrw -(sp)
movew ccr,-(sp)
/..* The arguments are pushed at this point by GDB;
no code is needed in the dummy for this.
The CALL_DUMMY_START_OFFSET gives the position of
the following jsr instruction. *../
jsr @#32323232
addl #69696969,sp
trap #2
nop
Note this is 28 bytes.
We actually start executing at the jsr, since the pushing of the
registers is done by PUSH_DUMMY_FRAME. If this were real code,
the arguments for the function called by the jsr would be pushed
between the moveml and the jsr, and we could allow it to execute through.
But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
and we cannot allow the moveml to push the registers again lest they be
taken for the arguments. */
#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e424e71}
#define CALL_DUMMY_LENGTH 28
#define CALL_DUMMY_START_OFFSET 12
/* Insert the specified number of args and function address
into a call sequence of the above form stored at DUMMYNAME. */
#define FIX_CALL_DUMMY(dummyname, fun, nargs) \
{ *(int *)((char *) dummyname + 20) = nargs * 4; \
*(int *)((char *) dummyname + 14) = fun; }
/* Interface definitions for kernel debugger KDB. */
/* Map machine fault codes into signal numbers.
First subtract 0, divide by 4, then index in a table.
Faults for which the entry in this table is 0
are not handled by KDB; the program's own trap handler
gets to handle then. */
#define FAULT_CODE_ORIGIN 0
#define FAULT_CODE_UNITS 4
#define FAULT_TABLE \
{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
0, 0, 0, 0, 0, 0, 0, 0, \
SIGILL }
/* Start running with a stack stretching from BEG to END.
BEG and END should be symbols meaningful to the assembler.
This is used only for kdb. */
#define INIT_STACK(beg, end) \
{ asm (".globl end"); \
asm ("movel #end, sp"); \
asm ("movel #0,a6"); }
/* Push the frame pointer register on the stack. */
#define PUSH_FRAME_PTR \
asm ("movel a6,sp@-");
/* Copy the top-of-stack to the frame pointer register. */
#define POP_FRAME_PTR \
asm ("movl sp@,a6");
/* After KDB is entered by a fault, push all registers
that GDB thinks about (all NUM_REGS of them),
so that they appear in order of ascending GDB register number.
The fault code will be on the stack beyond the last register. */
#define PUSH_REGISTERS \
{ asm ("clrw -(sp)"); \
asm ("pea sp@(10)"); \
asm ("movem #0xfffe,sp@-"); }
/* Assuming the registers (including processor status) have been
pushed on the stack in order of ascending GDB register number,
restore them and return to the address in the saved PC register. */
#define POP_REGISTERS \
{ asm ("subil #8,sp@(28)"); \
asm ("movem sp@,#0xffff"); \
asm ("rte"); }

View File

@ -137,7 +137,7 @@ read_memory_integer (read_register (SP_REGNUM), 4)
/* Nonzero if instruction at PC is a return instruction. */
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e76)
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e75)
/* Return 1 if P points to an invalid floating point value. */
@ -175,8 +175,14 @@ read_memory_integer (read_register (SP_REGNUM), 4)
#define FP0_REGNUM 18 /* Floating point register 0 */
#define FPC_REGNUM 26 /* 68881 control register */
#define REGISTER_U_ADDR(addr, blockend, regno) \
{ if (regno < 2) addr = blockend - 0x18 + regno * 4; \
#ifdef BSD43_ISI40D
#define BLOCKFUDGE 0x400000
#else
#define BLOCKFUDGE 0
#endif
#define REGISTER_U_ADDR(addr, blockend, regno) \
{ blockend -= BLOCKFUDGE; \
if (regno < 2) addr = blockend - 0x18 + regno * 4; \
else if (regno < 8) addr = blockend - 0x54 + regno * 4; \
else if (regno < 10) addr = blockend - 0x30 + regno * 4;\
else if (regno < 15) addr = blockend - 0x5c + regno * 4;\
@ -392,6 +398,9 @@ retry: \
(frame_saved_regs).regs[FP_REGNUM] = (frame_info).frame; \
(frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \
}
/* Compensate for lack of `vprintf' function. */
#define vprintf(format, ap) _doprnt (format, ap, stdout)
/* Things needed for making the inferior call functions. */

11
gdb/m-isiinit.h Normal file
View File

@ -0,0 +1,11 @@
/* Customize initialize.h for Integrated Solutions machines. */
/* Define this if you are using system version 4; undefine it for
version 3. This alters the action of m-isi-ov.h as well as this file. */
#define BSD43_ISI40D
#ifdef BSD43_ISI40D
#define FILEADDR_ROUND(addr) (addr)
#else
#define FILEADDR_ROUND(addr) ((addr + 3) & -4)
#endif

440
gdb/m-merlin.h Normal file
View File

@ -0,0 +1,440 @@
/* Definitions to make GDB run on a merlin under utek 2.1
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
#ifndef ns16000
#define ns16000
#endif
# include <machine/reg.h>
/* Define this if the C compiler puts an underscore at the front
of external names before giving them to the linker. */
#define NAMES_HAVE_UNDERSCORE
/* Debugger information will be in DBX format. */
#define READ_DBX_FORMAT
/* Offset from address of function to start of its code.
Zero on most machines. */
#define FUNCTION_START_OFFSET 0
/* Advance PC across any function entry prologue instructions
to reach some "real" code. */
#define SKIP_PROLOGUE(pc) \
{ register int op = read_memory_integer (pc, 1); \
if (op == 0x82) \
{ op = read_memory_integer (pc+2,1); \
if ((op & 0x80) == 0) pc += 3; \
else if ((op & 0xc0) == 0x80) pc += 4; \
else pc += 6; \
}}
/* Immediately after a function call, return the saved pc.
Can't always go through the frames for this because on some machines
the new frame is not set up until the new function executes
some instructions. */
#define SAVED_PC_AFTER_CALL(frame) \
read_memory_integer (read_register (SP_REGNUM), 4)
/* 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 (0xfef000)
/* Address of end of stack space. */
#define STACK_END_ADDR (0x800000)
/* Stack grows downward. */
#define INNER_THAN <
/* Sequence of bytes for breakpoint instruction. */
#define BREAKPOINT {0xf2}
/* Amount PC must be decremented by after a breakpoint.
This is often the number of bytes in BREAKPOINT
but not always. */
#define DECR_PC_AFTER_BREAK 0
/* Nonzero if instruction at PC is a return instruction. */
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0x12)
/* Return 1 if P points to an invalid floating point value. */
#define INVALID_FLOAT(p, len) 0
/* Define this to say that the "svc" insn is followed by
codes in memory saying which kind of system call it is. */
#define NS32K_SVC_IMMED_OPERANDS
/* Say how long (ordinary) registers are. */
#define REGISTER_TYPE long
/* Number of machine registers */
#define NUM_REGS 25
#define NUM_GENERAL_REGS 8
/* Initializer for an array of names of registers.
There should be NUM_REGS strings in this initializer. */
#define REGISTER_NAMES {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"pc", "sp", "fp", "ps", \
"fsr", \
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
"l0", "l1", "l2", "l3", "l4", \
}
/* Register numbers of various important registers.
Note that some of these values are "real" register numbers,
and correspond to the general registers of the machine,
and some are "phony" register numbers which are too large
to be actual register numbers as far as the user is concerned
but do serve to get the desired values when passed to read_register. */
#define AP_REGNUM FP_REGNUM
#define FP_REGNUM 10 /* Contains address of executing stack frame */
#define SP_REGNUM 9 /* Contains address of top of stack */
#define PC_REGNUM 8 /* Contains program counter */
#define PS_REGNUM 11 /* Contains processor status */
#define FPS_REGNUM 12 /* Floating point status register */
#define FP0_REGNUM 13 /* Floating point register 0 */
#define LP0_REGNUM 21 /* Double register 0 (same as FP0) */
#define REGISTER_U_ADDR(addr, blockend, regno) \
{ \
switch (regno) { \
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: \
addr = blockend + (R0 - regno) * sizeof (int); break; \
case PC_REGNUM: \
addr = blockend + PC * sizeof (int); break; \
case SP_REGNUM: \
addr = blockend + SP * sizeof (int); break; \
case FP_REGNUM: \
addr = blockend + FP * sizeof (int); break; \
case PS_REGNUM: \
addr = blockend + 12 * sizeof (int); break; \
case FPS_REGNUM: \
addr = 108; break; \
case FP0_REGNUM + 0: case FP0_REGNUM + 1: \
case FP0_REGNUM + 2: case FP0_REGNUM + 3: \
case FP0_REGNUM + 4: case FP0_REGNUM + 5: \
case FP0_REGNUM + 6: case FP0_REGNUM + 7: \
addr = 76 + (regno - FP0_REGNUM) * sizeof (float); break; \
case LP0_REGNUM + 0: case LP0_REGNUM + 1: \
case LP0_REGNUM + 2: case LP0_REGNUM + 3: \
addr = 76 + (regno - LP0_REGNUM) * sizeof (double); break; \
default: \
printf ("bad argument to REGISTER_U_ADDR %d\n", regno); \
abort (); \
} \
}
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'. */
#define REGISTER_BYTES ((NUM_REGS - 4) * sizeof (int) + 4 * sizeof (double))
/* Index within `registers' of the first byte of the space for
register N. */
#define REGISTER_BYTE(N) ((N) >= LP0_REGNUM ? \
LP0_REGNUM * 4 + ((N) - LP0_REGNUM) * 8 : (N) * 4)
/* Number of bytes of storage in the actual machine representation
for register N. On the 32000, all regs are 4 bytes
except for the doubled floating registers. */
#define REGISTER_RAW_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4)
/* Number of bytes of storage in the program's representation
for register N. On the 32000, all regs are 4 bytes
except for the doubled floating registers. */
#define REGISTER_VIRTUAL_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4)
/* Largest value REGISTER_RAW_SIZE can have. */
#define MAX_REGISTER_RAW_SIZE 8
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
#define MAX_REGISTER_VIRTUAL_SIZE 8
/* Nonzero if register N requires conversion
from raw format to virtual format. */
#define REGISTER_CONVERTIBLE(N) 0
/* Convert data from raw format for register REGNUM
to virtual format for register REGNUM. */
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
/* Convert data from virtual format for register REGNUM
to raw format for register REGNUM. */
#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
/* Return the GDB type object for the "standard" data type
of data in register N. */
#define REGISTER_VIRTUAL_TYPE(N) \
((N) >= FP0_REGNUM ? \
((N) >= LP0_REGNUM ? \
builtin_type_double \
: builtin_type_float) \
: builtin_type_int)
/* 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. */
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
/* Write into appropriate registers a function return value
of type TYPE, given in virtual format. */
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
write_register_bytes (0, 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 (or an expression that can be used as one). */
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
/* Describe the pointer in each stack frame to the previous stack frame
(its caller). */
/* FRAME_CHAIN takes a frame's nominal address
and produces the frame's chain-pointer.
FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
and produces the nominal address of the caller frame.
However, if FRAME_CHAIN_VALID returns zero,
it means the given frame is the outermost one and has no caller.
In that case, FRAME_CHAIN_COMBINE is not used. */
/* In the case of the Merlin, the frame's nominal address is the FP value,
and at that address is saved previous FP value as a 4-byte word. */
#define FRAME_CHAIN(thisframe) (read_memory_integer (thisframe, 4))
#define FRAME_CHAIN_VALID(chain, thisframe) \
(chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
/* Define other aspects of the stack frame. */
#define FRAME_SAVED_PC(frame) (read_memory_integer (frame + 4, 4))
/* compute base of arguments */
#define FRAME_ARGS_ADDRESS(fi) ((fi).frame)
#define FRAME_LOCALS_ADDRESS(fi) ((fi).frame)
/* Return number of args passed to a frame.
Can return -1, meaning no way to tell. */
#define FRAME_NUM_ARGS(numargs, fi) \
{ CORE_ADDR pc; \
int insn; \
int addr_mode; \
int width; \
\
pc = FRAME_SAVED_PC (fi.frame); \
insn = read_memory_integer (pc,2); \
addr_mode = (insn >> 11) & 0x1f; \
insn = insn & 0x7ff; \
if ((insn & 0x7fc) == 0x57c \
&& addr_mode == 0x14) /* immediate */ \
{ if (insn == 0x57c) /* adjspb */ \
width = 1; \
else if (insn == 0x57d) /* adjspw */ \
width = 2; \
else if (insn == 0x57f) /* adjspd */ \
width = 4; \
numargs = read_memory_integer (pc+2,width); \
if (width > 1) \
flip_bytes (&numargs, width); \
numargs = - sign_extend (numargs, width*8) / 4; } \
else numargs = -1; \
}
/* Return number of bytes at start of arglist that are not really args. */
#define FRAME_ARGS_SKIP 8
/* Put here the code to store, into a struct frame_saved_regs,
the addresses of the saved registers of frame described by FRAME_INFO.
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. */
#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
{ int regmask,regnum; \
int localcount; \
CORE_ADDR enter_addr; \
CORE_ADDR next_addr; \
\
enter_addr = get_pc_function_start ((frame_info).pc); \
regmask = read_memory_integer (enter_addr+1, 1); \
localcount = ns32k_localcount (enter_addr); \
next_addr = (frame_info).frame + localcount; \
for (regnum = 0; regnum < 8; regnum++, regmask >>= 1) \
(frame_saved_regs).regs[regnum] \
= (regmask & 1) ? (next_addr -= 4) : 0; \
(frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 4; \
(frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \
(frame_saved_regs).regs[FP_REGNUM] \
= read_memory_integer ((frame_info).frame, 4); }
/* Compensate for lack of `vprintf' function. */
#define vprintf(format, ap) _doprnt (format, ap, stdout)
/* Things needed for making the inferior call functions. */
/* Push an empty stack frame, to record the current PC, etc. */
#define PUSH_DUMMY_FRAME \
{ register CORE_ADDR sp = read_register (SP_REGNUM); \
register int regnum; \
sp = push_word (sp, read_register (PC_REGNUM)); \
sp = push_word (sp, read_register (FP_REGNUM)); \
write_register (FP_REGNUM, sp); \
for (regnum = 0; regnum < 8; regnum++) \
sp = push_word (sp, read_register (regnum)); \
write_register (SP_REGNUM, sp); \
}
/* Discard from the stack the innermost frame, restoring all registers. */
#define POP_FRAME \
{ register CORE_ADDR fp = read_register (FP_REGNUM); \
register int regnum; \
struct frame_saved_regs fsr; \
struct frame_info fi; \
fi = get_frame_info (fp); \
get_frame_saved_regs (&fi, &fsr); \
for (regnum = 0; regnum < 8; regnum++) \
if (fsr.regs[regnum]) \
write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
write_register (SP_REGNUM, fp + 8); \
}
/* This sequence of words is the instructions
enter 0xff,0 82 ff 00
jsr @0x00010203 7f ae c0 01 02 03
adjspd 0x69696969 7f a5 01 02 03 04
bpt f2
Note this is 16 bytes. */
#define CALL_DUMMY { 0x7f00ff82, 0x0201c0ae, 0x01a57f03, 0xf2040302 }
#define CALL_DUMMY_START_OFFSET 3
#define CALL_DUMMY_LENGTH 16
#define CALL_DUMMY_ADDR 5
#define CALL_DUMMY_NARGS 11
/* Insert the specified number of args and function address
into a call sequence of the above form stored at DUMMYNAME. */
#define FIX_CALL_DUMMY(dummyname, fun, nargs) \
{ int flipped = fun | 0xc0000000; \
flip_bytes (&flipped, 4); \
*((int *) (((char *) dummyname)+CALL_DUMMY_ADDR)) = flipped; \
flipped = - nargs * 4; \
flip_bytes (&flipped, 4); \
*((int *) (((char *) dummyname)+CALL_DUMMY_NARGS)) = flipped; \
}
#ifdef notdef
/* Interface definitions for kernel debugger KDB. */
/* Map machine fault codes into signal numbers.
First subtract 0, divide by 4, then index in a table.
Faults for which the entry in this table is 0
are not handled by KDB; the program's own trap handler
gets to handle then. */
#define FAULT_CODE_ORIGIN 0
#define FAULT_CODE_UNITS 4
#define FAULT_TABLE \
{ 0, SIGKILL, SIGSEGV, 0, 0, 0, 0, 0, \
0, 0, SIGTRAP, SIGTRAP, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0}
/* Start running with a stack stretching from BEG to END.
BEG and END should be symbols meaningful to the assembler.
This is used only for kdb. */
#define INIT_STACK(beg, end) \
{ asm (".globl end"); \
asm ("movl $ end, sp"); \
asm ("clrl fp"); }
/* Push the frame pointer register on the stack. */
#define PUSH_FRAME_PTR \
asm ("pushl fp");
/* Copy the top-of-stack to the frame pointer register. */
#define POP_FRAME_PTR \
asm ("movl (sp), fp");
/* After KDB is entered by a fault, push all registers
that GDB thinks about (all NUM_REGS of them),
so that they appear in order of ascending GDB register number.
The fault code will be on the stack beyond the last register. */
#define PUSH_REGISTERS \
{ asm ("pushl 8(sp)"); \
asm ("pushl 8(sp)"); \
asm ("pushal 0x14(sp)"); \
asm ("pushr $037777"); }
/* Assuming the registers (including processor status) have been
pushed on the stack in order of ascending GDB register number,
restore them and return to the address in the saved PC register. */
#define POP_REGISTERS \
{ asm ("popr $037777"); \
asm ("subl2 $8,(sp)"); \
asm ("movl (sp),sp"); \
asm ("rei"); }
#endif

534
gdb/m-news.h Normal file
View File

@ -0,0 +1,534 @@
/* Parameters for execution on a Sony/NEWS, for GDB, the GNU debugger.
Here is an m-news800.h file for gdb version 2.1. It supports the reading
the 68881 registers, but the kernel doesn't know how to write them
and probably cannot write the frame pointer register either.
Now(9/2 '87) NEWS's printf has a bug.
And support Sun assembly format instead of Motorola one.
Probably not well support floating registers from core file rarely that
I do not know detail.
(hikichi@srava.sra.junet or hikichi%srava.sra.junet%kddlabs%seismo.CSS.GOV)
Copyright (C) 1987 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
/* Identify this machine */
#ifndef news800
#define news800
#endif
#define USE_GAS
/* Motorola assembly format */
#ifndef USE_GAS
#define MOTOROLA
#endif
/* bug when printf special number; NAN */
#define PRINTF_BUG
/* Define this if the C compiler puts an underscore at the front
of external names before giving them to the linker. */
#define NAMES_HAVE_UNDERSCORE
/* Debugger info will be in DBX format. */
#define READ_DBX_FORMAT
/* Offset from address of function to start of its code.
Zero on most machines. */
#define FUNCTION_START_OFFSET 0
/* Advance PC across any function entry prologue instructions
to reach some "real" code. */
#define SKIP_PROLOGUE(pc) \
{ register int op = read_memory_integer (pc, 2); \
if (op == 0047126) \
pc += 4; /* Skip link #word */ \
else if (op == 0044016) \
pc += 6; /* Skip link #long */ \
}
/* Immediately after a function call, return the saved pc.
Can't always go through the frames for this because on some machines
the new frame is not set up until the new function executes
some instructions. */
#define SAVED_PC_AFTER_CALL(frame) \
read_memory_integer (read_register (SP_REGNUM), 4)
/* 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 UADDR
/* Address of end of stack space. */
#define STACK_END_ADDR (0x80000000 - ctob(UPAGES + 1))
/* Stack grows downward. */
#define INNER_THAN <
/* Sequence of bytes for breakpoint instruction. */
#define BREAKPOINT {0x4e, 0x4f}
/* Amount PC must be decremented by after a breakpoint.
This is often the number of bytes in BREAKPOINT
but not always. */
#define DECR_PC_AFTER_BREAK 2
/* Nonzero if instruction at PC is a return instruction. */
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e75)
/* Return 1 if P points to an invalid floating point value. */
#define INVALID_FLOAT(p, len) 0 /* Just a first guess; not checked */
/* Say how long registers are. */
#define REGISTER_TYPE long
/* Number of machine registers */
#define NUM_REGS 29
/* Initializer for an array of names of registers.
There should be NUM_REGS strings in this initializer. */
#define REGISTER_NAMES \
{"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
"a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \
"pc", "ps", \
"fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \
"fpcontrol", "fpstatus", "fpiaddr" }
/* Register numbers of various important registers.
Note that some of these values are "real" register numbers,
and correspond to the general registers of the machine,
and some are "phony" register numbers which are too large
to be actual register numbers as far as the user is concerned
but do serve to get the desired values when passed to read_register. */
#define FP_REGNUM 14 /* Contains address of executing stack frame */
#define SP_REGNUM 15 /* Contains address of top of stack */
#define PC_REGNUM 16 /* Contains program counter */
#define PS_REGNUM 17 /* Contains processor status */
#define FP0_REGNUM 18 /* Floating point register 0 */
#define FPC_REGNUM 26 /* 68881 control register */
#define REGISTER_U_ADDR(addr, blockend, regno) \
{ if (regno <= FP_REGNUM) \
addr = blockend + 4 + regno * 4; \
else if (regno == SP_REGNUM) \
addr = blockend - 4 * 4; \
else if (regno <= PS_REGNUM) \
addr = blockend + (regno - PS_REGNUM) * 4; \
else if (regno < FPC_REGNUM) \
addr = blockend + 4 + 4 * 14 + 4 * 5 + (regno - FP0_REGNUM) * 12; \
else \
addr = blockend + 4 + 4 * 16 + (regno - FPC_REGNUM) * 4; \
}
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'. */
#define REGISTER_BYTES (16*4+8*12+8+12)
/* Index within `registers' of the first byte of the space for
register N. */
#define REGISTER_BYTE(N) \
((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \
: (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \
: (N) * 4)
/* Number of bytes of storage in the actual machine representation
for register N. On the 68000, all regs are 4 bytes
except the floating point regs which are 12 bytes. */
#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4)
/* Number of bytes of storage in the program's representation
for register N. On the 68000, all regs are 4 bytes
except the floating point regs which are 8-byte doubles. */
#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4)
/* Largest value REGISTER_RAW_SIZE can have. */
#define MAX_REGISTER_RAW_SIZE 12
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
#define MAX_REGISTER_VIRTUAL_SIZE 8
/* Nonzero if register N requires conversion
from raw format to virtual format. */
#define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8)
/* Convert data from raw format for register REGNUM
to virtual format for register REGNUM. */
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
convert_from_68881 ((FROM), (TO)); \
else \
bcopy ((FROM), (TO), 4); }
/* Convert data from virtual format for register REGNUM
to raw format for register REGNUM. */
#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
convert_to_68881 ((FROM), (TO)); \
else \
bcopy ((FROM), (TO), 4); }
/* Return the GDB type object for the "standard" data type
of data in register N. */
#define REGISTER_VIRTUAL_TYPE(N) \
(((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double : builtin_type_int)
/* 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. */
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
{ if (TYPE_CODE (TYPE) != TYPE_CODE_FLT) \
bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE)); \
else \
convert_from_68881 (REGBUF + REGISTER_BYTE (FP0_REGNUM), VALBUF); }
/* Write into appropriate registers a function return value
of type TYPE, given in virtual format. */
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
{ if (TYPE_CODE (TYPE) != TYPE_CODE_FLT) \
write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE)); \
else \
{ \
char raw_buffer[12]; \
convert_to_68881 (VALBUF, raw_buffer); \
write_register_bytes (REGISTER_BYTE(FP0_REGNUM), raw_buffer, 12); }}
/* 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 (or an expression that can be used as one). */
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
/* Compensate for lack of `vprintf' function. */
#define vprintf(format, ap) _doprnt (format, ap, stdout)
/* Describe the pointer in each stack frame to the previous stack frame
(its caller). */
/* FRAME_CHAIN takes a frame's nominal address
and produces the frame's chain-pointer.
FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
and produces the nominal address of the caller frame.
However, if FRAME_CHAIN_VALID returns zero,
it means the given frame is the outermost one and has no caller.
In that case, FRAME_CHAIN_COMBINE is not used. */
/* In the case of the NEWS, the frame's nominal address
is the address of a 4-byte word containing the calling frame's address. */
#define FRAME_CHAIN(thisframe) (read_memory_integer (thisframe, 4))
#define FRAME_CHAIN_VALID(chain, thisframe) \
(chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
/* Define other aspects of the stack frame. */
#define FRAME_SAVED_PC(frame) (read_memory_integer (frame + 4, 4))
#define FRAME_ARGS_ADDRESS(fi) (fi.frame)
#define FRAME_LOCALS_ADDRESS(fi) (fi.frame)
/* Return number of args passed to a frame.
Can return -1, meaning no way to tell. */
#define FRAME_NUM_ARGS(val, fi) \
{ register CORE_ADDR pc = FRAME_SAVED_PC (fi.frame); \
register int insn = 0177777 & read_memory_integer (pc, 2); \
val = 0; \
if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ \
val = read_memory_integer (pc + 2, 2); \
else if ((insn & 0170777) == 0050217 /* addql #N, sp */ \
|| (insn & 0170777) == 0050117) /* addqw */ \
{ val = (insn >> 9) & 7; if (val == 0) val = 8; } \
else if (insn == 0157774) /* addal #WW, sp */ \
val = read_memory_integer (pc + 2, 4); \
val >>= 2; }
/* Return number of bytes at start of arglist that are not really args. */
#define FRAME_ARGS_SKIP 8
/* Put here the code to store, into a struct frame_saved_regs,
the addresses of the saved registers of frame described by FRAME_INFO.
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. */
#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
{ register int regnum; \
register int regmask; \
register CORE_ADDR next_addr; \
register CORE_ADDR pc; \
register int insn; \
register int offset; \
bzero (&frame_saved_regs, sizeof frame_saved_regs); \
if ((frame_info).pc >= (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
&& (frame_info).pc <= (frame_info).frame) \
{ next_addr = (frame_info).frame; \
pc = (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\
else \
{ pc = get_pc_function_start ((frame_info).pc); \
/* Verify we have a link a6 instruction next, \
or a branch followed by a link a6 instruction; \
if not we lose. If we win, find the address above the saved \
regs using the amount of storage from the link instruction. */\
retry: \
insn = read_memory_integer (pc, 2); \
if (insn == 044016) \
next_addr = (frame_info).frame - read_memory_integer (pc += 2, 4), pc+=4; \
else if (insn == 047126) \
next_addr = (frame_info).frame - read_memory_integer (pc += 2, 2), pc+=2; \
else if ((insn & 0177400) == 060000) /* bra insn */ \
{ offset = insn & 0377; \
pc += 2; /* advance past bra */ \
if (offset == 0) /* bra #word */ \
offset = read_memory_integer (pc, 2), pc += 2; \
else if (offset == 0377) /* bra #long */ \
offset = read_memory_integer (pc, 4), pc += 4; \
pc += offset; \
goto retry; \
} else goto lose; \
/* If have an addal #-n, sp next, adjust next_addr. */ \
if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \
next_addr += read_memory_integer (pc += 2, 4), pc += 4; \
} \
/* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \
insn = read_memory_integer (pc, 2), pc += 2; \
regmask = read_memory_integer (pc, 2); \
if ((insn & 0177760) == 022700) /* movl rn, (sp) */ \
(frame_saved_regs).regs[(insn&7) + ((insn&010)?8:0)] = next_addr; \
else if ((insn & 0177760) == 024700) /* movl rn, -(sp) */ \
(frame_saved_regs).regs[(insn&7) + ((insn&010)?8:0)] = next_addr-=4; \
else if (insn == 0044327) /* moveml mask, (sp) */ \
{ pc += 2; \
/* Regmask's low bit is for register 0, the first written */ \
next_addr -= 4; \
for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr += 4); \
} else if (insn == 0044347) /* moveml mask, -(sp) */ \
{ pc += 2; \
/* Regmask's low bit is for register 15, the first pushed */ \
for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
/* clrw -(sp); movw ccr,-(sp) may follow. */ \
if (read_memory_integer (pc, 2) == 041147 \
&& read_memory_integer (pc+2, 2) == 042347) \
(frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \
lose: ; \
(frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 8; \
(frame_saved_regs).regs[FP_REGNUM] = (frame_info).frame; \
(frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \
}
/* Things needed for making the inferior call functions. */
/* Push an empty stack frame, to record the current PC, etc. */
#define PUSH_DUMMY_FRAME \
{ register CORE_ADDR sp = read_register (SP_REGNUM); \
register int regnum; \
char raw_buffer[12]; \
sp = push_word (sp, read_register (PC_REGNUM)); \
sp = push_word (sp, read_register (FP_REGNUM)); \
write_register (FP_REGNUM, sp); \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
{ read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); \
sp = push_bytes (sp, raw_buffer, 12); } \
for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
sp = push_word (sp, read_register (regnum)); \
sp = push_word (sp, read_register (PS_REGNUM)); \
write_register (SP_REGNUM, sp); }
/* Discard from the stack the innermost frame, restoring all registers. */
#define POP_FRAME \
{ register CORE_ADDR fp = read_register (FP_REGNUM); \
register int regnum; \
struct frame_saved_regs fsr; \
struct frame_info fi; \
char raw_buffer[12]; \
fi = get_frame_info (fp); \
get_frame_saved_regs (&fi, &fsr); \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
if (fsr.regs[regnum]) \
{ read_memory (fsr.regs[regnum], raw_buffer, 12); \
write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
if (fsr.regs[regnum]) \
write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
if (fsr.regs[PS_REGNUM]) \
write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
write_register (SP_REGNUM, fp + 8); \
}
/* This sequence of words is the instructions
fmove.m #<f0-f7>,-(sp)
movem.l 0xfffc,-(sp)
clr.w -(sp)
move.w ccr,-(sp)
/..* The arguments are pushed at this point by GDB;
no code is needed in the dummy for this.
The CALL_DUMMY_START_OFFSET gives the position of
the following jsr instruction. *../
jbsr (#32323232)
add.l #69696969,sp
bpt
nop
Note this is 24 bytes.
We actually start executing at the jsr, since the pushing of the
registers is done by PUSH_DUMMY_FRAME. If this were real code,
the arguments for the function called by the jsr would be pushed
between the moveml and the jsr, and we could allow it to execute through.
But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
and we cannot allow the moveml to push the registers again lest they be
taken for the arguments. */
#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
#define CALL_DUMMY_LENGTH 28
#define CALL_DUMMY_START_OFFSET 12
/* Insert the specified number of args and function address
into a call sequence of the above form stored at DUMMYNAME. */
#define FIX_CALL_DUMMY(dummyname, fun, nargs) \
{ *(int *)((char *) dummyname + 20) = nargs * 4; \
*(int *)((char *) dummyname + 14) = fun; }
/* Interface definitions for kernel debugger KDB. */
/* Map machine fault codes into signal numbers.
First subtract 0, divide by 4, then index in a table.
Faults for which the entry in this table is 0
are not handled by KDB; the program's own trap handler
gets to handle then. */
#define FAULT_CODE_ORIGIN 0
#define FAULT_CODE_UNITS 4
#define FAULT_TABLE \
{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
0, 0, 0, 0, 0, 0, 0, 0, \
SIGILL }
/* Start running with a stack stretching from BEG to END.
BEG and END should be symbols meaningful to the assembler.
This is used only for kdb. */
#ifdef MOTOROLA
#define INIT_STACK(beg, end) \
{ asm (".globl end"); \
asm ("move.l $ end, sp"); \
asm ("clr.l fp"); }
#else
#define INIT_STACK(beg, end) \
{ asm (".globl end"); \
asm ("movel $ end, sp"); \
asm ("clrl fp"); }
#endif
/* Push the frame pointer register on the stack. */
#ifdef MOTOROLA
#define PUSH_FRAME_PTR \
asm ("move.l fp, -(sp)");
#else
#define PUSH_FRAME_PTR \
asm ("movel fp, -(sp)");
#endif
/* Copy the top-of-stack to the frame pointer register. */
#ifdef MOTOROLA
#define POP_FRAME_PTR \
asm ("move.l (sp), fp");
#else
#define POP_FRAME_PTR \
asm ("movl (sp), fp");
#endif
/* After KDB is entered by a fault, push all registers
that GDB thinks about (all NUM_REGS of them),
so that they appear in order of ascending GDB register number.
The fault code will be on the stack beyond the last register. */
#ifdef MOTOROLA
#define PUSH_REGISTERS \
{ asm ("clr.w -(sp)"); \
asm ("pea (10,sp)"); \
asm ("movem $ 0xfffe,-(sp)"); }
#else
#define PUSH_REGISTERS \
{ asm ("clrw -(sp)"); \
asm ("pea 10(sp)"); \
asm ("movem $ 0xfffe,-(sp)"); }
#endif
/* Assuming the registers (including processor status) have been
pushed on the stack in order of ascending GDB register number,
restore them and return to the address in the saved PC register. */
#ifdef MOTOROLA
#define POP_REGISTERS \
{ asm ("subi.l $8,28(sp)"); \
asm ("movem (sp),$ 0xffff"); \
asm ("rte"); }
#else
#define POP_REGISTERS \
{ asm ("subil $8,28(sp)"); \
asm ("movem (sp),$ 0xffff"); \
asm ("rte"); }
#endif

4
gdb/m-newsinit.h Normal file
View File

@ -0,0 +1,4 @@
/* This is how the size of an individual .o file's text segment
is rounded on a SONY NEWS. */
#define FILEADDR_ROUND(addr) ((addr + 3) & -4)

502
gdb/m-npl.h Normal file
View File

@ -0,0 +1,502 @@
/* Parameters for execution on a Gould NP1, for GDB, the GNU debugger.
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding! */
/* Read file headers properly in core.c */
#define gould
/* Macro for text-offset and data info (in NPL a.out format). */
#define TEXTINFO \
text_offset = N_TXTOFF (exec_coffhdr, exec_aouthdr); \
exec_data_offset = N_TXTOFF (exec_coffhdr, exec_aouthdr)\
+ exec_aouthdr.a_text
/* Macro for number of symbol table entries */
#define END_OF_TEXT_DEFAULT \
(0xffffff)
/* Macro for number of symbol table entries */
#define NUMBER_OF_SYMBOLS \
(coffhdr.f_nsyms)
/* Macro for file-offset of symbol table (in NPL a.out format). */
#define SYMBOL_TABLE_OFFSET \
N_SYMOFF (coffhdr)
/* Macro for file-offset of string table (in NPL a.out format). */
#define STRING_TABLE_OFFSET \
(N_STROFF (coffhdr) + sizeof(int))
/* Macro to store the length of the string table data in INTO. */
#define READ_STRING_TABLE_SIZE(INTO) \
{ INTO = hdr.a_stsize; }
/* Macro to declare variables to hold the file's header data. */
#define DECLARE_FILE_HEADERS struct exec hdr; \
FILHDR coffhdr
/* Macro to read the header data from descriptor DESC and validate it.
NAME is the file name, for error messages. */
#define READ_FILE_HEADERS(DESC, NAME) \
{ val = myread (DESC, &coffhdr, sizeof coffhdr); \
if (val < 0) \
perror_with_name (NAME); \
val = myread (DESC, &hdr, sizeof hdr); \
if (val < 0) \
perror_with_name (NAME); \
if (coffhdr.f_magic != GNP1MAGIC) \
error ("File \"%s\" not in coff executable format.", NAME); \
if (N_BADMAG (hdr)) \
error ("File \"%s\" not in executable format.", NAME); }
/* Define COFF and other symbolic names needed on NP1 */
#define NS32GMAGIC GNP1MAGIC
#define NS32SMAGIC GPNMAGIC
#define vprintf printf
/* Get rid of any system-imposed stack limit if possible. */
#define SET_STACK_LIMIT_HUGE
/* Define this if the C compiler puts an underscore at the front
of external names before giving them to the linker. */
#define NAMES_HAVE_UNDERSCORE
/* Debugger information will be in DBX format. */
#define READ_DBX_FORMAT
/* Offset from address of function to start of its code.
Zero on most machines. */
#define FUNCTION_START_OFFSET 8
/* Advance PC across any function entry prologue instructions
to reach some "real" code. One NPL we can have one two startup
sequences depending on the size of the local stack:
Either:
"suabr b2, #"
of
"lil r4, #", "suabr b2, #(r4)"
"lwbr b6, #", "stw r1, 8(b2)"
Optional "stwbr b3, c(b2)"
Optional "trr r2,r7" (Gould first argument register passing)
or
Optional "stw r2,8(b3)" (Gould first argument register passing)
*/
#define SKIP_PROLOGUE(pc) { \
register int op = read_memory_integer ((pc), 4); \
if ((op & 0xffff0000) == 0xFA0B0000) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if ((op & 0xffff0000) == 0x59400000) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if ((op & 0xffff0000) == 0x5F000000) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if (op == 0xD4820008) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if (op == 0x5582000C) { \
pc += 4; \
op = read_memory_integer ((pc), 2); \
if (op == 0x2fa0) { \
pc += 2; \
} else { \
op = read_memory_integer ((pc), 4); \
if (op == 0xd5030008) { \
pc += 4; \
} \
} \
} else { \
op = read_memory_integer ((pc), 2); \
if (op == 0x2fa0) { \
pc += 2; \
} \
} \
} \
} \
} \
} \
if ((op & 0xffff0000) == 0x59000000) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if ((op & 0xffff0000) == 0x5F000000) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if (op == 0xD4820008) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if (op == 0x5582000C) { \
pc += 4; \
op = read_memory_integer ((pc), 2); \
if (op == 0x2fa0) { \
pc += 2; \
} else { \
op = read_memory_integer ((pc), 4); \
if (op == 0xd5030008) { \
pc += 4; \
} \
} \
} else { \
op = read_memory_integer ((pc), 2); \
if (op == 0x2fa0) { \
pc += 2; \
} \
} \
} \
} \
} \
}
/* Immediately after a function call, return the saved pc.
Can't go through the frames for this because on some machines
the new frame is not set up until the new function executes
some instructions. True on NPL! Return address is in R1.
The true return address is REALLY 4 past that location! */
#define SAVED_PC_AFTER_CALL(frame) \
(read_register(R1_REGNUM) + 4)
/* Address of U in kernel space */
#define KERNEL_U_ADDR 0x7fffc000
/* Address of end of stack space. */
#define STACK_END_ADDR 0x7fffc000
/* Stack grows downward. */
#define INNER_THAN <
/* Sequence of bytes for breakpoint instruction. */
#define BREAKPOINT {0x28, 0x09}
/* Amount PC must be decremented by after a breakpoint.
This is often the number of bytes in BREAKPOINT
but not always. */
#define DECR_PC_AFTER_BREAK 2
/* Nonzero if instruction at PC is a return instruction. "bu 4(r1)" */
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 4) == 0x40100004)
/* Return 1 if P points to an invalid floating point value. */
#define INVALID_FLOAT(p, len) ((*(short *)p & 0xff80) == 0x8000)
/* Say how long (ordinary) registers are. */
#define REGISTER_TYPE long
/* Size of bytes of vector register (NP1 only), 32 elements * sizeof(int) */
#define VR_SIZE 128
/* Number of machine registers */
#define NUM_REGS 27
#define NUM_GEN_REGS 16
#define NUM_CPU_REGS 4
#define NUM_VECTOR_REGS 7
/* Initializer for an array of names of registers.
There should be NUM_REGS strings in this initializer. */
#define REGISTER_NAMES { \
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", \
"sp", "ps", "pc", "ve", \
"v1", "v2", "v3", "v4", "v5", "v6", "v7", \
}
/* Register numbers of various important registers.
Note that some of these values are "real" register numbers,
and correspond to the general registers of the machine,
and some are "phony" register numbers which are too large
to be actual register numbers as far as the user is concerned
but do serve to get the desired values when passed to read_register. */
#define R1_REGNUM 1 /* Gr1 => return address of caller */
#define R4_REGNUM 4 /* Gr4 => register save area */
#define R5_REGNUM 5 /* Gr5 => register save area */
#define R6_REGNUM 6 /* Gr6 => register save area */
#define R7_REGNUM 7 /* Gr7 => register save area */
#define B1_REGNUM 9 /* Br1 => start of this code routine */
#define FP_REGNUM 10 /* Br2 == (sp) */
#define AP_REGNUM 11 /* Br3 == (ap) */
#define SP_REGNUM 16 /* A copy of Br2 saved in trap */
#define PS_REGNUM 17 /* Contains processor status */
#define PC_REGNUM 18 /* Contains program counter */
#define VE_REGNUM 19 /* Vector end (user setup) register */
#define V1_REGNUM 20 /* First vector register */
#define V7_REGNUM 27 /* First vector register */
/* This is a piece of magic that is given a register number REGNO
and as BLOCKEND the address in the system of the end of the user structure
and stores in ADDR the address in the kernel or core dump
of that register. */
#define REGISTER_U_ADDR(addr, blockend, regno) { \
addr = blockend + regno * 4; \
if (regno == VE_REGNUM) addr = blockend - 9 * 4; \
if (regno == PC_REGNUM) addr = blockend - 8 * 4; \
if (regno == PS_REGNUM) addr = blockend - 7 * 4; \
if (regno == SP_REGNUM) addr = blockend - 6 * 4; \
if (regno >= V1_REGNUM) \
addr = blockend + 16 * 4 + (regno - V1_REGNUM) * VR_SIZE; \
}
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'. */
#define REGISTER_BYTES \
(NUM_GEN_REGS*4 + NUM_VECTOR_REGS*VR_SIZE + NUM_CPU_REGS*4)
/* Index within `registers' of the first byte of the space for
register N. */
#define REGISTER_BYTE(N) \
(((N) < V1_REGNUM) ? ((N) * 4) : (((N) - V1_REGNUM) * VR_SIZE) + 80)
/* Number of bytes of storage in the actual machine representation
for register N. On the NP1, all normal regs are 4 bytes, but
the vector registers are VR_SIZE*4 bytes long. */
#define REGISTER_RAW_SIZE(N) \
(((N) < V1_REGNUM) ? 4 : VR_SIZE)
/* Number of bytes of storage in the program's representation
for register N. On the NP1, all regs are 4 bytes. */
#define REGISTER_VIRTUAL_SIZE(N) \
(((N) < V1_REGNUM) ? 4 : VR_SIZE)
/* Largest value REGISTER_RAW_SIZE can have. */
#define MAX_REGISTER_RAW_SIZE VR_SIZE
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
#define MAX_REGISTER_VIRTUAL_SIZE VR_SIZE
/* Nonzero if register N requires conversion
from raw format to virtual format. */
#define REGISTER_CONVERTIBLE(N) (0)
/* Convert data from raw format for register REGNUM
to virtual format for register REGNUM. */
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
bcopy ((FROM), (TO), REGISTER_RAW_SIZE(REGNUM));
/* Convert data from virtual format for register REGNUM
to raw format for register REGNUM. */
#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
/* Return the GDB type object for the "standard" data type
of data in register N. */
#define REGISTER_VIRTUAL_TYPE(N) (builtin_type_int)
/* Extract from an arrary REGBUF containing the (raw) register state
a function return value of type TYPE, and copy that, in virtual format,
into VALBUF. */
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
/* Write into appropriate registers a function return value
of type TYPE, given in virtual format. */
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
write_register_bytes (0, 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 (or an expression that can be used as one). */
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
/* Describe the pointer in each stack frame to the previous stack frame
(its caller). */
/* FRAME_CHAIN takes a frame's nominal address
and produces the frame's chain-pointer.
FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
and produces the nominal address of the caller frame.
However, if FRAME_CHAIN_VALID returns zero,
it means the given frame is the outermost one and has no caller.
In that case, FRAME_CHAIN_COMBINE is not used. */
/* In the case of the NPL, the frame's norminal address is Br2 and the
previous routines frame is up the stack X bytes, where X is the
value stored in the code function header xA(Br1). */
#define FRAME_CHAIN(thisframe) (findframe(thisframe))
#define FRAME_CHAIN_VALID(chain, thisframe) \
(chain != 0 && chain != thisframe)
#define FRAME_CHAIN_COMBINE(chain, thisframe) \
(chain)
/* Define other aspects of the stack frame on NPL. */
#define FRAME_SAVED_PC(frame) \
(read_memory_integer (frame + 8, 4))
#define FRAME_ARGS_ADDRESS(fi) \
((fi).next_frame ? \
read_memory_integer ((fi).frame + 12, 4) : \
read_register (AP_REGNUM))
#define FRAME_LOCALS_ADDRESS(fi) ((fi).frame + 80)
/* Set VAL to the number of args passed to frame described by FI.
Can set VAL to -1, meaning no way to tell. */
/* We can check the stab info to see how
many arg we have. No info in stack will tell us */
#define FRAME_NUM_ARGS(val,fi) (val = findarg(fi))
/* Return number of bytes at start of arglist that are not really args. */
#define FRAME_ARGS_SKIP 8
/* Put here the code to store, into a struct frame_saved_regs,
the addresses of the saved registers of frame described by FRAME_INFO.
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. */
#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
{ \
bzero (&frame_saved_regs, sizeof frame_saved_regs); \
(frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 8; \
(frame_saved_regs).regs[R4_REGNUM] = (frame_info).frame + 0x30; \
(frame_saved_regs).regs[R5_REGNUM] = (frame_info).frame + 0x34; \
(frame_saved_regs).regs[R6_REGNUM] = (frame_info).frame + 0x38; \
(frame_saved_regs).regs[R7_REGNUM] = (frame_info).frame + 0x3C; \
}
/* Things needed for making the inferior call functions. */
/* Push an empty stack frame, to record the current PC, etc. */
#define PUSH_DUMMY_FRAME \
{ register CORE_ADDR sp = read_register (SP_REGNUM); \
register int regnum; \
sp = push_word (sp, read_register (PC_REGNUM)); \
sp = push_word (sp, read_register (FP_REGNUM)); \
write_register (FP_REGNUM, sp); \
for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
sp = push_word (sp, read_register (regnum)); \
sp = push_word (sp, read_register (PS_REGNUM)); \
write_register (SP_REGNUM, sp); }
/* Discard from the stack the innermost frame,
restoring all saved registers. */
#define POP_FRAME \
{ register CORE_ADDR fp = read_register (FP_REGNUM); \
register int regnum; \
struct frame_saved_regs fsr; \
struct frame_info fi; \
fi = get_frame_info (fp); \
get_frame_saved_regs (&fi, &fsr); \
for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
if (fsr.regs[regnum]) \
write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
if (fsr.regs[PS_REGNUM]) \
write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
write_register (SP_REGNUM, fp + 8); \
set_current_frame (read_register (FP_REGNUM)); }
/* This sequence of words is the instructions:
halt
halt
halt
halt
suabr b2, #<stacksize>
lwbr b6, #con
stw r1, 8(b2) - save caller address, do we care?
lw r2, 60(b2) - arg1
labr b3, 50(b2)
std r4, 30(b2) - save r4-r7
std r6, 38(b2)
lwbr b1, #<func> - load function call address
brlnk r1, 8(b1) - call function
halt
halt
ld r4, 30(b2) - restore r4-r7
ld r6, 38(b2)
Setup our stack frame, load argumemts, call and then restore registers.
*/
#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
#define CALL_DUMMY_LENGTH 28
#define CALL_DUMMY_START_OFFSET 12
/* Insert the specified number of args and function address
into a call sequence of the above form stored at DUMMYNAME. */
#define FIX_CALL_DUMMY(dummyname, fun, nargs) \
{ *(int *)((char *) dummyname + 20) = nargs * 4; \
*(int *)((char *) dummyname + 14) = fun; }
/*
* No KDB support, Yet! */
/* Interface definitions for kernel debugger KDB. */
/* Map machine fault codes into signal numbers.
First subtract 0, divide by 4, then index in a table.
Faults for which the entry in this table is 0
are not handled by KDB; the program's own trap handler
gets to handle then. */
#define FAULT_CODE_ORIGIN 0
#define FAULT_CODE_UNITS 4
#define FAULT_TABLE \
{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
0, 0, 0, 0, 0, 0, 0, 0, \
SIGILL }
/* Start running with a stack stretching from BEG to END.
BEG and END should be symbols meaningful to the assembler.
This is used only for kdb. */
#define INIT_STACK(beg, end) \
{ asm (".globl end"); \
asm ("movel $ end, sp"); \
asm ("clrl fp"); }
/* Push the frame pointer register on the stack. */
#define PUSH_FRAME_PTR \
asm ("movel fp, -(sp)");
/* Copy the top-of-stack to the frame pointer register. */
#define POP_FRAME_PTR \
asm ("movl (sp), fp");
/* After KDB is entered by a fault, push all registers
that GDB thinks about (all NUM_REGS of them),
so that they appear in order of ascending GDB register number.
The fault code will be on the stack beyond the last register. */
#define PUSH_REGISTERS \
{ asm ("clrw -(sp)"); \
asm ("pea 10(sp)"); \
asm ("movem $ 0xfffe,-(sp)"); }
/* Assuming the registers (including processor status) have been
pushed on the stack in order of ascending GDB register number,
restore them and return to the address in the saved PC register. */
#define POP_REGISTERS \
{ asm ("subil $8,28(sp)"); \
asm ("movem (sp),$ 0xffff"); \
asm ("rte"); }

4
gdb/m-nplinit.h Normal file
View File

@ -0,0 +1,4 @@
/* This is how the size of an individual .o file's text segment
is rounded on a NP1. See np1-pinsn.c for rounding function. */
#define FILEADDR_ROUND(addr) (((int)(addr) + 31) & ~0xf)

486
gdb/m-pn.h Normal file
View File

@ -0,0 +1,486 @@
/* Parameters for execution on a Gould PN, for GDB, the GNU debugger.
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding! */
/* Read file headers properly in core.c */
#define gould
/* Macro for text-offset and data info (in PN a.out format). */
#define TEXTINFO \
text_offset = N_TXTOFF (exec_coffhdr); \
exec_data_offset = N_TXTOFF (exec_coffhdr) \
+ exec_aouthdr.a_text
/* Macro for number of symbol table entries */
#define END_OF_TEXT_DEFAULT \
(0xffffff)
/* Macro for number of symbol table entries */
#define NUMBER_OF_SYMBOLS \
(coffhdr.f_nsyms)
/* Macro for file-offset of symbol table (in usual a.out format). */
#define SYMBOL_TABLE_OFFSET \
N_SYMOFF (coffhdr)
/* Macro for file-offset of string table (in usual a.out format). */
#define STRING_TABLE_OFFSET \
(N_STROFF (coffhdr) + sizeof(int))
/* Macro to store the length of the string table data in INTO. */
#define READ_STRING_TABLE_SIZE(INTO) \
{ INTO = hdr.a_stsize; }
/* Macro to declare variables to hold the file's header data. */
#define DECLARE_FILE_HEADERS struct old_exec hdr; \
FILHDR coffhdr
/* Macro to read the header data from descriptor DESC and validate it.
NAME is the file name, for error messages. */
#define READ_FILE_HEADERS(DESC, NAME) \
{ val = myread (DESC, &coffhdr, sizeof coffhdr); \
if (val < 0) \
perror_with_name (NAME); \
val = myread (DESC, &hdr, sizeof hdr); \
if (val < 0) \
perror_with_name (NAME); \
if (coffhdr.f_magic != GNP1MAGIC) \
error ("File \"%s\" not in coff executable format.", NAME); \
if (N_BADMAG (hdr)) \
error ("File \"%s\" not in executable format.", NAME); }
/* Define COFF and other symbolic names needed on NP1 */
#define NS32GMAGIC GDPMAGIC
#define NS32SMAGIC PN_MAGIC
#define vprintf printf
/* Get rid of any system-imposed stack limit if possible. */
#define SET_STACK_LIMIT_HUGE
/* Define this if the C compiler puts an underscore at the front
of external names before giving them to the linker. */
#define NAMES_HAVE_UNDERSCORE
/* Debugger information will be in DBX format. */
#define READ_DBX_FORMAT
/* Offset from address of function to start of its code.
Zero on most machines. */
#define FUNCTION_START_OFFSET 4
/* Advance PC across any function entry prologue instructions
to reach some "real" code. One PN we can have one or two startup
sequences depending on the size of the local stack:
Either:
"suabr b2, #"
of
"lil r4, #", "suabr b2, #(r4)"
"lwbr b6, #", "stw r1, 8(b2)"
Optional "stwbr b3, c(b2)"
Optional "trr r2,r7" (Gould first argument register passing)
or
Optional "stw r2,8(b3)" (Gould first argument register passing)
*/
#define SKIP_PROLOGUE(pc) { \
register int op = read_memory_integer ((pc), 4); \
if ((op & 0xffff0000) == 0x580B0000) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if ((op & 0xffff0000) == 0x59400000) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if ((op & 0xffff0000) == 0x5F000000) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if (op == 0xD4820008) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if (op == 0x5582000C) { \
pc += 4; \
op = read_memory_integer ((pc), 2); \
if (op == 0x2fa0) { \
pc += 2; \
} else { \
op = read_memory_integer ((pc), 4); \
if (op == 0xd5030008) { \
pc += 4; \
} \
} \
} else { \
op = read_memory_integer ((pc), 2); \
if (op == 0x2fa0) { \
pc += 2; \
} \
} \
} \
} \
} \
} \
if ((op & 0xffff0000) == 0x59000000) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if ((op & 0xffff0000) == 0x5F000000) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if (op == 0xD4820008) { \
pc += 4; \
op = read_memory_integer ((pc), 4); \
if (op == 0x5582000C) { \
pc += 4; \
op = read_memory_integer ((pc), 2); \
if (op == 0x2fa0) { \
pc += 2; \
} else { \
op = read_memory_integer ((pc), 4); \
if (op == 0xd5030008) { \
pc += 4; \
} \
} \
} else { \
op = read_memory_integer ((pc), 2); \
if (op == 0x2fa0) { \
pc += 2; \
} \
} \
} \
} \
} \
}
/* Immediately after a function call, return the saved pc.
Can't go through the frames for this because on some machines
the new frame is not set up until the new function executes
some instructions. True on PN! Return address is in R1.
Note: true return location is 4 bytes past R1! */
#define SAVED_PC_AFTER_CALL(frame) \
(read_register(R1_REGNUM) + 4)
/* Address of U in kernel space */
#define KERNEL_U_ADDR 0x3fc000
/* Address of end of stack space. */
#define STACK_END_ADDR 0x480000
/* Stack grows downward. */
#define INNER_THAN <
/* Sequence of bytes for breakpoint instruction. */
#define BREAKPOINT {0x28, 0x09}
/* Amount PC must be decremented by after a breakpoint.
This is often the number of bytes in BREAKPOINT
but not always. */
#define DECR_PC_AFTER_BREAK 2
/* Nonzero if instruction at PC is a return instruction. "bu 4(r1)" */
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 4) == 0xEC100004)
/* Return 1 if P points to an invalid floating point value. */
#define INVALID_FLOAT(p, len) ((*(short *)p & 0xff80) == 0x8000)
/* Say how long (ordinary) registers are. */
#define REGISTER_TYPE long
/* Number of machine registers */
#define NUM_REGS 19
#define NUM_GEN_REGS 16
#define NUM_CPU_REGS 3
/* Initializer for an array of names of registers.
There should be NUM_REGS strings in this initializer. */
#define REGISTER_NAMES { \
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", \
"sp", "ps", "pc", \
}
/* Register numbers of various important registers.
Note that some of these values are "real" register numbers,
and correspond to the general registers of the machine,
and some are "phony" register numbers which are too large
to be actual register numbers as far as the user is concerned
but do serve to get the desired values when passed to read_register. */
#define R1_REGNUM 1 /* Gr1 => return address of caller */
#define R4_REGNUM 4 /* Gr4 => register save area */
#define R5_REGNUM 5 /* Gr5 => register save area */
#define R6_REGNUM 6 /* Gr6 => register save area */
#define R7_REGNUM 7 /* Gr7 => register save area */
#define B1_REGNUM 9 /* Br1 => start of this code routine */
#define FP_REGNUM 10 /* Br2 == (sp) */
#define AP_REGNUM 11 /* Br3 == (ap) */
#define SP_REGNUM 16 /* A copy of Br2 saved in trap */
#define PS_REGNUM 17 /* Contains processor status */
#define PC_REGNUM 18 /* Contains program counter */
/* This is a piece of magic that is given a register number REGNO
and as BLOCKEND the address in the system of the end of the user structure
and stores in ADDR the address in the kernel or core dump
of that register. */
#define REGISTER_U_ADDR(addr, blockend, regno) { \
addr = blockend + regno * 4; \
if (regno == PC_REGNUM) addr = blockend - 8 * 4; \
if (regno == PS_REGNUM) addr = blockend - 7 * 4; \
if (regno == SP_REGNUM) addr = blockend - 6 * 4; \
}
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'. */
#define REGISTER_BYTES (NUM_GEN_REGS*4 + NUM_CPU_REGS*4)
/* Index within `registers' of the first byte of the space for
register N. */
#define REGISTER_BYTE(N) ((N) * 4)
/* Number of bytes of storage in the actual machine representation
for register N. On the PN, all normal regs are 4 bytes. */
#define REGISTER_RAW_SIZE(N) (4)
/* Number of bytes of storage in the program's representation
for register N. On the PN, all regs are 4 bytes. */
#define REGISTER_VIRTUAL_SIZE(N) (4)
/* Largest value REGISTER_RAW_SIZE can have. */
#define MAX_REGISTER_RAW_SIZE (4)
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
#define MAX_REGISTER_VIRTUAL_SIZE (4)
/* Nonzero if register N requires conversion
from raw format to virtual format. */
#define REGISTER_CONVERTIBLE(N) (0)
/* Convert data from raw format for register REGNUM
to virtual format for register REGNUM. */
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
bcopy ((FROM), (TO), REGISTER_RAW_SIZE(REGNUM));
/* Convert data from virtual format for register REGNUM
to raw format for register REGNUM. */
#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
/* Return the GDB type object for the "standard" data type
of data in register N. */
#define REGISTER_VIRTUAL_TYPE(N) (builtin_type_int)
/* Extract from an arrary REGBUF containing the (raw) register state
a function return value of type TYPE, and copy that, in virtual format,
into VALBUF. */
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
/* Write into appropriate registers a function return value
of type TYPE, given in virtual format. */
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
write_register_bytes (0, 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 (or an expression that can be used as one). */
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
/* Describe the pointer in each stack frame to the previous stack frame
(its caller). */
/* FRAME_CHAIN takes a frame's nominal address
and produces the frame's chain-pointer.
FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
and produces the nominal address of the caller frame.
However, if FRAME_CHAIN_VALID returns zero,
it means the given frame is the outermost one and has no caller.
In that case, FRAME_CHAIN_COMBINE is not used. */
/* In the case of the NPL, the frame's norminal address is Br2 and the
previous routines frame is up the stack X bytes, where X is the
value stored in the code function header xA(Br1). */
#define FRAME_CHAIN(thisframe) (findframe(thisframe))
#define FRAME_CHAIN_VALID(chain, thisframe) \
(chain != 0 && chain != thisframe)
#define FRAME_CHAIN_COMBINE(chain, thisframe) \
(chain)
/* Define other aspects of the stack frame on NPL. */
#define FRAME_SAVED_PC(frame) \
(read_memory_integer (frame + 8, 4))
#define FRAME_ARGS_ADDRESS(fi) \
((fi).next_frame ? \
read_memory_integer ((fi).frame + 12, 4) : \
read_register (AP_REGNUM))
#define FRAME_LOCALS_ADDRESS(fi) ((fi).frame + 80)
/* Set VAL to the number of args passed to frame described by FI.
Can set VAL to -1, meaning no way to tell. */
/* We can check the stab info to see how
many arg we have. No info in stack will tell us */
#define FRAME_NUM_ARGS(val,fi) (val = findarg(fi))
/* Return number of bytes at start of arglist that are not really args. */
#define FRAME_ARGS_SKIP 8
/* Put here the code to store, into a struct frame_saved_regs,
the addresses of the saved registers of frame described by FRAME_INFO.
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. */
#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
{ \
bzero (&frame_saved_regs, sizeof frame_saved_regs); \
(frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 8; \
(frame_saved_regs).regs[R4_REGNUM] = (frame_info).frame + 0x30; \
(frame_saved_regs).regs[R5_REGNUM] = (frame_info).frame + 0x34; \
(frame_saved_regs).regs[R6_REGNUM] = (frame_info).frame + 0x38; \
(frame_saved_regs).regs[R7_REGNUM] = (frame_info).frame + 0x3C; \
}
/* Things needed for making the inferior call functions. */
/* Push an empty stack frame, to record the current PC, etc. */
#define PUSH_DUMMY_FRAME \
{ register CORE_ADDR sp = read_register (SP_REGNUM); \
register int regnum; \
sp = push_word (sp, read_register (PC_REGNUM)); \
sp = push_word (sp, read_register (FP_REGNUM)); \
write_register (FP_REGNUM, sp); \
for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
sp = push_word (sp, read_register (regnum)); \
sp = push_word (sp, read_register (PS_REGNUM)); \
write_register (SP_REGNUM, sp); }
/* Discard from the stack the innermost frame,
restoring all saved registers. */
#define POP_FRAME \
{ register CORE_ADDR fp = read_register (FP_REGNUM); \
register int regnum; \
struct frame_saved_regs fsr; \
struct frame_info fi; \
fi = get_frame_info (fp); \
get_frame_saved_regs (&fi, &fsr); \
for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
if (fsr.regs[regnum]) \
write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
if (fsr.regs[PS_REGNUM]) \
write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
write_register (SP_REGNUM, fp + 8); \
set_current_frame (read_register (FP_REGNUM)); }
/* This sequence of words is the instructions:
halt
halt
halt
halt
suabr b2, #<stacksize>
lwbr b6, #con
stw r1, 8(b2) - save caller address, do we care?
lw r2, 60(b2) - arg1
labr b3, 50(b2)
std r4, 30(b2) - save r4-r7
std r6, 38(b2)
lwbr b1, #<func> - load function call address
brlnk r1, 8(b1) - call function
halt
halt
ld r4, 30(b2) - restore r4-r7
ld r6, 38(b2)
Setup our stack frame, load argumemts, call and then restore registers.
*/
#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
#define CALL_DUMMY_LENGTH 28
#define CALL_DUMMY_START_OFFSET 12
/* Insert the specified number of args and function address
into a call sequence of the above form stored at DUMMYNAME. */
#define FIX_CALL_DUMMY(dummyname, fun, nargs) \
{ *(int *)((char *) dummyname + 20) = nargs * 4; \
*(int *)((char *) dummyname + 14) = fun; }
/*
* No KDB support, Yet! */
/* Interface definitions for kernel debugger KDB. */
/* Map machine fault codes into signal numbers.
First subtract 0, divide by 4, then index in a table.
Faults for which the entry in this table is 0
are not handled by KDB; the program's own trap handler
gets to handle then. */
#define FAULT_CODE_ORIGIN 0
#define FAULT_CODE_UNITS 4
#define FAULT_TABLE \
{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
0, 0, 0, 0, 0, 0, 0, 0, \
SIGILL }
/* Start running with a stack stretching from BEG to END.
BEG and END should be symbols meaningful to the assembler.
This is used only for kdb. */
#define INIT_STACK(beg, end) \
{ asm (".globl end"); \
asm ("movel $ end, sp"); \
asm ("clrl fp"); }
/* Push the frame pointer register on the stack. */
#define PUSH_FRAME_PTR \
asm ("movel fp, -(sp)");
/* Copy the top-of-stack to the frame pointer register. */
#define POP_FRAME_PTR \
asm ("movl (sp), fp");
/* After KDB is entered by a fault, push all registers
that GDB thinks about (all NUM_REGS of them),
so that they appear in order of ascending GDB register number.
The fault code will be on the stack beyond the last register. */
#define PUSH_REGISTERS \
{ asm ("clrw -(sp)"); \
asm ("pea 10(sp)"); \
asm ("movem $ 0xfffe,-(sp)"); }
/* Assuming the registers (including processor status) have been
pushed on the stack in order of ascending GDB register number,
restore them and return to the address in the saved PC register. */
#define POP_REGISTERS \
{ asm ("subil $8,28(sp)"); \
asm ("movem (sp),$ 0xffff"); \
asm ("rte"); }

4
gdb/m-pninit.h Normal file
View File

@ -0,0 +1,4 @@
/* This is how the size of an individual .o file's text segment
is rounded on a Concept. See pn-pinsn.c for rounding function. */
#define FILEADDR_ROUND(addr) (((int)(addr) + 7) & ~0x7)

View File

@ -80,7 +80,7 @@ read_memory_integer (read_register (SP_REGNUM), 4)
/* Nonzero if instruction at PC is a return instruction. */
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e76)
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e75)
/* Return 1 if P points to an invalid floating point value. */

5
gdb/m-sun2init.h Normal file
View File

@ -0,0 +1,5 @@
/* This is how the size of an individual .o file's text segment
is rounded on a sun. */
#define FILEADDR_ROUND(addr) (addr)

View File

@ -79,7 +79,7 @@ read_memory_integer (read_register (SP_REGNUM), 4)
/* Nonzero if instruction at PC is a return instruction. */
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e76)
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e75)
/* Return 1 if P points to an invalid floating point value. */

5
gdb/m-sun3init.h Normal file
View File

@ -0,0 +1,5 @@
/* This is how the size of an individual .o file's text segment
is rounded on a sun. */
#define FILEADDR_ROUND(addr) ((addr + 3) & -4)

436
gdb/m-umax.h Normal file
View File

@ -0,0 +1,436 @@
/* Definitions to make GDB run on an encore under umax 4.2
Copyright (C) 1987 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
#ifndef ns16000
#define ns16000
#endif
#define HAVE_WAIT_STRUCT
/* Encore's modifications to ptrace format */
#define UMAX_PTRACE
/* Encore's modifications to core-file format */
#define UMAX_CORE
/* Do implement the attach and detach commands. */
#define ATTACH_DETACH
/* Define this if the C compiler puts an underscore at the front
of external names before giving them to the linker. */
#define NAMES_HAVE_UNDERSCORE
/* Exec files and symbol tables are in COFF format */
#define COFF_FORMAT
/* Offset from address of function to start of its code.
Zero on most machines. */
#define FUNCTION_START_OFFSET 0
/* Advance PC across any function entry prologue instructions
to reach some "real" code. */
#define SKIP_PROLOGUE(pc) \
{ register unsigned char op = read_memory_integer (pc, 1); \
if (op == 0x82) { op = read_memory_integer (pc+2,1); \
if ((op & 0x80) == 0) pc += 3; \
else if ((op & 0xc0) == 0x80) pc += 4; \
else pc += 6; \
} \
}
/* Immediately after a function call, return the saved pc.
Can't always go through the frames for this because on some machines
the new frame is not set up until the new function executes
some instructions. */
#define SAVED_PC_AFTER_CALL(frame) \
read_memory_integer (read_register (SP_REGNUM), 4)
/* Address of end of stack space. */
#define STACK_END_ADDR (0xfffff000)
/* Stack grows downward. */
#define INNER_THAN <
/* Sequence of bytes for breakpoint instruction. */
#define BREAKPOINT {0xf2}
/* Amount PC must be decremented by after a breakpoint.
This is often the number of bytes in BREAKPOINT
but not always. */
#define DECR_PC_AFTER_BREAK 0
/* Nonzero if instruction at PC is a return instruction. */
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0x12)
#ifndef NaN
#include <nan.h>
#endif NaN
/* Return 1 if P points to an invalid floating point value. */
#define INVALID_FLOAT(p, s) \
((s == sizeof (float))? \
NaF (*(float *) p) : \
NaD (*(double *) p))
/* Say how long (ordinary) registers are. */
#define REGISTER_TYPE long
/* Number of machine registers */
#define NUM_REGS 25
#define NUM_GENERAL_REGS 8
/* Initializer for an array of names of registers.
There should be NUM_REGS strings in this initializer. */
#define REGISTER_NAMES {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
"sp", "fp", "pc", "ps", \
"fsr", \
"l0", "l1", "l2", "l3", "xx", \
}
/* Register numbers of various important registers.
Note that some of these values are "real" register numbers,
and correspond to the general registers of the machine,
and some are "phony" register numbers which are too large
to be actual register numbers as far as the user is concerned
but do serve to get the desired values when passed to read_register. */
#define FP0_REGNUM 8 /* Floating point register 0 */
#define SP_REGNUM 16 /* Contains address of top of stack */
#define AP_REGNUM FP_REGNUM
#define FP_REGNUM 17 /* Contains address of executing stack frame */
#define PC_REGNUM 18 /* Contains program counter */
#define PS_REGNUM 19 /* Contains processor status */
#define FPS_REGNUM 20 /* Floating point status register */
#define LP0_REGNUM 21 /* Double register 0 (same as FP0) */
/* called from register_addr() -- blockend not used for now */
#define REGISTER_U_ADDR(addr, blockend, regno) \
{ \
switch (regno) { \
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: \
addr = PU_R0 - (regno * sizeof (int)); break; \
case SP_REGNUM: \
addr = PU_SP; break; \
case PC_REGNUM: \
addr = PU_PC; break; \
case FP_REGNUM: \
addr = PU_FP; break; \
case PS_REGNUM: \
addr = PU_PSL; break; \
case FPS_REGNUM: \
addr = PU_FSR; break; \
case FP0_REGNUM + 0: case FP0_REGNUM + 1: \
case FP0_REGNUM + 2: case FP0_REGNUM + 3: \
case FP0_REGNUM + 4: case FP0_REGNUM + 5: \
case FP0_REGNUM + 6: case FP0_REGNUM + 7: \
addr = PU_F0 + (regno - FP0_REGNUM) * sizeof (float); break; \
case LP0_REGNUM + 0: case LP0_REGNUM + 1: \
case LP0_REGNUM + 2: case LP0_REGNUM + 3: \
addr = PU_F0 + (regno - LP0_REGNUM) * sizeof (double); break; \
default: \
printf ("bad argument to REGISTER_U_ADDR %d\n", regno); \
abort (); \
} \
}
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'. */
#define REGISTER_BYTES ((NUM_REGS - 4) * sizeof (int) + 4 * sizeof (double))
/* Index within `registers' of the first byte of the space for
register N. */
#define REGISTER_BYTE(N) ((N) >= LP0_REGNUM ? \
LP0_REGNUM * 4 + ((N) - LP0_REGNUM) * 8 : (N) * 4)
/* Number of bytes of storage in the actual machine representation
for register N. On the 32000, all regs are 4 bytes
except for the doubled floating registers. */
#define REGISTER_RAW_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4)
/* Number of bytes of storage in the program's representation
for register N. On the 32000, all regs are 4 bytes
except for the doubled floating registers. */
#define REGISTER_VIRTUAL_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4)
/* Largest value REGISTER_RAW_SIZE can have. */
#define MAX_REGISTER_RAW_SIZE 8
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
#define MAX_REGISTER_VIRTUAL_SIZE 8
/* Nonzero if register N requires conversion
from raw format to virtual format. */
#define REGISTER_CONVERTIBLE(N) 0
/* Convert data from raw format for register REGNUM
to virtual format for register REGNUM. */
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
/* Convert data from virtual format for register REGNUM
to raw format for register REGNUM. */
#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM));
/* Return the GDB type object for the "standard" data type
of data in register N. */
#define REGISTER_VIRTUAL_TYPE(N) \
(((N) < FP0_REGNUM) ? \
builtin_type_int : \
((N) < FP0_REGNUM + 8) ? \
builtin_type_float : \
((N) < LP0_REGNUM) ? \
builtin_type_int : \
builtin_type_double)
/* 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. */
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
bcopy (REGBUF+REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 0), VALBUF, TYPE_LENGTH (TYPE))
/* Write into appropriate registers a function return value
of type TYPE, given in virtual format. */
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
write_register_bytes (REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 0), 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 (or an expression that can be used as one). */
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
/* Describe the pointer in each stack frame to the previous stack frame
(its caller). */
/* FRAME_CHAIN takes a frame's nominal address
and produces the frame's chain-pointer.
FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
and produces the nominal address of the caller frame.
However, if FRAME_CHAIN_VALID returns zero,
it means the given frame is the outermost one and has no caller.
In that case, FRAME_CHAIN_COMBINE is not used. */
/* In the case of the ns32000 series, the frame's nominal address is the FP
value, and at that address is saved previous FP value as a 4-byte word. */
#define FRAME_CHAIN(thisframe) (read_memory_integer (thisframe, 4))
#define FRAME_CHAIN_VALID(chain, thisframe) \
(chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
/* Define other aspects of the stack frame. */
#define FRAME_SAVED_PC(frame) (read_memory_integer (frame + 4, 4))
/* Compute base of arguments. */
#define FRAME_ARGS_ADDRESS(fi) \
((ns32k_get_enter_addr (fi.pc) > 1) ? \
((fi).frame) : (read_register (SP_REGNUM) - 4))
#define FRAME_LOCALS_ADDRESS(fi) ((fi).frame)
/* Get the address of the enter opcode for this function, if it is active.
Returns positive address > 1 if pc is between enter/exit,
1 if pc before enter or after exit, 0 otherwise. */
#ifndef CORE_ADDR
#include "defs.h" /* Make sure CORE_ADDR is defined. */
#endif
extern CORE_ADDR ns32k_get_enter_addr ();
/* Return number of args passed to a frame.
Can return -1, meaning no way to tell.
Encore's C compiler often reuses same area on stack for args,
so this will often not work properly. If the arg names
are known, it's likely most of them will be printed. */
#define FRAME_NUM_ARGS(numargs, fi) \
{ CORE_ADDR pc; \
CORE_ADDR enter_addr; \
unsigned int insn; \
unsigned int addr_mode; \
int width; \
\
numargs = -1; \
enter_addr = ns32k_get_enter_addr (fi.pc); \
if (enter_addr > 0) \
{ \
pc = (enter_addr == 1) ? \
SAVED_PC_AFTER_CALL () : \
FRAME_SAVED_PC (fi.frame); \
insn = read_memory_integer (pc,2); \
addr_mode = (insn >> 11) & 0x1f; \
insn = insn & 0x7ff; \
if ((insn & 0x7fc) == 0x57c && \
addr_mode == 0x14) /* immediate */ \
{ \
if (insn == 0x57c) /* adjspb */ \
width = 1; \
else if (insn == 0x57d) /* adjspw */ \
width = 2; \
else if (insn == 0x57f) /* adjspd */ \
width = 4; \
numargs = read_memory_integer (pc+2,width); \
if (width > 1) \
flip_bytes (&numargs, width); \
numargs = - sign_extend (numargs, width*8) / 4;\
} \
} \
}
/* Return number of bytes at start of arglist that are not really args. */
#define FRAME_ARGS_SKIP 8
/* Put here the code to store, into a struct frame_saved_regs,
the addresses of the saved registers of frame described by FRAME_INFO.
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. */
#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
{ \
register int regmask, regnum; \
int localcount; \
register CORE_ADDR enter_addr; \
register CORE_ADDR next_addr; \
\
bzero (&(frame_saved_regs), sizeof (frame_saved_regs)); \
enter_addr = ns32k_get_enter_addr ((frame_info).pc); \
if (enter_addr > 1) \
{ \
regmask = read_memory_integer (enter_addr+1, 1) & 0xff; \
localcount = ns32k_localcount (enter_addr); \
next_addr = (frame_info).frame + localcount; \
for (regnum = 0; regnum < 8; regnum++, regmask >>= 1) \
(frame_saved_regs).regs[regnum] = (regmask & 1) ? \
(next_addr -= 4) : 0; \
(frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 4;\
(frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4;\
(frame_saved_regs).regs[FP_REGNUM] = \
(read_memory_integer ((frame_info).frame, 4));\
} \
else if (enter_addr == 1) \
{ \
CORE_ADDR sp = read_register (SP_REGNUM); \
(frame_saved_regs).regs[PC_REGNUM] = sp; \
(frame_saved_regs).regs[SP_REGNUM] = sp + 4; \
} \
}
/* Compensate for lack of `vprintf' function. */
#define vprintf(format, ap) _doprnt (format, ap, stdout)
/* Things needed for making the inferior call functions. */
/* Push an empty stack frame, to record the current PC, etc. */
#define PUSH_DUMMY_FRAME \
{ register CORE_ADDR sp = read_register (SP_REGNUM);\
register int regnum; \
sp = push_word (sp, read_register (PC_REGNUM)); \
sp = push_word (sp, read_register (FP_REGNUM)); \
write_register (FP_REGNUM, sp); \
for (regnum = 0; regnum < 8; regnum++) \
sp = push_word (sp, read_register (regnum)); \
write_register (SP_REGNUM, sp); \
}
/* Discard from the stack the innermost frame, restoring all registers. */
#define POP_FRAME \
{ register CORE_ADDR fp = read_register (FP_REGNUM); \
register int regnum; \
struct frame_saved_regs fsr; \
struct frame_info fi; \
fi = get_frame_info (fp); \
get_frame_saved_regs (&fi, &fsr); \
for (regnum = 0; regnum < 8; regnum++) \
if (fsr.regs[regnum]) \
write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
write_register (SP_REGNUM, fp + 8); \
}
/* This sequence of words is the instructions
enter 0xff,0 82 ff 00
jsr @0x00010203 7f ae c0 01 02 03
adjspd 0x69696969 7f a5 01 02 03 04
bpt f2
Note this is 16 bytes. */
#define CALL_DUMMY { 0x7f00ff82, 0x0201c0ae, 0x01a57f03, 0xf2040302 }
#define CALL_DUMMY_START_OFFSET 3
#define CALL_DUMMY_LENGTH 16
#define CALL_DUMMY_ADDR 5
#define CALL_DUMMY_NARGS 11
/* Insert the specified number of args and function address
into a call sequence of the above form stored at DUMMYNAME. */
#define FIX_CALL_DUMMY(dummyname, fun, nargs) \
{ \
int flipped; \
flipped = fun | 0xc0000000; \
flip_bytes (&flipped, 4); \
*((int *) (((char *) dummyname)+CALL_DUMMY_ADDR)) = flipped; \
flipped = - nargs * 4; \
flip_bytes (&flipped, 4); \
*((int *) (((char *) dummyname)+CALL_DUMMY_NARGS)) = flipped; \
}

4
gdb/m-umaxinit.h Normal file
View File

@ -0,0 +1,4 @@
/* This is how the size of an individual .o file's text segment
is rounded on the multimax. */
#define FILEADDR_ROUND(addr) ((addr + 3) & -4)

View File

@ -189,6 +189,9 @@ anyone else from sharing it farther. Help stamp out software hoarding!
as a CORE_ADDR (or an expression that can be used as one). */
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
/* Compensate for lack of `vprintf' function. */
#define vprintf(format, ap) _doprnt (format, ap, stdout)
/* Describe the pointer in each stack frame to the previous stack frame
(its caller). */

View File

@ -406,8 +406,8 @@ struct m68k_opcode m68k_opcodes[] =
{"muls", one(0140700), one(0170700), ";wDd"},
{"mulul", two(0046000, 000000), two(0177700, 0107770), ";lD1"},
{"mulul", two(0046000, 002000), two(0177700, 0107770), ";lD3D1"},
{"muluw", one(0140300), one(0170700), ";lDd"},
{"mulu", one(0140300), one(0170700), ";lDd"},
{"muluw", one(0140300), one(0170700), ";wDd"},
{"mulu", one(0140300), one(0170700), ";wDd"},
{"nbcd", one(0044000), one(0177700), "$s"},
{"negb", one(0042000), one(0177700), "$s"},
{"negl", one(0042200), one(0177700), "$s"},
@ -875,8 +875,8 @@ struct m68k_opcode m68k_opcodes[] =
{"fmovel", two(0xF000, 0x4000), two(0xF1C0, 0xFC7F), "Ii;lF7"}, /* fmove from <ea> to fp<n> */
{"fmovel", two(0xF000, 0x6000), two(0xF1C0, 0xFC7F), "IiF7@l"}, /* fmove from fp<n> to <ea> */
/* JF for the assembler */
{"fmovel", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "Iis8@s"},
{"fmovel", two(0xF000, 0x8000), two(0xF1C0, 0xE3FF), "Ii@ss8"},
{"fmovel", two(0xF000, 0xA000), two(0xF1C0, 0xE3FF), "Iis8%l"},
{"fmovel", two(0xF000, 0x8000), two(0xF1C0, 0xE3FF), "Ii*ls8"},
/* JF {"fmovep", two(0xF000, 0x4C00), two(0xF1C0, 0xFC7F), "Ii;pF7"}, /* fmove from <ea> to fp<n> */
{"fmovep", two(0xF000, 0x6C00), two(0xF1C0, 0xFC00), "IiF7@pkC"}, /* fmove.p with k-factors: */
{"fmovep", two(0xF000, 0x7C00), two(0xF1C0, 0xFC0F), "IiF7@pDk"}, /* fmove.p with k-factors: */

View File

@ -23,7 +23,7 @@ anyone else from sharing it farther. Help stamp out software hoarding!
#include "defs.h"
#include "param.h"
#include "symtab.h"
#include "m68k-opcode.h"
#include "opcode.h"
/* 68k instructions are never longer than this many bytes. */
#define MAXLEN 22
@ -714,6 +714,12 @@ convert_from_68881 (from, to)
char *from;
double *to;
{
#ifdef HPUX_ASM
asm ("mov.l 8(%a6),%a0");
asm ("mov.l 12(%a6),%a1");
asm ("fmove.x (%a0),%fp0");
asm ("fmove.d %fp0,(%a1)");
#else /* not HPUX_ASM */
#if 0
asm ("movl a6@(8),a0");
asm ("movl a6@(12),a1");
@ -729,6 +735,7 @@ convert_from_68881 (from, to)
asm (".long 0xf2104800");
asm (".long 0xf2117400");
#endif
#endif /* not HPUX_ASM */
}
/* The converse: convert the double *FROM to an extended float
@ -738,6 +745,12 @@ convert_to_68881 (from, to)
double *from;
char *to;
{
#ifdef HPUX_ASM
asm ("mov.l 8(%a6),%a0");
asm ("mov.l 12(%a6),%a1");
asm ("fmove.d (%a0),%fp0");
asm ("fmove.x %fp0,(%a1)");
#else /* not HPUX_ASM */
#if 0
asm ("movl a6@(8),a0");
asm ("movl a6@(12),a1");
@ -752,4 +765,5 @@ convert_to_68881 (from, to)
asm (".long 0xf2105400");
asm (".long 0xf2116800");
#endif
#endif /* not HPUX_ASM */
}

View File

@ -1,5 +1,5 @@
/* Top level for GDB, the GNU debugger.
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
@ -52,13 +52,19 @@ FILE *instream;
char *current_directory;
/* The directory name is actually stored here. */
/* The directory name is actually stored here (usually). */
static char dirbuf[MAXPATHLEN];
/* Nonzero if we should refrain from using an X window. */
int inhibit_windows = 0;
/* Hook for window manager argument parsing. */
int *win_argc;
char **win_argv;
char *win_prgm;
/* Function to call before reading a command, if nonzero.
The function receives two args: an input stream,
and a prompt string. */
@ -82,7 +88,7 @@ static char *prompt;
char *line;
int linesize;
/* This is how `error' returns to command level. */
jmp_buf to_top_level;
@ -93,9 +99,48 @@ return_to_top_level ()
immediate_quit = 0;
clear_breakpoint_commands ();
clear_momentary_breakpoints ();
delete_current_display ();
do_cleanups (0);
longjmp (to_top_level, 1);
}
/* Call FUNC with arg ARG, catching any errors.
If there is no error, return the value returned by FUNC.
If there is an error, return zero after printing ERRSTRING
(which is in addition to the specific error message already printed). */
int
catch_errors (func, arg, errstring)
int (*func) ();
int arg;
char *errstring;
{
jmp_buf saved;
int val;
bcopy (to_top_level, saved, sizeof (jmp_buf));
if (setjmp (to_top_level) == 0)
val = (*func) (arg);
else
{
fprintf (stderr, "%s\n", errstring);
val = 0;
}
bcopy (saved, to_top_level, sizeof (jmp_buf));
return val;
}
/* Handler for SIGHUP. */
static void
disconnect ()
{
kill_inferior_fast ();
signal (SIGHUP, SIG_DFL);
kill (getpid (), SIGHUP);
}
main (argc, argv, envp)
int argc;
@ -117,6 +162,10 @@ main (argc, argv, envp)
getwd (dirbuf);
current_directory = dirbuf;
win_argc = &argc;
win_argv = argv;
win_prgm = argv[0];
#ifdef SET_STACK_LIMIT_HUGE
{
struct rlimit rlim;
@ -129,8 +178,6 @@ main (argc, argv, envp)
}
#endif /* SET_STACK_LIMIT_HUGE */
/* Run the init function of each source file */
/* Look for flag arguments. */
for (i = 1; i < argc; i++)
@ -141,10 +188,10 @@ main (argc, argv, envp)
inhibit_gdbinit = 1;
else if (!strcmp (argv[i], "-nw"))
inhibit_windows = 1;
else if (!strcmp (argv[i], "-fullname"))
frame_file_full_name = 1;
else if (!strcmp (argv[i], "-batch"))
batch = 1, quiet = 1;
else if (!strcmp (argv[i], "-fullname"))
frame_file_full_name = 1;
else if (argv[i][0] == '-')
i++;
}
@ -156,6 +203,8 @@ main (argc, argv, envp)
signal (SIGINT, request_quit);
signal (SIGQUIT, SIG_IGN);
if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
signal (SIGHUP, disconnect);
if (!quiet)
print_gdb_version ();
@ -206,6 +255,17 @@ main (argc, argv, envp)
else if (!strcmp (arg, "-d") || !strcmp (arg, "-dir")
|| !strcmp (arg, "-directory"))
directory_command (argv[i], 0);
/* -cd FOO: specify current directory as FOO.
GDB remembers the precise string FOO as the dirname. */
else if (!strcmp (arg, "-cd"))
{
int len = strlen (argv[i]);
current_directory = argv[i];
if (len > 1 && current_directory[len - 1] == '/')
current_directory = savestring (current_directory, len-1);
chdir (current_directory);
init_source_path ();
}
/* -t /def/ttyp1: use /dev/ttyp1 for inferior I/O. */
else if (!strcmp (arg, "-t") || !strcmp (arg, "-tty"))
tty_command (argv[i], 0);
@ -292,8 +352,7 @@ execute_command (p, from_tty)
else if (c->class == (int) class_user)
{
if (*p)
error ("User-defined commands cannot take command-line arguments: \"%s\"",
p);
error ("User-defined commands cannot take arguments.");
cmdlines = (struct command_line *) c->function;
if (cmdlines == (struct command_line *) 0)
/* Null command */
@ -339,6 +398,7 @@ command_loop ()
}
}
#ifdef SIGTSTP
static void
stop_sig ()
{
@ -352,6 +412,7 @@ stop_sig ()
/* Forget about any previous command -- null line now will do nothing. */
*line = 0;
}
#endif /* SIGTSTP */
/* Commands call this if they do not want to be repeated by null lines. */
@ -378,17 +439,25 @@ read_line (repeat)
/* Control-C quits instantly if typed while in this loop
since it should not wait until the user types a newline. */
immediate_quit++;
#ifdef SIGTSTP
signal (SIGTSTP, stop_sig);
#endif
while (1)
{
c = fgetc (instream);
if (c == -1 || c == '\n')
break;
/* Ignore backslash-newline; keep adding to the same line. */
else if (c == '\\')
if ((c = fgetc (instream)) == '\n')
continue;
else ungetc (c, instream);
{
int c1 = fgetc (instream);
if (c1 == '\n')
continue;
else
ungetc (c1, instream);
}
if (p - line == linesize - 1)
{
linesize *= 2;
@ -398,7 +467,10 @@ read_line (repeat)
}
*p++ = c;
}
#ifdef SIGTSTP
signal (SIGTSTP, SIG_DFL);
#endif
immediate_quit--;
/* If we just got an empty line, and that is supposed
@ -573,7 +645,7 @@ validate_comname (comname)
{
if (!(*p >= 'A' && *p <= 'Z')
&& !(*p >= 'a' && *p <= 'z')
&& !(*p >= '1' && *p <= '9')
&& !(*p >= '0' && *p <= '9')
&& *p != '-')
error ("Junk in argument list: \"%s\"", p);
p++;
@ -668,7 +740,7 @@ copying_info ()
{
immediate_quit++;
printf (" GDB GENERAL PUBLIC LICENSE\n\
\n (Clarified 11 Feb 1988)\
(Clarified 11 Feb 1988)\n\
\n\
Copyright (C) 1988 Richard M. Stallman\n\
Everyone is permitted to copy and distribute verbatim copies\n\
@ -862,6 +934,17 @@ version_info ()
immediate_quit--;
}
/* xgdb calls this to reprint the usual GDB prompt. */
void
print_prompt ()
{
printf ("%s", prompt);
fflush (stdout);
}
/* Command to specify a prompt string instead of "(gdb) ". */
static void
set_prompt_command (text)
char *text;
@ -930,7 +1013,13 @@ pwd_command (arg, from_tty)
int from_tty;
{
if (arg) error ("The \"pwd\" command does not take an argument: %s", arg);
printf ("Working directory %s.\n", dirbuf);
getwd (dirbuf);
if (strcmp (dirbuf, current_directory))
printf ("Working directory %s\n (canonically %s).\n",
current_directory, dirbuf);
else
printf ("Working directory %s.\n", current_directory);
}
static void
@ -938,16 +1027,57 @@ cd_command (dir, from_tty)
char *dir;
int from_tty;
{
int len;
int change;
if (dir == 0)
error_no_arg ("new working directory");
len = strlen (dir);
dir = savestring (dir, len - (len > 1 && dir[len-1] == '/'));
if (dir[0] == '/')
current_directory = dir;
else
{
current_directory = concat (current_directory, "/", dir);
free (dir);
}
/* Now simplify any occurrences of `.' and `..' in the pathname. */
change = 1;
while (change)
{
char *p;
change = 0;
for (p = current_directory; *p;)
{
if (!strncmp (p, "/./", 2)
&& (p[2] == 0 || p[2] == '/'))
strcpy (p, p + 2);
else if (!strncmp (p, "/..", 3)
&& (p[3] == 0 || p[3] == '/')
&& p != current_directory)
{
char *q = p;
while (q != current_directory && q[-1] != '/') q--;
if (q != current_directory)
{
strcpy (q-1, p+3);
p = q-1;
}
}
else p++;
}
}
if (chdir (dir) < 0)
perror_with_name (dir);
getwd (dirbuf);
if (from_tty)
pwd_command ((char *) 0, 1);
}
/* Clean up on error during a "source" command.
Close the file opened by the command
@ -1019,12 +1149,11 @@ dump_me_command ()
kill (getpid (), SIGQUIT);
}
}
static void
initialize_main ()
{
prompt = savestring ("(gdb+) ", 7);
prompt = savestring ("(gdb) ", 6);
/* Define the classes of commands.
They will appear in the help list in the reverse of this order. */

423
gdb/npl-opcode.h Normal file
View File

@ -0,0 +1,423 @@
/* Print GOULD NPL instructions for GDB, the GNU debugger.
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
struct gld_opcode
{
char *name;
unsigned long opcode;
unsigned long mask;
char *args;
int length;
};
/* We store four bytes of opcode for all opcodes because that
is the most any of them need. The actual length of an instruction
is always at least 2 bytes, and at most four. The length of the
instruction is based on the opcode.
The mask component is a mask saying which bits must match
particular opcode in order for an instruction to be an instance
of that opcode.
The args component is a string containing characters
that are used to format the arguments to the instruction. */
/* Kinds of operands:
r Register in first field
R Register in second field
b Base register in first field
B Base register in second field
v Vector register in first field
V Vector register in first field
A Optional address register (base register)
X Optional index register
I Immediate data (16bits signed)
O Offset field (16bits signed)
h Offset field (15bits signed)
d Offset field (14bits signed)
S Shift count field
any other characters are printed as is...
*/
/* The assembler requires that this array be sorted as follows:
all instances of the same mnemonic must be consecutive.
All instances of the same mnemonic with the same number of operands
must be consecutive.
*/
struct gld_opcode gld_opcodes[] =
{
{ "lb", 0xb4080000, 0xfc080000, "r,xOA,X", 4 },
{ "lnb", 0xb8080000, 0xfc080000, "r,xOA,X", 4 },
{ "lbs", 0xec080000, 0xfc080000, "r,xOA,X", 4 },
{ "lh", 0xb4000001, 0xfc080001, "r,xOA,X", 4 },
{ "lnh", 0xb8000001, 0xfc080001, "r,xOA,X", 4 },
{ "lw", 0xb4000000, 0xfc080000, "r,xOA,X", 4 },
{ "lnw", 0xb8000000, 0xfc080000, "r,xOA,X", 4 },
{ "ld", 0xb4000002, 0xfc080002, "r,xOA,X", 4 },
{ "lnd", 0xb8000002, 0xfc080002, "r,xOA,X", 4 },
{ "li", 0xf8000000, 0xfc7f0000, "r,I", 4 },
{ "lpa", 0x50080000, 0xfc080000, "r,xOA,X", 4 },
{ "la", 0x50000000, 0xfc080000, "r,xOA,X", 4 },
{ "labr", 0x58080000, 0xfc080000, "b,xOA,X", 4 },
{ "lbp", 0x90080000, 0xfc080000, "r,xOA,X", 4 },
{ "lhp", 0x90000001, 0xfc080001, "r,xOA,X", 4 },
{ "lwp", 0x90000000, 0xfc080000, "r,xOA,X", 4 },
{ "ldp", 0x90000002, 0xfc080002, "r,xOA,X", 4 },
{ "suabr", 0x58000000, 0xfc080000, "b,xOA,X", 4 },
{ "lf", 0xbc000000, 0xfc080000, "r,xOA,X", 4 },
{ "lfbr", 0xbc080000, 0xfc080000, "b,xOA,X", 4 },
{ "lwbr", 0x5c000000, 0xfc080000, "b,xOA,X", 4 },
{ "stb", 0xd4080000, 0xfc080000, "r,xOA,X", 4 },
{ "sth", 0xd4000001, 0xfc080001, "r,xOA,X", 4 },
{ "stw", 0xd4000000, 0xfc080000, "r,xOA,X", 4 },
{ "std", 0xd4000002, 0xfc080002, "r,xOA,X", 4 },
{ "stf", 0xdc000000, 0xfc080000, "r,xOA,X", 4 },
{ "stfbr", 0xdc080000, 0xfc080000, "b,xOA,X", 4 },
{ "stwbr", 0x54000000, 0xfc080000, "b,xOA,X", 4 },
{ "zmb", 0xd8080000, 0xfc080000, "r,xOA,X", 4 },
{ "zmh", 0xd8000001, 0xfc080001, "r,xOA,X", 4 },
{ "zmw", 0xd8000000, 0xfc080000, "r,xOA,X", 4 },
{ "zmd", 0xd8000002, 0xfc080002, "r,xOA,X", 4 },
{ "stbp", 0x94080000, 0xfc080000, "r,xOA,X", 4 },
{ "sthp", 0x94000001, 0xfc080001, "r,xOA,X", 4 },
{ "stwp", 0x94000000, 0xfc080000, "r,xOA,X", 4 },
{ "stdp", 0x94000002, 0xfc080002, "r,xOA,X", 4 },
{ "lil", 0xf8080000, 0xfc7f0000, "r,D", 4 },
{ "lwsl1", 0xec000000, 0xfc080000, "r,xOA,X", 4 },
{ "lwsl2", 0xfc000000, 0xfc080000, "r,xOA,X", 4 },
{ "lwsl3", 0xfc080000, 0xfc080000, "r,xOA,X", 4 },
{ "lvb", 0xb0080000, 0xfc080000, "v,xOA,X", 4 },
{ "lvh", 0xb0000001, 0xfc080001, "v,xOA,X", 4 },
{ "lvw", 0xb0000000, 0xfc080000, "v,xOA,X", 4 },
{ "lvd", 0xb0000002, 0xfc080002, "v,xOA,X", 4 },
{ "liv", 0x3c040000, 0xfc0f0000, "v,R", 2 },
{ "livf", 0x3c080000, 0xfc0f0000, "v,R", 2 },
{ "stvb", 0xd0080000, 0xfc080000, "v,xOA,X", 4 },
{ "stvh", 0xd0000001, 0xfc080001, "v,xOA,X", 4 },
{ "stvw", 0xd0000000, 0xfc080000, "v,xOA,X", 4 },
{ "stvd", 0xd0000002, 0xfc080002, "v,xOA,X", 4 },
{ "trr", 0x2c000000, 0xfc0f0000, "r,R", 2 },
{ "trn", 0x2c040000, 0xfc0f0000, "r,R", 2 },
{ "trnd", 0x2c0c0000, 0xfc0f0000, "r,R", 2 },
{ "trabs", 0x2c010000, 0xfc0f0000, "r,R", 2 },
{ "trabsd", 0x2c090000, 0xfc0f0000, "r,R", 2 },
{ "trc", 0x2c030000, 0xfc0f0000, "r,R", 2 },
{ "xcr", 0x28040000, 0xfc0f0000, "r,R", 2 },
{ "cxcr", 0x2c060000, 0xfc0f0000, "r,R", 2 },
{ "cxcrd", 0x2c0e0000, 0xfc0f0000, "r,R", 2 },
{ "tbrr", 0x2c020000, 0xfc0f0000, "r,B", 2 },
{ "trbr", 0x28030000, 0xfc0f0000, "b,R", 2 },
{ "xcbr", 0x28020000, 0xfc0f0000, "b,B", 2 },
{ "tbrbr", 0x28010000, 0xfc0f0000, "b,B", 2 },
{ "trvv", 0x28050000, 0xfc0f0000, "v,V", 2 },
{ "trvvn", 0x2c050000, 0xfc0f0000, "v,V", 2 },
{ "trvvnd", 0x2c0d0000, 0xfc0f0000, "v,V", 2 },
{ "trvab", 0x2c070000, 0xfc0f0000, "v,V", 2 },
{ "trvabd", 0x2c0f0000, 0xfc0f0000, "v,V", 2 },
{ "cmpv", 0x14060000, 0xfc0f0000, "v,V", 2 },
{ "expv", 0x14070000, 0xfc0f0000, "v,V", 2 },
{ "mrvvlt", 0x10030000, 0xfc0f0000, "v,V", 2 },
{ "mrvvle", 0x10040000, 0xfc0f0000, "v,V", 2 },
{ "mrvvgt", 0x14030000, 0xfc0f0000, "v,V", 2 },
{ "mrvvge", 0x14040000, 0xfc0f0000, "v,V", 2 },
{ "mrvveq", 0x10050000, 0xfc0f0000, "v,V", 2 },
{ "mrvvne", 0x10050000, 0xfc0f0000, "v,V", 2 },
{ "mrvrlt", 0x100d0000, 0xfc0f0000, "v,R", 2 },
{ "mrvrle", 0x100e0000, 0xfc0f0000, "v,R", 2 },
{ "mrvrgt", 0x140d0000, 0xfc0f0000, "v,R", 2 },
{ "mrvrge", 0x140e0000, 0xfc0f0000, "v,R", 2 },
{ "mrvreq", 0x100f0000, 0xfc0f0000, "v,R", 2 },
{ "mrvrne", 0x140f0000, 0xfc0f0000, "v,R", 2 },
{ "trvr", 0x140b0000, 0xfc0f0000, "r,V", 2 },
{ "trrv", 0x140c0000, 0xfc0f0000, "v,R", 2 },
{ "bu", 0x40000000, 0xff880000, "xOA,X", 4 },
{ "bns", 0x70080000, 0xff880000, "xOA,X", 4 },
{ "bnco", 0x70880000, 0xff880000, "xOA,X", 4 },
{ "bge", 0x71080000, 0xff880000, "xOA,X", 4 },
{ "bne", 0x71880000, 0xff880000, "xOA,X", 4 },
{ "bunge", 0x72080000, 0xff880000, "xOA,X", 4 },
{ "bunle", 0x72880000, 0xff880000, "xOA,X", 4 },
{ "bgt", 0x73080000, 0xff880000, "xOA,X", 4 },
{ "bnany", 0x73880000, 0xff880000, "xOA,X", 4 },
{ "bs" , 0x70000000, 0xff880000, "xOA,X", 4 },
{ "bco", 0x70800000, 0xff880000, "xOA,X", 4 },
{ "blt", 0x71000000, 0xff880000, "xOA,X", 4 },
{ "beq", 0x71800000, 0xff880000, "xOA,X", 4 },
{ "buge", 0x72000000, 0xff880000, "xOA,X", 4 },
{ "bult", 0x72800000, 0xff880000, "xOA,X", 4 },
{ "ble", 0x73000000, 0xff880000, "xOA,X", 4 },
{ "bany", 0x73800000, 0xff880000, "xOA,X", 4 },
{ "brlnk", 0x44000000, 0xfc080000, "r,xOA,X", 4 },
{ "bib", 0x48000000, 0xfc080000, "r,xOA,X", 4 },
{ "bih", 0x48080000, 0xfc080000, "r,xOA,X", 4 },
{ "biw", 0x4c000000, 0xfc080000, "r,xOA,X", 4 },
{ "bid", 0x4c080000, 0xfc080000, "r,xOA,X", 4 },
{ "bivb", 0x60000000, 0xfc080000, "r,xOA,X", 4 },
{ "bivh", 0x60080000, 0xfc080000, "r,xOA,X", 4 },
{ "bivw", 0x64000000, 0xfc080000, "r,xOA,X", 4 },
{ "bivd", 0x64080000, 0xfc080000, "r,xOA,X", 4 },
{ "bvsb", 0x68000000, 0xfc080000, "r,xOA,X", 4 },
{ "bvsh", 0x68080000, 0xfc080000, "r,xOA,X", 4 },
{ "bvsw", 0x6c000000, 0xfc080000, "r,xOA,X", 4 },
{ "bvsd", 0x6c080000, 0xfc080000, "r,xOA,X", 4 },
{ "camb", 0x80080000, 0xfc080000, "r,xOA,X", 4 },
{ "camh", 0x80000001, 0xfc080001, "r,xOA,X", 4 },
{ "camw", 0x80000000, 0xfc080000, "r,xOA,X", 4 },
{ "camd", 0x80000002, 0xfc080002, "r,xOA,X", 4 },
{ "car", 0x10000000, 0xfc0f0000, "r,R", 2 },
{ "card", 0x14000000, 0xfc0f0000, "r,R", 2 },
{ "ci", 0xf8050000, 0xfc7f0000, "r,I", 4 },
{ "chkbnd", 0x5c080000, 0xfc080000, "r,xOA,X", 4 },
{ "cavv", 0x10010000, 0xfc0f0000, "v,V", 2 },
{ "cavr", 0x10020000, 0xfc0f0000, "v,R", 2 },
{ "cavvd", 0x10090000, 0xfc0f0000, "v,V", 2 },
{ "cavrd", 0x100b0000, 0xfc0f0000, "v,R", 2 },
{ "anmb", 0x84080000, 0xfc080000, "r,xOA,X", 4 },
{ "anmh", 0x84000001, 0xfc080001, "r,xOA,X", 4 },
{ "anmw", 0x84000000, 0xfc080000, "r,xOA,X", 4 },
{ "anmd", 0x84000002, 0xfc080002, "r,xOA,X", 4 },
{ "anr", 0x04000000, 0xfc0f0000, "r,R", 2 },
{ "ani", 0xf8080000, 0xfc7f0000, "r,I", 4 },
{ "ormb", 0xb8080000, 0xfc080000, "r,xOA,X", 4 },
{ "ormh", 0xb8000001, 0xfc080001, "r,xOA,X", 4 },
{ "ormw", 0xb8000000, 0xfc080000, "r,xOA,X", 4 },
{ "ormd", 0xb8000002, 0xfc080002, "r,xOA,X", 4 },
{ "orr", 0x08000000, 0xfc0f0000, "r,R", 2 },
{ "oi", 0xf8090000, 0xfc7f0000, "r,I", 4 },
{ "eomb", 0x8c080000, 0xfc080000, "r,xOA,X", 4 },
{ "eomh", 0x8c000001, 0xfc080001, "r,xOA,X", 4 },
{ "eomw", 0x8c000000, 0xfc080000, "r,xOA,X", 4 },
{ "eomd", 0x8c000002, 0xfc080002, "r,xOA,X", 4 },
{ "eor", 0x0c000000, 0xfc0f0000, "r,R", 2 },
{ "eoi", 0xf80a0000, 0xfc7f0000, "r,I", 4 },
{ "anvv", 0x04010000, 0xfc0f0000, "v,V", 2 },
{ "anvr", 0x04020000, 0xfc0f0000, "v,R", 2 },
{ "orvv", 0x08010000, 0xfc0f0000, "v,V", 2 },
{ "orvr", 0x08020000, 0xfc0f0000, "v,R", 2 },
{ "eovv", 0x0c010000, 0xfc0f0000, "v,V", 2 },
{ "eovr", 0x0c020000, 0xfc0f0000, "v,R", 2 },
{ "sacz", 0x100c0000, 0xfc0f0000, "r,R", 2 },
{ "sla", 0x1c400000, 0xfc600000, "r,S", 2 },
{ "sll", 0x1c600000, 0xfc600000, "r,S", 2 },
{ "slc", 0x24400000, 0xfc600000, "r,S", 2 },
{ "slad", 0x20400000, 0xfc600000, "r,S", 2 },
{ "slld", 0x20600000, 0xfc600000, "r,S", 2 },
{ "sra", 0x1c000000, 0xfc600000, "r,S", 2 },
{ "srl", 0x1c200000, 0xfc600000, "r,S", 2 },
{ "src", 0x24000000, 0xfc600000, "r,S", 2 },
{ "srad", 0x20000000, 0xfc600000, "r,S", 2 },
{ "srld", 0x20200000, 0xfc600000, "r,S", 2 },
{ "sda", 0x3c030000, 0xfc0f0000, "r,R", 2 },
{ "sdl", 0x3c020000, 0xfc0f0000, "r,R", 2 },
{ "sdc", 0x3c010000, 0xfc0f0000, "r,R", 2 },
{ "sdad", 0x3c0b0000, 0xfc0f0000, "r,R", 2 },
{ "sdld", 0x3c0a0000, 0xfc0f0000, "r,R", 2 },
{ "svda", 0x3c070000, 0xfc0f0000, "v,R", 2 },
{ "svdl", 0x3c060000, 0xfc0f0000, "v,R", 2 },
{ "svdc", 0x3c050000, 0xfc0f0000, "v,R", 2 },
{ "svdad", 0x3c0e0000, 0xfc0f0000, "v,R", 2 },
{ "svdld", 0x3c0d0000, 0xfc0f0000, "v,R", 2 },
{ "sbm", 0xac080000, 0xfc080000, "f,xOA,X", 4 },
{ "zbm", 0xac000000, 0xfc080000, "f,xOA,X", 4 },
{ "tbm", 0xa8080000, 0xfc080000, "f,xOA,X", 4 },
{ "incmb", 0xa0000000, 0xfc080000, "xOA,X", 4 },
{ "incmh", 0xa0080000, 0xfc080000, "xOA,X", 4 },
{ "incmw", 0xa4000000, 0xfc080000, "xOA,X", 4 },
{ "incmd", 0xa4080000, 0xfc080000, "xOA,X", 4 },
{ "sbmd", 0x7c080000, 0xfc080000, "r,xOA,X", 4 },
{ "zbmd", 0x7c000000, 0xfc080000, "r,xOA,X", 4 },
{ "tbmd", 0x78080000, 0xfc080000, "r,xOA,X", 4 },
{ "ssm", 0x9c080000, 0xfc080000, "f,xOA,X", 4 },
{ "zsm", 0x9c000000, 0xfc080000, "f,xOA,X", 4 },
{ "tsm", 0x98080000, 0xfc080000, "f,xOA,X", 4 },
{ "admb", 0xc8080000, 0xfc080000, "r,xOA,X", 4 },
{ "admh", 0xc8000001, 0xfc080001, "r,xOA,X", 4 },
{ "admw", 0xc8000000, 0xfc080000, "r,xOA,X", 4 },
{ "admd", 0xc8000002, 0xfc080002, "r,xOA,X", 4 },
{ "adr", 0x38000000, 0xfc0f0000, "r,R", 2 },
{ "armb", 0xe8080000, 0xfc080000, "r,xOA,X", 4 },
{ "armh", 0xe8000001, 0xfc080001, "r,xOA,X", 4 },
{ "armw", 0xe8000000, 0xfc080000, "r,xOA,X", 4 },
{ "armd", 0xe8000002, 0xfc080002, "r,xOA,X", 4 },
{ "adi", 0xf8010000, 0xfc0f0000, "r,I", 4 },
{ "sumb", 0xcc080000, 0xfc080000, "r,xOA,X", 4 },
{ "sumh", 0xcc000001, 0xfc080001, "r,xOA,X", 4 },
{ "sumw", 0xcc000000, 0xfc080000, "r,xOA,X", 4 },
{ "sumd", 0xcc000002, 0xfc080002, "r,xOA,X", 4 },
{ "sur", 0x3c000000, 0xfc0f0000, "r,R", 2 },
{ "sui", 0xf8020000, 0xfc0f0000, "r,I", 4 },
{ "mpmb", 0xc0080000, 0xfc080000, "r,xOA,X", 4 },
{ "mpmh", 0xc0000001, 0xfc080001, "r,xOA,X", 4 },
{ "mpmw", 0xc0000000, 0xfc080000, "r,xOA,X", 4 },
{ "mpr", 0x38020000, 0xfc0f0000, "r,R", 2 },
{ "mprd", 0x3c0f0000, 0xfc0f0000, "r,R", 2 },
{ "mpi", 0xf8030000, 0xfc0f0000, "r,I", 4 },
{ "dvmb", 0xc4080000, 0xfc080000, "r,xOA,X", 4 },
{ "dvmh", 0xc4000001, 0xfc080001, "r,xOA,X", 4 },
{ "dvmw", 0xc4000000, 0xfc080000, "r,xOA,X", 4 },
{ "dvr", 0x380a0000, 0xfc0f0000, "r,R", 2 },
{ "dvi", 0xf8040000, 0xfc0f0000, "r,I", 4 },
{ "exs", 0x38080000, 0xfc0f0000, "r,R", 2 },
{ "advv", 0x30000000, 0xfc0f0000, "v,V", 2 },
{ "advvd", 0x30080000, 0xfc0f0000, "v,V", 2 },
{ "adrv", 0x34000000, 0xfc0f0000, "v,R", 2 },
{ "adrvd", 0x34080000, 0xfc0f0000, "v,R", 2 },
{ "suvv", 0x30010000, 0xfc0f0000, "v,V", 2 },
{ "suvvd", 0x30090000, 0xfc0f0000, "v,V", 2 },
{ "surv", 0x34010000, 0xfc0f0000, "v,R", 2 },
{ "survd", 0x34090000, 0xfc0f0000, "v,R", 2 },
{ "mpvv", 0x30020000, 0xfc0f0000, "v,V", 2 },
{ "mprv", 0x34020000, 0xfc0f0000, "v,R", 2 },
{ "adfw", 0xe0080000, 0xfc080000, "r,xOA,X", 4 },
{ "adfd", 0xe0080002, 0xfc080002, "r,xOA,X", 4 },
{ "adrfw", 0x38010000, 0xfc0f0000, "r,R", 2 },
{ "adrfd", 0x38090000, 0xfc0f0000, "r,R", 2 },
{ "surfw", 0xe0000000, 0xfc080000, "r,xOA,X", 4 },
{ "surfd", 0xe0000002, 0xfc080002, "r,xOA,X", 4 },
{ "surfw", 0x38030000, 0xfc0f0000, "r,R", 2 },
{ "surfd", 0x380b0000, 0xfc0f0000, "r,R", 2 },
{ "mpfw", 0xe4080000, 0xfc080000, "r,xOA,X", 4 },
{ "mpfd", 0xe4080002, 0xfc080002, "r,xOA,X", 4 },
{ "mprfw", 0x38060000, 0xfc0f0000, "r,R", 2 },
{ "mprfd", 0x380e0000, 0xfc0f0000, "r,R", 2 },
{ "rfw", 0xe4000000, 0xfc080000, "r,xOA,X", 4 },
{ "rfd", 0xe4000002, 0xfc080002, "r,xOA,X", 4 },
{ "rrfw", 0x0c0e0000, 0xfc0f0000, "r", 2 },
{ "rrfd", 0x0c0f0000, 0xfc0f0000, "r", 2 },
{ "advvfw", 0x30040000, 0xfc0f0000, "v,V", 2 },
{ "advvfd", 0x300c0000, 0xfc0f0000, "v,V", 2 },
{ "adrvfw", 0x34040000, 0xfc0f0000, "v,R", 2 },
{ "adrvfd", 0x340c0000, 0xfc0f0000, "v,R", 2 },
{ "suvvfw", 0x30050000, 0xfc0f0000, "v,V", 2 },
{ "suvvfd", 0x300d0000, 0xfc0f0000, "v,V", 2 },
{ "survfw", 0x34050000, 0xfc0f0000, "v,R", 2 },
{ "survfd", 0x340d0000, 0xfc0f0000, "v,R", 2 },
{ "mpvvfw", 0x30060000, 0xfc0f0000, "v,V", 2 },
{ "mpvvfd", 0x300e0000, 0xfc0f0000, "v,V", 2 },
{ "mprvfw", 0x34060000, 0xfc0f0000, "v,R", 2 },
{ "mprvfd", 0x340e0000, 0xfc0f0000, "v,R", 2 },
{ "rvfw", 0x30070000, 0xfc0f0000, "v", 2 },
{ "rvfd", 0x300f0000, 0xfc0f0000, "v", 2 },
{ "fltw", 0x38070000, 0xfc0f0000, "r,R", 2 },
{ "fltd", 0x380f0000, 0xfc0f0000, "r,R", 2 },
{ "fixw", 0x38050000, 0xfc0f0000, "r,R", 2 },
{ "fixd", 0x380d0000, 0xfc0f0000, "r,R", 2 },
{ "cfpds", 0x3c090000, 0xfc0f0000, "r,R", 2 },
{ "fltvw", 0x080d0000, 0xfc0f0000, "v,V", 2 },
{ "fltvd", 0x080f0000, 0xfc0f0000, "v,V", 2 },
{ "fixvw", 0x080c0000, 0xfc0f0000, "v,V", 2 },
{ "fixvd", 0x080e0000, 0xfc0f0000, "v,V", 2 },
{ "cfpvds", 0x0c0d0000, 0xfc0f0000, "v,V", 2 },
{ "orvrn", 0x000a0000, 0xfc0f0000, "r,V", 2 },
{ "andvrn", 0x00080000, 0xfc0f0000, "r,V", 2 },
{ "frsteq", 0x04090000, 0xfc0f0000, "r,V", 2 },
{ "sigma", 0x0c080000, 0xfc0f0000, "r,V", 2 },
{ "sigmad", 0x0c0a0000, 0xfc0f0000, "r,V", 2 },
{ "sigmf", 0x08080000, 0xfc0f0000, "r,V", 2 },
{ "sigmfd", 0x080a0000, 0xfc0f0000, "r,V", 2 },
{ "prodf", 0x04080000, 0xfc0f0000, "r,V", 2 },
{ "prodfd", 0x040a0000, 0xfc0f0000, "r,V", 2 },
{ "maxv", 0x10080000, 0xfc0f0000, "r,V", 2 },
{ "maxvd", 0x100a0000, 0xfc0f0000, "r,V", 2 },
{ "minv", 0x14080000, 0xfc0f0000, "r,V", 2 },
{ "minvd", 0x140a0000, 0xfc0f0000, "r,V", 2 },
{ "lpsd", 0xf0000000, 0xfc080000, "xOA,X", 4 },
{ "ldc", 0xf0080000, 0xfc080000, "xOA,X", 4 },
{ "spm", 0x040c0000, 0xfc0f0000, "r", 2 },
{ "rpm", 0x040d0000, 0xfc0f0000, "r", 2 },
{ "tritr", 0x00070000, 0xfc0f0000, "r", 2 },
{ "trrit", 0x00060000, 0xfc0f0000, "r", 2 },
{ "rpswt", 0x04080000, 0xfc0f0000, "r", 2 },
{ "exr", 0xf8070000, 0xfc0f0000, "", 4 },
{ "halt", 0x00000000, 0xfc0f0000, "", 2 },
{ "wait", 0x00010000, 0xfc0f0000, "", 2 },
{ "nop", 0x00020000, 0xfc0f0000, "", 2 },
{ "eiae", 0x00030000, 0xfc0f0000, "", 2 },
{ "efae", 0x000d0000, 0xfc0f0000, "", 2 },
{ "diae", 0x000e0000, 0xfc0f0000, "", 2 },
{ "dfae", 0x000f0000, 0xfc0f0000, "", 2 },
{ "spvc", 0xf8060000, 0xfc0f0000, "r,T,N", 4 },
{ "rdsts", 0x00090000, 0xfc0f0000, "r", 2 },
{ "setcpu", 0x000c0000, 0xfc0f0000, "r", 2 },
{ "cmc", 0x000b0000, 0xfc0f0000, "r", 2 },
{ "trrcu", 0x00040000, 0xfc0f0000, "r", 2 },
{ "attnio", 0x00050000, 0xfc0f0000, "", 2 },
{ "fudit", 0x28080000, 0xfc0f0000, "", 2 },
{ "break", 0x28090000, 0xfc0f0000, "", 2 },
{ "frzss", 0x280a0000, 0xfc0f0000, "", 2 },
{ "ripi", 0x04040000, 0xfc0f0000, "r,R", 2 },
{ "xcp", 0x04050000, 0xfc0f0000, "r", 2 },
{ "block", 0x04060000, 0xfc0f0000, "", 2 },
{ "unblock", 0x04070000, 0xfc0f0000, "", 2 },
{ "trsc", 0x08060000, 0xfc0f0000, "r,R", 2 },
{ "tscr", 0x08070000, 0xfc0f0000, "r,R", 2 },
{ "fq", 0x04080000, 0xfc0f0000, "r", 2 },
{ "flupte", 0x2c080000, 0xfc0f0000, "r", 2 },
{ "rviu", 0x040f0000, 0xfc0f0000, "", 2 },
{ "ldel", 0x280c0000, 0xfc0f0000, "r,R", 2 },
{ "ldu", 0x280d0000, 0xfc0f0000, "r,R", 2 },
{ "stdecc", 0x280b0000, 0xfc0f0000, "r,R", 2 },
{ "trpc", 0x08040000, 0xfc0f0000, "r", 2 },
{ "tpcr", 0x08050000, 0xfc0f0000, "r", 2 },
{ "ghalt", 0x0c050000, 0xfc0f0000, "r", 2 },
{ "grun", 0x0c040000, 0xfc0f0000, "", 2 },
{ "tmpr", 0x2c0a0000, 0xfc0f0000, "r,R", 2 },
{ "trmp", 0x2c0b0000, 0xfc0f0000, "r,R", 2 },
{ "trrve", 0x28060000, 0xfc0f0000, "r", 2 },
{ "trver", 0x28070000, 0xfc0f0000, "r", 2 },
{ "trvlr", 0x280f0000, 0xfc0f0000, "r", 2 },
{ "linkfl", 0x18000000, 0xfc0f0000, "r,R", 2 },
{ "linkbl", 0x18020000, 0xfc0f0000, "r,R", 2 },
{ "linkfp", 0x18010000, 0xfc0f0000, "r,R", 2 },
{ "linkbp", 0x18030000, 0xfc0f0000, "r,R", 2 },
{ "linkpl", 0x18040000, 0xfc0f0000, "r,R", 2 },
{ "ulinkl", 0x18080000, 0xfc0f0000, "r,R", 2 },
{ "ulinkp", 0x18090000, 0xfc0f0000, "r,R", 2 },
{ "ulinktl", 0x180a0000, 0xfc0f0000, "r,R", 2 },
{ "ulinktp", 0x180b0000, 0xfc0f0000, "r,R", 2 },
};
int numopcodes = sizeof(gld_opcodes) / sizeof(gld_opcodes[0]);
struct gld_opcode *endop = gld_opcodes + sizeof(gld_opcodes) /
sizeof(gld_opcodes[0]);

307
gdb/ns32k-opcode.h Normal file
View File

@ -0,0 +1,307 @@
/* ns32k-opcode.h */
#ifndef ns32k_opcodeT
#define ns32k_opcodeT int
#endif /* no ns32k_opcodeT */
struct not_wot /* ns32k opcode table: wot to do with this */
/* particular opcode */
{
int obits; /* number of opcode bits */
int ibits; /* number of instruction bits */
ns32k_opcodeT code; /* op-code (may be > 8 bits!) */
char *args; /* how to compile said opcode */
};
struct not /* ns32k opcode text */
{
char * name; /* opcode name: lowercase string [key] */
struct not_wot detail; /* rest of opcode table [datum] */
};
/* F : 32 bit float
* L : 64 bit float
* B : byte
* W : word
* D : double-word
* Q : quad-word
* d : displacement
* q : quick
* i : immediate (8 bits)
* r : register number (3 bits)
* p : displacement - pc relative addressing
*/
static struct not
notstrs[] =
{
{ "absf", 14,24, 0x35be, "1F2F" },
{ "absl", 14,24, 0x34be, "1L2L" },
{ "absb", 14,24, 0x304e, "1B2B" },
{ "absw", 14,24, 0x314e, "1W2W" },
{ "absd", 14,24, 0x334e, "1D2D" },
{ "acbb", 7,16, 0x4c, "2B1q3p" },
{ "addf", 14,24, 0x01be, "1F2F" },
{ "addl", 14,24, 0x00be, "1L2L" },
{ "addb", 6,16, 0x00, "1B2B" },
{ "addw", 6,16, 0x01, "1W2W" },
{ "addd", 6,16, 0x03, "1D2D" },
{ "addcb", 6,16, 0x10, "1B2B" },
{ "addcw", 6,16, 0x11, "1W2W" },
{ "addcd", 6,16, 0x13, "1D2D" },
{ "addpb", 14,24, 0x3c4e, "1B2B" },
{ "addpw", 14,24, 0x3d4e, "1W2W" },
{ "addpd", 14,24, 0x3f4e, "1D2D" },
{ "addqb", 7,16, 0x0c, "2B1q" },
{ "addqw", 7,16, 0x0d, "2W1q" },
{ "addqd", 7,16, 0x0f, "2D1q" },
{ "addr", 6,16, 0x27, "1D2D" },
{ "adjspb", 11,16, 0x057c, "1B" },
{ "adjspw", 11,16, 0x057d, "1W" },
{ "adjspd", 11,16, 0x057f, "1D" },
{ "andb", 6,16, 0x28, "1B2B" },
{ "andw", 6,16, 0x29, "1W2W" },
{ "andd", 6,16, 0x2b, "1D2D" },
{ "ashb", 14,24, 0x044e, "1B2B" },
{ "ashw", 14,24, 0x054e, "1B2W" },
{ "ashd", 14,24, 0x074e, "1B2D" },
{ "beq", 8,8, 0x0a, "1p" },
{ "bne", 8,8, 0x1a, "1p" },
{ "bcs", 8,8, 0x2a, "1p" },
{ "bcc", 8,8, 0x3a, "1p" },
{ "bhi", 8,8, 0x4a, "1p" },
{ "bls", 8,8, 0x5a, "1p" },
{ "bgt", 8,8, 0x6a, "1p" },
{ "ble", 8,8, 0x7a, "1p" },
{ "bfs", 8,8, 0x8a, "1p" },
{ "bfc", 8,8, 0x9a, "1p" },
{ "blo", 8,8, 0xaa, "1p" },
{ "bhs", 8,8, 0xba, "1p" },
{ "blt", 8,8, 0xca, "1p" },
{ "bge", 8,8, 0xda, "1p" },
{ "bicb", 6,16, 0x08, "1B2B" },
{ "bicw", 6,16, 0x09, "1W2W" },
{ "bicd", 6,16, 0x0b, "1D2D" },
{ "bicpsrb", 11,16, 0x17c, "1B" },
{ "bicpsrw", 11,16, 0x17d, "1W" },
{ "bispsrb", 11,16, 0x37c, "1B" },
{ "bispsrw", 11,16, 0x37d, "1W" },
{ "bpt", 8,8, 0xf2, "" },
{ "br", 8,8, 0xea, "1p" },
{ "bsr", 8,8, 0x02, "1p" },
{ "caseb", 11,16, 0x77c, "1B" },
{ "casew", 11,16, 0x77d, "1W" },
{ "cased", 11,16, 0x77f, "1D" },
{ "cbitb", 14,24, 0x084e, "1B2D" },
{ "cbitw", 14,24, 0x094e, "1W2D" },
{ "cbitd", 14,24, 0x0b4e, "1D2D" },
{ "cbitib", 14,24, 0x0c4e, "1B2D" },
{ "cbitiw", 14,24, 0x0d4e, "1W2D" },
{ "cbitid", 14,24, 0x0f4e, "1D2D" },
{ "checkb", 11,24, 0x0ee, "2A3B1r" },
{ "checkw", 11,24, 0x1ee, "2A3B1r" },
{ "checkd", 11,24, 0x3ee, "2A3D1r" },
{ "cmpf", 14,24, 0x09be, "1F2F" },
{ "cmpl", 14,24, 0x08be, "1L2L" },
{ "cmpb", 6,16, 0x04, "1B2B" },
{ "cmpw", 6,16, 0x05, "1W2W" },
{ "cmpd", 6,16, 0x07, "1D2D" },
{ "cmpmb", 14,24, 0x04ce, "1D2D3d" },
{ "cmpmw", 14,24, 0x05ce, "1D2D3d" },
{ "cmpmd", 14,24, 0x07ce, "1D2D3d" },
{ "cmpqb", 7,16, 0x1c, "2B1q" },
{ "cmpqw", 7,16, 0x1d, "2W1q" },
{ "cmpqd", 7,16, 0x1f, "2D1q" },
{ "cmpsb", 16,16, 0x040e, "1i" },
{ "cmpsw", 16,16, 0x050e, "1i" },
{ "cmpsd", 16,16, 0x070e, "1i" },
{ "cmpst", 16,16, 0x840e, "1i" },
{ "comb", 14,24, 0x344e, "1B2B" },
{ "comw", 14,24, 0x354e, "1W2W" },
{ "comd", 14,24, 0x374e, "1D2D" },
{ "cvtp", 11,24, 0x036e, "2D3D1r" },
{ "cxp", 8,8, 0x22, "1p" },
{ "cxpd", 11,16, 0x07f, "1D" },
{ "deib", 14,24, 0x2cce, "1B2W" },
{ "deiw", 14,24, 0x2cce, "1W2D" },
{ "deid", 14,24, 0x2cce, "1D2Q" },
{ "dia", 8,8, 0xc2, "" },
{ "divf", 14,24, 0x21be, "1F2F" },
{ "divl", 14,24, 0x20be, "1L2L" },
{ "divb", 14,24, 0x3cce, "1B2B" },
{ "divw", 14,24, 0x3dce, "1W2W" },
{ "divd", 14,24, 0x3fce, "1D2D" },
{ "enter", 8,8, 0x82, "1i2d" },
{ "exit", 8,8, 0x92, "1i" },
{ "extb", 11,24, 0x02e, "2D3B1r4d" },
{ "extw", 11,24, 0x12e, "2D3W1r4d" },
{ "extd", 11,24, 0x32e, "2D3D1r4d" },
{ "extsb", 14,24, 0x0cce, "1D2B3i" },
{ "extsw", 14,24, 0x0dce, "1D2W3i" },
{ "extsd", 14,24, 0x0fce, "1D2D3i" },
{ "ffsb", 14,24, 0x046e, "1B2B" },
{ "ffsw", 14,24, 0x056e, "1W2B" },
{ "ffsd", 14,24, 0x076e, "1D2B" },
{ "flag", 8,8, 0xd2, "" },
{ "floorfb", 14,24, 0x3c3e, "1F2B" },
{ "floorfw", 14,24, 0x3d3e, "1F2W" },
{ "floorfd", 14,24, 0x3f3e, "1F2D" },
{ "floorlb", 14,24, 0x383e, "1L2B" },
{ "floorlw", 14,24, 0x393e, "1L2W" },
{ "floorld", 14,24, 0x3b3e, "1L2D" },
{ "ibitb", 14,24, 0x384e, "1B2D" },
{ "ibitw", 14,24, 0x394e, "1W2D" },
{ "ibitd", 14,24, 0x3b4e, "1D2D" },
{ "indexb", 11,24, 0x42e, "2B3B1r" },
{ "indexw", 11,24, 0x52e, "2W3W1r" },
{ "indexd", 11,24, 0x72e, "2D3D1r" },
{ "insb", 11,24, 0x0ae, "2B3B1r4d" },
{ "insw", 11,24, 0x1ae, "2W3W1r4d" },
{ "insd", 11,24, 0x3ae, "2D3D1r4d" },
{ "inssb", 14,24, 0x08ce, "1B2D3i" },
{ "inssw", 14,24, 0x09ce, "1W2D3i" },
{ "inssd", 14,24, 0x0bce, "1D2D3i" },
{ "jsr", 11,16, 0x67f, "1A" },
{ "jump", 11,16, 0x27f, "1A" },
{ "lfsr", 19,24, 0x00f3e,"1D" },
{ "lmr", 15,24, 0x0b1e, "2D1q" },
{ "lprb", 7,16, 0x6c, "2B1q" },
{ "lprw", 7,16, 0x6d, "2W1q" },
{ "lprd", 7,16, 0x6f, "2D1q" },
{ "lshb", 14,24, 0x144e, "1B2B" },
{ "lshw", 14,24, 0x154e, "1B2W" },
{ "lshd", 14,24, 0x174e, "1B2D" },
{ "meib", 14,24, 0x24ce, "1B2W" },
{ "meiw", 14,24, 0x25ce, "1W2D" },
{ "meid", 14,24, 0x27ce, "1D2Q" },
{ "modb", 14,24, 0x38ce, "1B2B" },
{ "modw", 14,24, 0x39ce, "1W2W" },
{ "modd", 14,24, 0x3bce, "1D2D" },
{ "movf", 14,24, 0x05be, "1F2F" },
{ "movl", 14,24, 0x04be, "1L2L" },
{ "movb", 6,16, 0x14, "1B2B" },
{ "movw", 6,16, 0x15, "1W2W" },
{ "movd", 6,16, 0x17, "1D2D" },
{ "movbf", 14,24, 0x043e, "1B2F" },
{ "movwf", 14,24, 0x053e, "1W2F" },
{ "movdf", 14,24, 0x073e, "1D2F" },
{ "movbl", 14,24, 0x003e, "1B2L" },
{ "movwl", 14,24, 0x013e, "1W2L" },
{ "movdl", 14,24, 0x033e, "1D2L" },
{ "movfl", 14,24, 0x1b3e, "1F2L" },
{ "movlf", 14,24, 0x163e, "1L2F" },
{ "movmb", 14,24, 0x00ce, "1D2D3d" },
{ "movmw", 14,24, 0x00de, "1D2D3d" },
{ "movmd", 14,24, 0x00fe, "1D2D3d" },
{ "movqb", 7,16, 0x5c, "2B1q" },
{ "movqw", 7,16, 0x5d, "2B1q" },
{ "movqd", 7,16, 0x5f, "2B1q" },
{ "movsb", 16,16, 0x000e, "1i" },
{ "movsw", 16,16, 0x010e, "1i" },
{ "movsd", 16,16, 0x030e, "1i" },
{ "movst", 16,16, 0x800e, "1i" },
{ "movsub", 14,24, 0x0cae, "1A1A" },
{ "movsuw", 14,24, 0x0dae, "1A1A" },
{ "movsud", 14,24, 0x0fae, "1A1A" },
{ "movusb", 14,24, 0x1cae, "1A1A" },
{ "movusw", 14,24, 0x1dae, "1A1A" },
{ "movusd", 14,24, 0x1fae, "1A1A" },
{ "movxbd", 14,24, 0x1cce, "1B2D" },
{ "movxwd", 14,24, 0x1dce, "1W2D" },
{ "movxbw", 14,24, 0x10ce, "1B2W" },
{ "movzbd", 14,24, 0x18ce, "1B2D" },
{ "movzwd", 14,24, 0x19ce, "1W2D" },
{ "movzbw", 14,24, 0x14ce, "1B2W" },
{ "mulf", 14,24, 0x31be, "1F2F" },
{ "mull", 14,24, 0x30be, "1L2L" },
{ "mulb", 14,24, 0x20ce, "1B2B" },
{ "mulw", 14,24, 0x21ce, "1W2W" },
{ "muld", 14,24, 0x23ce, "1D2D" },
{ "negf", 14,24, 0x15be, "1F2F" },
{ "negl", 14,24, 0x14be, "1L2L" },
{ "negb", 14,24, 0x204e, "1B2B" },
{ "negw", 14,24, 0x214e, "1W2W" },
{ "negd", 14,24, 0x234e, "1D2D" },
{ "nop", 8,8, 0xa2, "" },
{ "notb", 14,24, 0x244e, "1B2B" },
{ "notw", 14,24, 0x254e, "1W2W" },
{ "notd", 14,24, 0x274e, "1D2D" },
{ "orb", 6,16, 0x18, "1B1B" },
{ "orw", 6,16, 0x19, "1W1W" },
{ "ord", 6,16, 0x1b, "1D1D" },
{ "quob", 14,24, 0x30ce, "1B2B" },
{ "quow", 14,24, 0x31ce, "1W2W" },
{ "quod", 14,24, 0x33ce, "1D2D" },
{ "rdval", 19,24, 0x0031e,"1A" },
{ "remb", 14,24, 0x34ce, "1B2B" },
{ "remw", 14,24, 0x35ce, "1W2W" },
{ "remd", 14,24, 0x37ce, "1D2D" },
{ "restore", 8,8, 0x72, "1i" },
{ "ret", 8,8, 0x12, "1d" },
{ "reti", 8,8, 0x52, "" },
{ "rett", 8,8, 0x42, "" },
{ "rotb", 14,24, 0x004e, "1B2B" },
{ "rotw", 14,24, 0x014e, "1B2W" },
{ "rotd", 14,24, 0x034e, "1B2D" },
{ "roundfb", 14,24, 0x243e, "1F2B" },
{ "roundfw", 14,24, 0x253e, "1F2W" },
{ "roundfd", 14,24, 0x273e, "1F2D" },
{ "roundlb", 14,24, 0x203e, "1L2B" },
{ "roundlw", 14,24, 0x213e, "1L2W" },
{ "roundld", 14,24, 0x233e, "1L2D" },
{ "rxp", 8,8, 0x32, "1d" },
{ "sCONDb", 7,16, 0x3c, "2B1q" },
{ "sCONDw", 7,16, 0x3d, "2D1q" },
{ "sCONDd", 7,16, 0x3f, "2D1q" },
{ "save", 8,8, 0x62, "1i" },
{ "sbitb", 14,24, 0x184e, "1B2A" },
{ "sbitw", 14,24, 0x194e, "1W2A" },
{ "sbitd", 14,24, 0x1b4e, "1D2A" },
{ "sbitib", 14,24, 0x1c4e, "1B2A" },
{ "sbitiw", 14,24, 0x1d4e, "1W2A" },
{ "sbitid", 14,24, 0x1f4e, "1D2A" },
{ "setcfg", 15,24, 0x0b0e, "5D1q" },
{ "sfsr", 14,24, 0x673e, "5D1D" },
{ "skpsb", 16,16, 0x0c0e, "1i" },
{ "skpsw", 16,16, 0x0d0e, "1i" },
{ "skpsd", 16,16, 0x0f0e, "1i" },
{ "skpst", 16,16, 0x8c0e, "1i" },
{ "smr", 15,24, 0x0f1e, "2D1q" },
{ "sprb", 7,16, 0x2c, "2B1q" },
{ "sprw", 7,16, 0x2d, "2W1q" },
{ "sprd", 7,16, 0x2f, "2D1q" },
{ "subf", 14,24, 0x11be, "1F2F" },
{ "subl", 14,24, 0x10be, "1L2L" },
{ "subb", 6,16, 0x20, "1B2B" },
{ "subw", 6,16, 0x21, "1W2W" },
{ "subd", 6,16, 0x23, "1D2D" },
{ "subcb", 6,16, 0x30, "1B2B" },
{ "subcw", 6,16, 0x31, "1W2W" },
{ "subcd", 6,16, 0x33, "1D2D" },
{ "subpb", 14,24, 0x2c4e, "1B2B" },
{ "subpw", 14,24, 0x2d4e, "1W2W" },
{ "subpd", 14,24, 0x2f4e, "1D2D" },
#ifndef NS32K_SVC_IMMED_OPERANDS
{ "svc", 8,8, 0xe2, "2i1i" }, /* not really, but unix uses it */
#else
{ "svc", 8,8, 0xe2, "" }, /* not really, but unix uses it */
#endif
{ "tbitb", 6,16, 0x34, "1B2A" },
{ "tbitw", 6,16, 0x35, "1W2A" },
{ "tbitd", 6,16, 0x37, "1D2A" },
{ "truncfb", 14,24, 0x2c3e, "1F2B" },
{ "truncfw", 14,24, 0x2d3e, "1F2W" },
{ "truncfd", 14,24, 0x2f3e, "1F2D" },
{ "trunclb", 14,24, 0x283e, "1L2B" },
{ "trunclw", 14,24, 0x293e, "1L2W" },
{ "truncld", 14,24, 0x2b3e, "1L2D" },
{ "wait", 8,8, 0xb2, "" },
{ "wrval", 19,24, 0x0071e,"1A" },
{ "xorb", 6,16, 0x38, "1B2B" },
{ "xorw", 6,16, 0x39, "1W2W" },
{ "xord", 6,16, 0x3b, "1D2D" },
}; /* notstrs */
/* end: ns32k.opcode.h */
#define MAX_ARGS 4
#define ARG_LEN 50

457
gdb/ns32k-pinsn.c Normal file
View File

@ -0,0 +1,457 @@
/* Print 32000 instructions for GDB, the GNU debugger.
Copyright (C) 1986,1988 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
#include <stdio.h>
#include "defs.h"
#include "param.h"
#include "symtab.h"
#include "opcode.h"
/* 32000 instructions are never longer than this. */
#define MAXLEN 62
/* Number of elements in the opcode table. */
#define NOPCODES (sizeof notstrs / sizeof notstrs[0])
extern char *reg_names[];
#define NEXT_IS_ADDR '|'
/*
* extract "count" bits starting "offset" bits
* into buffer
*/
int
bit_extract (buffer, offset, count)
char *buffer;
int offset;
int count;
{
int result;
int mask;
int bit;
buffer += offset >> 3;
offset &= 7;
bit = 1;
result = 0;
while (count--)
{
if ((*buffer & (1 << offset)))
result |= bit;
if (++offset == 8)
{
offset = 0;
buffer++;
}
bit <<= 1;
}
return result;
}
float
fbit_extract (buffer, offset, count)
{
union {
int ival;
float fval;
} foo;
foo.ival = bit_extract (buffer, offset, 32);
return foo.fval;
}
double
dbit_extract (buffer, offset, count)
{
union {
struct {int low, high; } ival;
double dval;
} foo;
foo.ival.low = bit_extract (buffer, offset, 32);
foo.ival.high = bit_extract (buffer, offset+32, 32);
return foo.dval;
}
sign_extend (value, bits)
{
value = value & ((1 << bits) - 1);
return (value & (1 << (bits-1))
? value | (~((1 << bits) - 1))
: value);
}
flip_bytes (ptr, count)
char *ptr;
int count;
{
char tmp;
while (count > 0)
{
tmp = *ptr;
ptr[0] = ptr[count-1];
ptr[count-1] = tmp;
ptr++;
count -= 2;
}
}
/* Print the 32000 instruction at address MEMADDR in debugged memory,
on STREAM. Returns length of the instruction, in bytes. */
int
print_insn (memaddr, stream)
CORE_ADDR memaddr;
FILE *stream;
{
unsigned char buffer[MAXLEN];
register int i;
register unsigned char *p;
register char *d;
unsigned short first_word;
int gen, disp;
int ioffset; /* bits into instruction */
int aoffset; /* bits into arguments */
char arg_bufs[MAX_ARGS+1][ARG_LEN];
int argnum;
int maxarg;
read_memory (memaddr, buffer, MAXLEN);
first_word = *(unsigned short *) buffer;
for (i = 0; i < NOPCODES; i++)
if ((first_word & ((1 << notstrs[i].detail.obits) - 1))
== notstrs[i].detail.code)
break;
/* Handle undefined instructions. */
if (i == NOPCODES)
{
fprintf (stream, "0%o", buffer[0]);
return 1;
}
fprintf (stream, "%s", notstrs[i].name);
ioffset = notstrs[i].detail.ibits;
aoffset = notstrs[i].detail.ibits;
d = notstrs[i].detail.args;
if (*d)
{
fputc ('\t', stream);
maxarg = 0;
while (*d)
{
argnum = *d - '1';
d++;
if (argnum > maxarg && argnum < MAX_ARGS)
maxarg = argnum;
ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
memaddr, arg_bufs[argnum]);
d++;
}
for (argnum = 0; argnum <= maxarg; argnum++)
{
CORE_ADDR addr;
char *ch, *index ();
for (ch = arg_bufs[argnum]; *ch;)
{
if (*ch == NEXT_IS_ADDR)
{
++ch;
addr = atoi (ch);
print_address (addr, stream);
while (*ch && *ch != NEXT_IS_ADDR)
++ch;
if (*ch)
++ch;
}
else
putc (*ch++, stream);
}
if (argnum < maxarg)
fprintf (stream, ", ");
}
}
return aoffset / 8;
}
print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result)
char d;
int ioffset, *aoffsetp;
char *buffer;
CORE_ADDR addr;
char *result;
{
int addr_mode;
float Fvalue;
double Lvalue;
int Ivalue;
int disp1, disp2;
int index;
switch (d)
{
case 'F':
case 'L':
case 'B':
case 'W':
case 'D':
case 'A':
addr_mode = bit_extract (buffer, ioffset-5, 5);
ioffset -= 5;
switch (addr_mode)
{
case 0x0: case 0x1: case 0x2: case 0x3:
case 0x4: case 0x5: case 0x6: case 0x7:
switch (d)
{
case 'F':
case 'L':
sprintf (result, "f%d", addr_mode);
break;
default:
sprintf (result, "r%d", addr_mode);
}
break;
case 0x8: case 0x9: case 0xa: case 0xb:
case 0xc: case 0xd: case 0xe: case 0xf:
disp1 = get_displacement (buffer, aoffsetp);
sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
break;
case 0x10:
case 0x11:
case 0x12:
disp1 = get_displacement (buffer, aoffsetp);
disp2 = get_displacement (buffer, aoffsetp);
sprintf (result, "%d(%d(%s))", disp2, disp1,
addr_mode==0x10?"fp":addr_mode==0x11?"sp":"sb");
break;
case 0x13:
sprintf (result, "reserved");
break;
case 0x14:
switch (d)
{
case 'B':
Ivalue = bit_extract (buffer, *aoffsetp, 8);
Ivalue = sign_extend (Ivalue, 8);
*aoffsetp += 8;
sprintf (result, "$%d", Ivalue);
break;
case 'W':
Ivalue = bit_extract (buffer, *aoffsetp, 16);
flip_bytes (&Ivalue, 2);
*aoffsetp += 16;
Ivalue = sign_extend (Ivalue, 16);
sprintf (result, "$%d", Ivalue);
break;
case 'D':
Ivalue = bit_extract (buffer, *aoffsetp, 32);
flip_bytes (&Ivalue, 4);
*aoffsetp += 32;
sprintf (result, "$%d", Ivalue);
break;
case 'A':
Ivalue = bit_extract (buffer, *aoffsetp, 32);
flip_bytes (&Ivalue, 4);
*aoffsetp += 32;
sprintf (result, "$|%d|", Ivalue);
break;
case 'F':
Fvalue = fbit_extract (buffer, *aoffsetp, 32);
flip_bytes (&Fvalue, 4);
*aoffsetp += 32;
sprintf (result, "$%g", Fvalue);
break;
case 'L':
Lvalue = dbit_extract (buffer, *aoffsetp, 64);
flip_bytes (&Lvalue, 8);
*aoffsetp += 64;
sprintf (result, "$%g", Lvalue);
break;
}
break;
case 0x15:
disp1 = get_displacement (buffer, aoffsetp);
sprintf (result, "@|%d|", disp1);
break;
case 0x16:
disp1 = get_displacement (buffer, aoffsetp);
disp2 = get_displacement (buffer, aoffsetp);
sprintf (result, "EXT(%d) + %d", disp1, disp2);
break;
case 0x17:
sprintf (result, "tos");
break;
case 0x18:
disp1 = get_displacement (buffer, aoffsetp);
sprintf (result, "%d(fp)", disp1);
break;
case 0x19:
disp1 = get_displacement (buffer, aoffsetp);
sprintf (result, "%d(sp)", disp1);
break;
case 0x1a:
disp1 = get_displacement (buffer, aoffsetp);
sprintf (result, "%d(sb)", disp1);
break;
case 0x1b:
disp1 = get_displacement (buffer, aoffsetp);
sprintf (result, "|%d|", addr + disp1);
break;
case 0x1c:
case 0x1d:
case 0x1e:
case 0x1f:
index = bit_extract (buffer, *aoffsetp, 8);
*aoffsetp += 8;
print_insn_arg (d, *aoffsetp, aoffsetp, buffer, addr,
result);
{
static char *ind[] = {"b", "w", "d", "q"};
char *off;
off = result + strlen (result);
sprintf (off, "[r%d:%s]", index & 7,
ind[addr_mode & 3]);
}
break;
}
break;
case 'q':
Ivalue = bit_extract (buffer, ioffset-4, 4);
Ivalue = sign_extend (Ivalue, 4);
sprintf (result, "%d", Ivalue);
ioffset -= 4;
break;
case 'r':
Ivalue = bit_extract (buffer, ioffset-3, 3);
sprintf (result, "r%d", Ivalue&7);
ioffset -= 3;
break;
case 'd':
sprintf (result, "%d", get_displacement (buffer, aoffsetp));
break;
case 'p':
sprintf (result, "%c%d%c", NEXT_IS_ADDR,
addr + get_displacement (buffer, aoffsetp),
NEXT_IS_ADDR);
break;
case 'i':
Ivalue = bit_extract (buffer, *aoffsetp, 8);
*aoffsetp += 8;
sprintf (result, "0x%x", Ivalue);
break;
}
return ioffset;
}
get_displacement (buffer, aoffsetp)
char *buffer;
int *aoffsetp;
{
int Ivalue;
Ivalue = bit_extract (buffer, *aoffsetp, 8);
switch (Ivalue & 0xc0)
{
case 0x00:
case 0x40:
Ivalue = sign_extend (Ivalue, 7);
*aoffsetp += 8;
break;
case 0x80:
Ivalue = bit_extract (buffer, *aoffsetp, 16);
flip_bytes (&Ivalue, 2);
Ivalue = sign_extend (Ivalue, 14);
*aoffsetp += 16;
break;
case 0xc0:
Ivalue = bit_extract (buffer, *aoffsetp, 32);
flip_bytes (&Ivalue, 4);
Ivalue = sign_extend (Ivalue, 30);
*aoffsetp += 32;
break;
}
return Ivalue;
}
/* Return the number of locals in the current frame given a pc
pointing to the enter instruction. This is used in the macro
FRAME_FIND_SAVED_REGS. */
ns32k_localcount (enter_pc)
CORE_ADDR enter_pc;
{
unsigned char localtype;
int localcount;
localtype = read_memory_integer (enter_pc+2, 1);
if ((localtype & 0x80) == 0)
localcount = localtype;
else if ((localtype & 0xc0) == 0x80)
localcount = (((localtype & 0x3f) << 8)
| (read_memory_integer (enter_pc+3, 1) & 0xff));
else
localcount = (((localtype & 0x3f) << 24)
| ((read_memory_integer (enter_pc+3, 1) & 0xff) << 16)
| ((read_memory_integer (enter_pc+4, 1) & 0xff) << 8 )
| (read_memory_integer (enter_pc+5, 1) & 0xff));
return localcount;
}
/*
* Get the address of the enter opcode for the function
* containing PC, if there is an enter for the function,
* and if the pc is between the enter and exit.
* Returns positive address if pc is between enter/exit,
* 1 if pc before enter or after exit, 0 otherwise.
*/
CORE_ADDR
ns32k_get_enter_addr (pc)
CORE_ADDR pc;
{
CORE_ADDR enter_addr;
unsigned char op;
if (ABOUT_TO_RETURN (pc))
return 1; /* after exit */
enter_addr = get_pc_function_start (pc);
if (pc == enter_addr)
return 1; /* before enter */
op = read_memory_integer (enter_addr, 1);
if (op != 0x82)
return 0; /* function has no enter/exit */
return enter_addr; /* pc is between enter and exit */
}

View File

@ -57,9 +57,9 @@ Mere aggregation of another unrelated program with this program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other program under the scope of these terms.
3. You may copy and distribute this program (or a portion or derivative
of it, under Paragraph 2) in object code or executable form under the terms
of Paragraphs 1 and 2 above provided that you also do one of the following:
3. You may copy and distribute this program or any portion of it in
compiled, executable or object code form under the terms of Paragraphs
1 and 2 above provided that you do the following:
a) accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
@ -111,13 +111,30 @@ what you give them. Help stamp out software-hoarding! */
#define POINTER char *
#endif
/* Determine default alignment. */
struct fooalign {char x; double d;};
#define DEFAULT_ALIGNMENT ((char *)&((struct fooalign *) 0)->d - (char *)0)
/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
But in fact it might be less smart and round addresses to as much as
DEFAULT_ROUNDING. So we prepare for it to do that. */
union fooround {long x; double d;};
#define DEFAULT_ROUNDING (sizeof (union fooround))
/* When we copy a long block of data, this is the unit to do it with.
On some machines, copying successive ints does not work;
in such a case, redefine COPYING_UNIT to `long' (if that works)
or `char' as a last resort. */
#ifndef COPYING_UNIT
#define COPYING_UNIT int
#endif
/* The non-GNU-C macros copy the obstack into this global variable
to avoid multiple evaluation. */
struct obstack *_obstack;
/* Initialize an obstack H for use. Specify chunk size SIZE.
Objects start on multiples of ALIGNMENT.
/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
Objects start on multiples of ALIGNMENT (0 means use default).
CHUNKFUN is the function to use to allocate chunks,
and FREEFUN the function to free them. */
@ -129,7 +146,21 @@ _obstack_begin (h, size, alignment, chunkfun, freefun)
POINTER (*chunkfun) ();
void (*freefun) ();
{
register struct _obstack_chunk* chunk; /* points to new chunk */
register struct _obstack_chunk* chunk; /* points to new chunk */
if (alignment == 0)
alignment = DEFAULT_ALIGNMENT;
if (size == 0)
/* Default size is what GNU malloc can fit in a 4096-byte block.
Pick a number small enough that when rounded up to DEFAULT_ROUNDING
it is still smaller than 4096 - 4. */
{
int extra = 4;
if (extra < DEFAULT_ROUNDING)
extra = DEFAULT_ROUNDING;
size = 4096 - extra;
}
h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
h->freefun = freefun;
h->chunk_size = size;
@ -172,8 +203,10 @@ _obstack_newchunk (h, length)
/* Move the existing object to the new chunk.
Word at a time is fast and is safe because these
structures are aligned at least that much. */
for (i = (obj_size + sizeof (int) - 1) / sizeof (int); i >= 0; i--)
((int *)new_chunk->contents)[i] = ((int *)h->object_base)[i];
for (i = (obj_size + sizeof (COPYING_UNIT) - 1) / sizeof (COPYING_UNIT) - 1;
i >= 0; i--)
((COPYING_UNIT *)new_chunk->contents)[i]
= ((COPYING_UNIT *)h->object_base)[i];
h->object_base = new_chunk->contents;
h->next_free = h->object_base + obj_size;
@ -214,6 +247,10 @@ _obstack_free (h, obj)
abort ();
}
#if 0
/* These are now turned off because the applications do not use it
and it uses bcopy via obstack_grow, which causes trouble on sysV. */
/* Now define the functional versions of the obstack macros.
Define them to simply use the corresponding macros to do the job. */
@ -322,3 +359,5 @@ POINTER (obstack_copy0) (obstack, pointer, length)
}
#endif /* __STDC__ */
#endif /* 0 */

View File

@ -1,5 +1,5 @@
/* obstack.h - object stack macros
Copyright (C) 1986, 1988 Free Software Foundation, Inc.
Copyright (C) 1988 Free Software Foundation, Inc.
NO WARRANTY
@ -30,7 +30,7 @@ DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
1. You may copy and distribute verbatim copies of this source file
as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy a valid copyright notice "Copyright
(C) 1988 Free Software Foundation, Inc."; and include following the
(C) 1988 Free Software Foundation, Inc."; and include following the
copyright notice a verbatim copy of the above disclaimer of warranty
and of this License. You may charge a distribution fee for the
physical act of transferring a copy.
@ -57,9 +57,9 @@ Mere aggregation of another unrelated program with this program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other program under the scope of these terms.
3. You may copy and distribute this program (or a portion or derivative
of it, under Paragraph 2) in object code or executable form under the terms
of Paragraphs 1 and 2 above provided that you also do one of the following:
3. You may copy and distribute this program or any portion of it in
compiled, executable or object code form under the terms of Paragraphs
1 and 2 above provided that you do the following:
a) accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
@ -191,9 +191,42 @@ Summary:
#ifndef __OBSTACKS__
#define __OBSTACKS__
/* We use subtraction of (char *)0 instead of casting to int
because on word-addressable machines a simple cast to int
may ignore the byte-within-word field of the pointer. */
#ifndef __PTR_TO_INT
#define __PTR_TO_INT(P) ((P) - (char *)0)
#endif
#ifndef __INT_TO_PTR
#define __INT_TO_PTR(P) ((P) + (char *)0)
#endif
struct _obstack_chunk /* Lives at front of each chunk. */
{
char *limit; /* 1 past end of this chunk */
struct _obstack_chunk *prev; /* address of prior chunk or NULL */
char contents[4]; /* objects begin here */
};
struct obstack /* control current object in current chunk */
{
long chunk_size; /* preferred size to allocate chunks in */
struct _obstack_chunk* chunk; /* address of current struct obstack_chunk */
char *object_base; /* address of object we are building */
char *next_free; /* where to add next char to current object */
char *chunk_limit; /* address of char after current chunk */
int temp; /* Temporary for some macros. */
int alignment_mask; /* Mask of alignment for each object. */
struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */
void (*freefun) (); /* User's function to free a chunk. */
};
#ifdef __STDC__
/* Do the function-declarations before defining the macros. */
/* Do the function-declarations after the structs
but before defining the macros. */
void obstack_init (struct obstack *obstack);
@ -219,8 +252,8 @@ int obstack_room (struct obstack *obstack);
void obstack_1grow_fast (struct obstack *obstack, int data_char);
void obstack_blank_fast (struct obstack *obstack, int size);
void * object_base (struct obstack *obstack);
void * object_next_free (struct obstack *obstack);
void * obstack_base (struct obstack *obstack);
void * obstack_next_free (struct obstack *obstack);
int obstack_alignment_mask (struct obstack *obstack);
int obstack_chunk_size (struct obstack *obstack);
@ -229,26 +262,6 @@ int obstack_chunk_size (struct obstack *obstack);
/* Non-ANSI C cannot really support alternative functions for these macros,
so we do not declare them. */
struct _obstack_chunk /* Lives at front of each chunk. */
{
char *limit; /* 1 past end of this chunk */
struct _obstack_chunk *prev; /* address of prior chunk or NULL */
char contents[4]; /* objects begin here */
};
struct obstack /* control current object in current chunk */
{
long chunk_size; /* preferred size to allocate chunks in */
struct _obstack_chunk* chunk; /* address of current struct obstack_chunk */
char *object_base; /* address of object we are building */
char *next_free; /* where to add next char to current object */
char *chunk_limit; /* address of char after current chunk */
int temp; /* Temporary for some macros. */
int alignment_mask; /* Mask of alignment for each object. */
struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */
void (*freefun) (); /* User's function to free a chunk. */
};
/* Pointer to beginning of object being allocated or to be allocated next.
Note that this might not be the final address of the object
because a new chunk might be needed to hold the final size. */
@ -268,23 +281,20 @@ struct obstack /* control current object in current chunk */
#define obstack_alignment_mask(h) ((h)->alignment_mask)
#define obstack_init(h) \
_obstack_begin ((h), 4096 - 4, 4, obstack_chunk_alloc, obstack_chunk_free)
_obstack_begin ((h), 0, 0, obstack_chunk_alloc, obstack_chunk_free)
#define obstack_begin(h, size) \
_obstack_begin ((h), (size), 4, obstack_chunk_alloc, obstack_chunk_free)
_obstack_begin ((h), (size), 0, obstack_chunk_alloc, obstack_chunk_free)
#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
#define obstack_blank_fast(h,n) ((h)->next_free += (n))
#if defined (__GNU__) && defined (__STDC__)
#ifdef __GNUC__
/* For GNU C we can define these macros to compute all args only once
without using a global variable.
Also, we can avoid using the `temp' slot, to make faster code.
By checking both __GNU__ and __STDC__, we can make sure
both GNU language extensions and ANSI preprocessing are available. */
Also, we can avoid using the `temp' slot, to make faster code. */
#define obstack_object_size(OBSTACK) \
({ struct obstack *__o = (OBSTACK); \
@ -347,11 +357,11 @@ struct obstack /* control current object in current chunk */
({ struct obstack *__o = (OBSTACK); \
void *value = (void *) __o->object_base; \
__o->next_free \
= (char*)((int)(__o->next_free+__o->alignment_mask) \
& ~ (__o->alignment_mask)); \
= __INT_TO_PTR ((__PTR_TO_INT (__o->next_free)+__o->alignment_mask)\
& ~ (__o->alignment_mask)); \
((__o->next_free - (char *)__o->chunk \
> __o->chunk_limit - (char *)__o->chunk) \
? __o->next_free = __o->chunk_limit : 0); \
? (__o->next_free = __o->chunk_limit) : 0); \
__o->object_base = __o->next_free; \
value; })
@ -362,7 +372,7 @@ struct obstack /* control current object in current chunk */
__o->next_free = __o->object_base = __obj; \
else (obstack_free) (__o, __obj); })
#else /* not __GNU__ */
#else /* not __GNUC__ */
/* The non-GNU macros copy the obstack-pointer into this global variable
to avoid multiple evaluation. */
@ -411,15 +421,15 @@ extern struct obstack *_obstack;
(obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
#define obstack_finish(h) \
( (h)->temp = (int) (h)->object_base, \
( (h)->temp = __PTR_TO_INT ((h)->object_base), \
(h)->next_free \
= (char*)((int)((h)->next_free+(h)->alignment_mask) \
& ~ ((h)->alignment_mask)), \
= __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \
& ~ ((h)->alignment_mask)), \
(((h)->next_free - (char *)(h)->chunk \
> (h)->chunk_limit - (char *)(h)->chunk) \
? (h)->next_free = (h)->chunk_limit : 0), \
? ((h)->next_free = (h)->chunk_limit) : 0), \
(h)->object_base = (h)->next_free, \
(char *) (h)->temp)
__INT_TO_PTR ((h)->temp))
#ifdef __STDC__
#define obstack_free(h,obj) \
@ -427,7 +437,7 @@ extern struct obstack *_obstack;
(((h)->temp >= 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
? (int) ((h)->next_free = (h)->object_base \
= (h)->temp + (char *) (h)->chunk) \
: (int) (obstack_free) ((h), (h)->temp + (char *) (h)->chunk)))
: ((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0)))
#else
#define obstack_free(h,obj) \
( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \
@ -437,7 +447,7 @@ extern struct obstack *_obstack;
: (int) _obstack_free ((h), (h)->temp + (char *) (h)->chunk)))
#endif
#endif /* not __GNU__ */
#endif /* not __GNUC__ */
#endif /* not __OBSTACKS__ */

1272
gdb/opcode.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1 +1,477 @@
#include "m-sun3.h"
/* Parameters for execution on a Sun, for GDB, the GNU debugger.
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
#ifndef sun3
#define sun3
#endif
/* Get rid of any system-imposed stack limit if possible. */
#define SET_STACK_LIMIT_HUGE
/* Define this if the C compiler puts an underscore at the front
of external names before giving them to the linker. */
#define NAMES_HAVE_UNDERSCORE
/* Debugger information will be in DBX format. */
#define READ_DBX_FORMAT
/* Offset from address of function to start of its code.
Zero on most machines. */
#define FUNCTION_START_OFFSET 0
/* Advance PC across any function entry prologue instructions
to reach some "real" code. */
#define SKIP_PROLOGUE(pc) \
{ register int op = read_memory_integer (pc, 2); \
if (op == 0047126) \
pc += 4; /* Skip link #word */ \
else if (op == 0044016) \
pc += 6; /* Skip link #long */ \
}
/* Immediately after a function call, return the saved pc.
Can't go through the frames for this because on some machines
the new frame is not set up until the new function executes
some instructions. */
#define SAVED_PC_AFTER_CALL(frame) \
read_memory_integer (read_register (SP_REGNUM), 4)
/* Address of end of stack space. */
#define STACK_END_ADDR 0xf000000
/* Stack grows downward. */
#define INNER_THAN <
/* Sequence of bytes for breakpoint instruction. */
#define BREAKPOINT {0x4e, 0x4f}
/* Amount PC must be decremented by after a breakpoint.
This is often the number of bytes in BREAKPOINT
but not always. */
#define DECR_PC_AFTER_BREAK 2
/* Nonzero if instruction at PC is a return instruction. */
#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e75)
/* Return 1 if P points to an invalid floating point value. */
#define INVALID_FLOAT(p, len) 0 /* Just a first guess; not checked */
/* Say how long (ordinary) registers are. */
#define REGISTER_TYPE long
/* Number of machine registers */
#define NUM_REGS 31
/* Initializer for an array of names of registers.
There should be NUM_REGS strings in this initializer. */
#define REGISTER_NAMES \
{"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
"a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \
"ps", "pc", \
"fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \
"fpcontrol", "fpstatus", "fpiaddr", "fpcode", "fpflags" }
/* Register numbers of various important registers.
Note that some of these values are "real" register numbers,
and correspond to the general registers of the machine,
and some are "phony" register numbers which are too large
to be actual register numbers as far as the user is concerned
but do serve to get the desired values when passed to read_register. */
#define FP_REGNUM 14 /* Contains address of executing stack frame */
#define SP_REGNUM 15 /* Contains address of top of stack */
#define PS_REGNUM 16 /* Contains processor status */
#define PC_REGNUM 17 /* Contains program counter */
#define FP0_REGNUM 18 /* Floating point register 0 */
#define FPC_REGNUM 26 /* 68881 control register */
/* Total amount of space needed to store our copies of the machine's
register state, the array `registers'. */
#define REGISTER_BYTES (16*4+8*12+8+20)
/* Index within `registers' of the first byte of the space for
register N. */
#define REGISTER_BYTE(N) \
((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \
: (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \
: (N) * 4)
/* Number of bytes of storage in the actual machine representation
for register N. On the 68000, all regs are 4 bytes
except the floating point regs which are 12 bytes. */
#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4)
/* Number of bytes of storage in the program's representation
for register N. On the 68000, all regs are 4 bytes
except the floating point regs which are 8-byte doubles. */
#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4)
/* Largest value REGISTER_RAW_SIZE can have. */
#define MAX_REGISTER_RAW_SIZE 12
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
#define MAX_REGISTER_VIRTUAL_SIZE 8
/* Nonzero if register N requires conversion
from raw format to virtual format. */
#define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8)
/* Convert data from raw format for register REGNUM
to virtual format for register REGNUM. */
#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
convert_from_68881 ((FROM), (TO)); \
else \
bcopy ((FROM), (TO), 4); }
/* Convert data from virtual format for register REGNUM
to raw format for register REGNUM. */
#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
convert_to_68881 ((FROM), (TO)); \
else \
bcopy ((FROM), (TO), 4); }
/* Return the GDB type object for the "standard" data type
of data in register N. */
#define REGISTER_VIRTUAL_TYPE(N) \
(((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double : builtin_type_int)
/* 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. */
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
/* Write into appropriate registers a function return value
of type TYPE, given in virtual format. */
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
write_register_bytes (0, 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 (or an expression that can be used as one). */
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
/* Enable use of alternate code to read and write registers. */
#define NEW_SUN_PTRACE
/* Enable use of alternate code for Sun's format of core dump file. */
#define NEW_SUN_CORE
/* Do implement the attach and detach commands. */
#define ATTACH_DETACH
/* It is safe to look for symsegs on a Sun, because Sun's ld
does not screw up with random garbage at end of file. */
#define READ_GDB_SYMSEGS
/* Describe the pointer in each stack frame to the previous stack frame
(its caller). */
/* FRAME_CHAIN takes a frame's nominal address
and produces the frame's chain-pointer.
FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
and produces the nominal address of the caller frame.
However, if FRAME_CHAIN_VALID returns zero,
it means the given frame is the outermost one and has no caller.
In that case, FRAME_CHAIN_COMBINE is not used. */
/* In the case of the Sun, the frame's nominal address
is the address of a 4-byte word containing the calling frame's address. */
#define FRAME_CHAIN(thisframe) (read_memory_integer (thisframe, 4))
#define FRAME_CHAIN_VALID(chain, thisframe) \
(chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
/* Define other aspects of the stack frame. */
#define FRAME_SAVED_PC(frame) (read_memory_integer (frame + 4, 4))
#define FRAME_ARGS_ADDRESS(fi) (fi.frame)
#define FRAME_LOCALS_ADDRESS(fi) (fi.frame)
/* Set VAL to the number of args passed to frame described by FI.
Can set VAL to -1, meaning no way to tell. */
/* We can't tell how many args there are
now that the C compiler delays popping them. */
#define FRAME_NUM_ARGS(val,fi) (val = -1)
#if 0
#define FRAME_NUM_ARGS(val, fi) \
{ register CORE_ADDR pc = FRAME_SAVED_PC (fi.frame); \
register int insn = 0177777 & read_memory_integer (pc, 2); \
val = 0; \
if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ \
val = read_memory_integer (pc + 2, 2); \
else if ((insn & 0170777) == 0050217 /* addql #N, sp */ \
|| (insn & 0170777) == 0050117) /* addqw */ \
{ val = (insn >> 9) & 7; if (val == 0) val = 8; } \
else if (insn == 0157774) /* addal #WW, sp */ \
val = read_memory_integer (pc + 2, 4); \
val >>= 2; }
#endif
/* Return number of bytes at start of arglist that are not really args. */
#define FRAME_ARGS_SKIP 8
/* Put here the code to store, into a struct frame_saved_regs,
the addresses of the saved registers of frame described by FRAME_INFO.
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. */
#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
{ register int regnum; \
register int regmask; \
register CORE_ADDR next_addr; \
register CORE_ADDR pc; \
int nextinsn; \
bzero (&frame_saved_regs, sizeof frame_saved_regs); \
if ((frame_info).pc >= (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
&& (frame_info).pc <= (frame_info).frame) \
{ next_addr = (frame_info).frame; \
pc = (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\
else \
{ pc = get_pc_function_start ((frame_info).pc); \
/* Verify we have a link a6 instruction next; \
if not we lose. If we win, find the address above the saved \
regs using the amount of storage from the link instruction. */\
if (044016 == read_memory_integer (pc, 2)) \
next_addr = (frame_info).frame + read_memory_integer (pc += 2, 4), pc+=4; \
else if (047126 == read_memory_integer (pc, 2)) \
next_addr = (frame_info).frame + read_memory_integer (pc += 2, 2), pc+=2; \
else goto lose; \
/* If have an addal #-n, sp next, adjust next_addr. */ \
if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \
next_addr += read_memory_integer (pc += 2, 4), pc += 4; \
} \
/* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \
regmask = read_memory_integer (pc + 2, 2); \
/* But before that can come an fmovem. Check for it. */ \
nextinsn = 0xffff & read_memory_integer (pc, 2); \
if (0xf227 == nextinsn \
&& (regmask & 0xff00) == 0xe000) \
{ pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr -= 12); \
regmask = read_memory_integer (pc + 2, 2); } \
if (0044327 == read_memory_integer (pc, 2)) \
{ pc += 4; /* Regmask's low bit is for register 0, the first written */ \
for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; } \
else if (0044347 == read_memory_integer (pc, 2)) \
{ pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \
for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
else if (0x2f00 == 0xfff0 & read_memory_integer (pc, 2)) \
{ regnum = 0xf & read_memory_integer (pc, 2); pc += 2; \
(frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
/* fmovemx to index of sp may follow. */ \
regmask = read_memory_integer (pc + 2, 2); \
nextinsn = 0xffff & read_memory_integer (pc, 2); \
if (0xf236 == nextinsn \
&& (regmask & 0xff00) == 0xf000) \
{ pc += 10; /* Regmask's low bit is for register fp0, the first written */ \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
if (regmask & 1) \
(frame_saved_regs).regs[regnum] = (next_addr += 12) - 12; \
regmask = read_memory_integer (pc + 2, 2); } \
/* clrw -(sp); movw ccr,-(sp) may follow. */ \
if (0x426742e7 == read_memory_integer (pc, 4)) \
(frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \
lose: ; \
(frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 8; \
(frame_saved_regs).regs[FP_REGNUM] = (frame_info).frame; \
(frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \
}
/* Things needed for making the inferior call functions. */
/* Push an empty stack frame, to record the current PC, etc. */
#define PUSH_DUMMY_FRAME \
{ register CORE_ADDR sp = read_register (SP_REGNUM); \
register int regnum; \
char raw_buffer[12]; \
sp = push_word (sp, read_register (PC_REGNUM)); \
sp = push_word (sp, read_register (FP_REGNUM)); \
write_register (FP_REGNUM, sp); \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
{ read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); \
sp = push_bytes (sp, raw_buffer, 12); } \
for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
sp = push_word (sp, read_register (regnum)); \
sp = push_word (sp, read_register (PS_REGNUM)); \
write_register (SP_REGNUM, sp); }
/* Discard from the stack the innermost frame,
restoring all saved registers. */
#define POP_FRAME \
{ register CORE_ADDR fp = read_register (FP_REGNUM); \
register int regnum; \
struct frame_saved_regs fsr; \
struct frame_info fi; \
char raw_buffer[12]; \
fi = get_frame_info (fp); \
get_frame_saved_regs (&fi, &fsr); \
for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
if (fsr.regs[regnum]) \
{ read_memory (fsr.regs[regnum], raw_buffer, 12); \
write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
if (fsr.regs[regnum]) \
write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
if (fsr.regs[PS_REGNUM]) \
write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
write_register (SP_REGNUM, fp + 8); \
set_current_frame (read_register (FP_REGNUM)); }
/* This sequence of words is the instructions
fmovem 0xff,-(sp)
moveml 0xfffc,-(sp)
clrw -(sp)
movew ccr,-(sp)
/..* The arguments are pushed at this point by GDB;
no code is needed in the dummy for this.
The CALL_DUMMY_START_OFFSET gives the position of
the following jsr instruction. *../
jsr @#32323232
addl #69696969,sp
trap #15
nop
Note this is 28 bytes.
We actually start executing at the jsr, since the pushing of the
registers is done by PUSH_DUMMY_FRAME. If this were real code,
the arguments for the function called by the jsr would be pushed
between the moveml and the jsr, and we could allow it to execute through.
But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
and we cannot allow the moveml to push the registers again lest they be
taken for the arguments. */
#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
#define CALL_DUMMY_LENGTH 28
#define CALL_DUMMY_START_OFFSET 12
/* Insert the specified number of args and function address
into a call sequence of the above form stored at DUMMYNAME. */
#define FIX_CALL_DUMMY(dummyname, fun, nargs) \
{ *(int *)((char *) dummyname + 20) = nargs * 4; \
*(int *)((char *) dummyname + 14) = fun; }
/* Interface definitions for kernel debugger KDB. */
/* Map machine fault codes into signal numbers.
First subtract 0, divide by 4, then index in a table.
Faults for which the entry in this table is 0
are not handled by KDB; the program's own trap handler
gets to handle then. */
#define FAULT_CODE_ORIGIN 0
#define FAULT_CODE_UNITS 4
#define FAULT_TABLE \
{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
0, 0, 0, 0, 0, 0, 0, 0, \
SIGILL }
/* Start running with a stack stretching from BEG to END.
BEG and END should be symbols meaningful to the assembler.
This is used only for kdb. */
#define INIT_STACK(beg, end) \
{ asm (".globl end"); \
asm ("movel #end, sp"); \
asm ("movel #0,a6"); }
/* Push the frame pointer register on the stack. */
#define PUSH_FRAME_PTR \
asm ("movel a6,sp@-");
/* Copy the top-of-stack to the frame pointer register. */
#define POP_FRAME_PTR \
asm ("movl sp@,a6");
/* After KDB is entered by a fault, push all registers
that GDB thinks about (all NUM_REGS of them),
so that they appear in order of ascending GDB register number.
The fault code will be on the stack beyond the last register. */
#define PUSH_REGISTERS \
{ asm ("clrw -(sp)"); \
asm ("pea sp@(10)"); \
asm ("movem #0xfffe,sp@-"); }
/* Assuming the registers (including processor status) have been
pushed on the stack in order of ascending GDB register number,
restore them and return to the address in the saved PC register. */
#define POP_REGISTERS \
{ asm ("subil #8,sp@(28)"); \
asm ("movem sp@,#0xffff"); \
asm ("rte"); }

View File

@ -1,126 +0,0 @@
#include <stdio.h>
class math_stuff
{
char name[40];
int value;
public:
void bla();
math_stuff(char*);
~math_stuff();
void add(int);
void print_value(char*);
};
void math_stuff::bla()
{
printf("bla\n");
}
math_stuff::math_stuff(char* new_name)
{
sprintf((char *)this->name,(char *)"MATH_STUFF_%s",new_name);
value = 0;
}
math_stuff::~math_stuff()
{
printf((char *)"Deleting MATH_STUFF instance '%s'\n",this->name);
}
void math_stuff::add(int x)
{
this->value += x;
}
void math_stuff::print_value(char *where)
{
printf((char *)"current value of '%s' at '%s' = %d\n", this->name, where, this->value);
}
class derived : public math_stuff
{
char *dname;
int val;
public:
math_stuff stuff;
derived(char*);
~derived();
void print_all(char*);
};
derived::derived(char *der_name)
: ((char *)"hello, world!"), stuff("derived stuff"), val(10)
{
printf((char *)"derived name = %s\n", der_name);
dname = der_name;
stuff.add(6);
stuff.print_value ((char *)"grind");
}
derived::~derived()
{
printf ((char *)"Good bye! \n");
}
derived::print_all(char *msg)
{
printf((char *)"Here's the lowdown:\n");
printf((char *)"My name is %s\n", dname);
printf((char *)"My value = %d\n", val);
stuff.print_value ((char *)"low");
this->print_value((char *)"down");
printf((char *)"That's all you get tonight.\n\n");
}
main()
{
int pid;
int i;
pid = vfork();
if (pid > 0)
printf(" the inferior pid of the child is %d\n",pid);
if (pid == 0)
{
/* execl ("/bin/sh", "sh", "-c",argv[1],0);*/
math_stuff* a;
derived* d;
math_stuff b $ (" no gnus are good gnus ");
int child;
child = getpid();
printf( " the child from parent.c is %d\n",child);
ptrace (0);
a = new math_stuff((char *)"a");
d = new derived((char *)"two words");
a->add(2);
a->add(4);
a->add(5);
a->print_value((char *)"here");
a->add(7);
a->print_value((char *)"there");
a->add(3);
a->add(1);
a->print_value((char *)"end");
d->print_all ((char *)"all");
delete a;
delete d;
exit(0);
}
i = 5;
i = 6;
i = 7;
}

View File

@ -1 +1,769 @@
#include "m68k-pinsn.c"
/* Print m68k instructions for GDB, the GNU debugger.
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
#include <stdio.h>
#include "defs.h"
#include "param.h"
#include "symtab.h"
#include "opcode.h"
/* 68k instructions are never longer than this many bytes. */
#define MAXLEN 22
/* Number of elements in the opcode table. */
#define NOPCODES (sizeof m68k_opcodes / sizeof m68k_opcodes[0])
extern char *reg_names[];
char *fpcr_names[] = { "", "fpiar", "fpsr", "fpiar/fpsr", "fpcr",
"fpiar/fpcr", "fpsr/fpcr", "fpiar-fpcr"};
static unsigned char *print_insn_arg ();
static unsigned char *print_indexed ();
static void print_base ();
static int fetch_arg ();
#define NEXTBYTE(p) (p += 2, ((char *)p)[-1])
#define NEXTWORD(p) \
(p += 2, ((((char *)p)[-2]) << 8) + p[-1])
#define NEXTLONG(p) \
(p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
#define NEXTSINGLE(p) \
(p += 4, *((float *)(p - 4)))
#define NEXTDOUBLE(p) \
(p += 8, *((double *)(p - 8)))
#define NEXTEXTEND(p) \
(p += 12, 0.0) /* Need a function to convert from extended to double
precision... */
#define NEXTPACKED(p) \
(p += 12, 0.0) /* Need a function to convert from packed to double
precision. Actually, it's easier to print a
packed number than a double anyway, so maybe
there should be a special case to handle this... */
/* Print the m68k instruction at address MEMADDR in debugged memory,
on STREAM. Returns length of the instruction, in bytes. */
int
print_insn (memaddr, stream)
CORE_ADDR memaddr;
FILE *stream;
{
unsigned char buffer[MAXLEN];
register int i;
register unsigned char *p;
register char *d;
register int bestmask;
int best;
read_memory (memaddr, buffer, MAXLEN);
bestmask = 0;
best = -1;
for (i = 0; i < NOPCODES; i++)
{
register unsigned int opcode = m68k_opcodes[i].opcode;
register unsigned int match = m68k_opcodes[i].match;
if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
&& ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
&& ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
&& ((0xff & buffer[3] & match) == (0xff & opcode)))
{
/* Don't use for printout the variants of divul and divsl
that have the same register number in two places.
The more general variants will match instead. */
for (d = m68k_opcodes[i].args; *d; d += 2)
if (d[1] == 'D')
break;
/* Don't use for printout the variants of most floating
point coprocessor instructions which use the same
register number in two places, as above. */
if (*d == 0)
for (d = m68k_opcodes[i].args; *d; d += 2)
if (d[1] == 't')
break;
if (*d == 0 && match > bestmask)
{
best = i;
bestmask = match;
}
}
}
/* Handle undefined instructions. */
if (best < 0)
{
fprintf (stream, "0%o", (buffer[0] << 8) + buffer[1]);
return 2;
}
fprintf (stream, "%s", m68k_opcodes[best].name);
/* Point at first word of argument data,
and at descriptor for first argument. */
p = buffer + 2;
/* Why do this this way? -MelloN */
for (d = m68k_opcodes[best].args; *d; d += 2)
{
if (d[0] == '#')
{
if (d[1] == 'l' && p - buffer < 6)
p = buffer + 6;
else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8' )
p = buffer + 4;
}
if (d[1] >= '1' && d[1] <= '3' && p - buffer < 4)
p = buffer + 4;
if (d[1] >= '4' && d[1] <= '6' && p - buffer < 6)
p = buffer + 6;
}
d = m68k_opcodes[best].args;
if (*d)
fputc (' ', stream);
while (*d)
{
p = print_insn_arg (d, buffer, p, memaddr + p - buffer, stream);
d += 2;
if (*d && *(d - 2) != 'I' && *d != 'k')
fprintf (stream, ",");
}
return p - buffer;
}
static unsigned char *
print_insn_arg (d, buffer, p, addr, stream)
char *d;
unsigned char *buffer;
register unsigned char *p;
CORE_ADDR addr; /* PC for this arg to be relative to */
FILE *stream;
{
register int val;
register int place = d[1];
int regno;
register char *regname;
register unsigned char *p1;
register double flval;
int flt_p;
switch (*d)
{
case 'C':
fprintf (stream, "ccr");
break;
case 'S':
fprintf (stream, "sr");
break;
case 'U':
fprintf (stream, "usp");
break;
case 'J':
{
static struct { char *name; int value; } names[]
= {{"sfc", 0x000}, {"dfc", 0x001}, {"cacr", 0x002},
{"usp", 0x800}, {"vbr", 0x801}, {"caar", 0x802},
{"msp", 0x803}, {"isp", 0x804}};
val = fetch_arg (buffer, place, 12);
for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
if (names[regno].value == val)
{
fprintf (stream, names[regno].name);
break;
}
if (regno < 0)
fprintf (stream, "%d", val);
}
break;
case 'Q':
val = fetch_arg (buffer, place, 3);
if (val == 0) val = 8;
fprintf (stream, "#%d", val);
break;
case 'M':
val = fetch_arg (buffer, place, 8);
if (val & 0x80)
val = val - 0x100;
fprintf (stream, "#%d", val);
break;
case 'T':
val = fetch_arg (buffer, place, 4);
fprintf (stream, "#%d", val);
break;
case 'D':
fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 3)]);
break;
case 'A':
fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 3) + 010]);
break;
case 'R':
fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 4)]);
break;
case 'F':
fprintf (stream, "fp%d", fetch_arg (buffer, place, 3));
break;
case 'O':
val = fetch_arg (buffer, place, 6);
if (val & 0x20)
fprintf (stream, "%s", reg_names [val & 7]);
else
fprintf (stream, "%d", val);
break;
case '+':
fprintf (stream, "(%s)+", reg_names[fetch_arg (buffer, place, 3) + 8]);
break;
case '-':
fprintf (stream, "-(%s)", reg_names[fetch_arg (buffer, place, 3) + 8]);
break;
case 'k':
if (place == 'k')
fprintf (stream, "{%s}", reg_names[fetch_arg (buffer, place, 3)]);
else if (place == 'C')
{
val = fetch_arg (buffer, place, 7);
if ( val > 63 ) /* This is a signed constant. */
val -= 128;
fprintf (stream, "{#%d}", val);
}
else
error ("Invalid arg format in opcode table: \"%c%c\".",
*d, place);
break;
case '#':
p1 = buffer + 2;
if (place == 's')
val = fetch_arg (buffer, place, 4);
else if (place == 'C')
val = fetch_arg (buffer, place, 7);
else if (place == '8')
val = fetch_arg (buffer, place, 3);
else if (place == '3')
val = fetch_arg (buffer, place, 8);
else if (place == 'b')
val = NEXTBYTE (p1);
else if (place == 'w')
val = NEXTWORD (p1);
else if (place == 'l')
val = NEXTLONG (p1);
else
error ("Invalid arg format in opcode table: \"%c%c\".",
*d, place);
fprintf (stream, "#%d", val);
break;
case '^':
if (place == 's')
val = fetch_arg (buffer, place, 4);
else if (place == 'C')
val = fetch_arg (buffer, place, 7);
else if (place == '8')
val = fetch_arg (buffer, place, 3);
else if (place == 'b')
val = NEXTBYTE (p);
else if (place == 'w')
val = NEXTWORD (p);
else if (place == 'l')
val = NEXTLONG (p);
else
error ("Invalid arg format in opcode table: \"%c%c\".",
*d, place);
fprintf (stream, "#%d", val);
break;
case 'B':
if (place == 'b')
val = NEXTBYTE (p);
else if (place == 'w')
val = NEXTWORD (p);
else if (place == 'l')
val = NEXTLONG (p);
else if (place == 'g')
{
val = ((char *)buffer)[1];
if (val == 0)
val = NEXTWORD (p);
else if (val == -1)
val = NEXTLONG (p);
}
else if (place == 'c')
{
if (buffer[1] & 0x40) /* If bit six is one, long offset */
val = NEXTLONG (p);
else
val = NEXTWORD (p);
}
else
error ("Invalid arg format in opcode table: \"%c%c\".",
*d, place);
print_address (addr + val, stream);
break;
case 'd':
val = NEXTWORD (p);
fprintf (stream, "%d(%s)", val, reg_names[fetch_arg (buffer, place, 3)]);
break;
case 's':
fprintf (stream, "%s", fpcr_names[fetch_arg (buffer, place, 3)]);
break;
case 'I':
val = fetch_arg (buffer, 'd', 3); /* Get coprocessor ID... */
if (val != 1) /* Unusual coprocessor ID? */
fprintf (stream, "(cpid=%d) ", val);
if (place == 'i')
p += 2; /* Skip coprocessor extended operands */
break;
case '*':
case '~':
case '%':
case ';':
case '@':
case '!':
case '$':
case '?':
case '/':
case '&':
if (place == 'd')
{
val = fetch_arg (buffer, 'x', 6);
val = ((val & 7) << 3) + ((val >> 3) & 7);
}
else
val = fetch_arg (buffer, 's', 6);
/* Get register number assuming address register. */
regno = (val & 7) + 8;
regname = reg_names[regno];
switch (val >> 3)
{
case 0:
fprintf (stream, "%s", reg_names[val]);
break;
case 1:
fprintf (stream, "%s", regname);
break;
case 2:
fprintf (stream, "(%s)", regname);
break;
case 3:
fprintf (stream, "(%s)+", regname);
break;
case 4:
fprintf (stream, "-(%s)", regname);
break;
case 5:
val = NEXTWORD (p);
fprintf (stream, "%d(%s)", val, regname);
break;
case 6:
p = print_indexed (regno, p, addr, stream);
break;
case 7:
switch (val & 7)
{
case 0:
val = NEXTWORD (p);
fprintf (stream, "@#");
print_address (val, stream);
break;
case 1:
val = NEXTLONG (p);
fprintf (stream, "@#");
print_address (val, stream);
break;
case 2:
val = NEXTWORD (p);
print_address (addr + val, stream);
break;
case 3:
p = print_indexed (-1, p, addr, stream);
break;
case 4:
flt_p = 1; /* Assume it's a float... */
switch( place )
{
case 'b':
val = NEXTBYTE (p);
flt_p = 0;
break;
case 'w':
val = NEXTWORD (p);
flt_p = 0;
break;
case 'l':
val = NEXTLONG (p);
flt_p = 0;
break;
case 'f':
flval = NEXTSINGLE(p);
break;
case 'F':
flval = NEXTDOUBLE(p);
break;
case 'x':
flval = NEXTEXTEND(p);
break;
case 'p':
flval = NEXTPACKED(p);
break;
default:
error ("Invalid arg format in opcode table: \"%c%c\".",
*d, place);
}
if ( flt_p ) /* Print a float? */
fprintf (stream, "#%g", flval);
else
fprintf (stream, "#%d", val);
break;
default:
fprintf (stream, "<invalid address mode 0%o>", val);
}
}
break;
default:
error ("Invalid arg format in opcode table: \"%c\".", *d);
}
return (unsigned char *) p;
}
/* Fetch BITS bits from a position in the instruction specified by CODE.
CODE is a "place to put an argument", or 'x' for a destination
that is a general address (mode and register).
BUFFER contains the instruction. */
static int
fetch_arg (buffer, code, bits)
unsigned char *buffer;
char code;
int bits;
{
register int val;
switch (code)
{
case 's':
val = buffer[1];
break;
case 'd': /* Destination, for register or quick. */
val = (buffer[0] << 8) + buffer[1];
val >>= 9;
break;
case 'x': /* Destination, for general arg */
val = (buffer[0] << 8) + buffer[1];
val >>= 6;
break;
case 'k':
val = (buffer[3] >> 4);
break;
case 'C':
val = buffer[3];
break;
case '1':
val = (buffer[2] << 8) + buffer[3];
val >>= 12;
break;
case '2':
val = (buffer[2] << 8) + buffer[3];
val >>= 6;
break;
case '3':
case 'j':
val = (buffer[2] << 8) + buffer[3];
break;
case '4':
val = (buffer[4] << 8) + buffer[5];
val >>= 12;
break;
case '5':
val = (buffer[4] << 8) + buffer[5];
val >>= 6;
break;
case '6':
val = (buffer[4] << 8) + buffer[5];
break;
case '7':
val = (buffer[2] << 8) + buffer[3];
val >>= 7;
break;
case '8':
val = (buffer[2] << 8) + buffer[3];
val >>= 10;
break;
default:
abort ();
}
switch (bits)
{
case 3:
return val & 7;
case 4:
return val & 017;
case 5:
return val & 037;
case 6:
return val & 077;
case 7:
return val & 0177;
case 8:
return val & 0377;
case 12:
return val & 07777;
default:
abort ();
}
}
/* Print an indexed argument. The base register is BASEREG (-1 for pc).
P points to extension word, in buffer.
ADDR is the nominal core address of that extension word. */
static unsigned char *
print_indexed (basereg, p, addr, stream)
int basereg;
unsigned char *p;
FILE *stream;
CORE_ADDR addr;
{
register int word;
static char *scales[] = {"", "*2", "*4", "*8"};
register int base_disp;
register int outer_disp;
char buf[40];
word = NEXTWORD (p);
/* Generate the text for the index register.
Where this will be output is not yet determined. */
sprintf (buf, "[%s.%c%s]",
reg_names[(word >> 12) & 0xf],
(word & 0x800) ? 'l' : 'w',
scales[(word >> 9) & 3]);
/* Handle the 68000 style of indexing. */
if ((word & 0x100) == 0)
{
print_base (basereg,
((word & 0x80) ? word | 0xff00 : word & 0xff)
+ ((basereg == -1) ? addr : 0),
stream);
fprintf (stream, "%s", buf);
return p;
}
/* Handle the generalized kind. */
/* First, compute the displacement to add to the base register. */
if (word & 0200)
basereg = -2;
if (word & 0100)
buf[0] = 0;
base_disp = 0;
switch ((word >> 4) & 3)
{
case 2:
base_disp = NEXTWORD (p);
break;
case 3:
base_disp = NEXTLONG (p);
}
if (basereg == -1)
base_disp += addr;
/* Handle single-level case (not indirect) */
if ((word & 7) == 0)
{
print_base (basereg, base_disp, stream);
fprintf (stream, "%s", buf);
return p;
}
/* Two level. Compute displacement to add after indirection. */
outer_disp = 0;
switch (word & 3)
{
case 2:
outer_disp = NEXTWORD (p);
break;
case 3:
outer_disp = NEXTLONG (p);
}
fprintf (stream, "%d(", outer_disp);
print_base (basereg, base_disp, stream);
/* If postindexed, print the closeparen before the index. */
if (word & 4)
fprintf (stream, ")%s", buf);
/* If preindexed, print the closeparen after the index. */
else
fprintf (stream, "%s)", buf);
return p;
}
/* Print a base register REGNO and displacement DISP, on STREAM.
REGNO = -1 for pc, -2 for none (suppressed). */
static void
print_base (regno, disp, stream)
int regno;
int disp;
FILE *stream;
{
if (regno == -2)
fprintf (stream, "%d", disp);
else if (regno == -1)
fprintf (stream, "0x%x", disp);
else
fprintf (stream, "%d(%s)", disp, reg_names[regno]);
}
/* This is not part of insn printing, but it is machine-specific,
so this is a convenient place to put it.
Convert a 68881 extended float to a double.
FROM is the address of the extended float.
Store the double in *TO. */
convert_from_68881 (from, to)
char *from;
double *to;
{
#ifdef HPUX_ASM
asm ("mov.l 8(%a6),%a0");
asm ("mov.l 12(%a6),%a1");
asm ("fmove.x (%a0),%fp0");
asm ("fmove.d %fp0,(%a1)");
#else /* not HPUX_ASM */
#if 0
asm ("movl a6@(8),a0");
asm ("movl a6@(12),a1");
asm ("fmovex a0@,fp0");
asm ("fmoved fp0,a1@");
#else
/* Hand-assemble those insns since some assemblers lose
and some have different syntax. */
asm (".word 020156");
asm (".word 8");
asm (".word 021156");
asm (".word 12");
asm (".long 0xf2104800");
asm (".long 0xf2117400");
#endif
#endif /* not HPUX_ASM */
}
/* The converse: convert the double *FROM to an extended float
and store where TO points. */
convert_to_68881 (from, to)
double *from;
char *to;
{
#ifdef HPUX_ASM
asm ("mov.l 8(%a6),%a0");
asm ("mov.l 12(%a6),%a1");
asm ("fmove.d (%a0),%fp0");
asm ("fmove.x %fp0,(%a1)");
#else /* not HPUX_ASM */
#if 0
asm ("movl a6@(8),a0");
asm ("movl a6@(12),a1");
asm ("fmoved a0@,fp0");
asm ("fmovex fp0,a1@");
#else
/* Hand-assemble those insns since some assemblers lose. */
asm (".word 020156");
asm (".word 8");
asm (".word 021156");
asm (".word 12");
asm (".long 0xf2105400");
asm (".long 0xf2116800");
#endif
#endif /* not HPUX_ASM */
}

283
gdb/pn-opcode.h Normal file
View File

@ -0,0 +1,283 @@
/* Print PN instructions for GDB, the GNU debugger.
Copyright (C) 1986, 1987 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing.
Refer to the GDB General Public License for full details.
Everyone is granted permission to copy, modify and redistribute GDB,
but only under the conditions described in the GDB General Public
License. A copy of this license is supposed to have been given to you
along with GDB so you can know your rights and responsibilities. It
should be in a file named COPYING. Among other things, the copyright
notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
struct gld_opcode
{
char *name;
unsigned long opcode;
unsigned long mask;
char *args;
int length;
};
/* We store four bytes of opcode for all opcodes because that
is the most any of them need. The actual length of an instruction
is always at least 2 bytes, and at most four. The length of the
instruction is based on the opcode.
The mask component is a mask saying which bits must match
particular opcode in order for an instruction to be an instance
of that opcode.
The args component is a string containing characters
that are used to format the arguments to the instruction. */
/* Kinds of operands:
r Register in first field
R Register in second field
b Base register in first field
B Base register in second field
v Vector register in first field
V Vector register in first field
A Optional address register (base register)
X Optional index register
I Immediate data (16bits signed)
O Offset field (16bits signed)
h Offset field (15bits signed)
d Offset field (14bits signed)
S Shift count field
any other characters are printed as is...
*/
/* The assembler requires that this array be sorted as follows:
all instances of the same mnemonic must be consecutive.
All instances of the same mnemonic with the same number of operands
must be consecutive.
*/
struct gld_opcode gld_opcodes[] =
{
{ "abm", 0xa0080000, 0xfc080000, "f,xOA,X", 4 },
{ "abr", 0x18080000, 0xfc0c0000, "r,f", 2 },
{ "aci", 0xfc770000, 0xfc7f8000, "r,I", 4 },
{ "adfd", 0xe0080002, 0xfc080002, "r,xOA,X", 4 },
{ "adfw", 0xe0080000, 0xfc080000, "r,xOA,X", 4 },
{ "adi", 0xc8010000, 0xfc7f0000, "r,I", 4 },
{ "admb", 0xb8080000, 0xfc080000, "r,xOA,X", 4 },
{ "admd", 0xb8000002, 0xfc080002, "r,xOA,X", 4 },
{ "admh", 0xb8000001, 0xfc080001, "r,xOA,X", 4 },
{ "admw", 0xb8000000, 0xfc080000, "r,xOA,X", 4 },
{ "adr", 0x38000000, 0xfc0f0000, "r,R", 2 },
{ "adrfd", 0x38090000, 0xfc0f0000, "r,R", 2 },
{ "adrfw", 0x38010000, 0xfc0f0000, "r,R", 2 },
{ "adrm", 0x38080000, 0xfc0f0000, "r,R", 2 },
{ "ai", 0xfc030000, 0xfc07ffff, "I", 4 },
{ "anmb", 0x84080000, 0xfc080000, "r,xOA,X", 4 },
{ "anmd", 0x84000002, 0xfc080002, "r,xOA,X", 4 },
{ "anmh", 0x84000001, 0xfc080001, "r,xOA,X", 4 },
{ "anmw", 0x84000000, 0xfc080000, "r,xOA,X", 4 },
{ "anr", 0x04000000, 0xfc0f0000, "r,R", 2 },
{ "armb", 0xe8080000, 0xfc080000, "r,xOA,X", 4 },
{ "armd", 0xe8000002, 0xfc080002, "r,xOA,X", 4 },
{ "armh", 0xe8000001, 0xfc080001, "r,xOA,X", 4 },
{ "armw", 0xe8000000, 0xfc080000, "r,xOA,X", 4 },
{ "bcf", 0xf0000000, 0xfc080000, "I,xOA,X", 4 },
{ "bct", 0xec000000, 0xfc080000, "I,xOA,X", 4 },
{ "bei", 0x00060000, 0xffff0000, "", 2 },
{ "bft", 0xf0000000, 0xff880000, "xOA,X", 4 },
{ "bib", 0xf4000000, 0xfc780000, "r,xOA", 4 },
{ "bid", 0xf4600000, 0xfc780000, "r,xOA", 4 },
{ "bih", 0xf4200000, 0xfc780000, "r,xOA", 4 },
{ "biw", 0xf4400000, 0xfc780000, "r,xOA", 4 },
{ "bl", 0xf8800000, 0xff880000, "xOA,X", 4 },
{ "bsub", 0x5c080000, 0xff8f0000, "", 2 },
{ "bsubm", 0x28080000, 0xfc080000, "", 4 },
{ "bu", 0xec000000, 0xff880000, "xOA,X", 4 },
{ "call", 0x28080000, 0xfc0f0000, "", 2 },
{ "callm", 0x5c080000, 0xff880000, "", 4 },
{ "camb", 0x90080000, 0xfc080000, "r,xOA,X", 4 },
{ "camd", 0x90000002, 0xfc080002, "r,xOA,X", 4 },
{ "camh", 0x90000001, 0xfc080001, "r,xOA,X", 4 },
{ "camw", 0x90000000, 0xfc080000, "r.xOA,X", 4 },
{ "car", 0x10000000, 0xfc0f0000, "r,R", 2 },
{ "cd", 0xfc060000, 0xfc070000, "r,f", 4 },
{ "cea", 0x000f0000, 0xffff0000, "", 2 },
{ "ci", 0xc8050000, 0xfc7f0000, "r,I", 4 },
{ "cmc", 0x040a0000, 0xfc7f0000, "r", 2 },
{ "cmmb", 0x94080000, 0xfc080000, "r,xOA,X", 4 },
{ "cmmd", 0x94000002, 0xfc080002, "r,xOA,X", 4 },
{ "cmmh", 0x94000001, 0xfc080001, "r,xOA,X", 4 },
{ "cmmw", 0x94000000, 0xfc080000, "r,xOA,X", 4 },
{ "cmr", 0x14000000, 0xfc0f0000, "r,R", 2 },
{ "daci", 0xfc7f0000, 0xfc7f8000, "r,I", 4 },
{ "dae", 0x000e0000, 0xffff0000, "", 2 },
{ "dai", 0xfc040000, 0xfc07ffff, "I", 4 },
{ "dci", 0xfc6f0000, 0xfc7f8000, "r,I", 4 },
{ "di", 0xfc010000, 0xfc07ffff, "I", 4 },
{ "dvfd", 0xe4000002, 0xfc080002, "r,xOA,X", 4 },
{ "dvfw", 0xe4000000, 0xfc080000, "r,xOA,X", 4 },
{ "dvi", 0xc8040000, 0xfc7f0000, "r,I", 4 },
{ "dvmb", 0xc4080000, 0xfc080000, "r,xOA,X", 4 },
{ "dvmh", 0xc4000001, 0xfc080001, "r,xOA,X", 4 },
{ "dvmw", 0xc4000000, 0xfc080000, "r,xOA,X", 4 },
{ "dvr", 0x380a0000, 0xfc0f0000, "r,R", 2 },
{ "dvrfd", 0x380c0000, 0xfc0f0000, "r,R", 4 },
{ "dvrfw", 0x38040000, 0xfc0f0000, "r,xOA,X", 4 },
{ "eae", 0x00080000, 0xffff0000, "", 2 },
{ "eci", 0xfc670000, 0xfc7f8080, "r,I", 4 },
{ "ecwcs", 0xfc4f0000, 0xfc7f8000, "", 4 },
{ "ei", 0xfc000000, 0xfc07ffff, "I", 4 },
{ "eomb", 0x8c080000, 0xfc080000, "r,xOA,X", 4 },
{ "eomd", 0x8c000002, 0xfc080002, "r,xOA,X", 4 },
{ "eomh", 0x8c000001, 0xfc080001, "r,xOA,X", 4 },
{ "eomw", 0x8c000000, 0xfc080000, "r,xOA,X", 4 },
{ "eor", 0x0c000000, 0xfc0f0000, "r,R", 2 },
{ "eorm", 0x0c080000, 0xfc0f0000, "r,R", 2 },
{ "es", 0x00040000, 0xfc7f0000, "r", 2 },
{ "exm", 0xa8000000, 0xff880000, "xOA,X", 4 },
{ "exr", 0xc8070000, 0xfc7f0000, "r", 2 },
{ "exrr", 0xc8070002, 0xfc7f0002, "r", 2 },
{ "fixd", 0x380d0000, 0xfc0f0000, "r,R", 2 },
{ "fixw", 0x38050000, 0xfc0f0000, "r,R", 2 },
{ "fltd", 0x380f0000, 0xfc0f0000, "r,R", 2 },
{ "fltw", 0x38070000, 0xfc0f0000, "r,R", 2 },
{ "grio", 0xfc3f0000, 0xfc7f8000, "r,I", 4 },
{ "halt", 0x00000000, 0xffff0000, "", 2 },
{ "hio", 0xfc370000, 0xfc7f8000, "r,I", 4 },
{ "jwcs", 0xfa080000, 0xff880000, "xOA,X", 4 },
{ "la", 0x50000000, 0xfc000000, "r,xOA,X", 4 },
{ "labr", 0x58080000, 0xfc080000, "b,xOA,X", 4 },
{ "lb", 0xac080000, 0xfc080000, "r,xOA,X", 4 },
{ "lcs", 0x00030000, 0xfc7f0000, "r", 2 },
{ "ld", 0xac000002, 0xfc080002, "r,xOA,X", 4 },
{ "lear", 0x80000000, 0xfc080000, "r,xOA,X", 4 },
{ "lf", 0xcc000000, 0xfc080000, "r,xOA,X", 4 },
{ "lfbr", 0xcc080000, 0xfc080000, "b,xOA,X", 4 },
{ "lh", 0xac000001, 0xfc080001, "r,xOA,X", 4 },
{ "li", 0xc8000000, 0xfc7f0000, "r,I", 4 },
{ "lmap", 0x2c070000, 0xfc7f0000, "r", 2 },
{ "lmb", 0xb0080000, 0xfc080000, "r,xOA,X", 4 },
{ "lmd", 0xb0000002, 0xfc080002, "r,xOA,X", 4 },
{ "lmh", 0xb0000001, 0xfc080001, "r,xOA,X", 4 },
{ "lmw", 0xb0000000, 0xfc080000, "r,xOA,X", 4 },
{ "lnb", 0xb4080000, 0xfc080000, "r,xOA,X", 4 },
{ "lnd", 0xb4000002, 0xfc080002, "r,xOA,X", 4 },
{ "lnh", 0xb4000001, 0xfc080001, "r,xOA,X", 4 },
{ "lnw", 0xb4000000, 0xfc080000, "r,xOA,X", 4 },
{ "lpsd", 0xf9800000, 0xff880000, "r,xOA,X", 4 },
{ "lpsdcm", 0xfa800000, 0xff880000, "r,xOA,X", 4 },
{ "lw", 0xac000000, 0xfc080000, "r,xOA,X", 4 },
{ "lwbr", 0x5c000000, 0xfc080000, "b,xOA,X", 4 },
{ "mpfd", 0xe4080002, 0xfc080002, "r,xOA,X", 4 },
{ "mpfw", 0xe4080000, 0xfc080000, "r,xOA,X", 4 },
{ "mpi", 0xc8030000, 0xfc7f0000, "r,I", 4 },
{ "mpmb", 0xc0080000, 0xfc080000, "r,xOA,X", 4 },
{ "mpmh", 0xc0000001, 0xfc080001, "r,xOA,X", 4 },
{ "mpmw", 0xc0000000, 0xfc080000, "r,xOA,X", 4 },
{ "mpr", 0x38020000, 0xfc0f0000, "r,R", 2 },
{ "mprfd", 0x380e0000, 0xfc0f0000, "r,R", 2 },
{ "mprfw", 0x38060000, 0xfc0f0000, "r,R", 2 },
{ "nop", 0x00020000, 0xffff0000, "", 2 },
{ "ormb", 0x88080000, 0xfc080000, "r,xOA,X", 4 },
{ "ormd", 0x88000002, 0xfc080002, "r,xOA,X", 4 },
{ "ormh", 0x88000001, 0xfc080001, "r,xOA,X", 4 },
{ "ormw", 0x88000000, 0xfc080000, "r,xOA,X", 4 },
{ "orr", 0x08000000, 0xfc0f0000, "r,R", 2 },
{ "orrm", 0x08080000, 0xfc0f0000, "r,R", 2 },
{ "rdsts", 0x00090000, 0xfc7f0000, "r", 2 },
{ "return", 0x280e0000, 0xfc7f0000, "", 2 },
{ "ri", 0xfc020000, 0xfc07ffff, "I", 4 },
{ "rnd", 0x00050000, 0xfc7f0000, "r", 2 },
{ "rpswt", 0x040b0000, 0xfc7f0000, "r", 2 },
{ "rschnl", 0xfc2f0000, 0xfc7f8000, "r,I", 4 },
{ "rsctl", 0xfc470000, 0xfc7f8000, "r,I", 4 },
{ "rwcs", 0x000b0000, 0xfc0f0000, "r,R", 2 },
{ "sacz", 0x10080000, 0xfc0f0000, "r,R", 2 },
{ "sbm", 0x98080000, 0xfc080000, "f,xOA,X", 4 },
{ "sbr", 0x18000000, 0xfc0c0000, "r,f", 4 },
{ "sea", 0x000d0000, 0xffff0000, "", 2 },
{ "setcpu", 0x2c090000, 0xfc7f0000, "r", 2 },
{ "sio", 0xfc170000, 0xfc7f8000, "r,I", 4 },
{ "sipu", 0x000a0000, 0xffff0000, "", 2 },
{ "sla", 0x1c400000, 0xfc600000, "r,S", 2 },
{ "slad", 0x20400000, 0xfc600000, "r,S", 2 },
{ "slc", 0x24400000, 0xfc600000, "r,S", 2 },
{ "sll", 0x1c600000, 0xfc600000, "r,S", 2 },
{ "slld", 0x20600000, 0xfc600000, "r,S", 2 },
{ "smc", 0x04070000, 0xfc070000, "", 2 },
{ "sra", 0x1c000000, 0xfc600000, "r,S", 2 },
{ "srad", 0x20000000, 0xfc600000, "r,S", 2 },
{ "src", 0x24000000, 0xfc600000, "r,S", 2 },
{ "srl", 0x1c200000, 0xfc600000, "r,S", 2 },
{ "srld", 0x20200000, 0xfc600000, "r,S", 2 },
{ "stb", 0xd4080000, 0xfc080000, "r,xOA,X", 4 },
{ "std", 0xd4000002, 0xfc080002, "r,xOA,X", 4 },
{ "stf", 0xdc000000, 0xfc080000, "r,xOA,X", 4 },
{ "stfbr", 0x54000000, 0xfc080000, "b,xOA,X", 4 },
{ "sth", 0xd4000001, 0xfc080001, "r,xOA,X", 4 },
{ "stmb", 0xd8080000, 0xfc080000, "r,xOA,X", 4 },
{ "stmd", 0xd8000002, 0xfc080002, "r,xOA,X", 4 },
{ "stmh", 0xd8000001, 0xfc080001, "r,xOA,X", 4 },
{ "stmw", 0xd8000000, 0xfc080000, "r,xOA,X", 4 },
{ "stpio", 0xfc270000, 0xfc7f8000, "r,I", 4 },
{ "stw", 0xd4000000, 0xfc080000, "r,xOA,X", 4 },
{ "stwbr", 0x54000000, 0xfc080000, "b,xOA,X", 4 },
{ "suabr", 0x58000000, 0xfc080000, "b,xOA,X", 4 },
{ "sufd", 0xe0000002, 0xfc080002, "r,xOA,X", 4 },
{ "sufw", 0xe0000000, 0xfc080000, "r,xOA,X", 4 },
{ "sui", 0xc8020000, 0xfc7f0000, "r,I", 4 },
{ "sumb", 0xbc080000, 0xfc080000, "r,xOA,X", 4 },
{ "sumd", 0xbc000002, 0xfc080002, "r,xOA,X", 4 },
{ "sumh", 0xbc000001, 0xfc080001, "r,xOA,X", 4 },
{ "sumw", 0xbc000000, 0xfc080000, "r,xOA,X", 4 },
{ "sur", 0x3c000000, 0xfc0f0000, "r,R", 2 },
{ "surfd", 0x380b0000, 0xfc0f0000, "r,xOA,X", 4 },
{ "surfw", 0x38030000, 0xfc0f0000, "r,R", 2 },
{ "surm", 0x3c080000, 0xfc0f0000, "r,R", 2 },
{ "svc", 0xc8060000, 0xffff0000, "", 4 },
{ "tbm", 0xa4080000, 0xfc080000, "f,xOA,X", 4 },
{ "tbr", 0x180c0000, 0xfc0c0000, "r,f", 2 },
{ "tbrr", 0x2c020000, 0xfc0f0000, "r,B", 2 },
{ "tccr", 0x28040000, 0xfc7f0000, "", 2 },
{ "td", 0xfc050000, 0xfc070000, "r,f", 4 },
{ "tio", 0xfc1f0000, 0xfc7f8000, "r,I", 4 },
{ "tmapr", 0x2c0a0000, 0xfc0f0000, "r,R", 2 },
{ "tpcbr", 0x280c0000, 0xfc7f0000, "r", 2 },
{ "trbr", 0x2c010000, 0xfc0f0000, "b,R", 2 },
{ "trc", 0x2c030000, 0xfc0f0000, "r,R", 2 },
{ "trcc", 0x28050000, 0xfc7f0000, "", 2 },
{ "trcm", 0x2c0b0000, 0xfc0f0000, "r,R", 2 },
{ "trn", 0x2c040000, 0xfc0f0000, "r,R", 2 },
{ "trnm", 0x2c0c0000, 0xfc0f0000, "r,R", 2 },
{ "trr", 0x2c000000, 0xfc0f0000, "r,R", 2 },
{ "trrm", 0x2c080000, 0xfc0f0000, "r,R", 2 },
{ "trsc", 0x2c0e0000, 0xfc0f0000, "r,R", 2 },
{ "trsw", 0x28000000, 0xfc7f0000, "r", 2 },
{ "tscr", 0x2c0f0000, 0xfc0f0000, "r,R", 2 },
{ "uei", 0x00070000, 0xffff0000, "", 2 },
{ "wait", 0x00010000, 0xffff0000, "", 2 },
{ "wcwcs", 0xfc5f0000, 0xfc7f8000, "", 4 },
{ "wwcs", 0x000c0000, 0xfc0f0000, "r,R", 2 },
{ "xcbr", 0x28020000, 0xfc0f0000, "b,B", 2 },
{ "xcr", 0x2c050000, 0xfc0f0000, "r,R", 2 },
{ "xcrm", 0x2c0d0000, 0xfc0f0000, "r,R", 2 },
{ "zbm", 0x9c080000, 0xfc080000, "f,xOA,X", 4 },
{ "zbr", 0x18040000, 0xfc0c0000, "r,f", 2 },
{ "zmb", 0xf8080000, 0xfc080000, "r,xOA,X", 4 },
{ "zmd", 0xf8000002, 0xfc080002, "r,xOA,X", 4 },
{ "zmh", 0xf8000001, 0xfc080001, "r,xOA,X", 4 },
{ "zmw", 0xf8000000, 0xfc080000, "r,xOA,X", 4 },
{ "zr", 0x0c000000, 0xfc0f0000, "r", 2 },
};
int numopcodes = sizeof(gld_opcodes) / sizeof(gld_opcodes[0]);
struct gld_opcode *endop = gld_opcodes + sizeof(gld_opcodes) /
sizeof(gld_opcodes[0]);

View File

@ -1,4 +1,4 @@
/* Print values for GNU debugger gdb.
/* Print values for GNU debugger GDB.
Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
@ -54,8 +54,17 @@ static CORE_ADDR last_examine_address;
static value last_examine_value;
/* Number of auto-display expression currently being displayed.
So that we can deleted it if we get an error or a signal within it.
-1 when not doing one. */
int current_display_number;
static void do_one_display ();
void do_displays ();
void print_address ();
void print_scalar_formatted ();
START_FILE
@ -123,25 +132,11 @@ print_formatted (val, format, size)
if (VALUE_LVAL (val) == lval_memory)
next_address = VALUE_ADDRESS (val) + len;
if (format && format != 's')
{
val_long = value_as_long (val);
/* If value is unsigned, truncate it in case negative. */
if (format != 'd')
{
if (len == sizeof (char))
val_long &= (1 << 8 * sizeof(char)) - 1;
else if (len == sizeof (short))
val_long &= (1 << 8 * sizeof(short)) - 1;
}
}
switch (format)
{
case 's':
next_address = VALUE_ADDRESS (val)
+ value_print (value_addr (val), stdout);
+ value_print (value_addr (val), stdout, 0);
break;
case 'i':
@ -149,6 +144,49 @@ print_formatted (val, format, size)
+ print_insn (VALUE_ADDRESS (val), stdout);
break;
default:
if (format == 0
|| TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_ARRAY
|| TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_STRUCT
|| TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_UNION)
value_print (val, stdout, format);
else
print_scalar_formatted (VALUE_CONTENTS (val), VALUE_TYPE (val),
format, size, stdout);
}
}
/* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
according to letters FORMAT and SIZE on STREAM.
FORMAT may not be zero. Formats s and i are not supported at this level.
This is how the elements of an array or structure are printed
with a format. */
void
print_scalar_formatted (valaddr, type, format, size, stream)
char *valaddr;
struct type *type;
char format;
int size;
FILE *stream;
{
long val_long;
int len = TYPE_LENGTH (type);
val_long = unpack_long (type, valaddr);
/* If value is unsigned, truncate it in case negative. */
if (format != 'd')
{
if (len == sizeof (char))
val_long &= (1 << 8 * sizeof(char)) - 1;
else if (len == sizeof (short))
val_long &= (1 << 8 * sizeof(short)) - 1;
}
switch (format)
{
case 'x':
switch (size)
{
@ -186,31 +224,30 @@ print_formatted (val, format, size)
break;
case 'a':
print_address (val_long, stdout);
print_address (val_long, stream);
break;
case 'c':
value_print (value_cast (builtin_type_char, val), stdout);
value_print (value_from_long (builtin_type_char, val_long), stream, 0);
break;
case 'f':
if (TYPE_LENGTH (VALUE_TYPE (val)) == sizeof (float))
VALUE_TYPE (val) = builtin_type_float;
if (TYPE_LENGTH (VALUE_TYPE (val)) == sizeof (double))
VALUE_TYPE (val) = builtin_type_double;
if (len == sizeof (float))
type = builtin_type_float;
if (len == sizeof (double))
type = builtin_type_double;
#ifdef IEEE_FLOAT
if (is_nan (value_as_double (val)))
if (is_nan (unpack_double (type, valaddr)))
{
printf ("Nan");
break;
}
#endif
printf ("%g", value_as_double (val));
printf ("%g", unpack_double (type, valaddr));
break;
case 0:
value_print (val, stdout);
break;
abort ();
default:
error ("Undefined output format \"%c\".", format);
@ -364,7 +401,6 @@ print_command (exp)
else
val = access_value_history (0);
if (!val) return; /* C++ */
histindex = record_latest_value (val);
printf ("$%d = ", histindex);
@ -414,41 +450,17 @@ set_command (exp)
do_cleanups (old_chain);
}
/* C++: Modified to give useful information about variable which
hang off of `this'. */
static void
address_info (exp)
char *exp;
{
register struct symbol *sym;
register CORE_ADDR val;
struct block *block, *get_selected_block ();
if (exp == 0)
error ("Argument required.");
block = get_selected_block ();
sym = lookup_symbol_1 (exp, block, VAR_NAMESPACE);
if (! sym)
{
value v;
/* C++: see if it hangs off of `this'. Must
not inadvertently convert from a method call
to data ref. */
v = value_of_this (0);
if (v)
{
val = check_field (v, exp);
if (val)
{
printf ("Symbol \"%s\" is a field of the local class variable `this'\n", exp);
return;
}
}
else
sym = lookup_symbol_2 (exp, 0, VAR_NAMESPACE);
}
sym = lookup_symbol (exp, get_selected_block (), VAR_NAMESPACE);
if (sym == 0)
{
register int i;
@ -572,12 +584,9 @@ whatis_command (exp)
else
val = access_value_history (0);
if (val != 0)
{
printf ("type = ");
type_print (VALUE_TYPE (val), "", stdout, 1);
printf ("\n");
}
printf ("type = ");
type_print (VALUE_TYPE (val), "", stdout, 1);
printf ("\n");
if (exp)
do_cleanups (old_chain);
@ -639,143 +648,6 @@ ptype_command (typename)
type_print (type, "", stdout, 1);
printf ("\n");
}
/* Print all the methods that correspond to the name METHOD.
Can optionally qualify the method with a CLASSNAME, as
in CLASSNAME :: METHODNAME. This routine does not call
parse_c_expression, so the input must conform to one of
these two forms. */
static void
pmethod_command (exp)
char *exp;
{
# if 0
struct expression *expr;
register value val;
register struct cleanup *old_chain;
char *classname, *methodname;
methodname = exp;
while (*exp++ <= ' ') ; /* remove leading whitespace */
if (exp[-1] == ':')
if (*exp == ':')
classname = (char *)1;
else error ("Invalid syntax: \"%s\"", methodname);
else
{
classname = exp-1;
while (*exp++ != ':') ;
exp[-1] = '\0';
if (*exp == ':')
{
while (*exp++ <= ' ') ; /* remove leading 2nd whitespace */
methodname = exp-1;
while (((*exp | 0x20) >= 'a' && ((*exp | 0x20) <= 'z')) || *exp == '_')
exp++;
if (*exp)
{
*exp++ = '\0';
while (*exp)
if (*exp > ' ') error ("junk after method name");
}
}
else error ("Invalid syntax: \"%s\"", methodname);
}
if (classname)
{
if (classname != (char *)1)
classtype = lookup_typename (classname);
else
{
register struct symtab *s;
register struct blockvector *bv;
struct blockvector *prev_bv = 0;
register struct block *b;
register int i, j;
register struct symbol *sym;
char *val;
int found_in_file;
static char *classnames[]
= {"variable", "function", "type", "method"};
int print_count = 0;
if (regexp)
if (val = (char *) re_comp (regexp))
error ("Invalid regexp: %s", val);
printf (regexp
? "All %ss matching regular expression \"%s\":\n"
: "All defined %ss:\n",
classnames[class],
regexp);
for (s = symtab_list; s; s = s->next)
{
found_in_file = 0;
bv = BLOCKVECTOR (s);
/* Often many files share a blockvector.
Scan each blockvector only once so that
we don't get every symbol many times.
It happens that the first symtab in the list
for any given blockvector is the main file. */
if (bv != prev_bv)
for (i = 0; i < 2; i++)
{
b = BLOCKVECTOR_BLOCK (bv, i);
for (j = 0; j < BLOCK_NSYMS (b); j++)
{
QUIT;
sym = BLOCK_SYM (b, j);
if ((regexp == 0 || re_exec (SYMBOL_NAME (sym)))
&& ((class == 0 && SYMBOL_CLASS (sym) != LOC_TYPEDEF
&& SYMBOL_CLASS (sym) != LOC_BLOCK)
|| (class == 1 && SYMBOL_CLASS (sym) == LOC_BLOCK)
|| (class == 2 && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
|| (class == 3 && SYMBOL_CLASS (sym) == LOC_BLOCK)))
{
if (!found_in_file)
{
printf ("\nFile %s:\n", s->filename);
print_count += 2;
}
found_in_file = 1;
MORE;
if (i == 1)
printf ("static ");
type_print (SYMBOL_TYPE (sym),
(SYMBOL_CLASS (sym) == LOC_TYPEDEF
? "" : SYMBOL_NAME (sym)),
stdout, 0);
printf (";\n");
}
}
}
prev_bv = bv;
}
}
}
if (exp)
{
expr = parse_c_expression (exp);
old_chain = make_cleanup (free_current_contents, &expr);
val = evaluate_type (expr);
}
else
val = access_value_history (0);
if (val != 0)
{
printf ("type = ");
type_print (VALUE_TYPE (val), "", stdout, 1);
printf ("\n");
}
if (exp)
do_cleanups (old_chain);
# endif
}
struct display
{
@ -802,8 +674,9 @@ static int display_number;
Specify the expression. */
static void
display_command (exp)
display_command (exp, from_tty)
char *exp;
int from_tty;
{
struct format_data fmt;
register struct expression *expr;
@ -841,6 +714,9 @@ display_command (exp)
new->format = fmt;
display_chain = new;
if (from_tty)
do_one_display (new);
dont_repeat ();
}
@ -869,6 +745,38 @@ clear_displays ()
}
}
/* Delete the auto-display number NUM. */
void
delete_display (num)
int num;
{
register struct display *d1, *d;
if (!display_chain)
error ("No display number %d.", num);
if (display_chain->number == num)
{
d1 = display_chain;
display_chain = d1->next;
free_display (d1);
}
else
for (d = display_chain; ; d = d->next)
{
if (d->next == 0)
error ("No display number %d.", num);
if (d->next->number == num)
{
d1 = d->next;
d->next = d1->next;
free_display (d1);
break;
}
}
}
/* Delete some values from the auto-display chain.
Specify the element numbers. */
@ -898,25 +806,7 @@ undisplay_command (args)
num = atoi (p);
if (display_chain->number == num)
{
d1 = display_chain;
display_chain = d1->next;
free_display (d1);
}
else
for (d = display_chain; ; d = d->next)
{
if (d->next == 0)
error ("No display number %d.", num);
if (d->next->number == num)
{
d1 = d->next;
d->next = d1->next;
free_display (d1);
break;
}
}
delete_display (num);
p = p1;
while (*p == ' ' || *p == '\t') p++;
@ -924,6 +814,47 @@ undisplay_command (args)
dont_repeat ();
}
/* Display a single auto-display. */
static void
do_one_display (d)
struct display *d;
{
current_display_number = d->number;
printf ("%d: ", d->number);
if (d->format.size)
{
printf ("x/");
if (d->format.count != 1)
printf ("%d", d->format.count);
printf ("%c", d->format.format);
if (d->format.format != 'i' && d->format.format != 's')
printf ("%c", d->format.size);
printf (" ");
print_expression (d->exp, stdout);
if (d->format.count != 1)
printf ("\n");
else
printf (" ");
do_examine (d->format,
value_as_long (evaluate_expression (d->exp)));
}
else
{
if (d->format.format)
printf ("/%c ", d->format.format);
print_expression (d->exp, stdout);
printf (" = ");
print_formatted (evaluate_expression (d->exp),
d->format.format, d->format.size);
printf ("\n");
}
fflush (stdout);
current_display_number = -1;
}
/* Display all of the values on the auto-display chain. */
void
@ -932,37 +863,22 @@ do_displays ()
register struct display *d;
for (d = display_chain; d; d = d->next)
do_one_display (d);
}
/* Delete the auto-display which we were in the process of displaying.
This is done when there is an error or a signal. */
void
delete_current_display ()
{
if (current_display_number >= 0)
{
printf ("%d: ", d->number);
if (d->format.size)
{
printf ("x/");
if (d->format.count != 1)
printf ("%d", d->format.count);
printf ("%c", d->format.format);
if (d->format.format != 'i' && d->format.format != 's')
printf ("%c", d->format.size);
printf (" ");
print_expression (d->exp, stdout);
if (d->format.count != 1)
printf ("\n");
else
printf (" ");
do_examine (d->format,
value_as_long (evaluate_expression (d->exp)));
}
else
{
if (d->format.format)
printf ("/%c ", d->format.format);
print_expression (d->exp, stdout);
printf (" = ");
print_formatted (evaluate_expression (d->exp),
d->format.format, d->format.size);
printf ("\n");
}
fflush (stdout);
delete_display (current_display_number);
fprintf (stderr, "Deleting display %d to avoid infinite recursion.\n",
current_display_number);
}
current_display_number = -1;
}
static void
@ -998,7 +914,7 @@ print_variable_value (var, frame, stream)
FILE *stream;
{
value val = read_var_value (var, frame);
value_print (val, stream);
value_print (val, stream, 0);
}
/* Print the arguments of a stack frame, given the function FUNC
@ -1057,7 +973,7 @@ print_frame_args (func, addr, num, stream)
if (! first)
fprintf (stream, ", ");
fprintf (stream, "%s=", SYMBOL_NAME (sym));
value_print (val, stream);
value_print (val, stream, 0);
first = 0;
last_offset = SYMBOL_VALUE (sym) + TYPE_LENGTH (SYMBOL_TYPE (sym));
/* Round up address of next arg to multiple of size of int. */
@ -1255,6 +1171,8 @@ printf_command (arg)
static
initialize ()
{
current_display_number = -1;
add_info ("address", address_info,
"Describe where variable VAR is stored.");
@ -1281,11 +1199,6 @@ The selected stack frame's lexical context is used to look up the name.");
add_com ("whatis", class_vars, whatis_command,
"Print data type of expression EXP.");
add_com ("pmethod", class_vars, pmethod_command,
"Print definitions of method METHOD.\n\
Argument must resolve to a method name within the containing scope.\n\
All definitions found go into history array.");
add_info ("display", display_info,
"Expressions to display when program stops, with code numbers.");
add_com ("undisplay", class_vars, undisplay_command,

View File

@ -71,11 +71,24 @@ anyone else from sharing it farther. Help stamp out software hoarding!
#include "frame.h"
#include "inferior.h"
#include <sys/wait.h>
#include "wait.h"
#include <sys/ioctl.h>
#include <a.out.h>
#include <sys/file.h>
#ifdef HAVE_TERMIO
#include <termio.h>
#undef TIOCGETP
#define TIOCGETP TCGETA
#undef TIOCSETN
#define TIOCSETN TCSETA
#undef TIOCSETP
#define TIOCSETP TCSETAF
#define TERMINAL struct termio
#else
#include <sgtty.h>
#define TERMINAL struct sgttyb
#endif
int kiodebug;
@ -101,7 +114,7 @@ remote_open (name, from_tty)
char *name;
int from_tty;
{
struct sgttyb sg;
TERMINAL sg;
remote_debugging = 0;
dcache_init ();
@ -111,7 +124,11 @@ remote_open (name, from_tty)
perror_with_name (name);
ioctl (remote_desc, TIOCGETP, &sg);
#ifdef HAVE_TERMIO
sg.c_lflag &= ~ICANON;
#else
sg.sg_flags = RAW;
#endif
ioctl (remote_desc, TIOCSETP, &sg);
if (from_tty)
@ -165,18 +182,17 @@ remote_resume (step, signal)
int
remote_wait (status)
union wait *status;
WAITTYPE *status;
{
char buf[PBUFSIZ];
status->w_status = 0;
WSETEXIT ((*status), 0);
getpkt (buf);
if (buf[0] == 'E')
error ("Remote failure reply: %s", buf);
if (buf[0] != 'S')
error ("Invalid remote reply: %s", buf);
status->w_stopval = WSTOPPED;
status->w_stopsig = (fromhex (buf[1]) << 4) + fromhex (buf[2]);
WSETSTOP ((*status), (((fromhex (buf[1])) << 4) + (fromhex (buf[2]))));
}
/* Read the remote registers into the block REGS. */

View File

@ -59,16 +59,13 @@ select_source_symtab (s)
{
if (s)
{
struct symtabs_and_lines sals;
struct symtab_and_line sal;
/* Make the default place to list be the function `main'
if one exists. */
if (lookup_symbol ("main", 0, VAR_NAMESPACE))
{
sals = decode_line_spec ("main", 1);
sal = sals.sals[0];
free (sals.sals);
sal = decode_line_spec ("main", 1);
current_source_symtab = sal.symtab;
current_source_line = sal.line - 9;
return;
@ -96,15 +93,12 @@ directories_info ()
printf ("Source directories searched: %s\n", source_path);
}
static void
void
init_source_path ()
{
register struct symtab *s;
char wd[MAXPATHLEN];
if (getwd (wd) == NULL)
perror_with_name ("getwd");
source_path = savestring (wd, strlen (wd));
source_path = savestring (current_directory, strlen (current_directory));
/* Forget what we learned about line positions in source files;
must check again now since files may be found in
@ -124,13 +118,9 @@ directory_command (dirname, from_tty)
{
char *old = source_path;
char wd[MAXPATHLEN];
if (getwd (wd) == NULL)
perror_with_name ("getwd");
if (dirname == 0)
{
if (query ("Reinitialize source path to %s? ", wd))
if (query ("Reinitialize source path to %s? ", current_directory))
{
init_source_path ();
free (old);
@ -154,7 +144,7 @@ directory_command (dirname, from_tty)
if (len == 1)
{
/* "." => getwd () */
dirname = wd;
dirname = current_directory;
goto append;
}
else if (dirname[len - 2] == '/')
@ -176,7 +166,7 @@ directory_command (dirname, from_tty)
}
if (dirname[0] != '/')
dirname = concat (wd, "/", dirname);
dirname = concat (current_directory, "/", dirname);
else
dirname = savestring (dirname, len);
make_cleanup (free, dirname);
@ -302,7 +292,7 @@ find_source_lines (s, desc)
extern int exec_mtime;
fstat (desc, &st);
if (get_exec_file () != 0 && exec_mtime < st.st_mtime)
if (get_exec_file (0) != 0 && exec_mtime < st.st_mtime)
printf ("Source file is more recent than executable.\n");
data = (char *) alloca (st.st_size);
@ -313,11 +303,16 @@ find_source_lines (s, desc)
nlines = 1;
while (p != end)
{
if (*p++ == '\n')
if (*p++ == '\n'
/* A newline at the end does not start a new line. */
&& p != end)
{
if (nlines == lines_allocated)
line_charpos = (int *) xrealloc (line_charpos,
sizeof (int) * (lines_allocated *= 2));
{
lines_allocated *= 2;
line_charpos = (int *) xrealloc (line_charpos,
sizeof (int) * lines_allocated);
}
line_charpos[nlines++] = p - data;
}
}
@ -396,18 +391,27 @@ get_filename_and_charpos (s, line, fullname)
The text starts with two Ctrl-z so that the Emacs-GDB interface
can easily find it.
MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
Return 1 if successful, 0 if could not find the file. */
int
identify_source_line (s, line)
identify_source_line (s, line, mid_statement)
struct symtab *s;
int line;
int mid_statement;
{
if (s->line_charpos == 0)
get_filename_and_charpos (s, line, 0);
if (s->fullname == 0)
return 0;
printf ("\032\032%s:%d:%d\n", s->fullname, line, s->line_charpos[line - 1]);
printf ("\032\032%s:%d:%d:%s\n", s->fullname,
line, s->line_charpos[line - 1],
mid_statement ? "middle" : "beg");
current_source_line = line;
first_line_listed = line;
last_line_listed = line;
current_source_symtab = s;
return 1;
}
@ -415,9 +419,10 @@ identify_source_line (s, line)
starting with line number LINE and stopping before line number STOPLINE. */
void
print_source_lines (s, line, stopline)
print_source_lines (s, line, stopline, noerror)
struct symtab *s;
int line, stopline;
int noerror;
{
register int c;
register int desc;
@ -426,12 +431,18 @@ print_source_lines (s, line, stopline)
desc = openp (source_path, 0, s->filename, O_RDONLY, 0, &s->fullname);
if (desc < 0)
perror_with_name (s->filename);
{
extern int errno;
if (! noerror)
perror_with_name (s->filename);
print_sys_errmsg (s->filename, errno);
return;
}
if (s->line_charpos == 0)
find_source_lines (s, desc);
if (line < 1 || line >= s->nlines)
if (line < 1 || line > s->nlines)
{
close (desc);
error ("Line number out of range; %s has %d lines.",
@ -479,7 +490,6 @@ list_command (arg, from_tty)
char *arg;
int from_tty;
{
struct symtabs_and_lines sals, sals_end;
struct symtab_and_line sal, sal_end;
struct symbol *sym;
char *arg1;
@ -499,7 +509,7 @@ list_command (arg, from_tty)
if (current_source_symtab == 0)
error ("No default source file yet. Do \"help list\".");
print_source_lines (current_source_symtab, current_source_line,
current_source_line + 10);
current_source_line + 10, 0);
return;
}
@ -510,7 +520,7 @@ list_command (arg, from_tty)
error ("No default source file yet. Do \"help list\".");
print_source_lines (current_source_symtab,
max (first_line_listed - 10, 1),
first_line_listed);
first_line_listed, 0);
return;
}
@ -524,18 +534,7 @@ list_command (arg, from_tty)
if (*arg1 == ',')
dummy_beg = 1;
else
{
sals = decode_line_1 (&arg1, 0, 0, 0);
if (! sals.nelts) return; /* C++ */
if (sals.nelts != 1)
{
error ("Unreasonable listing request");
}
sal = sals.sals[0];
free (sals.sals);
}
sal = decode_line_1 (&arg1, 0, 0, 0);
/* Record whether the BEG arg is all digits. */
@ -552,16 +551,10 @@ list_command (arg, from_tty)
arg1++;
if (*arg1 == 0)
dummy_end = 1;
else if (dummy_beg)
sal_end = decode_line_1 (&arg1, 0, 0, 0);
else
{
if (dummy_beg)
sals_end = decode_line_1 (&arg1, 0, 0, 0);
else
sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line);
if (! sals_end.nelts) return; /* C++ */
sal_end = sals_end.sals[0];
free (sals_end.sals);
}
sal_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line);
}
if (*arg1)
@ -607,14 +600,15 @@ list_command (arg, from_tty)
error ("No default source file yet. Do \"help list\".");
if (dummy_beg)
print_source_lines (sal_end.symtab, max (sal_end.line - 9, 1),
sal_end.line + 1);
sal_end.line + 1, 0);
else if (sal.symtab == 0)
error ("No default source file yet. Do \"help list\".");
else if (no_end)
print_source_lines (sal.symtab, max (sal.line - 5, 1), sal.line + 5);
print_source_lines (sal.symtab, max (sal.line - 5, 1), sal.line + 5, 0);
else
print_source_lines (sal.symtab, sal.line,
dummy_end ? sal.line + 10 : sal_end.line + 1);
dummy_end ? sal.line + 10 : sal_end.line + 1,
0);
}
/* Print info on range of pc's in a specified line. */
@ -624,7 +618,6 @@ line_info (arg, from_tty)
char *arg;
int from_tty;
{
struct symtabs_and_lines sals;
struct symtab_and_line sal;
int start_pc, end_pc;
@ -635,15 +628,8 @@ line_info (arg, from_tty)
}
else
{
sals = decode_line_spec (arg);
sal = decode_line_spec (arg, 0);
if (sals.nelts == 0)
return; /* C++ */
if (sals.nelts != 1)
error ("unreasonable line info request");
sal = sals.sals[0];
free (sals.sals);
/* If this command is repeated with RET,
turn it into the no-arg variant. */
@ -701,7 +687,7 @@ forward_search_command (regex, from_tty)
if (current_source_symtab->line_charpos == 0)
find_source_lines (current_source_symtab, desc);
if (line < 1 || line >= current_source_symtab->nlines)
if (line < 1 || line > current_source_symtab->nlines)
{
close (desc);
error ("Expression not found");
@ -733,7 +719,7 @@ forward_search_command (regex, from_tty)
/* Match! */
fclose (stream);
print_source_lines (current_source_symtab,
line, line+1);
line, line+1, 0);
current_source_line = max (line - 5, 1);
return;
}
@ -771,7 +757,7 @@ reverse_search_command (regex, from_tty)
if (current_source_symtab->line_charpos == 0)
find_source_lines (current_source_symtab, desc);
if (line < 1 || line >= current_source_symtab->nlines)
if (line < 1 || line > current_source_symtab->nlines)
{
close (desc);
error ("Expression not found");
@ -804,7 +790,7 @@ reverse_search_command (regex, from_tty)
/* Match! */
fclose (stream);
print_source_lines (current_source_symtab,
line, line+1);
line, line+1, 0);
current_source_line = max (line - 5, 1);
return;
}

View File

@ -120,12 +120,15 @@ print_frame_info (fi, level, source, args)
if (source != 0 && sal.symtab)
{
int done = 0;
if (source < 0 && fi->pc != sal.pc)
printf ("0x%x\t", fi->pc);
int mid_statement = source < 0 && fi->pc != sal.pc;
if (frame_file_full_name)
done = identify_source_line (sal.symtab, sal.line);
done = identify_source_line (sal.symtab, sal.line, mid_statement);
if (!done)
print_source_lines (sal.symtab, sal.line, sal.line + 1);
{
if (mid_statement)
printf ("0x%x\t", fi->pc);
print_source_lines (sal.symtab, sal.line, sal.line + 1, 1);
}
current_source_line = max (sal.line - 5, 1);
}
if (source != 0)
@ -278,7 +281,8 @@ print_block_frame_locals (b, frame, stream)
{
sym = BLOCK_SYM (b, i);
if (SYMBOL_CLASS (sym) == LOC_LOCAL
|| SYMBOL_CLASS (sym) == LOC_REGISTER)
|| SYMBOL_CLASS (sym) == LOC_REGISTER
|| SYMBOL_CLASS (sym) == LOC_STATIC)
{
fprintf (stream, "%s = ", SYMBOL_NAME (sym));
print_variable_value (sym, frame, stream);

View File

@ -341,7 +341,8 @@ core_file_command ()
{}
char *
get_exec_file ()
get_exec_file (err)
int err;
{
/* Makes one printout look reasonable; value does not matter otherwise. */
return "run";

View File

@ -397,6 +397,8 @@ print_symtabs (filename)
if (filename == 0)
error_no_arg ("file to write symbol data in");
outfile = fopen (filename, "w");
if (outfile == 0)
perror_with_name (filename);
cleanups = make_cleanup (fclose, outfile);
immediate_quit++;

View File

@ -1,6 +1,5 @@
/* GDB symbol table format definitions.
Copyright (C) 1986 Free Software Foundation, Inc.
Hacked by Michael Tiemann (tiemann@mcc.com)
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
@ -118,10 +117,6 @@ enum type_code
TYPE_CODE_SET, /* Pascal sets */
TYPE_CODE_RANGE, /* Range (integers within spec'd bounds) */
TYPE_CODE_PASCAL_ARRAY, /* Array with explicit type of index */
/* C++ */
TYPE_CODE_MEMBER, /* Member type */
TYPE_CODE_REF, /* C++ Reference types */
};
/* This appears in a type's flags word for an unsigned integer type. */
@ -149,22 +144,11 @@ struct type
The debugger may add the address of such a type
if it has to construct one later. */
struct type *pointer_type;
/* C++: also need a reference type. */
struct type *reference_type;
/* Type that is a function returning this type.
Zero if no such function type is known here.
The debugger may add the address of such a type
if it has to construct one later. */
struct type *function_type;
/* Handling of pointers to members:
TYPE_MAIN_VARIANT is used for pointer and pointer
to member types. Normally it the value of the address of its
containing type. However, for pointers to members, we must be
able to allocate pointer to member types and look them up
from some place of reference. */
struct type *main_variant;
/* Flags about this type. */
short flags;
/* Number of fields described for this type */
@ -201,75 +185,6 @@ struct type
Zero for range bounds and array domains. */
char *name;
} *fields;
/* C++ */
int *private_field_bits;
int *protected_field_bits;
/* Some flags to make life easier. */
unsigned char has_constructor;
unsigned char has_destructor;
/* Number of methods described for this type */
short nfn_fields;
/* Number of methods described for this type plus all the
methods that it derives from. */
int nfn_fields_total;
/* For classes, structures, and unions, a description of each field,
which consists of an overloaded name, followed by the types of
arguments that the method expects, and then the name after it
has been renamed to make it distinct. */
struct fn_fieldlist
{
/* The overloaded name. */
char *name;
/* The number of methods with this name. */
int length;
/* The list of methods. */
struct fn_field
{
#if 0
/* The overloaded name */
char *name;
#endif
/* The type of the argument */
struct type *type;
/* The argument list */
struct type **args;
/* The name after it has been processed */
char *physname;
/* If this is a virtual function, the offset into the vtbl-1,
else 0. */
int voffset;
} *fn_fields;
int *private_fn_field_bits;
int *protected_fn_field_bits;
} *fn_fieldlists;
unsigned char via_protected;
unsigned char via_public;
/* For types with virtual functions, VPTR_BASETYPE is the base class which
defined the virtual function table pointer. VPTR_FIELDNO is
the field number of that pointer in the structure.
For types that are pointer to member types, VPTR_BASETYPE
ifs the type that this pointer is a member of.
Unused otherwise. */
struct type *vptr_basetype;
int vptr_fieldno;
/* If this type has a base class, put it here.
If this type is a pointer type, the chain of member pointer
types goes here.
Unused otherwise. */
struct type *baseclass;
};
/* All of the name-scope contours of the program

View File

@ -139,7 +139,7 @@ lookup_struct (name, block)
if (sym == 0)
error ("No struct type named %s.", name);
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
error ("This context has class, union or enum %s, not a struct.", name);
error ("This context has union or enum %s, not a struct.", name);
return SYMBOL_TYPE (sym);
}
@ -155,7 +155,7 @@ lookup_union (name, block)
if (sym == 0)
error ("No union type named %s.", name);
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_UNION)
error ("This context has class, struct or enum %s, not a union.", name);
error ("This context has struct or enum %s, not a union.", name);
return SYMBOL_TYPE (sym);
}
@ -171,22 +171,19 @@ lookup_enum (name, block)
if (sym == 0)
error ("No enum type named %s.", name);
if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_ENUM)
error ("This context has class, struct or union %s, not an enum.", name);
error ("This context has struct or union %s, not an enum.", name);
return SYMBOL_TYPE (sym);
}
/* Given a type TYPE, return a type of pointers to that type.
May need to construct such a type if this is the first use.
C++: use TYPE_MAIN_VARIANT and TYPE_CHAIN to keep pointer
to member types under control. */
May need to construct such a type if this is the first use. */
struct type *
lookup_pointer_type (type)
struct type *type;
{
register struct type *ptype = TYPE_POINTER_TYPE (type);
if (ptype) return TYPE_MAIN_VARIANT (ptype);
if (ptype) return ptype;
/* This is the first time anyone wanted a pointer to a TYPE. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
@ -196,7 +193,6 @@ lookup_pointer_type (type)
sizeof (struct type));
bzero (ptype, sizeof (struct type));
TYPE_MAIN_VARIANT (ptype) = ptype;
TYPE_TARGET_TYPE (ptype) = type;
TYPE_POINTER_TYPE (type) = ptype;
/* New type is permanent if type pointed to is permanent. */
@ -208,91 +204,12 @@ lookup_pointer_type (type)
return ptype;
}
struct type *
lookup_reference_type (type)
struct type *type;
{
register struct type *rtype = TYPE_REFERENCE_TYPE (type);
if (rtype) return TYPE_MAIN_VARIANT (rtype);
/* This is the first time anyone wanted a pointer to a TYPE. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
rtype = (struct type *) xmalloc (sizeof (struct type));
else
rtype = (struct type *) obstack_alloc (symbol_obstack,
sizeof (struct type));
bzero (rtype, sizeof (struct type));
TYPE_MAIN_VARIANT (rtype) = rtype;
TYPE_TARGET_TYPE (rtype) = type;
TYPE_REFERENCE_TYPE (type) = rtype;
/* New type is permanent if type pointed to is permanent. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
TYPE_FLAGS (rtype) |= TYPE_FLAG_PERM;
/* We assume the machine has only one representation for pointers! */
TYPE_LENGTH (rtype) = sizeof (char *);
TYPE_CODE (rtype) = TYPE_CODE_REF;
return rtype;
}
/* Implement direct support for MEMBER_TYPE in GNU C++.
May need to construct such a type if this is the first use.
The TYPE is the type of the member. The DOMAIN is the type
of the aggregate that the member belongs to. */
struct type *
lookup_member_type (type, domain)
struct type *type, *domain;
{
register struct type *mtype = TYPE_MAIN_VARIANT (type);
struct type *main_type;
main_type = mtype;
while (mtype)
{
if (TYPE_DOMAIN_TYPE (mtype) == domain)
return mtype;
mtype = TYPE_CHAIN (mtype);
}
/* This is the first time anyone wanted this member type. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
mtype = (struct type *) xmalloc (sizeof (struct type));
else
mtype = (struct type *) obstack_alloc (symbol_obstack,
sizeof (struct type));
bzero (mtype, sizeof (struct type));
TYPE_MAIN_VARIANT (mtype) = main_type;
TYPE_TARGET_TYPE (mtype) = type;
TYPE_DOMAIN_TYPE (mtype) = domain;
/* New type is permanent if type pointed to is permanent. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
TYPE_FLAGS (mtype) |= TYPE_FLAG_PERM;
/* In practice, this is never used. */
TYPE_LENGTH (mtype) = 1;
TYPE_CODE (mtype) = TYPE_CODE_MEMBER;
/* Now splice in the new member pointer type. */
if (main_type)
{
/* This type was not "smashed". */
TYPE_CHAIN (mtype) = TYPE_CHAIN (main_type);
TYPE_CHAIN (main_type) = mtype;
}
return mtype;
}
/* Given a type TYPE, return a type of functions that return that type.
May need to construct such a type if this is the first use. */
struct type *
lookup_function_type (type, argtypes)
lookup_function_type (type)
struct type *type;
struct type **argtypes;
{
register struct type *ptype = TYPE_FUNCTION_TYPE (type);
if (ptype) return ptype;
@ -330,8 +247,6 @@ smash_to_pointer_type (type, to_type)
TYPE_LENGTH (type) = sizeof (char *);
TYPE_CODE (type) = TYPE_CODE_PTR;
TYPE_MAIN_VARIANT (type) = type;
if (TYPE_POINTER_TYPE (to_type) == 0
&& !(TYPE_FLAGS (type) & TYPE_FLAG_PERM))
{
@ -339,46 +254,6 @@ smash_to_pointer_type (type, to_type)
}
}
/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE. */
void
smash_to_member_type (type, domain, to_type)
struct type *type, *domain, *to_type;
{
bzero (type, sizeof (struct type));
TYPE_TARGET_TYPE (type) = to_type;
TYPE_DOMAIN_TYPE (type) = domain;
/* In practice, this is never needed. */
TYPE_LENGTH (type) = 1;
TYPE_CODE (type) = TYPE_CODE_MEMBER;
TYPE_MAIN_VARIANT (type) = lookup_member_type (domain, to_type);
}
/* Smash TYPE to be a type of reference to TO_TYPE.
If TO_TYPE is not permanent and has no pointer-type yet,
record TYPE as its pointer-type. */
void
smash_to_reference_type (type, to_type)
struct type *type, *to_type;
{
bzero (type, sizeof (struct type));
TYPE_TARGET_TYPE (type) = to_type;
/* We assume the machine has only one representation for pointers! */
TYPE_LENGTH (type) = sizeof (char *);
TYPE_CODE (type) = TYPE_CODE_REF;
TYPE_MAIN_VARIANT (type) = type;
if (TYPE_REFERENCE_TYPE (to_type) == 0
&& !(TYPE_FLAGS (type) & TYPE_FLAG_PERM))
{
TYPE_REFERENCE_TYPE (to_type) = type;
}
}
/* Smash TYPE to be a type of functions returning TO_TYPE.
If TO_TYPE is not permanent and has no function-type yet,
record TYPE as its function-type. */
@ -406,62 +281,6 @@ static struct symbol *lookup_block_symbol ();
in namespace NAMESPACE, visible from lexical block BLOCK.
Returns the struct symbol pointer, or zero if no symbol is found. */
struct symbol *
lookup_symbol_1 (name, block, namespace)
char *name;
register struct block *block;
enum namespace namespace;
{
register int i, n;
register struct symbol *sym;
register struct symtab *s;
struct blockvector *bv;
/* Search specified block and its superiors. */
while (block != 0)
{
sym = lookup_block_symbol (block, name, namespace);
if (sym) return sym;
block = BLOCK_SUPERBLOCK (block);
}
return 0;
}
struct symbol *
lookup_symbol_2 (name, block, namespace)
char *name;
register struct block *block; /* ignored as parameter */
enum namespace namespace;
{
register int i, n;
register struct symbol *sym;
register struct symtab *s;
struct blockvector *bv;
/* Now search all symtabs' global blocks. */
for (s = symtab_list; s; s = s->next)
{
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, 0);
sym = lookup_block_symbol (block, name, namespace);
if (sym) return sym;
}
/* Now search all symtabs' per-file blocks.
Not strictly correct, but more useful than an error. */
for (s = symtab_list; s; s = s->next)
{
bv = BLOCKVECTOR (s);
block = BLOCKVECTOR_BLOCK (bv, 1);
sym = lookup_block_symbol (block, name, namespace);
if (sym) return sym;
}
return 0;
}
struct symbol *
lookup_symbol (name, block, namespace)
char *name;
@ -505,7 +324,7 @@ lookup_symbol (name, block, namespace)
return 0;
}
/* Look for a symbol in block BLOCK using binary search. */
/* Look for a symbol in block BLOCK. */
static struct symbol *
lookup_block_symbol (block, name, namespace)
@ -519,39 +338,67 @@ lookup_block_symbol (block, name, namespace)
top = BLOCK_NSYMS (block);
bot = 0;
/* First, advance BOT to not far before
the first symbol whose name is NAME. */
/* If the blocks's symbols were sorted, start with a binary search. */
while (1)
if (BLOCK_SHOULD_SORT (block))
{
inc = (top - bot + 1);
/* No need to keep binary searching for the last few bits worth. */
if (inc < 7)
break;
inc >>= 1;
sym = BLOCK_SYM (block, bot + inc);
if (strcmp (SYMBOL_NAME (sym), name) < 0)
bot += inc;
else
top = bot + inc;
/* First, advance BOT to not far before
the first symbol whose name is NAME. */
while (1)
{
inc = (top - bot + 1);
/* No need to keep binary searching for the last few bits worth. */
if (inc < 4)
break;
inc = (inc >> 1) + bot;
sym = BLOCK_SYM (block, inc);
if (SYMBOL_NAME (sym)[0] < name[0])
bot = inc;
else if (SYMBOL_NAME (sym)[0] > name[0])
top = inc;
else if (strcmp (SYMBOL_NAME (sym), name) < 0)
bot = inc;
else
top = inc;
}
/* Now scan forward until we run out of symbols,
find one whose name is greater than NAME,
or find one we want.
If there is more than one symbol with the right name and namespace,
we return the first one. dbxread.c is careful to make sure
that if one is a register then it comes first. */
top = BLOCK_NSYMS (block);
while (bot < top)
{
sym = BLOCK_SYM (block, bot);
inc = SYMBOL_NAME (sym)[0] - name[0];
if (inc == 0)
inc = strcmp (SYMBOL_NAME (sym), name);
if (inc == 0 && SYMBOL_NAMESPACE (sym) == namespace)
return sym;
if (inc > 0)
return 0;
bot++;
}
return 0;
}
/* Now scan forward until we run out of symbols,
find one whose name is greater than NAME,
or find one we want.
If there is more than one symbol with the right name and namespace,
we return the first one. dbxread.c is careful to make sure
that if one is a register then it comes first. */
/* Here if block isn't sorted.
This loop is equivalent to the loop above,
but hacked greatly for speed. */
top = BLOCK_NSYMS (block);
inc = name[0];
while (bot < top)
{
sym = BLOCK_SYM (block, bot);
inc = strcmp (SYMBOL_NAME (sym), name);
if (inc == 0 && SYMBOL_NAMESPACE (sym) == namespace)
if (SYMBOL_NAME (sym)[0] == inc
&& !strcmp (SYMBOL_NAME (sym), name)
&& SYMBOL_NAMESPACE (sym) == namespace)
return sym;
if (inc > 0)
return 0;
bot++;
}
return 0;
@ -895,15 +742,13 @@ find_pc_line_pc_range (pc, startptr, endptr)
if no file is validly specified. Callers must check that.
Also, the line number returned may be invalid. */
struct symtabs_and_lines
struct symtab_and_line
decode_line_1 (argptr, funfirstline, default_symtab, default_line)
char **argptr;
int funfirstline;
struct symtab *default_symtab;
int default_line;
{
struct symtabs_and_lines decode_line_2 ();
struct symtabs_and_lines values;
struct symtab_and_line value;
register char *p, *p1;
register struct symtab *s;
@ -911,14 +756,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
register CORE_ADDR pc;
register int i;
char *copy;
struct symbol *sym_class;
char *class_name, *method_name, *phys_name;
int method_counter;
int i1;
struct symbol **sym_arr;
struct type *t, *field;
char **physnames;
/* Defaults have defaults. */
if (default_symtab == 0)
@ -933,11 +771,9 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
{
(*argptr)++;
pc = parse_and_eval_address_1 (argptr);
values.sals = (struct symtab_and_line *)malloc (sizeof (struct symtab_and_line));
values.nelts = 1;
values.sals[0] = find_pc_line (pc, 0);
values.sals[0].pc = pc;
return values;
value = find_pc_line (pc, 0);
value.pc = pc;
return value;
}
/* Maybe arg is FILE : LINENUM or FILE : FUNCTION */
@ -953,125 +789,6 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
if (p[0] == ':')
{
/* C++ */
if (p[1] ==':')
{
/* Extract the class name. */
p1 = p;
while (p != *argptr && p[-1] == ' ') --p;
copy = (char *) alloca (p - *argptr + 1);
bcopy (*argptr, copy, p - *argptr);
copy[p - *argptr] = 0;
/* Discard the class name from the arg. */
p = p1 + 2;
while (*p == ' ' || *p == '\t') p++;
*argptr = p;
sym_class = lookup_symbol (copy, 0, STRUCT_NAMESPACE);
if (sym_class &&
(TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_STRUCT
|| TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_UNION))
{
/* Arg token is not digits => try it as a function name
Find the next token (everything up to end or next whitespace). */
p = *argptr;
while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p !=':') p++;
copy = (char *) alloca (p - *argptr + 1);
bcopy (*argptr, copy, p - *argptr);
copy[p - *argptr] = '\0';
/* no line number may be specified */
while (*p == ' ' || *p == '\t') p++;
*argptr = p;
sym = 0;
i1 = 0; /* counter for the symbol array */
t = SYMBOL_TYPE (sym_class);
sym_arr = (struct symbol **) alloca(TYPE_NFN_FIELDS_TOTAL (t) * sizeof(struct symbol*));
physnames = (char **) alloca (TYPE_NFN_FIELDS_TOTAL (t) * sizeof(char*));
if (destructor_name_p (copy, t))
{
/* destructors are a special case. */
struct fn_field *f = TYPE_FN_FIELDLIST1 (t, 0);
int len = TYPE_FN_FIELDLIST_LENGTH (t, 0) - 1;
phys_name = TYPE_FN_FIELD_PHYSNAME (f, len);
physnames[i1] = (char *)alloca (strlen (phys_name) + 1);
strcpy (physnames[i1], phys_name);
sym_arr[i1] = lookup_symbol (phys_name, SYMBOL_BLOCK_VALUE (sym_class), VAR_NAMESPACE);
if (sym_arr[i1]) i1++;
}
else while (t)
{
int constructor_p;
class_name = TYPE_NAME (t);
while (*class_name++ != ' ');
constructor_p = ! strcmp (class_name, copy);
sym_class = lookup_symbol (class_name, 0, STRUCT_NAMESPACE);
for (method_counter = TYPE_NFN_FIELDS (SYMBOL_TYPE (sym_class)) - 1;
method_counter >= 0;
--method_counter)
{
int field_counter;
struct fn_field *f =
TYPE_FN_FIELDLIST1 (SYMBOL_TYPE (sym_class), method_counter);
method_name = TYPE_FN_FIELDLIST_NAME (SYMBOL_TYPE (sym_class), method_counter);
if (!strcmp (copy, method_name))
for (field_counter = TYPE_FN_FIELDLIST_LENGTH (SYMBOL_TYPE (sym_class), method_counter) - (1 + constructor_p);
field_counter >= 0;
--field_counter)
{
phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter);
physnames[i1] = (char*) alloca (strlen (phys_name) + 1);
strcpy (physnames[i1], phys_name);
sym_arr[i1] = lookup_symbol (phys_name, SYMBOL_BLOCK_VALUE (sym_class), VAR_NAMESPACE);
if (sym_arr[i1]) i1++;
}
}
t = TYPE_BASECLASS(t);
}
if (i1 == 1)
{
sym = sym_arr[0];
if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK)
{
/* Arg is the name of a function */
pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) + FUNCTION_START_OFFSET;
if (funfirstline)
SKIP_PROLOGUE (pc);
values.sals = (struct symtab_and_line *)malloc (sizeof (struct symtab_and_line));
values.nelts = 1;
values.sals[0] = find_pc_line (pc, 0);
values.sals[0].pc = (values.sals[0].end && values.sals[0].pc != pc) ? values.sals[0].end : pc;
}
else
{
values.nelts = 0;
}
return values;
}
if (i1 > 0)
{
return decode_line_2 (argptr, sym_arr, physnames, i1, funfirstline);
}
else
error ("that class does not have any method named %s",copy);
}
else
error("no class, struct, or union named %s", copy );
}
/* end of C++ */
/* Extract the file name. */
p1 = p;
while (p != *argptr && p[-1] == ' ') --p;
@ -1138,10 +855,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
s = default_symtab;
value.symtab = s;
value.pc = 0;
values.sals = (struct symtab_and_line *)malloc (sizeof (struct symtab_and_line));
values.sals[0] = value;
values.nelts = 1;
return values;
return value;
}
/* Arg token is not digits => try it as a function name
@ -1168,10 +882,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
SKIP_PROLOGUE (pc);
value = find_pc_line (pc, 0);
value.pc = (value.end && value.pc != pc) ? value.end : pc;
values.sals = (struct symtab_and_line *)malloc (sizeof (struct symtab_and_line));
values.sals[0] = value;
values.nelts = 1;
return values;
return value;
}
if (sym)
@ -1186,10 +897,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
value.pc = misc_function_vector[i].address + FUNCTION_START_OFFSET;
if (funfirstline)
SKIP_PROLOGUE (value.pc);
values.sals = (struct symtab_and_line *)malloc (sizeof (struct symtab_and_line));
values.sals[0] = value;
values.nelts = 1;
return values;
return value;
}
if (symtab_list == 0)
@ -1197,114 +905,19 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
error ("Function %s not defined.", copy);
}
struct symtabs_and_lines
struct symtab_and_line
decode_line_spec (string, funfirstline)
char *string;
int funfirstline;
{
struct symtabs_and_lines sals;
struct symtab_and_line sal;
if (string == 0)
error ("Empty line specification.");
sals = decode_line_1 (&string, funfirstline,
current_source_symtab, current_source_line);
sal = decode_line_1 (&string, funfirstline,
current_source_symtab, current_source_line);
if (*string)
error ("Junk at end of line specification: %s", string);
return sals;
}
struct symtabs_and_lines
decode_line_2 (argptr, sym_arr, physnames, nelts, funfirstline)
char **argptr;
struct symbol *sym_arr[];
char *physnames[];
int nelts;
int funfirstline;
{
char *getenv();
struct symtabs_and_lines values, return_values;
register CORE_ADDR pc;
char *args, *arg1, *read_line ();
int i;
char *prompt;
values.sals = (struct symtab_and_line *) alloca (nelts * sizeof(struct symtab_and_line));
return_values.sals = (struct symtab_and_line *) malloc (nelts * sizeof(struct symtab_and_line));
i = 0;
printf("[0] cancel\n[1] all\n");
while (i < nelts)
{
if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK)
{
/* Arg is the name of a function */
pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym_arr[i]))
+ FUNCTION_START_OFFSET;
if (funfirstline)
SKIP_PROLOGUE (pc);
values.sals[i] = find_pc_line (pc, 0);
printf("[%d] file:%s; line number:%d\n",
(i+2), values.sals[i].symtab->filename, values.sals[i].line);
}
else printf ("?HERE\n");
i++;
}
if ((prompt = getenv ("PS2")) == NULL)
{
prompt = ">";
}
printf("%s ",prompt);
fflush(stdout);
args = read_line (0);
if (args == 0)
error_no_arg ("one or more choice numbers");
i = 0;
while (*args)
{
int num;
arg1 = args;
while (*arg1 >= '0' && *arg1 <= '9') arg1++;
if (*arg1 && *arg1 != ' ' && *arg1 != '\t')
error ("Arguments must be choice numbers.");
num = atoi (args);
if (num == 0)
error ("cancelled");
else if (num == 1)
{
bcopy (values.sals, return_values.sals, (nelts * sizeof(struct symtab_and_line)));
return_values.nelts = nelts;
return return_values;
}
if (num > nelts + 2)
{
printf ("No choice number %d.\n", num);
}
else
{
num -= 2;
if (values.sals[num].pc)
{
return_values.sals[i++] = values.sals[num];
values.sals[num].pc = 0;
}
else
{
printf ("duplicate request for %d ignored.\n", num);
}
}
args = arg1;
while (*args == ' ' || *args == '\t') args++;
}
return_values.nelts = i;
return return_values;
return sal;
}
/* Return the index of misc function named NAME. */
@ -1369,6 +982,8 @@ sources_info ()
fflush (stdout); \
read_line (); } }
static void sort_block_syms ();
static void
list_symbols (regexp, class)
char *regexp;
@ -1383,7 +998,7 @@ list_symbols (regexp, class)
char *val;
int found_in_file;
static char *classnames[]
= {"variable", "function", "type", "method"};
= {"variable", "function", "type"};
int print_count = 0;
if (regexp)
@ -1409,6 +1024,9 @@ list_symbols (regexp, class)
for (i = 0; i < 2; i++)
{
b = BLOCKVECTOR_BLOCK (bv, i);
/* Skip the sort if this block is always sorted. */
if (!BLOCK_SHOULD_SORT (b))
sort_block_syms (b);
for (j = 0; j < BLOCK_NSYMS (b); j++)
{
QUIT;
@ -1417,8 +1035,7 @@ list_symbols (regexp, class)
&& ((class == 0 && SYMBOL_CLASS (sym) != LOC_TYPEDEF
&& SYMBOL_CLASS (sym) != LOC_BLOCK)
|| (class == 1 && SYMBOL_CLASS (sym) == LOC_BLOCK)
|| (class == 2 && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
|| (class == 3 && SYMBOL_CLASS (sym) == LOC_BLOCK)))
|| (class == 2 && SYMBOL_CLASS (sym) == LOC_TYPEDEF)))
{
if (!found_in_file)
{
@ -1433,30 +1050,17 @@ list_symbols (regexp, class)
&& SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE)
printf ("typedef ");
if (class < 3)
{
type_print (SYMBOL_TYPE (sym),
(SYMBOL_CLASS (sym) == LOC_TYPEDEF
? "" : SYMBOL_NAME (sym)),
stdout, 0);
printf (";\n");
}
else
{
char buf[1024];
# if 0
type_print_base (TYPE_FN_FIELD_TYPE(t, i), stdout, 0, 0);
type_print_varspec_prefix (TYPE_FN_FIELD_TYPE(t, i), stdout, 0);
sprintf (buf, " %s::", TYPE_NAME (t));
type_print_method_args (TYPE_FN_FIELD_ARGS (t, i), buf, name, stdout);
# endif
}
type_print (SYMBOL_TYPE (sym),
(SYMBOL_CLASS (sym) == LOC_TYPEDEF
? "" : SYMBOL_NAME (sym)),
stdout, 0);
if (class == 2
&& SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE
&& (TYPE_NAME ((SYMBOL_TYPE (sym))) == 0
|| 0 != strcmp (TYPE_NAME ((SYMBOL_TYPE (sym))),
SYMBOL_NAME (sym))))
printf (" %s", SYMBOL_NAME (sym));
printf (";\n");
}
}
}
@ -1484,12 +1088,27 @@ types_info (regexp)
{
list_symbols (regexp, 2);
}
/* Call sort_block_syms to sort alphabetically the symbols of one block. */
static int
compare_symbols (s1, s2)
struct symbol **s1, **s2;
{
/* Names that are less should come first. */
register int namediff = strcmp (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2));
if (namediff != 0) return namediff;
/* For symbols of the same name, registers should come first. */
return ((SYMBOL_CLASS (*s2) == LOC_REGISTER)
- (SYMBOL_CLASS (*s1) == LOC_REGISTER));
}
static void
methods_info (regexp)
char *regexp;
sort_block_syms (b)
register struct block *b;
{
list_symbols (regexp, 3);
qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
sizeof (struct symbol *), compare_symbols);
}
/* Initialize the standard C scalar types. */
@ -1505,7 +1124,6 @@ init_type (code, length, uns, name)
type = (struct type *) xmalloc (sizeof (struct type));
bzero (type, sizeof *type);
TYPE_MAIN_VARIANT (type) = type;
TYPE_CODE (type) = code;
TYPE_LENGTH (type) = length;
TYPE_FLAGS (type) = uns ? TYPE_FLAG_UNSIGNED : 0;
@ -1513,9 +1131,6 @@ init_type (code, length, uns, name)
TYPE_NFIELDS (type) = 0;
TYPE_NAME (type) = name;
/* C++ fancies. */
TYPE_NFN_FIELDS (type) = 0;
TYPE_BASECLASS (type) = 0;
return type;
}
@ -1528,11 +1143,6 @@ initialize ()
"All function names, or those matching REGEXP.");
add_info ("types", types_info,
"All types names, or those matching REGEXP.");
add_info ("methods", methods_info,
"All method names, or those matching REGEXP::REGEXP.\n\
If the class qualifier is ommited, it is assumed to be the current scope.\n\
If the first REGEXP is ommited, then all methods matching the second REGEXP\n\
are listed.");
add_info ("sources", sources_info,
"Source files in the program.");

View File

@ -53,8 +53,8 @@ int misc_function_count;
#include "symseg.h"
/* Each source file is represented by a struct symtab. */
/* These objects are chained through the `next' field. */
/* Each source file is represented by a struct symtab.
These objects are chained through the `next' field. */
struct symtab
{
@ -75,7 +75,7 @@ struct symtab
free_linetable => free just the linetable. */
enum free_code {free_nothing, free_contents, free_linetable}
free_code;
/* Pointer to one block of storage to be freed, if nonzero. */
/* Pointer to one block storage to be freed, if nonzero. */
char *free_ptr;
/* Total number of lines found in source file. */
int nlines;
@ -132,6 +132,9 @@ int current_source_line;
#define BLOCK_FUNCTION(bl) (bl)->function
#define BLOCK_SUPERBLOCK(bl) (bl)->superblock
/* Nonzero if symbols of block BL should be sorted alphabetically. */
#define BLOCK_SHOULD_SORT(bl) ((bl)->nsyms >= 40)
#define SYMBOL_NAME(symbol) (symbol)->name
#define SYMBOL_NAMESPACE(symbol) (symbol)->namespace
#define SYMBOL_CLASS(symbol) (symbol)->class
@ -145,34 +148,16 @@ int current_source_line;
These types are never freed. */
#define TYPE_FLAG_PERM 4
/* Some macros for bitfields. */
#define B_SET(a,x) (a[x>>5] |= (1 << (x&31)))
#define B_CLR(a,x) (a[x>>5] &= ~(1 << (x&31)))
#define B_TST(a,x) (a[x>>5] & (1 << (x&31)))
#define TYPE_NAME(thistype) (thistype)->name
#define TYPE_TARGET_TYPE(thistype) (thistype)->target_type
#define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type
#define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
#define TYPE_FUNCTION_TYPE(thistype) (thistype)->function_type
#define TYPE_MAIN_VARIANT(thistype) (thistype)->main_variant
#define TYPE_LENGTH(thistype) (thistype)->length
#define TYPE_FLAGS(thistype) (thistype)->flags
#define TYPE_UNSIGNED(thistype) ((thistype)->flags & TYPE_FLAG_UNSIGNED)
#define TYPE_CODE(thistype) (thistype)->code
#define TYPE_NFIELDS(thistype) (thistype)->nfields
#define TYPE_FIELDS(thistype) (thistype)->fields
/* C++ */
#define TYPE_VPTR_BASETYPE(thistype) (thistype)->vptr_basetype
#define TYPE_DOMAIN_TYPE(thistype) (thistype)->vptr_basetype
#define TYPE_VPTR_FIELDNO(thistype) (thistype)->vptr_fieldno
#define TYPE_FN_FIELDS(thistype) (thistype)->fn_fields
#define TYPE_NFN_FIELDS(thistype) (thistype)->nfn_fields
#define TYPE_NFN_FIELDS_TOTAL(thistype) (thistype)->nfn_fields_total
#define TYPE_BASECLASS(thistype) (thistype)->baseclass
#define TYPE_VIA_PUBLIC(thistype) (thistype)->via_public
#define TYPE_VIA_PROTECTED(thistype) (thistype)->via_protected
#define TYPE_CHAIN(thistype) (thistype)->baseclass
#define TYPE_FIELD(thistype, n) (thistype)->fields[n]
#define TYPE_FIELD_TYPE(thistype, n) (thistype)->fields[n].type
@ -181,46 +166,11 @@ int current_source_line;
#define TYPE_FIELD_BITPOS(thistype, n) (thistype)->fields[n].bitpos
#define TYPE_FIELD_BITSIZE(thistype, n) (thistype)->fields[n].bitsize
#define TYPE_FIELD_PACKED(thistype, n) (thistype)->fields[n].bitsize
#define TYPE_FIELD_PRIVATE_BITS(thistype) (thistype)->private_field_bits
#define TYPE_FIELD_PROTECTED_BITS(thistype) (thistype)->protected_field_bits
#define SET_TYPE_FIELD_PRIVATE(thistype, n) B_SET ((thistype)->private_field_bits, (n))
#define SET_TYPE_FIELD_PROTECTED(thistype, n) B_SET ((thistype)->protected_field_bits, (n))
#define TYPE_FIELD_PRIVATE(thistype, n) B_TST((thistype)->private_field_bits, (n))
#define TYPE_FIELD_PROTECTED(thistype, n) B_TST((thistype)->protected_field_bits, (n))
#define TYPE_HAS_DESTRUCTOR(thistype) ((thistype)->has_destructor)
#define TYPE_HAS_CONSTRUCTOR(thistype) ((thistype)->has_constructor)
#define TYPE_FIELD_STATIC(thistype, n) ((thistype)->fields[n].bitpos == -1)
#define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) ((char *)(thistype)->fields[n].bitsize)
#define TYPE_FN_FIELDLISTS(thistype) (thistype)->fn_fieldlists
#define TYPE_FN_FIELDLIST(thistype, n) (thistype)->fn_fieldlists[n]
#define TYPE_FN_FIELDLIST1(thistype, n) (thistype)->fn_fieldlists[n].fn_fields
#define TYPE_FN_FIELDLIST_NAME(thistype, n) (thistype)->fn_fieldlists[n].name
#define TYPE_FN_FIELDLIST_LENGTH(thistype, n) (thistype)->fn_fieldlists[n].length
#define TYPE_FN_FIELD(thistype) (thistype)[n]
#define TYPE_FN_FIELD_NAME(thistype, n) (thistype)[n].name
#define TYPE_FN_FIELD_TYPE(thistype, n) (thistype)[n].type
#define TYPE_FN_FIELD_ARGS(thistype, n) (thistype)[n].args
#define TYPE_FN_FIELD_PHYSNAME(thistype, n) (thistype)[n].physname
#define TYPE_FN_FIELD_VIRTUAL_P(thistype, n) (thistype)[n].voffset
#define TYPE_FN_FIELD_VOFFSET(thistype, n) ((thistype)[n].voffset-1)
#define TYPE_FN_PRIVATE_BITS(thistype) (thistype).private_fn_field_bits
#define TYPE_FN_PROTECTED_BITS(thistype) (thistype).protected_fn_field_bits
#define SET_TYPE_FN_PRIVATE(thistype, n) B_SET ((thistype).private_fn_field_bits, n)
#define SET_TYPE_FN_PROTECTED(thistype, n) B_SET ((thistype).protected_fn_field_bits, n)
#define TYPE_FN_PRIVATE(thistype, n) B_TST ((thistype).private_fn_field_bits, n)
#define TYPE_FN_PROTECTED(thistype, n) B_TST ((thistype).protected_fn_field_bits, n)
/* Functions that work on the objects described above */
extern struct symtab *lookup_symtab ();
extern struct symbol *lookup_symbol ();
extern struct symbol *lookup_symbol_1 (), *lookup_symbol_2 ();
extern struct type *lookup_typename ();
extern struct type *lookup_unsigned_typename ();
extern struct type *lookup_struct ();
@ -232,12 +182,6 @@ extern struct symbol *block_function ();
extern struct symbol *find_pc_function ();
extern int find_pc_misc_function ();
/* C++ stuff. */
extern struct type *lookup_reference_type ();
extern struct type *lookup_member_type ();
extern struct type *lookup_class ();
/* end of C++ stuff. */
extern struct type *builtin_type_void;
extern struct type *builtin_type_char;
extern struct type *builtin_type_short;
@ -258,12 +202,6 @@ struct symtab_and_line
CORE_ADDR end;
};
struct symtabs_and_lines
{
struct symtab_and_line *sals;
int nelts;
};
/* Given a pc value, return line number it is in.
Second arg nonzero means if pc is on the boundary
use the previous statement's line number. */
@ -273,5 +211,5 @@ struct symtab_and_line find_pc_line ();
/* Given a string, return the line specified by it.
For commands like "list" and "breakpoint". */
struct symtabs_and_lines decode_line_spec ();
struct symtabs_and_lines decode_line_1 ();
struct symtab_and_line decode_line_spec ();
struct symtab_and_line decode_line_1 ();

13
gdb/test2.c Normal file
View File

@ -0,0 +1,13 @@
#include <sys/param.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <stdio.h>
main ()
{
struct user u;
printf ("&u.u_ar0 - &u = %d, 0%o\n", (int) &u.u_ar0 - (int) &u,
(int) &u.u_ar0 - (int) &u);
printf ("sizeof (struct pcb) = %d, 0%o\n",
sizeof (struct pcb), sizeof (struct pcb));
}

View File

@ -1,12 +0,0 @@
struct foo
{
unsigned bar : 1;
unsigned lose : 1;
};
main ()
{
struct foo *win;
printf ("%d, %d\n", win->bar, win->lose);
}

33
gdb/testbpt.c Normal file
View File

@ -0,0 +1,33 @@
/* Run this program straight. Then set a breakpoint in `dump',
run it again, and continue the program. Diff the outputs
and you will see what the supplied debugger does for a breakpoint. */
int dump ();
int after_dump ();
main ()
{
printf ("main = 0x%x\ndump = 0x%x\nend = 0x%x\n", main, dump, after_dump);
dump (main, after_dump);
}
int dump (p, q)
int *p;
int *q;
{
int cnt = 0;
printf ("dump: 0x%x-0x%x\n", p, q);
while (p < q)
{
if ((cnt++ & 3) == 0)
printf ("\n0x%08x: ", p);
printf ("0x%08x ", *p++);
}
printf ("\n");
}
after_dump ()
{
}

View File

@ -1,5 +0,0 @@
main()
{
printf("foo\n");
}

View File

@ -19,8 +19,13 @@ anyone else from sharing it farther. Help stamp out software hoarding!
*/
#include <stdio.h>
#include <signal.h>
#include <sys/ioctl.h>
#include "defs.h"
#include "param.h"
#ifdef HAVE_TERMIO
#include <termio.h>
#endif
void error ();
void fatal ();
@ -191,8 +196,16 @@ void
quit ()
{
fflush (stdout);
#ifdef HAVE_TERMIO
ioctl (fileno (stdout), TCFLSH, 1);
#else /* not HAVE_TERMIO */
ioctl (fileno (stdout), TIOCFLUSH, 0);
#endif /* not HAVE_TERMIO */
#ifdef TIOCGPGRP
error ("Quit");
#else
error ("Quit (expect signal %d when inferior is resumed)", SIGINT);
#endif /* TIOCGPGRP */
}
/* Control C comes here */
@ -386,10 +399,14 @@ parse_escape (string_ptr)
}
}
/* Print the character CH on STREAM as part of the contents
of a literal string whose delimiter is QUOTER. */
void
printchar (ch, stream)
printchar (ch, stream, quoter)
unsigned char ch;
FILE *stream;
int quoter;
{
register int c = ch;
if (c < 040 || c >= 0177)
@ -413,7 +430,7 @@ printchar (ch, stream)
}
else
{
if (c == '\\' || c == '"' || c == '\'')
if (c == '\\' || c == quoter)
fputc ('\\', stream);
fputc (c, stream);
}

View File

@ -107,162 +107,7 @@ value_subscript (array, idx)
{
return value_ind (value_add (array, idx));
}
/* Check to see if either argument is a structure. This is called so
we know whether to go ahead with the normal binop or look for a
user defined function instead */
int
binop_must_be_user_defined (arg1, arg2)
value arg1, arg2;
{
return (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT
|| TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_STRUCT
|| (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF
&& TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_STRUCT)
|| (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_REF
&& TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))) == TYPE_CODE_STRUCT));
}
/* Check to see if argument is a structure. This is called so
we know whether to go ahead with the normal unop or look for a
user defined function instead */
int unop_must_be_user_defined (arg1)
value arg1;
{
return (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRUCT
|| (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF
&& TYPE_CODE (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))) == TYPE_CODE_STRUCT));
}
/* We know either arg1 or arg2 is a structure, so try to find the right
user defined function. Create an argument vector that calls
arg1.operator @ (arg1,arg2) and return that value (where '@' is any
binary operator which is legal for GNU C++). */
value
value_x_binop (arg1, arg2, op, otherop)
value arg1, arg2;
int op, otherop;
{
value * argvec;
char *ptr;
char tstr[13];
COERCE_ENUM (arg1);
COERCE_ENUM (arg2);
/* now we know that what we have to do is construct our
arg vector and find the right function to call it with. */
if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)
error ("friend functions not implemented yet");
argvec = (value *) alloca (sizeof (value) * 4);
argvec[1] = value_addr (arg1);
argvec[2] = arg2;
argvec[3] = 0;
/* make the right function name up */
strcpy(tstr, "operator __");
ptr = tstr+9;
switch (op)
{
case BINOP_ADD: strcpy(ptr,"+"); break;
case BINOP_SUB: strcpy(ptr,"-"); break;
case BINOP_MUL: strcpy(ptr,"*"); break;
case BINOP_DIV: strcpy(ptr,"/"); break;
case BINOP_REM: strcpy(ptr,"%"); break;
case BINOP_LSH: strcpy(ptr,"<<"); break;
case BINOP_RSH: strcpy(ptr,">>"); break;
case BINOP_LOGAND: strcpy(ptr,"&"); break;
case BINOP_LOGIOR: strcpy(ptr,"|"); break;
case BINOP_LOGXOR: strcpy(ptr,"^"); break;
case BINOP_AND: strcpy(ptr,"&&"); break;
case BINOP_OR: strcpy(ptr,"||"); break;
case BINOP_MIN: strcpy(ptr,"<?"); break;
case BINOP_MAX: strcpy(ptr,">?"); break;
case BINOP_ASSIGN: strcpy(ptr,"="); break;
case BINOP_ASSIGN_MODIFY:
switch (otherop)
{
case BINOP_ADD: strcpy(ptr,"+="); break;
case BINOP_SUB: strcpy(ptr,"-="); break;
case BINOP_MUL: strcpy(ptr,"*="); break;
case BINOP_DIV: strcpy(ptr,"/="); break;
case BINOP_REM: strcpy(ptr,"%="); break;
case BINOP_LOGAND: strcpy(ptr,"&="); break;
case BINOP_LOGIOR: strcpy(ptr,"|="); break;
case BINOP_LOGXOR: strcpy(ptr,"^="); break;
default:
error ("Invalid binary operation specified.");
}
break;
case BINOP_SUBSCRIPT: strcpy(ptr,"[]"); break;
case BINOP_EQUAL: strcpy(ptr,"=="); break;
case BINOP_NOTEQUAL: strcpy(ptr,"!="); break;
case BINOP_LESS: strcpy(ptr,"<"); break;
case BINOP_GTR: strcpy(ptr,">"); break;
case BINOP_GEQ: strcpy(ptr,">="); break;
case BINOP_LEQ: strcpy(ptr,"<="); break;
default:
error ("Invalid binary operation specified.");
}
argvec[0] = value_struct_elt (arg1, argvec+1, tstr, "structure");
if (argvec[0])
return call_function (argvec[0], 2, argvec + 1);
else error ("member function %s not found", tstr);
}
/* We know that arg1 is a structure, so try to find a unary user
defined operator that matches the operator in question.
Create an argument vector that calls arg1.operator @ (arg1)
and return that value (where '@' is (almost) any unary operator which
is legal for GNU C++). */
value
value_x_unop (arg1, op)
value arg1;
int op;
{
value * argvec;
char *ptr;
char tstr[13];
COERCE_ENUM (arg1);
/* now we know that what we have to do is construct our
arg vector and find the right function to call it with. */
if (TYPE_CODE (VALUE_TYPE (arg1)) != TYPE_CODE_STRUCT)
error ("friend functions not implemented yet");
argvec = (value *) alloca (sizeof (value) * 3);
argvec[1] = value_addr (arg1);
argvec[2] = 0;
/* make the right function name up */
strcpy(tstr,"operator __");
ptr = tstr+9;
switch (op)
{
case UNOP_PREINCREMENT: strcpy(ptr,"++"); break;
case UNOP_PREDECREMENT: strcpy(ptr,"++"); break;
case UNOP_POSTINCREMENT: strcpy(ptr,"++"); break;
case UNOP_POSTDECREMENT: strcpy(ptr,"++"); break;
case UNOP_ZEROP: strcpy(ptr,"!"); break;
case UNOP_LOGNOT: strcpy(ptr,"~"); break;
case UNOP_NEG: strcpy(ptr,"-"); break;
default:
error ("Invalid binary operation specified.");
}
argvec[0] = value_struct_elt (arg1, argvec+1, tstr, "structure");
if (argvec[0])
return call_function (argvec[0], 1, argvec + 1);
else error ("member function %s not found", tstr);
}
/* Perform a binary operation on two integers or two floats.
Does not support addition and subtraction on pointers;
use value_add or value_sub if you want to handle those possibilities. */
@ -374,14 +219,6 @@ value_binop (arg1, arg2, op)
v = v1 || v2;
break;
case BINOP_MIN:
v = v1 < v2 ? v1 : v2;
break;
case BINOP_MAX:
v = v1 > v2 ? v1 : v2;
break;
default:
error ("Invalid binary operation on numbers.");
}

View File

@ -17,7 +17,7 @@ notice and this notice must be preserved on all copies.
In other words, go ahead and share GDB, but don't try to stop
anyone else from sharing it farther. Help stamp out software hoarding!
*/
#include "stdio.h"
#include "defs.h"
#include "initialize.h"
#include "param.h"
@ -60,9 +60,7 @@ value_cast (type, arg2)
return arg2;
}
else if (VALUE_LVAL (arg2) == lval_memory)
{
return value_at (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2));
}
return value_at (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2));
else
error ("Invalid cast.");
}
@ -280,9 +278,6 @@ value_ind (arg1)
{
COERCE_ARRAY (arg1);
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_MEMBER)
error ("not implemented: member types in value_ind");
/* Allow * on an integer so we can cast it to whatever we want. */
if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT)
return value_at (builtin_type_long,
@ -290,9 +285,6 @@ value_ind (arg1)
else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR)
return value_at (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)),
(CORE_ADDR) value_as_long (arg1));
else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF)
return value_at (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)),
(CORE_ADDR) value_as_long (arg1));
error ("Attempt to take contents of a non-pointer value.");
}
@ -419,14 +411,6 @@ call_function (function, nargs, args)
register struct type *ftype = VALUE_TYPE (function);
register enum type_code code = TYPE_CODE (ftype);
/* If it's a member function, just look at the function
part of it. */
if (code == TYPE_CODE_MEMBER)
{
ftype = TYPE_TARGET_TYPE (ftype);
code = TYPE_CODE (ftype);
}
/* Determine address to call. */
if (code == TYPE_CODE_FUNC)
{
@ -568,24 +552,16 @@ value_string (ptr, len)
/* Given ARG1, a value of type (pointer to a)* structure/union,
extract the component named NAME from the ultimate target structure/union
and return it as a value with its appropriate type.
ERR is used in the error message if ARG1's type is wrong.
C++: ARGS is a list of argument types to aid in the selection of
an appropriate method. Also, handle derived types.
ERR is an error message to be printed in case the field is not found. */
ERR is used in the error message if ARG1's type is wrong. */
value
value_struct_elt (arg1, args, name, err)
register value arg1, *args;
value_struct_elt (arg1, name, err)
register value arg1;
char *name;
char *err;
{
register struct type *t;
register int i;
int found = 0;
struct type *baseclass;
COERCE_ARRAY (arg1);
@ -593,428 +569,28 @@ value_struct_elt (arg1, args, name, err)
/* Follow pointers until we get to a non-pointer. */
while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
while (TYPE_CODE (t) == TYPE_CODE_PTR)
{
arg1 = value_ind (arg1);
COERCE_ARRAY (arg1);
t = VALUE_TYPE (arg1);
}
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
error ("not implemented: member type in value_struct_elt");
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION)
&&
TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Attempt to extract a component of a value that is not a %s.", err);
baseclass = t;
if (!args)
{
/* if there are no arguments ...do this... */
/* Try as a variable first, because if we succeed, there
is less work to be done. */
while (t)
{
for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--)
{
if (!strcmp (TYPE_FIELD_NAME (t, i), name))
{
found = 1;
break;
}
}
if (i >= 0)
return TYPE_FIELD_STATIC (t, i)
? value_static_field (t, name, i) : value_field (arg1, i);
t = TYPE_BASECLASS (t);
VALUE_TYPE (arg1) = t; /* side effect! */
}
/* C++: If it was not found as a data field, then try to
return it as a pointer to a method. */
t = baseclass;
VALUE_TYPE (arg1) = t; /* side effect! */
if (destructor_name_p (name, t))
error ("use `info method' command to print out value of destructor");
while (t)
{
for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
{
if (! strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name))
{
error ("use `info method' command to print value of method \"%s\"", name);
}
}
t = TYPE_BASECLASS (t);
}
if (found == 0)
error("there is no field named %s", name);
return 0;
}
if (destructor_name_p (name, t))
for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--)
{
if (!args[1])
{
/* destructors are a special case. */
return (value)value_fn_field (arg1, 0, TYPE_FN_FIELDLIST_LENGTH (t, 0));
}
else
{
error ("destructor should not have any argument");
}
if (!strcmp (TYPE_FIELD_NAME (t, i), name))
break;
}
/* This following loop is for methods with arguments. */
while (t)
{
/* Look up as method first, because that is where we
expect to find it first. */
for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; i--)
{
struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
if (i < 0)
error ("Structure has no component named %s.", name);
if (!strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name))
{
int j;
struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
found = 1;
for (j = TYPE_FN_FIELDLIST_LENGTH (t, i) - 1; j >= 0; --j)
{
if (!typecmp (TYPE_FN_FIELD_ARGS (f, j), args))
{
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
{
/* First, get the virtual function table pointer.
That comes with a strange type, so cast
it to type `pointer to long' (which
should serve just fine as a function type).
Then, index into the table, and convert
final value to appropriate function type. */
value vfn, vtbl;
value vi = value_from_long (builtin_type_int,
TYPE_FN_FIELD_VOFFSET (f, j));
VALUE_TYPE (arg1) = TYPE_VPTR_BASETYPE (t);
if (TYPE_VPTR_FIELDNO (t) < 0)
TYPE_VPTR_FIELDNO (t)
= fill_in_vptr_fieldno (t);
vtbl = value_field (arg1, TYPE_VPTR_FIELDNO (t));
vfn = value_subscript (vtbl, vi);
VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
return vfn;
}
else
return (value)value_fn_field (arg1, i, j);
}
}
}
}
t = TYPE_BASECLASS (t);
VALUE_TYPE (arg1) = t; /* side effect! */
}
if (found)
{
error ("Structure method %s not defined for arglist.", name);
return 0;
}
else
{
/* See if user tried to invoke data as function */
t = baseclass;
while (t)
{
for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--)
{
if (!strcmp (TYPE_FIELD_NAME (t, i), name))
{
found = 1;
break;
}
}
if (i >= 0)
return TYPE_FIELD_STATIC (t, i)
? value_static_field (t, name, i) : value_field (arg1, i);
t = TYPE_BASECLASS (t);
VALUE_TYPE (arg1) = t; /* side effect! */
}
error ("Structure has no component named %s.", name);
}
}
/* C++: return 1 is NAME is a legitimate name for the destructor
of type TYPE. If TYPE does not have a destructor, or
if NAME is inappropriate for TYPE, an error is signaled. */
int
destructor_name_p (name, type)
char *name;
struct type *type;
{
/* destructors are a special case. */
char *dname = TYPE_NAME (type);
if (name[0] == '~')
{
if (! TYPE_HAS_DESTRUCTOR (type))
error ("type `%s' does not have destructor defined",
TYPE_NAME (type));
/* Skip past the "struct " at the front. */
while (*dname++ != ' ') ;
if (strcmp (dname, name+1))
error ("destructor specification error");
else
return 1;
}
return 0;
}
/* C++: Given ARG1, a value of type (pointer to a)* structure/union,
return 1 if the component named NAME from the ultimate
target structure/union is defined, otherwise, return 0. */
int
check_field (arg1, name)
register value arg1;
char *name;
{
register struct type *t;
register int i;
int found = 0;
struct type *baseclass;
COERCE_ARRAY (arg1);
t = VALUE_TYPE (arg1);
/* Follow pointers until we get to a non-pointer. */
while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
{
arg1 = value_ind (arg1);
COERCE_ARRAY (arg1);
t = VALUE_TYPE (arg1);
}
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
error ("not implemented: member type in check_field");
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Internal error: `this' is not an aggregate");
baseclass = t;
while (t)
{
for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--)
{
if (!strcmp (TYPE_FIELD_NAME (t, i), name))
{
return 1;
}
}
t = TYPE_BASECLASS (t);
VALUE_TYPE (arg1) = t; /* side effect! */
}
/* C++: If it was not found as a data field, then try to
return it as a pointer to a method. */
t = baseclass;
VALUE_TYPE (arg1) = t; /* side effect! */
/* Destructors are a special case. */
if (destructor_name_p (name, t))
return 1;
while (t)
{
for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
{
if (!strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name))
return 1;
}
t = TYPE_BASECLASS (t);
}
return 0;
}
/* C++: Given an aggregate type DOMAIN, and a member name NAME,
return the address of this member as a pointer to member
type. If INTYPE is non-null, then it will be the type
of the member we are looking for. This will help us resolve
pointers to member functions. */
value
value_struct_elt_for_address (domain, intype, name)
struct type *domain, *intype;
char *name;
{
register struct type *t = domain;
register int i;
int found = 0;
value v;
struct type *baseclass;
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Internal error: non-aggregate type to value_struct_elt_for_address");
baseclass = t;
while (t)
{
for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--)
{
if (!strcmp (TYPE_FIELD_NAME (t, i), name))
{
if (TYPE_FIELD_PACKED (t, i))
error ("pointers to bitfield members not allowed");
v = value_from_long (builtin_type_int, TYPE_FIELD_BITPOS (t, i) >> 3);
VALUE_TYPE (v) = lookup_member_type (TYPE_FIELD_TYPE (t, i), baseclass);
return v;
}
}
t = TYPE_BASECLASS (t);
}
/* C++: If it was not found as a data field, then try to
return it as a pointer to a method. */
t = baseclass;
/* Destructors are a special case. */
if (destructor_name_p (name, t))
{
error ("pointers to destructors not implemented yet");
}
while (t)
{
for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
{
if (!strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name))
{
int j = TYPE_FN_FIELDLIST_LENGTH (t, i);
struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i);
if (intype == 0 && j > 1)
error ("non-unique member `%s' requires type instantiation", name);
if (intype)
{
while (j--)
if (TYPE_FN_FIELD_TYPE (f, j) == intype)
break;
if (j < 0)
error ("no member function matches that type instantiation");
}
else
j = 0;
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
{
v = value_from_long (builtin_type_long,
TYPE_FN_FIELD_VOFFSET (f, j));
}
else
{
struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),
0, VAR_NAMESPACE);
v = locate_var_value (s, 0);
}
VALUE_TYPE (v) = lookup_member_type (TYPE_FN_FIELD_TYPE (f, j), baseclass);
return v;
}
}
t = TYPE_BASECLASS (t);
}
return 0;
}
/* Compare two argument lists and return the position in which they differ,
or zero if equal. Note that we ignore the first argument, which is
the type of the instance variable. This is because we want to handle
derived classes. This is not entirely correct: we should actually
check to make sure that a requested operation is type secure,
shouldn't we? */
int typecmp(t1, t2)
struct type *t1[];
value t2[];
{
int i;
if (t1[0]->code == TYPE_CODE_VOID) return 0;
if (!t1[1]) return 0;
for (i = 1; t1[i] && t1[i]->code != TYPE_CODE_VOID; i++)
{
if (! t2[i]
|| t1[i]->code != t2[i]->type->code
|| t1[i]->target_type != t2[i]->type->target_type)
{
return i+1;
}
}
if (!t1[i]) return 0;
return t2[i] ? i+1 : 0;
}
#ifndef FRAME
#include "frame.h"
#endif
/* C++: return the value of the class instance variable, if one exists.
Flag COMPLAIN signals an error if the request is made in an
inappropriate context. */
value
value_of_this (complain)
int complain;
{
extern FRAME selected_frame;
struct symbol *func, *sym;
char *funname = 0;
struct block *b;
int i;
if (selected_frame == 0)
if (complain)
error ("no frame selected");
else return 0;
func = get_frame_function (selected_frame);
if (func)
funname = SYMBOL_NAME (func);
else
if (complain)
error ("no `this' in nameless context");
else return 0;
b = SYMBOL_BLOCK_VALUE (func);
i = BLOCK_NSYMS (b);
if (i <= 0)
if (complain)
error ("no args, no `this'");
else return 0;
sym = BLOCK_SYM (b, 0);
if (strncmp ("$this", SYMBOL_NAME (sym), 5))
if (complain)
error ("current stack frame not in method");
else return 0;
return read_var_value (sym, selected_frame);
return value_field (arg1, i);
}
static

View File

@ -1,5 +1,5 @@
/* Print values for GNU debugger gdb.
Copyright (C) 1986 Free Software Foundation, Inc.
Copyright (C) 1986, 1988 Free Software Foundation, Inc.
GDB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY. No author or distributor accepts responsibility to anyone
@ -21,6 +21,7 @@ anyone else from sharing it farther. Help stamp out software hoarding!
#include <stdio.h>
#include "defs.h"
#include "initialize.h"
#include "param.h"
#include "symtab.h"
#include "value.h"
@ -32,7 +33,6 @@ static int print_max;
static void type_print_varspec_suffix ();
static void type_print_varspec_prefix ();
static void type_print_base ();
static void type_print_method_args ();
START_FILE
@ -41,12 +41,14 @@ char **signed_type_table;
char **float_type_table;
/* Print the value VAL in C-ish syntax on stream STREAM.
FORMAT is a format-letter, or 0 for print in natural format of data type.
If the object printed is a string pointer, returns
the number of string bytes printed. */
value_print (val, stream)
value_print (val, stream, format)
value val;
FILE *stream;
char format;
{
register int i, n, typelen;
@ -60,14 +62,14 @@ value_print (val, stream)
typelen = TYPE_LENGTH (VALUE_TYPE (val));
fputc ('{', stream);
/* Print arrays of characters using string syntax. */
if (VALUE_TYPE (val) == builtin_type_char
|| VALUE_TYPE (val) == builtin_type_unsigned_char)
if (typelen == 1 && TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT
&& format == 0)
{
fputc ('"', stream);
for (i = 0; i < n && i < print_max; i++)
{
QUIT;
printchar (VALUE_CONTENTS (val)[i], stream);
printchar (VALUE_CONTENTS (val)[i], stream, '"');
}
if (i < n)
fprintf (stream, "...");
@ -80,7 +82,7 @@ value_print (val, stream)
if (i)
fprintf (stream, ", ");
val_print (VALUE_TYPE (val), VALUE_CONTENTS (val) + typelen * i,
VALUE_ADDRESS (val) + typelen * i, stream);
VALUE_ADDRESS (val) + typelen * i, stream, format);
}
if (i < n)
fprintf (stream, "...");
@ -89,10 +91,8 @@ value_print (val, stream)
}
else
{
/* If it is a pointer, indicate what it points to.
C++: if it is a member pointer, we will take care
of that when we print it. */
/* A simple (nonrepeated) value */
/* If it is a pointer, indicate what it points to. */
if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_PTR)
{
fprintf (stream, "(");
@ -100,24 +100,25 @@ value_print (val, stream)
fprintf (stream, ") ");
}
return val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
VALUE_ADDRESS (val), stream);
VALUE_ADDRESS (val), stream, format);
}
}
/* Print on STREAM data stored in debugger at address VALADDR
according to the format of type TYPE.
ADDRESS is the location in the inferior that the data
is supposed to have come from.
/* Print data of type TYPE located at VALADDR (within GDB),
which came from the inferior at address ADDRESS,
onto stdio stream STREAM according to FORMAT
(a letter or 0 for natural format).
If the data are a string pointer, returns the number of
sting characters printed. */
int
val_print (type, valaddr, address, stream)
val_print (type, valaddr, address, stream, format)
struct type *type;
char *valaddr;
CORE_ADDR address;
FILE *stream;
char format;
{
register int i;
int len;
@ -138,14 +139,14 @@ val_print (type, valaddr, address, stream)
len = TYPE_LENGTH (type) / eltlen;
fprintf (stream, "{");
/* For an array of chars, print with string syntax. */
if (elttype == builtin_type_char
|| elttype == builtin_type_unsigned_char)
if (eltlen == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT
&& format == 0)
{
fputc ('"', stream);
for (i = 0; i < len && i < print_max; i++)
{
QUIT;
printchar (valaddr[i], stream);
printchar (valaddr[i], stream, '"');
}
if (i < len)
fprintf (stream, "...");
@ -157,7 +158,7 @@ val_print (type, valaddr, address, stream)
{
if (i) fprintf (stream, ", ");
val_print (elttype, valaddr + i * eltlen,
0, stream);
0, stream, format);
}
if (i < len)
fprintf (stream, "...");
@ -168,208 +169,68 @@ val_print (type, valaddr, address, stream)
/* Array of unspecified length: treat like pointer. */
case TYPE_CODE_PTR:
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
if (format)
{
struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
struct type *target = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type));
struct fn_field *f;
int j, len2;
char *kind = "";
val = unpack_long (builtin_type_int, valaddr);
if (TYPE_CODE (target) == TYPE_CODE_FUNC)
{
if (val < 128)
{
len = TYPE_NFN_FIELDS (domain);
for (i = 0; i < len; i++)
{
f = TYPE_FN_FIELDLIST1 (domain, i);
len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
for (j = 0; j < len2; j++)
{
QUIT;
if (TYPE_FN_FIELD_VOFFSET (f, j) == val)
{
kind = "virtual";
goto common;
}
}
}
}
else
{
struct symbol *sym = find_pc_function (val);
if (sym == 0)
error ("invalid pointer to member function");
len = TYPE_NFN_FIELDS (domain);
for (i = 0; i < len; i++)
{
f = TYPE_FN_FIELDLIST1 (domain, i);
len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
for (j = 0; j < len2; j++)
{
QUIT;
if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
goto common;
}
}
}
common:
if (i < len)
{
fputc ('&', stream);
type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
fprintf (stream, kind);
if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
&& TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$')
type_print_method_args
(TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
TYPE_FN_FIELDLIST_NAME (domain, i), stream);
else
type_print_method_args
(TYPE_FN_FIELD_ARGS (f, j), "",
TYPE_FN_FIELDLIST_NAME (domain, i), stream);
break;
}
}
else
{
/* VAL is a byte offset into the structure type DOMAIN.
Find the name of the field for that offset and
print it. */
int extra = 0;
int bits = 0;
len = TYPE_NFIELDS (domain);
val <<= 3; /* @@ Make VAL into bit offset */
for (i = 0; i < len; i++)
{
int bitpos = TYPE_FIELD_BITPOS (domain, i);
QUIT;
if (val == bitpos)
break;
if (val < bitpos && i > 0)
{
int ptrsize = (TYPE_LENGTH (builtin_type_char) * TYPE_LENGTH (target));
/* Somehow pointing into a field. */
i -= 1;
extra = (val - TYPE_FIELD_BITPOS (domain, i));
if (extra & 0x3)
bits = 1;
else
extra >>= 3;
break;
}
}
if (i < len)
{
fputc ('&', stream);
type_print_base (domain, stream, 0, 0);
fprintf (stream, "::");
fprintf (stream, "%s", TYPE_FIELD_NAME (domain, i));
if (extra)
fprintf (stream, " + %d bytes", extra);
if (bits)
fprintf (stream, " (offset in bits)");
break;
}
}
fputc ('(', stream);
type_print (type, "", stream, -1);
fprintf (stream, ") %d", val >> 3);
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
else
fprintf (stream, "0x%x", * (int *) valaddr);
/* For a pointer to char or unsigned char,
also print the string pointed to, unless pointer is null. */
/* For an array of chars, print with string syntax. */
elttype = TYPE_TARGET_TYPE (type);
if (TYPE_LENGTH (elttype) == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT
&& format == 0
&& unpack_long (type, valaddr) != 0)
{
fprintf (stream, "0x%x", * (int *) valaddr);
/* For a pointer to char or unsigned char,
also print the string pointed to, unless pointer is null. */
if ((TYPE_TARGET_TYPE (type) == builtin_type_char
|| TYPE_TARGET_TYPE (type) == builtin_type_unsigned_char)
&& unpack_long (type, valaddr) != 0)
fputc (' ', stream);
fputc ('"', stream);
for (i = 0; i < print_max; i++)
{
fputc (' ', stream);
fputc ('"', stream);
for (i = 0; i < print_max; i++)
{
QUIT;
read_memory (unpack_long (type, valaddr) + i, &c, 1);
if (c == 0)
break;
printchar (c, stream);
}
fputc ('"', stream);
if (i == print_max)
fprintf (stream, "...");
fflush (stream);
/* Return number of characters printed, plus one for the
terminating null if we have "reached the end". */
return i + (i != print_max);
QUIT;
read_memory (unpack_long (type, valaddr) + i, &c, 1);
if (c == 0)
break;
printchar (c, stream, '"');
}
fputc ('"', stream);
if (i == print_max)
fprintf (stream, "...");
fflush (stream);
/* Return number of characters printed, plus one for the
terminating null if we have "reached the end". */
return i + (i != print_max);
}
break;
case TYPE_CODE_MEMBER:
error ("not implemented: member type in val_print");
break;
case TYPE_CODE_REF:
fprintf (stream, "(0x%x &) = ", * (int *) valaddr);
/* De-reference the reference. */
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF)
{
value val = value_at (TYPE_TARGET_TYPE (type), * (int *)valaddr);
val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
VALUE_ADDRESS (val), stream);
}
else
fprintf (stream, "???");
break;
case TYPE_CODE_STRUCT:
case TYPE_CODE_UNION:
fprintf (stream, "{");
len = TYPE_NFIELDS (type);
if (TYPE_BASECLASS (type))
{
i = 1;
fprintf (stream, "<%s> = ", TYPE_NAME (TYPE_BASECLASS (type)));
val_print (TYPE_FIELD_TYPE (type, 0),
valaddr + TYPE_FIELD_BITPOS (type, 0) / 8,
0, stream);
}
else i = 0;
for (; i < len; i++)
for (i = 0; i < len; i++)
{
if (i) fprintf (stream, ", ");
fprintf (stream, "%s = ", TYPE_FIELD_NAME (type, i));
/* check if static field */
if (TYPE_FIELD_STATIC (type, i))
{
value v;
v = value_static_field (type, TYPE_FIELD_NAME (type, i), i);
val_print (TYPE_FIELD_TYPE (type, i),
VALUE_CONTENTS (v), 0, stream);
}
else if (TYPE_FIELD_PACKED (type, i))
if (TYPE_FIELD_PACKED (type, i))
{
val = unpack_field_as_long (type, valaddr, i);
val_print (TYPE_FIELD_TYPE (type, i), &val, 0, stream);
val_print (TYPE_FIELD_TYPE (type, i), &val, 0, stream, format);
}
else
{
val_print (TYPE_FIELD_TYPE (type, i),
valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
0, stream);
}
val_print (TYPE_FIELD_TYPE (type, i),
valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
0, stream, format);
}
fprintf (stream, "}");
break;
case TYPE_CODE_ENUM:
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
len = TYPE_NFIELDS (type);
val = unpack_long (builtin_type_int, valaddr);
for (i = 0; i < len; i++)
@ -385,6 +246,11 @@ val_print (type, valaddr, address, stream)
break;
case TYPE_CODE_FUNC:
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
fprintf (stream, "{");
type_print (type, "", stream, -1);
fprintf (stream, "} ");
@ -392,19 +258,28 @@ val_print (type, valaddr, address, stream)
break;
case TYPE_CODE_INT:
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
fprintf (stream,
TYPE_UNSIGNED (type) ? "%u" : "%d",
unpack_long (type, valaddr));
if (type == builtin_type_char
|| type == builtin_type_unsigned_char)
if (TYPE_LENGTH (type) == 1)
{
fprintf (stream, " '");
printchar (unpack_long (type, valaddr), stream);
printchar (unpack_long (type, valaddr), stream, '\'');
fputc ('\'', stream);
}
break;
case TYPE_CODE_FLT:
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
#ifdef IEEE_FLOAT
if (is_nan (unpack_double (type, valaddr)))
{
@ -492,46 +367,13 @@ type_print_1 (type, varstring, stream, show, level)
((show > 0 || TYPE_NAME (type) == 0)
&&
(code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
|| code == TYPE_CODE_ARRAY
|| code == TYPE_CODE_MEMBER
|| code == TYPE_CODE_REF)))
|| code == TYPE_CODE_ARRAY)))
fprintf (stream, " ");
type_print_varspec_prefix (type, stream, show, 0);
fprintf (stream, "%s", varstring);
type_print_varspec_suffix (type, stream, show, 0);
}
/* Print the method arguments ARGS to the file STREAM. */
static void
type_print_method_args (args, prefix, varstring, stream)
struct type **args;
char *prefix, *varstring;
FILE *stream;
{
int i;
fprintf (stream, " %s%s (", prefix, varstring);
if (args[1] && args[1]->code != TYPE_CODE_VOID)
{
i = 1; /* skip the class variable */
while (1)
{
type_print (args[i++], "", stream, 0);
if (!args[i])
{
fprintf (stream, " ...");
break;
}
else if (args[i]->code != TYPE_CODE_VOID)
{
fprintf (stream, ", ");
}
else break;
}
}
fprintf (stream, ")");
}
/* Print any asterisks or open-parentheses needed before the
variable name (to describe its type).
@ -547,6 +389,9 @@ type_print_varspec_prefix (type, stream, show, passed_a_ptr)
int show;
int passed_a_ptr;
{
if (type == 0)
return;
if (TYPE_NAME (type) && show <= 0)
return;
@ -559,30 +404,12 @@ type_print_varspec_prefix (type, stream, show, passed_a_ptr)
fputc ('*', stream);
break;
case TYPE_CODE_MEMBER:
type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0,
passed_a_ptr);
fputc (' ', stream);
type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0,
passed_a_ptr);
fprintf (stream, "::");
break;
case TYPE_CODE_REF:
type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
fputc ('&', stream);
break;
case TYPE_CODE_FUNC:
type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0,
passed_a_ptr);
case TYPE_CODE_ARRAY:
type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
if (passed_a_ptr)
fputc ('(', stream);
break;
case TYPE_CODE_ARRAY:
type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0,
passed_a_ptr);
}
}
@ -597,6 +424,9 @@ type_print_varspec_suffix (type, stream, show, passed_a_ptr)
int show;
int passed_a_ptr;
{
if (type == 0)
return;
if (TYPE_NAME (type) && show <= 0)
return;
@ -605,8 +435,9 @@ type_print_varspec_suffix (type, stream, show, passed_a_ptr)
switch (TYPE_CODE (type))
{
case TYPE_CODE_ARRAY:
type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
passed_a_ptr);
type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0);
if (passed_a_ptr)
fprintf (stream, ")");
fprintf (stream, "[");
if (TYPE_LENGTH (type) >= 0)
fprintf (stream, "%d",
@ -614,20 +445,12 @@ type_print_varspec_suffix (type, stream, show, passed_a_ptr)
fprintf (stream, "]");
break;
case TYPE_CODE_MEMBER:
if (passed_a_ptr)
fputc (')', stream);
type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0);
break;
case TYPE_CODE_PTR:
case TYPE_CODE_REF:
type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1);
break;
case TYPE_CODE_FUNC:
type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
passed_a_ptr);
type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0);
if (passed_a_ptr)
fprintf (stream, ")");
fprintf (stream, "()");
@ -662,6 +485,12 @@ type_print_base (type, stream, show, level)
QUIT;
if (type == 0)
{
fprintf (stream, "type unknown");
return;
}
if (TYPE_NAME (type) && show <= 0)
{
fprintf (stream, TYPE_NAME (type));
@ -672,8 +501,6 @@ type_print_base (type, stream, show, level)
{
case TYPE_CODE_ARRAY:
case TYPE_CODE_PTR:
case TYPE_CODE_MEMBER:
case TYPE_CODE_REF:
case TYPE_CODE_FUNC:
type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
break;
@ -694,83 +521,46 @@ type_print_base (type, stream, show, level)
fprintf (stream, "{...}");
else
{
struct type *basetype, *dtype;
dtype = type;
basetype = TYPE_BASECLASS (type);
while (basetype)
{
if (TYPE_NAME (basetype) && (name = TYPE_NAME (basetype)))
{
while (*name != ' ') name++;
fprintf (stream, ": %s %s ",
TYPE_VIA_PUBLIC (dtype) ? "public" : "private",
name + 1);
}
dtype = basetype;
basetype = TYPE_BASECLASS (basetype);
}
fprintf (stream, "{");
len = TYPE_NFIELDS (type);
if (len) fprintf (stream, "\n");
else fprintf (stream, "<no data fields>\n");
/* If there is a base class for this type,
do not print the field that it occupies. */
for (i = !! TYPE_BASECLASS (type); i < len; i++)
fprintf (stream, "\n");
for (i = 0; i < len; i++)
{
QUIT;
/* Don't print out virtual function table. */
if (! strncmp (TYPE_FIELD_NAME (type, i),
"_vptr$", 6))
continue;
print_spaces (level + 4, stream);
if (TYPE_FIELD_STATIC (type, i))
/* If this is a bit-field and there is a gap before it,
print a nameless field to account for the gap. */
if (TYPE_FIELD_PACKED (type, i))
{
fprintf (stream, "static ");
int gap = (TYPE_FIELD_BITPOS (type, i)
- (i > 0
? (TYPE_FIELD_BITPOS (type, i - 1)
+ (TYPE_FIELD_PACKED (type, i - 1)
? TYPE_FIELD_BITSIZE (type, i - 1)
: TYPE_LENGTH (TYPE_FIELD_TYPE (type, i - 1)) * 8))
: 0));
if (gap != 0)
{
fprintf (stream, "int : %d;\n", gap);
print_spaces (level + 4, stream);
}
}
/* Print the declaration of this field. */
type_print_1 (TYPE_FIELD_TYPE (type, i),
TYPE_FIELD_NAME (type, i),
stream, show - 1, level + 4);
if (!TYPE_FIELD_STATIC (type, i)
&& TYPE_FIELD_PACKED (type, i))
{
/* ??? don't know what to put here ??? */;
}
/* Print the field width. */
if (TYPE_FIELD_PACKED (type, i))
fprintf (stream, " : %d", TYPE_FIELD_BITSIZE (type, i));
fprintf (stream, ";\n");
}
/* C++: print out the methods */
len = TYPE_NFN_FIELDS (type);
if (len) fprintf (stream, "\n");
for (i = 0; i < len; i++)
{
struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
for (j = 0; j < len2; j++)
{
QUIT;
print_spaces (level + 4, stream);
if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
fprintf (stream, "virtual ");
type_print (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j))), "", stream, 0);
if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
&& TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$')
type_print_method_args
(TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
TYPE_FN_FIELDLIST_NAME (type, i), stream);
else
type_print_method_args
(TYPE_FN_FIELD_ARGS (f, j), "",
TYPE_FN_FIELDLIST_NAME (type, i), stream);
fprintf (stream, ";\n");
}
if (len2) fprintf (stream, "\n");
}
print_spaces (level, stream);
fputc ('}', stream);
}

View File

@ -56,14 +56,10 @@ typedef struct value *value;
#define VALUE_REGNO(val) (val)->regno
/* If ARG is an array, convert it to a pointer.
If ARG is an enum, convert it to an integer.
References are dereferenced. */
If ARG is an enum, convert it to an integer. */
#define COERCE_ARRAY(arg) \
{ if (TYPE_CODE (arg) == TYPE_CODE_REF) \
arg = value_ind (arg); \
if (VALUE_REPEATED (arg) \
{ if (VALUE_REPEATED (arg) \
|| TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY) \
arg = value_coerce_array (arg); \
if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ENUM) \
@ -73,9 +69,7 @@ typedef struct value *value;
/* If ARG is an enum, convert it to an integer. */
#define COERCE_ENUM(arg) \
{ if (TYPE_CODE (arg) == TYPE_CODE_REF) \
arg = value_ind (arg); \
if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ENUM) \
{ if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ENUM) \
arg = value_cast (builtin_type_unsigned_int, arg); \
}
@ -114,7 +108,7 @@ value value_addr ();
value value_assign ();
value value_neg ();
value value_lognot ();
value value_struct_elt (), value_struct_elt_for_address ();
value value_struct_elt ();
value value_field ();
value value_cast ();
value value_repeat ();
@ -135,11 +129,3 @@ struct internalvar *lookup_internalvar ();
int value_equal ();
int value_less ();
int value_zerop ();
/* C++ */
value value_of_this ();
value value_static_field ();
value value_x_binop ();
value value_x_unop ();
int binop_must_be_user_defined ();
int unop_must_be_user_defined ();

View File

@ -286,7 +286,7 @@ history_info (num_exp)
{
val = access_value_history (i);
printf ("$%d = ", i);
value_print (val, stdout);
value_print (val, stdout, 0);
printf ("\n");
}
}
@ -330,6 +330,7 @@ value_of_internalvar (var)
register value val = value_copy (var->value);
VALUE_LVAL (val) = lval_internalvar;
VALUE_INTERNALVAR (val) = var;
return val;
}
void
@ -397,7 +398,7 @@ use \"set\" as in \"set $foo = 5\" to define them.\n");
for (var = internalvars; var; var = var->next)
{
printf ("$%s: ", var->name);
value_print (var->value, stdout);
value_print (var->value, stdout, 0);
printf ("\n");
}
}
@ -424,12 +425,7 @@ value_as_double (val)
/* Unpack raw data (copied from debugee) at VALADDR
as a long, or as a double, assuming the raw data is described
by type TYPE. Knows how to convert different sizes of values
and can convert between fixed and floating point.
C++: It is assumed that the front-end has taken care of
all matters concerning pointers to members. A pointer
to member which reaches here is considered to be equivalent
to an INT (or some size). After all, it is only an offset. */
and can convert between fixed and floating point. */
long
unpack_long (type, valaddr)
@ -478,14 +474,11 @@ unpack_long (type, valaddr)
if (len == sizeof (long))
return * (long *) valaddr;
}
else if (code == TYPE_CODE_PTR
|| code == TYPE_CODE_REF)
else if (code == TYPE_CODE_PTR)
{
if (len == sizeof (char *))
return (CORE_ADDR) * (char **) valaddr;
}
else if (code == TYPE_CODE_MEMBER)
error ("not impelmented: member types in unpack_long");
error ("Value not integer or pointer.");
}
@ -508,7 +501,13 @@ unpack_double (type, valaddr)
return * (float *) valaddr;
if (len == sizeof (double))
return * (double *) valaddr;
{
/* Some machines require doubleword alignment for doubles.
This code works on them, and on other machines. */
double temp;
bcopy ((char *) valaddr, (char *) &temp, sizeof (double));
return temp;
}
}
else if (code == TYPE_CODE_INT && nosign)
{
@ -544,9 +543,7 @@ unpack_double (type, valaddr)
/* Given a value ARG1 of a struct or union type,
extract and return the value of one of its fields.
FIELDNO says which field.
For C++, must also be able to return values from static fields */
FIELDNO says which field. */
value
value_field (arg1, fieldno)
@ -584,96 +581,6 @@ value_field (arg1, fieldno)
return v;
}
value
value_fn_field (arg1, fieldno, subfieldno)
register value arg1;
register int fieldno;
{
register value v;
struct fn_field *f = TYPE_FN_FIELDLIST1 (VALUE_TYPE (arg1), fieldno);
register struct type *type = TYPE_FN_FIELD_TYPE (f, subfieldno);
struct symbol *sym;
sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, subfieldno),
0, VAR_NAMESPACE);
if (! sym) error ("Internal error: could not find physical method named %s",
TYPE_FN_FIELD_PHYSNAME (f, subfieldno));
v = allocate_value (type);
VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
VALUE_TYPE (v) = type;
return v;
}
/* The value of a static class member does not depend
on its instance, only on its type. If FIELDNO >= 0,
then fieldno is a valid field number and is used directly.
Otherwise, FIELDNAME is the name of the field we are
searching for. If it is not a static field name, an
error is signaled. TYPE is the type in which we look for the
static field member. */
value
value_static_field (type, fieldname, fieldno)
register struct type *type;
char *fieldname;
register int fieldno;
{
register value v;
struct symbol *sym;
if (fieldno < 0)
{
register struct type *t = type;
/* Look for static field. */
while (t)
{
int i;
for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--)
if (! strcmp (TYPE_FIELD_NAME (t, i), fieldname))
{
if (TYPE_FIELD_STATIC (t, i))
{
fieldno = i;
goto found;
}
else
error ("field `%s' is not static");
}
t = TYPE_BASECLASS (t);
}
t = type;
if (destructor_name_p (fieldname, t))
error ("use `info method' command to print out value of destructor");
while (t)
{
int i, j;
for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; i--)
{
if (! strcmp (TYPE_FN_FIELDLIST_NAME (t, i), fieldname))
{
error ("use `info method' command to print value of method \"%s\"", fieldname);
}
}
t = TYPE_BASECLASS (t);
}
error("there is no field named %s", fieldname);
}
found:
sym = lookup_symbol (TYPE_FIELD_STATIC_PHYSNAME (type, fieldno),
0, VAR_NAMESPACE);
if (! sym) error ("Internal error: could not find physical static variable named %s", TYPE_FIELD_BITSIZE (type, fieldno));
type = TYPE_FIELD_TYPE (type, fieldno);
v = value_at (type, (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
return v;
}
long
unpack_field_as_long (type, valaddr, fieldno)
struct type *type;

View File

@ -23,7 +23,7 @@ anyone else from sharing it farther. Help stamp out software hoarding!
#include "defs.h"
#include "param.h"
#include "symtab.h"
#include "vax-opcode.h"
#include "opcode.h"
/* Vax instructions are never longer than this. */
#define MAXLEN 62

View File

@ -1,3 +1,3 @@
/* Define the current version number of GDB. */
char *version = "2.5.3 (GNU C++ 1.22.0 compatible)";
char *version = "2.8";

View File

@ -12,6 +12,7 @@
#define WSTOPSIG(w) ((w) >> 8)
#define WCOREDUMP(w) (((w)&0200) != 0)
#define WTERMSIG(w) ((w) & 0177)
#define WSETEXIT(w, status) ((w) = (status))
#define WSETSTOP(w,sig) ((w) = (0177 | ((sig) << 8)))
#else
#include <sys/wait.h>
@ -20,6 +21,7 @@
#define WSTOPSIG(w) (w).w_stopsig
#define WCOREDUMP(w) (w).w_coredump
#define WTERMSIG(w) (w).w_termsig
#define WSETEXIT(w, status) ((w).w_status = (status))
#define WSETSTOP(w,sig) \
((w).stopsig = (sig), (w).coredump = 0, (w).termsig = 0177)
((w).w_stopsig = (sig), (w).w_coredump = 0, (w).w_termsig = 0177)
#endif

View File

@ -26,16 +26,13 @@ anyone else from sharing it farther. Help stamp out software hoarding!
#include "symtab.h"
#include "frame.h"
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <X11/Xresource.h>
#include <X11/Atoms.h>
#include <X11/TopLevel.h>
#include <X11/VPane.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Label.h>
#include <X11/Text.h>
#include <X11/Command.h>
#include <X11/ButtonBox.h>
#include <X11/TextP.h>
#include <X11/Box.h>
#include <X11/VPaned.h>
#include <stdio.h>
@ -63,21 +60,27 @@ static short gdb_mask_bits[] = {
/* The X display on which the window appears. */
Display *screen_display;
/* The graphics context. */
GC default_gc;
static Display *screen_display;
/* Windows manipulated by this package. */
static Window icon_window;
static Widget main_widget;
static Widget containing_widget;
static Widget title_widget;
static Widget source_name_widget;
static Widget source_text_widget;
static Widget exec_name_widget;
static Widget button_box_widget;
#ifdef VTFD
/* Interaction Window */
static Widget interactive_widget;
XtTextSource PseudoDiskSourceCreate();
XtTextSource TSource;
static int vtfd[2], vifd[2];
#endif
/* Source text display. */
static struct symtab *source_window_symtab = 0;
@ -88,14 +91,27 @@ static Widget create_text_widget ();
START_FILE
/* Return number of text lines displayed in text widget W. */
int /* was XtTextPosition */
XtTextLines (w)
Widget w;
{
TextWidget ctx = (TextWidget)w;
return ctx->text.lt.lines;
}
/* Display an appropriate piece of source code in the source window. */
xgdb_display_source ()
{
char *filename;
static Arg labelArgs[1];
Arg args[1];
Arg labelArgs[1];
int linenumbers_changed = 0;
static int new = 1;
int must_scroll = 0;
int height = XtTextLines (source_text_widget);
struct symtab_and_line get_selected_frame_sal ();
struct symtab_and_line sal;
@ -132,12 +148,18 @@ xgdb_display_source ()
if (linenumbers_changed || source_window_symtab != sal.symtab)
{
static Arg fileArgs[1];
new = 1;
Arg fileArgs[1];
XtTextSource src;
must_scroll = 1;
source_window_symtab = sal.symtab;
src = XtTextGetSource (source_text_widget);
XtDiskSourceDestroy (src);
XtSetArg (fileArgs[0], XtNfile, filename);
XtSetValues (source_text_widget, fileArgs, XtNumber (fileArgs));
src = XtDiskSourceCreate (source_text_widget->core.parent, fileArgs, 1);
XtTextSetSource (source_text_widget, src, 0);
XtSetArg (labelArgs[0], XtNlabel,
filename ? filename : "No source displayed.");
@ -148,46 +170,38 @@ xgdb_display_source ()
/* Update display and cursor positions as necessary.
Cursor should be placed on line sal.line. */
{
static int top_line_number, bottom_line_number;
int current_top;
Arg textArgs[1];
/* Find out where the display is positioned (in case user scrolled it). */
if (! new)
{
int new_top;
if (! must_scroll)
{
int top_line_number;
/* Get positions of start of display, and caret */
XtSetArg (textArgs[0], XtNdisplayPosition, NULL);
XtGetValues (source_text_widget, textArgs, XtNumber (textArgs));
new_top = source_charpos_line (source_window_symtab,
(int) textArgs[0].value);
bottom_line_number += new_top - top_line_number;
top_line_number = new_top;
}
XtSetArg (args[0], XtNdisplayPosition, NULL);
XtGetValues (source_text_widget, args, 1);
top_line_number = source_charpos_line (source_window_symtab,
(int) args[0].value);
/* If desired position is off screen, we must scroll. */
if (sal.line < top_line_number
|| sal.line >= top_line_number + height)
must_scroll = 1;
}
/* If appropriate, scroll the text display. */
if (sal.line < top_line_number
|| sal.line > bottom_line_number
|| new)
{
/* yes, these magic numbers are ugly, but I don't know how
* to get the height of a text widget in a V11-portable way
*/
top_line_number = (sal.line > 15) ? sal.line - 15 : 0;
bottom_line_number = top_line_number + 35;
XtSetArg (textArgs[0], XtNdisplayPosition,
source_line_charpos (source_window_symtab, top_line_number));
XtSetValues (source_text_widget, textArgs, XtNumber (textArgs));
}
/* If appropriate, scroll the text display. */
/* Set the text display cursor position within the text. */
if (must_scroll)
{
int top_line_number = (sal.line > height/3) ? sal.line - height/3 : 1;
XtSetArg (textArgs[0], XtNinsertPosition,
source_line_charpos (source_window_symtab, sal.line));
XtSetValues (source_text_widget, textArgs, XtNumber (textArgs));
}
XtSetArg (args[0], XtNdisplayPosition,
source_line_charpos (source_window_symtab, top_line_number));
XtSetValues (source_text_widget, args, 1);
}
/* Set the text display cursor position within the text. */
XtSetArg (args[0], XtNinsertPosition,
source_line_charpos (source_window_symtab, sal.line));
XtSetValues (source_text_widget, args, 1);
}
/* Display FILENAME in the title bar at bottom of window. */
@ -209,7 +223,10 @@ static void
print_prompt ()
{
if (prompt_string)
printf ("%s", prompt_string);
{
printf ("%s", prompt_string);
fflush (stdout);
}
}
/* Handlers for buttons. */
@ -219,16 +236,17 @@ print_prompt ()
Get the "selection" from X and use it as the operand of a print command. */
static void
print_1 (starflag)
print_button (w, starflag, call_data)
Widget w;
int starflag;
caddr_t call_data;
{
int selected_length;
char *selected_text;
char *cmd = starflag ? "print * " : "print ";
register int cmdlen = strlen (cmd);
selected_text = XFetchBytes (&selected_length);
selected_text = XFetchBytes (screen_display, &selected_length);
if (selected_length)
{
char *line = xmalloc (cmdlen + selected_length + 1);
@ -245,29 +263,20 @@ print_1 (starflag)
print_prompt ();
}
static void
print_button ()
{
print_1 (0);
}
static void
print_star_button ()
{
print_1 (1);
}
/* Subroutine used by "stop at" and "go till" buttons.
Set a breakpoint at the position indicated by the "selection"
in the source window, and, if RUNFLAG is nonzero, continue. */
static void
breakpoint_button_1 (runflag)
breakpoint_button (w, runflag, call_data)
Widget w;
int runflag;
caddr_t call_data;
{
XtTextPosition start, finish;
XtTextGetSelectionPos (screen_display, source_text_widget, &start, &finish);
XtTextGetSelectionPos (source_text_widget, &start, &finish);
if (!source_window_symtab)
printf ("No source file displayed.\n");
else
@ -284,18 +293,6 @@ breakpoint_button_1 (runflag)
print_prompt ();
}
static void
breakpoint_button ()
{
breakpoint_button_1 (0);
}
static void
until_button ()
{
breakpoint_button_1 (1);
}
/* decide if a character is trash */
static int
garbage (c)
@ -342,92 +339,50 @@ explicit_breakpoint_button ()
print_prompt ();
}
/* Various trivial buttons,
most of which just run one GDB command with no arg. */
/* Handle a button by running the command COMMAND. */
static void
next_button ()
do_command (w, command, call_data)
Widget w;
char *command;
caddr_t call_data;
{
execute_command ("next", 0);
execute_command (command, 0);
xgdb_display_source ();
print_prompt ();
}
static void
step_button ()
redisplay_button()
{
execute_command ("step", 0);
xgdb_display_source ();
print_prompt ();
}
static void
cont_button ()
{
execute_command ("cont", 0);
xgdb_display_source ();
print_prompt ();
}
static void
finish_button ()
{
execute_command ("finish", 0);
xgdb_display_source ();
print_prompt ();
}
#if 0
static void
deiconify_button ()
{
XUnmapWindow (screen_display, icon_window);
XMapWindow (screen_display, containing_widget);
}
static void
iconify_button ()
{
#if 0
static Arg iconArgs[1];
XtSetArg (iconArgs[0], XtNlabel, prompt_string);
XtCommandSetValues (icon_window, iconArgs, XtNumber (iconArgs));
#endif 0
XUnmapWindow (screen_display, containing_widget);
XMapWindow (screen_display, icon_window);
}
#endif 0
static void
up_button ()
{
execute_command ("up", 0);
xgdb_display_source ();
print_prompt ();
}
static void
down_button ()
{
execute_command ("down", 0);
xgdb_display_source ();
print_prompt ();
xgdb_display_source();
}
/* Define and display all the buttons. */
static void
addbutton (parent, name, function)
addbutton (parent, name, function, closure)
Widget parent;
char *name;
void (*function) ();
caddr_t closure;
{
static Arg commandArgs[2];
static XtCallbackRec Callback[] =
{
{NULL, (caddr_t)NULL},
{NULL, (caddr_t)NULL},
};
static Arg commandArgs[] =
{
{XtNlabel, (XtArgVal)NULL},
{XtNcallback, (XtArgVal)Callback},
};
XtSetArg (commandArgs[0], XtNlabel, name);
XtSetArg (commandArgs[1], XtNfunction, function);
XtCreateWidget (name, commandWidgetClass, parent,
commandArgs, XtNumber (commandArgs));
Callback[0].callback = (XtCallbackProc)function;
Callback[0].closure = (caddr_t)closure;
commandArgs[0].value = (XtArgVal)name;
XtCreateManagedWidget (name, commandWidgetClass, parent,
commandArgs, XtNumber(commandArgs));
}
/* Create the button windows and store them in `buttons'. */
@ -436,22 +391,25 @@ static void
create_buttons (parent)
Widget parent;
{
addbutton (parent, "Brk At", breakpoint_button);
addbutton (parent, "Brk In", explicit_breakpoint_button);
addbutton (parent, "Go 'til", until_button);
addbutton (parent, "run", do_command, "run");
addbutton (parent, "quit", do_command, "quit");
addbutton (parent, "Print", print_button);
addbutton (parent, "Print*", print_star_button);
addbutton (parent, "break in", explicit_breakpoint_button, NULL);
addbutton (parent, "break at", breakpoint_button, 0);
addbutton (parent, "go until", breakpoint_button, 1);
addbutton (parent, "Next", next_button);
addbutton (parent, "Step", step_button);
addbutton (parent, "Cont", cont_button);
addbutton (parent, "Finish", finish_button);
addbutton (parent, "print", print_button, 0);
addbutton (parent, "print*", print_button, 1);
addbutton (parent, "next", do_command, "next");
addbutton (parent, "step", do_command, "step");
addbutton (parent, "cont", do_command, "cont");
addbutton (parent, "finish", do_command, "finish");
addbutton (parent, "Up", up_button);
addbutton (parent, "Down", down_button);
addbutton (parent, "up", do_command, "up");
addbutton (parent, "down", do_command, "down");
/* addbutton (parent, "Iconify", iconify_button); */
addbutton (parent, "redisplay", redisplay_button, NULL);
}
/* Create a "label window" that just displays the string LABEL. */
@ -460,12 +418,16 @@ static Widget
create_label (name, label)
char *name, *label;
{
static Arg labelArgs[2];
Arg labelArgs[2];
Widget w;
XtSetArg (labelArgs[0], XtNname, name);
XtSetArg (labelArgs[1], XtNlabel, label);
return XtCreateWidget ("label1", labelWidgetClass, containing_widget,
labelArgs, XtNumber (labelArgs));
w = XtCreateManagedWidget ("label", labelWidgetClass, containing_widget,
labelArgs, XtNumber (labelArgs));
XtPanedSetMinMax (w, w->core.height, w->core.height);
return w;
}
/* Create a subwindow of PARENT that displays and scrolls the contents
@ -473,143 +435,138 @@ create_label (name, label)
static Widget
create_text_widget (parent, filename)
Window parent;
Widget parent;
char *filename;
{
static Arg fileArgs[2];
static Arg fileArgs[3];
XtTextSource src;
XtTextSink sink;
XtSetArg (fileArgs[0], XtNfile, filename);
XtSetArg (fileArgs[1], XtNtextOptions, scrollVertical);
return XtTextDiskCreate (parent, fileArgs, XtNumber (fileArgs));
src = XtDiskSourceCreate(parent, fileArgs, 1);
sink = XtAsciiSinkCreate(parent, NULL, 0);
XtSetArg (fileArgs[0], XtNtextOptions, scrollVertical);
XtSetArg (fileArgs[1], XtNtextSource, src);
XtSetArg (fileArgs[2], XtNtextSink, sink);
return XtCreateManagedWidget ("disk", textWidgetClass, parent,
fileArgs, XtNumber (fileArgs));
#if 0 /* This is tucker's method. */
/* Create an empty source-display window and add to containing_widget */
XtSetArg (argl[0], XtNfile, "/dev/null");
XtSetArg (argl[1], XtNtextOptions, scrollVertical);
XtSetArg (argl[2], XtNheight, (XtArgVal)sheight);
source_text_widget = XtCreateManagedWidget (NULL, asciiDiskWidgetClass,
containing_widget, argl,
XtNumber (argl));
/* Create NULL disk source */
XtSetArg (argl[0], XtNfile, "/dev/null");
NullSource = XtDiskSourceCreate (source_text_widget, argl, ONE);
#endif
}
/* Entry point to create the widgets representing our display. */
/* window manager argument parsing */
extern int *win_argc;
extern char **win_argv;
/* Entry point to create the widgets representing our display. */
int
xgdb_create_window ()
{
static Arg frameArgs[]= {
{XtNwidth, (XtArgVal) 600},
{XtNheight, (XtArgVal) 700},
};
int width, height;
int sheight;
Arg argl[3];
XrmResourceDataBase db;
FILE *rdb_file;
XGCValues dummy;
/* Init and database stuff. */
screen_display = XOpenDisplay (NULL);
if (screen_display == 0)
{
fprintf (stderr, "Cannot connect to X server");
return 0;
}
/* initialize toolkit, setup defaults */
main_widget = XtInitialize ("gdb", "gdb", NULL, 0, win_argc, win_argv);
screen_display = XtDisplay (main_widget);
/* Find out what size the user specified. */
XtSetArg (argl[0], XtNwidth, (XtArgVal)&width);
XtSetArg (argl[1], XtNheight, (XtArgVal)&height);
XtGetValues (main_widget, argl, XtNumber(argl));
/* If none specified, set a default size. */
if (!width || !height)
{
width = 500, height = 700;
XtSetArg (argl[0], XtNwidth, (XtArgVal)width);
XtSetArg (argl[1], XtNheight, (XtArgVal)height);
XtSetValues (main_widget, argl, XtNumber(argl));
}
sheight = (float)height / 2.5;
/* Create the (toplevel) main_widget */
XtSetArg (argl[0], XtNwidth, (XtArgVal)width);
XtSetArg (argl[1], XtNheight, (XtArgVal)height);
containing_widget
= XtCreateManagedWidget ("vpaned", vPanedWidgetClass,
main_widget, argl, XtNumber (argl));
XtPanedSetRefigureMode (containing_widget, FALSE);
/* Create title */
{
char *dummy1[1];
dummy1[0] = 0;
XtInitialize ("gdb", "gdb", 0, 0, 0, dummy1);
char buf[200];
extern char *version;
sprintf (buf, "GDB %s", version);
title_widget =
create_label ("Title", buf);
}
/* should be checking .Xdefaults in $HOME */
rdb_file = fopen (".Xresources", "r");
if (rdb_file != NULL)
{
XrmGetDataBase (rdb_file, &db);
XrmSetCurrentDataBase (db);
fclose (rdb_file);
}
/* Create the containing_widget. */
/* Create exec file name window and add */
exec_name_widget =
create_label ("Executable", "No executable specified");
containing_widget = XtCreateWidget ("frame", vPaneWidgetClass, 0,
frameArgs, XtNumber (frameArgs));
default_gc = XCreateGC (screen_display, containing_widget, 0, dummy);
/* Create window full of buttons. */
button_box_widget = XtCreateManagedWidget ("buttons", boxWidgetClass,
containing_widget, NULL, 0);
create_buttons (button_box_widget);
/* Create source file name window and add to containing_widget */
source_name_widget
= create_label ("Source File", "No source file yet.");
source_name_widget =
create_label ("Source File", "No source file yet.");
/* Create an empty source-display window and add to containing_widget */
source_text_widget = create_text_widget (containing_widget, "/dev/null");
/* Create window full of buttons. */
button_box_widget = XtCreateWidget ("Buttons", buttonBoxWidgetClass,
containing_widget, NULL, 0);
create_buttons (button_box_widget);
/* Create exec file name window and add */
exec_name_widget = create_label ("Executable", "No executable specified.");
#if 0
/* Create icon window. */
#ifdef VFTD
/* Create Fake Text source */
{
static Arg iconArgs[2];
void (*compiler_bug) () = deiconify_button;
XtSetArg (iconArgs[0], XtNlabel, "(gdb)");
XtSetArg (iconArgs[1], XtNfunction, compiler_bug);
icon_window = XtCommandCreate (DefaultRootWindow (screen_display),
iconArgs, XtNumber (iconArgs));
XMoveWindow (screen_display, icon_window, 100, 100); /* HACK */
#if 0
XSetIconWindow (screen_display, containing_widget, icon_window);
#endif 0
extern XtTextSource TCreateApAsSource();
TSource = TCreateApAsSource();
}
#endif 0
/* Create interactive box */
XtSetArg (argl[0], XtNtextSource, (XtArgVal)TSource);
XtSetArg (argl[1], XtNtextSink,
(XtArgVal)XtAsciiSinkCreate(containing_widget, NULL, 0));
XtSetArg (argl[2], XtNtextOptions,
(XtArgVal)(scrollVertical | wordBreak));
interactive_widget = XtCreateManagedWidget ("gdbWindow", textWidgetClass,
containing_widget, argl, THREE);
#endif
/* Put them one screen */
XtPanedSetRefigureMode(containing_widget, TRUE);
XtRealizeWidget (main_widget);
/* Define GDB cursor */
#if 0
/* Now make the whole thing appear on the display. */
{
Pixmap pm1, pm2;
XImage image;
Cursor curse;
XDefineCursor (screen_display, XtWindow (main_widget),
XCreateFontCursor (screen_display, XC_circle));
#endif
image.width = gdb_width;
image.height = gdb_height;
image.xoffset = 0;
image.format = XYBitmap;
image.byte_order = LSBFirst;
image.bitmap_unit = 16;
image.bitmap_bit_order = LSBFirst;
image.depth = 1;
image.bytes_per_line = 2;
image.bits_per_pixel = 1;
pm1 = XCreatePixmap (screen_display, DefaultScreen (screen_display),
gdb_width, gdb_height, 1);
pm2 = XCreatePixmap (screen_display, DefaultScreen (screen_display),
gdb_width, gdb_height, 1);
image.data = (char *) gdb_bits;
XPutImage (screen_display, pm1, default_gc, &image, 0, 0, 0, 0,
gdb_width, gdb_height);
image.data = (char *) gdb_mask_bits;
XPutImage (screen_display, pm2, default_gc, &image, 0, 0, 0, 0,
gdb_width, gdb_height);
curse = XCreatePixmapCursor (screen_display, pm1, pm2,
BlackPixel (screen_display,
DefaultScreen (screen_display)),
WhitePixel (screen_display,
DefaultScreen (screen_display)),
gdb_x_hot, gdb_y_hot);
XFreePixmap (screen_display, pm1);
XFreePixmap (screen_display, pm2);
XDefineCursor (screen_display, containing_widget, curse);
XDefineCursor (screen_display, icon_window, curse);
}
#endif 0
XtRealizeWidget (containing_widget);
XFlush (screen_display);
return 1;
}
#define MAX_XGDB_READ 128
/* xgdb_dispatch -- Loop, dispatching on window events,
until data is available on FP (which is normally stdin).
Then return, so the data on FP can be processed. */
@ -624,13 +581,20 @@ xgdb_dispatch (fp)
int nfds;
XEvent ev;
int pend;
int nread;
char buf[1024];
int ipmask;
#ifdef VTFD
ipmask = 1 << vtfd[0];
#endif
while (! (rfds & inmask))
{
pend = XPending ();
pend = XPending (screen_display);
if (!pend)
{
rfds = inmask | xmask;
rfds = inmask | xmask | ipmask;
/* this isn't right for 4.3 but it works 'cuz of 4.2 compatibility */
nfds = select (32, &rfds, 0, 0, (struct timeval *) 0);
}
@ -639,9 +603,132 @@ xgdb_dispatch (fp)
XNextEvent (screen_display, &ev);
XtDispatchEvent (&ev);
}
#ifdef VTFD
/* Handle I/O through the command window. */
if (pend == 0 && (rfds & ipmask))
{
nread = read (vtfd[0], buf, sizeof(buf));
xgdb_write (buf, nread);
}
nread = xgdb_read (buf, MAX_XGDB_READ);
if (pend == 0 && nread > 0)
{
write (vifd[1], buf, nread);
}
#endif
}
}
#ifdef VTFD
static int output_size;
static int used_size;
static char *output_string;
static void
xgdb_init_text ()
{
Arg args[2];
output_size = 1000;
output_string = (char *) xmalloc (output_size);
used_size = 0;
XtSetArg (args[0], XtNstring, (XtArgVal) output_string);
XtSetArg (args[1], XtNlength, (XtArgVal) output_size);
TSource
= XtStringSourceCreate (toplevel, args, 2);
XtSetArg (args[0], XtNtextSource, TSource);
XtSetValues (interaction_widget, Args, 1);
}
static void
xgdb_grow_text (size)
int size;
{
if (output_size < used_size + size + 200)
{
Arg args[2];
XtStringSourceDestroy (TSource);
output_size = (used_size + size + 1010 + 512) / 1010 * 1010;
output_string = xrealloc (output_string, output_size);
XtSetArg (args[0], XtNstring, (XtArgVal) output_string);
XtSetArg (args[1], XtNlength, (XtArgVal) output_size);
TSource
= XtStringSourceCreate (toplevel, args, 2);
XtSetArg (args[0], XtNtextSource, TSource);
XtSetValues (interaction_widget, Args, 1);
}
}
/*VARARGS*/
xgdb_printf (fmt, arg1, arg2, arg3, arg4)
char *fmt;
{
char buf[1024];
XtTextBlock text;
XtTextPosition pos;
/* ??? This will crash on the wrong data. */
pos = (*TSource->Scan)(TSource, 0, XtstAll, XtsdRight, 1, 0);
sprintf (buf, fmt, arg1, arg2, arg3, arg4);
text.length = strlen (buf);
text.ptr = buf;
xgdb_grow_text (text.length);
used_size += text.length;
XtTextReplace (interactive_widget, pos, pos, &text);
XtTextSetInsertionPoint (interactive_widget, pos + text.length);
XFlush (screen_display);
}
int
xgdb_write (buf, len)
char *buf;
int len;
{
XtTextBlock text;
XtTextPosition pos;
pos = (*TSource->Scan)(TSource, 0, XtstAll, XtsdRight, 1, 0);
text.length = len;
text.ptr = buf;
xgdb_grow_text (text.length);
used_size += text.length;
XtTextReplace (interactive_widget, pos, pos, &text);
XtTextSetInsertionPoint (interactive_widget, pos + text.length);
XFlush (screen_display);
}
int
xgdb_read (buf, maxlen)
char *buf;
int maxlen;
{
XtTextBlock text;
XtTextPosition endpos;
int length = 0;
xgdb_grow_text (maxlen);
endpos = XtTextGetInsertionPoint (interactive_widget);
length = endpos - used_size;
if (length > 0)
{
(*TSource->Read) (TSource, lastpos, &text, maxlen - 10);
length = text.length;
strncpy(buf, text.ptr, length);
buf[length] = NULL;
used_size += length;
}
return length;
}
#endif /* VTFD */
/* If we use an X window, the GDB command loop is told to call this function
before reading a command from stdin.
PROMPT is saved for later use so buttons can print a prompt-string. */
@ -670,3 +757,4 @@ initialize ()
}
END_FILE